00001 #ifndef s11n_DATA_NODE_FORMAT_H_INCLUDED
00002 #define s11n_DATA_NODE_FORMAT_H_INCLUDED
00003
00004 // data_node_format.hpp
00005
00006
00007
00008
00009
00010
00011
00012 #include <string>
00013 #include <list>
00014 #include <map>
00015 #include <stdexcept>
00016
00017 #include <s11n.net/s11n/s11n_debuggering_macros.hpp>
00018 #include <s11n.net/s11n/phoenix.hpp>
00019 #include <s11n.net/s11n/io/strtool.hpp>
00020 #include <s11n.net/s11n/classload.hpp>
00021
00022 #include <s11n.net/s11n/algo.hpp>
00023 #include <s11n.net/s11n/memory.hpp>
00024 #include <s11n.net/s11n/serialize.hpp>
00025
00026 #include <s11n.net/s11n/traits.hpp>
00027 #include <s11n.net/s11n/io/data_node_io.hpp>
00028
00029
00030
00031
00032
00033 #include <s11n.net/s11n/io/FlexLexer.hpp>
00034
00035
00036
00037 namespace s11n {
00038 namespace io {
00039
00040 namespace Private {
00041
00042
00043
00044
00045
00046
00047
00048
00049 int lex_api_hider_yylex( FlexLexer *, std::istream & );
00050
00051 }
00052
00053
00054
00055
00056
00057 typedef std::map<std::string,std::string> entity_translation_map;
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 class tree_builder
00074 {
00075 public:
00076 tree_builder() : m_autodel(true) {}
00077
00078 virtual ~tree_builder() {}
00079
00080
00081
00082
00083
00084
00085
00086 virtual bool
00087 open_node( const std::string & classname, const std::string & nodename ) = 0;
00088
00089
00090
00091
00092
00093
00094 virtual bool
00095 close_node() = 0;
00096
00097
00098
00099
00100
00101
00102 virtual bool
00103 add_property( const std::string & key, const std::string & val ) = 0;
00104
00105
00106
00107
00108
00109 virtual size_t node_depth() const = 0;
00110
00111
00112
00113
00114
00115
00116 virtual bool change_node_class( const std::string & newclassname ) = 0;
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 void auto_delete( bool b )
00127 {
00128 this->m_autodel = b;
00129 }
00130
00131
00132
00133
00134 bool auto_delete() const
00135 {
00136 return this->m_autodel;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146 virtual void reset()
00147 {
00148 }
00149
00150 private:
00151 bool m_autodel;
00152
00153 };
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 template <typename ContextT>
00183 class tree_builder_context
00184 {
00185 public:
00186
00187 typedef ContextT context_type;
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 static void bind( const FlexLexer * lexer, tree_builder * builder )
00210 {
00211 lmap()[lexer].builder = builder;
00212 }
00213
00214
00215
00216
00217
00218 static void unbind( const FlexLexer * lexer )
00219 {
00220 lmap().erase( lexer );
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 static tree_builder * builder( const FlexLexer * lexer )
00232 {
00233 return lmap()[lexer].builder;
00234 }
00235
00236
00237 #define IFNOLEXER(RET) if( lmap().end() == lmap().find(lexer) ) return RET;
00238
00239
00240
00241 static bool open_node( const FlexLexer * lexer,
00242 const std::string & classname,
00243 const std::string & nodename )
00244 {
00245 IFNOLEXER(false);
00246 return lmap()[lexer].builder->open_node( classname, nodename );
00247 }
00248
00249
00250
00251
00252 static bool close_node( const FlexLexer * lexer )
00253 {
00254 IFNOLEXER(false);
00255 return lmap()[lexer].builder->close_node();
00256 }
00257
00258
00259
00260
00261 static bool
00262 add_property( const FlexLexer * lexer,
00263 const std::string & key,
00264 const std::string & val )
00265 {
00266 IFNOLEXER(false);
00267 return lmap()[lexer].builder->add_property( key, val );
00268 }
00269
00270
00271
00272
00273 static size_t node_depth( const FlexLexer * lexer )
00274 {
00275 IFNOLEXER(0);
00276 return lmap()[lexer].builder->node_depth();
00277 }
00278
00279
00280
00281
00282 static bool change_node_class( const FlexLexer * lexer,
00283 const std::string & newclassname )
00284 {
00285 IFNOLEXER(false);
00286 return lmap()[lexer].builder->change_node_class( newclassname );
00287 }
00288 #undef IFNOLEXER
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 struct lexer_metadata
00300 {
00301 tree_builder * builder;
00302
00303 size_t internaldepth;
00304 std::string nodename;
00305 std::string nodeclass;
00306 std::string property;
00307 std::string bufferyy;
00308 lexer_metadata()
00309 {
00310 builder = 0;
00311 internaldepth = 0;
00312 nodename = nodeclass = property = bufferyy = "";
00313 }
00314 };
00315
00316
00317
00318
00319
00320
00321 static lexer_metadata & metadata( const FlexLexer * lexer )
00322 {
00323 return lmap()[lexer];
00324 }
00325
00326 private:
00327
00328 typedef tree_builder_context<context_type> this_type;
00329
00330 typedef std::map<const FlexLexer *,lexer_metadata> lexer_map;
00331 static lexer_map & lmap()
00332 {
00333 return ::s11n::Detail::phoenix<
00334 lexer_map,
00335 this_type
00336 >::instance();
00337 }
00338
00339 };
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 template <typename NodeType>
00361 class data_node_tree_builder : public tree_builder
00362 {
00363 public:
00364 typedef NodeType node_type;
00365
00366 typedef std::list< node_type * > child_list_type;
00367
00368
00369 data_node_tree_builder() : m_node_count(0), m_node(0),m_root(0)
00370 {
00371 }
00372
00373
00374
00375
00376
00377 virtual ~data_node_tree_builder()
00378 {
00379 if( this->auto_delete() && this->m_root )
00380 {
00381
00382 delete( this->m_root );
00383 }
00384 else
00385 {
00386
00387 }
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 bool open_node( const std::string & classname, const std::string & nodename )
00408 {
00409 ++m_node_count;
00410
00411 this->m_node = ( this->m_nodestack.empty()
00412 ? 0
00413 : this->m_nodestack.back() );
00414 typedef ::s11n::node_traits<node_type> NTR;
00415 node_type * newnode = new node_type();
00416 if ( m_node )
00417 {
00418 NTR::children( *m_node ).push_back( newnode );
00419 }
00420 this->m_node = newnode;
00421 NTR::name( *m_node, nodename );
00422 NTR::class_name( *m_node, classname );
00423 this->m_nodestack.push_back( m_node );
00424 bool ret = true;
00425 if ( 1 == this->m_nodestack.size() )
00426 {
00427 if( m_root )
00428 {
00429 CERR << "open_node("<<classname<<","<<nodename<<") WARNING: deleting extra root node!\n";
00430 delete( m_node );
00431 m_node = 0;
00432 ret = false;
00433 }
00434 else
00435 {
00436 m_root = m_node;
00437 }
00438 }
00439 return ret;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 virtual bool close_node()
00452 {
00453 if ( !m_node || m_nodestack.empty() )
00454 {
00455 CERR << "close_node() error: called with an empty node stack!" << std::endl;
00456 return false;
00457 }
00458 m_nodestack.pop_back();
00459 if ( m_nodestack.empty() )
00460 {
00461 m_node = NULL;
00462 }
00463 else
00464 {
00465 m_node = m_nodestack.back();
00466 }
00467 return true;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476 virtual bool add_property( const std::string & key, const std::string & val )
00477 {
00478 if( ! this->m_node ) return false;
00479 typedef ::s11n::node_traits<node_type> NTR;
00480 NTR::set( *m_node, key, val );
00481 return true;
00482 }
00483
00484
00485
00486
00487 size_t node_count() const
00488 {
00489 return m_node_count;
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499 size_t node_depth() const
00500 {
00501 return m_nodestack.size();
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 node_type * root_node() const
00513 {
00514 return m_root;
00515 }
00516
00517
00518
00519
00520
00521
00522
00523
00524 node_type * current_node() const
00525 {
00526 return m_node;
00527 }
00528
00529
00530
00531
00532
00533
00534 virtual bool change_node_class( const std::string & newclassname )
00535 {
00536 if( ! this->m_node ) return false;
00537 typedef ::s11n::node_traits<node_type> NTR;
00538 NTR::class_name( *(this->m_node), newclassname );
00539 return true;
00540 }
00541
00542
00543
00544
00545
00546
00547 virtual void reset()
00548 {
00549 if( this->auto_delete() && this->m_root ) delete this->m_root;
00550 this->m_root = 0;
00551
00552 this->m_node = 0;
00553 this->m_node_count = 0;
00554 this->m_nodestack = node_stack();
00555 }
00556
00557 private:
00558 size_t m_node_count;
00559 node_type * m_node;
00560 node_type * m_root;
00561 typedef std::deque < node_type * > node_stack;
00562 node_stack m_nodestack;
00563 };
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 template <typename NodeType, typename BuilderContext>
00594 NodeType * deserialize_lex_forwarder( const std::string & lexerClassName,
00595 std::istream & src
00596 )
00597 {
00598
00599 s11n::Detail::auto_ptr<FlexLexer> lexer( ::s11n::cl::classload<FlexLexer>( lexerClassName ) );
00600 if( ! lexer.get() )
00601 {
00602 throw ::s11n::s11n_exception(
00603 "%s:%d: s11n::io::deserialize_lex_forwarder(): Lexer '%s' was not found by classload<FlexLexer>(). It is probably not registered with the classloader.",
00604 __FILE__,
00605 __LINE__,
00606 lexerClassName.c_str() );
00607 }
00608
00609 typedef s11n::io::data_node_tree_builder<NodeType> BuilderType;
00610 typedef tree_builder_context<BuilderContext> BC;
00611 s11n::Detail::auto_ptr<BuilderType> treebuilder( new BuilderType );
00612 treebuilder->auto_delete( true );
00613 try
00614 {
00615 BC::bind( lexer.get(), treebuilder.get() );
00616
00617 Private::lex_api_hider_yylex(lexer.get(),src);
00618 }
00619 catch ( const std::exception & ex )
00620 {
00621 BC::unbind( lexer.get() );
00622 throw ex;
00623 }
00624 catch (...)
00625 {
00626 BC::unbind( lexer.get() );
00627 throw;
00628 }
00629 BC::unbind( lexer.get() );
00630 treebuilder->auto_delete( false );
00631 return treebuilder->root_node();
00632 }
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 template <typename NodeType, typename LexerSharingContext>
00646 class tree_builder_lexer : public data_node_serializer<NodeType>
00647 {
00648 public:
00649
00650 typedef NodeType node_type;
00651 typedef LexerSharingContext sharing_context;
00652 typedef data_node_serializer<NodeType> parent_type;
00653
00654
00655
00656
00657
00658 explicit tree_builder_lexer( const std::string & lexerClassName )
00659 : m_impl(lexerClassName)
00660 {}
00661
00662 virtual ~tree_builder_lexer(){}
00663
00664
00665
00666
00667
00668
00669 virtual node_type * deserialize( std::istream & src )
00670 {
00671 return deserialize_lex_forwarder<
00672 node_type,
00673 sharing_context
00674 >( this->lexer_class(), src );
00675 }
00676
00677 virtual node_type * deserialize( const std::string & src )
00678 {
00679
00680
00681 return this->parent_type::deserialize( src );
00682 }
00683
00684
00685
00686
00687
00688 std::string lexer_class() const { return this->m_impl; }
00689
00690
00691 protected:
00692
00693
00694
00695 void lexer_class( const std::string & classname )
00696 {
00697 this->m_impl = classname;
00698 }
00699
00700 private:
00701 std::string m_impl;
00702 };
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 template <typename NodeType>
00717 class key_value_serializer
00718 {
00719 public:
00720 typedef NodeType node_type;
00721 typedef typename node_type::value_type pair_type;
00722
00723 typedef std::map<std::string,std::string> entity_translation_map;
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 key_value_serializer( const entity_translation_map * map,
00741 std::ostream & dest,
00742 const std::string & prefix,
00743 const std::string & separator,
00744 const std::string & suffix
00745 )
00746 : m_pre(prefix), m_sep(separator), m_suf(suffix), m_os(dest), m_map(map)
00747 {
00748 }
00749
00750
00751
00752
00753
00754
00755
00756 void operator()( const pair_type & src ) const
00757 {
00758 static const std::string errval = "";
00759 std::string key = strtool::to( src.first );
00760 std::string val = strtool::to( src.second );
00761
00762 if( this->m_map )
00763 {
00764 strtool::translate_entities( val, *(this->m_map) );
00765 }
00766 this->m_os << this->m_pre;
00767 this->m_os << key;
00768 this->m_os << this->m_sep;
00769 this->m_os << val;
00770 this->m_os << this->m_suf;
00771 }
00772 private:
00773 std::string m_pre;
00774 std::string m_sep;
00775 std::string m_suf;
00776 std::ostream & m_os;
00777 const entity_translation_map * m_map;
00778 };
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794 template <typename SerializerT>
00795 struct node_child_simple_formatter
00796 {
00797 typedef SerializerT serializer_type;
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810 node_child_simple_formatter( serializer_type & ser, std::ostream & os,
00811 const std::string & prefix = "", const std::string & suffix = "\n" )
00812 : m_ser(ser), m_os(&os), m_pre(prefix), m_suf(suffix)
00813 {
00814 }
00815
00816
00817
00818
00819
00820 template <typename NodeType>
00821 bool operator()( const NodeType * src ) const
00822 {
00823 if( ! src ) return false;
00824 if( ! this->m_pre.empty() ) *(this->m_os) << this->m_pre;
00825 bool b = this->m_ser.serialize( *src, *(this->m_os) );
00826 if( ! this->m_suf.empty() ) *(this->m_os) << this->m_suf;
00827 return b;
00828 }
00829
00830 private:
00831 serializer_type & m_ser;
00832 std::ostream * m_os;
00833 std::string m_pre;
00834 std::string m_suf;
00835 };
00836
00837
00838
00839 }
00840 }
00841
00842
00843 #include <s11n.net/s11n/factory.hpp>
00844 #define S11N_FACREG_TYPE s11n::io::tree_builder
00845 #define S11N_FACREG_TYPE_NAME "s11n::io::tree_builder"
00846 #define S11N_FACREG_TYPE_IS_ABSTRACT 1
00847 #include <s11n.net/s11n/factory_reg.hpp>
00848
00849 #endif // s11n_DATA_NODE_FORMAT_H_INCLUDED