00001 #ifndef s11n_DATA_NODE_FORMAT_H_INCLUDED
00002 #define s11n_DATA_NODE_FORMAT_H_INCLUDED
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <string>
00013 #include <list>
00014 #include <map>
00015 #include <stdexcept>
00016
00017
00018
00019 #include <s11n/to_string.h>
00020 #include <s11n/debuggering_macros.h>
00021 #include <s11n/file_util.h>
00022 #include <s11n/string_util.h>
00023
00024
00025 #include <s11n/s11n_core.h>
00026
00027 #include "data_node_functor.h"
00028 #include "data_node_serialize.h"
00029 #include "data_node_io.h"
00030
00031
00032
00033
00034 #ifndef yyFlexLexer // aaarrrgggg!
00035 # include "FlexLexer.h"
00036 #endif
00037 s11n_CLASSLOADER_ABSTRACT_BASE(FlexLexer);
00038
00039
00040 namespace s11n {
00041 namespace io {
00042
00043 namespace Private {
00044
00045
00046
00047
00048
00049
00050
00051
00052 int lex_api_hider_yylex( FlexLexer *, std::istream & );
00053
00054 }
00055
00056
00057
00058
00059
00060 typedef std::map<std::string,std::string> entity_translation_map;
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 class tree_builder
00077 {
00078 public:
00079 tree_builder() : m_autodel(true) {}
00080
00081 virtual ~tree_builder() {}
00082
00083
00084
00085
00086
00087
00088
00089 virtual bool
00090 open_node( const std::string & classname, const std::string & nodename ) = 0;
00091
00092
00093
00094
00095
00096
00097 virtual bool
00098 close_node() = 0;
00099
00100
00101
00102
00103
00104
00105 virtual bool
00106 add_property( const std::string & key, const std::string & val ) = 0;
00107
00108
00109
00110
00111
00112 virtual size_t node_depth() const = 0;
00113
00114
00115
00116
00117
00118
00119 virtual bool change_node_class( const std::string & newclassname ) = 0;
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void auto_delete( bool b )
00130 {
00131 this->m_autodel = b;
00132 }
00133
00134
00135
00136
00137 bool auto_delete() const
00138 {
00139 return this->m_autodel;
00140 }
00141
00142
00143 private:
00144 bool m_autodel;
00145
00146 };
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 template <typename ContextT>
00176 class tree_builder_context
00177 {
00178 public:
00179
00180 typedef ContextT context_type;
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 static void bind( const FlexLexer * lexer, tree_builder * builder )
00203 {
00204 lmap()[lexer].builder = builder;
00205 }
00206
00207
00208
00209
00210
00211 static void unbind( const FlexLexer * lexer )
00212 {
00213 lmap().erase( lexer );
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 static tree_builder * builder( const FlexLexer * lexer )
00225 {
00226 return lmap()[lexer].builder;
00227 }
00228
00229
00230 #define IFNOLEXER(RET) if( lmap().end() == lmap().find(lexer) ) return RET;
00231
00232
00233
00234 static bool open_node( const FlexLexer * lexer,
00235 const std::string & classname,
00236 const std::string & nodename )
00237 {
00238 IFNOLEXER(false);
00239 return lmap()[lexer].builder->open_node( classname, nodename );
00240 }
00241
00242
00243
00244
00245 static bool close_node( const FlexLexer * lexer )
00246 {
00247 IFNOLEXER(false);
00248 return lmap()[lexer].builder->close_node();
00249 }
00250
00251
00252
00253
00254 static bool
00255 add_property( const FlexLexer * lexer,
00256 const std::string & key,
00257 const std::string & val )
00258 {
00259 IFNOLEXER(false);
00260 return lmap()[lexer].builder->add_property( key, val );
00261 }
00262
00263
00264
00265
00266 static size_t node_depth( const FlexLexer * lexer )
00267 {
00268 IFNOLEXER(0);
00269 return lmap()[lexer].builder->node_depth();
00270 }
00271
00272
00273
00274
00275 static bool change_node_class( const FlexLexer * lexer,
00276 const std::string & newclassname )
00277 {
00278 IFNOLEXER(false);
00279 return lmap()[lexer].builder->change_node_class( newclassname );
00280 }
00281 #undef IFNOLEXER
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 struct lexer_metadata
00293 {
00294 tree_builder * builder;
00295
00296 size_t internaldepth;
00297 std::string nodename;
00298 std::string nodeclass;
00299 std::string property;
00300 std::string bufferyy;
00301 lexer_metadata()
00302 {
00303 builder = 0;
00304 internaldepth = 0;
00305 nodename = nodeclass = property = bufferyy = "";
00306 }
00307 };
00308
00309
00310
00311
00312
00313
00314 static lexer_metadata & metadata( const FlexLexer * lexer )
00315 {
00316 return lmap()[lexer];
00317 }
00318
00319 private:
00320
00321 typedef tree_builder_context<context_type> this_type;
00322
00323 typedef std::map<const FlexLexer *,lexer_metadata> lexer_map;
00324 static lexer_map & lmap()
00325 {
00326 return s11n::phoenix<
00327 lexer_map,
00328 this_type
00329 >::instance();
00330 }
00331
00332 };
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 template <typename NodeType>
00354 class data_node_tree_builder : public tree_builder
00355 {
00356 public:
00357 typedef NodeType node_type;
00358
00359 typedef std::list< node_type * > child_list_type;
00360
00361
00362 data_node_tree_builder() : m_node_count(0), m_node(0),m_root(0)
00363 {
00364 }
00365
00366
00367
00368
00369
00370 virtual ~data_node_tree_builder()
00371 {
00372 if( this->auto_delete() && this->m_root )
00373 {
00374
00375 delete( this->m_root );
00376 }
00377 else
00378 {
00379
00380 }
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 bool open_node( const std::string & classname, const std::string & nodename )
00401 {
00402 ++m_node_count;
00403
00404 this->m_node = ( this->m_nodestack.empty()
00405 ? 0
00406 : this->m_nodestack.back() );
00407 node_type * newnode = new node_type();
00408 if ( m_node )
00409 {
00410 m_node->children().push_back( newnode );
00411 }
00412 this->m_node = newnode;
00413 m_node->name( nodename );
00414 m_node->impl_class( classname );
00415 this->m_nodestack.push_back( m_node );
00416 bool ret = true;
00417 if ( 1 == this->m_nodestack.size() )
00418 {
00419 if( m_root )
00420 {
00421 CERR << "open_node("<<classname<<","<<nodename<<") WARNING: deleting extra root node!\n";
00422 delete( m_node );
00423 ret = false;
00424 }
00425 else
00426 {
00427 m_root = m_node;
00428 }
00429 }
00430 return ret;
00431 }
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 virtual bool close_node()
00443 {
00444 if ( !m_node || m_nodestack.empty() )
00445 {
00446 CERR << "close_node() error: called with an empty node stack!" << std::endl;
00447 return false;
00448 }
00449 m_nodestack.pop_back();
00450 if ( m_nodestack.empty() )
00451 {
00452 m_node = NULL;
00453 }
00454 else
00455 {
00456 m_node = m_nodestack.back();
00457 }
00458 return true;
00459 }
00460
00461
00462
00463
00464
00465
00466
00467 virtual bool add_property( const std::string & key, const std::string & val )
00468 {
00469 if( ! this->m_node ) return false;
00470 this->m_node->set( key, val );
00471 return true;
00472 }
00473
00474
00475
00476
00477 size_t node_count() const
00478 {
00479 return m_node_count;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489 size_t node_depth() const
00490 {
00491 return m_nodestack.size();
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502 node_type * root_node() const
00503 {
00504 return m_root;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514 node_type * current_node() const
00515 {
00516 return m_node;
00517 }
00518
00519
00520
00521
00522
00523
00524 virtual bool change_node_class( const std::string & newclassname )
00525 {
00526 if( ! this->m_node ) return false;
00527 this->m_node->impl_class( newclassname );
00528 return true;
00529 }
00530
00531 private:
00532 size_t m_node_count;
00533 node_type * m_node;
00534 node_type * m_root;
00535 typedef std::deque < node_type * > node_stack;
00536 node_stack m_nodestack;
00537 };
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 template <typename NodeType, typename BuilderContext>
00561 NodeType * deserialize_lex_forwarder( const std::string & lexerClassName,
00562 std::istream & src
00563 )
00564 {
00565
00566 FlexLexer * lexer = s11n::classload<FlexLexer>( lexerClassName );
00567 if( ! lexer )
00568 {
00569 CERR << "Lexer '"<<lexerClassName
00570 <<"' was not found by classload<FlexLexer>()."
00571 << " It is probably not registered with class_loader<FlexLexer>.\n";
00572 return 0;
00573 }
00574
00575 typedef s11n::io::data_node_tree_builder<NodeType> BuilderType;
00576 typedef tree_builder_context<BuilderContext> BC;
00577
00578 NodeType * ret = 0;
00579 BuilderType * treebuilder = new BuilderType();
00580 treebuilder->auto_delete( false );
00581 bool err = false;
00582 try
00583 {
00584 BC::bind( lexer, treebuilder );
00585
00586
00587
00588
00589
00590 Private::lex_api_hider_yylex(lexer,src);
00591 }
00592 catch ( std::runtime_error & ex )
00593 {
00594 err = true;
00595 CERR << "deserialize_lex_forwarder(): Doh! Exception during lexing: " << ex.what() << "\n";
00596 }
00597 catch (...)
00598 {
00599 err = true;
00600 CERR << "deserialize_lex_forwarder(): Doh! Unknown exception during lexing:\n";
00601 }
00602 BC::unbind( lexer );
00603 delete( lexer );
00604 if( err )
00605 {
00606 treebuilder->auto_delete( true );
00607 }
00608 else
00609 {
00610 ret = treebuilder->root_node();
00611 }
00612
00613 delete( treebuilder );
00614 return ret;
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 template <typename NodeType, typename LexerSharingContext>
00630 class tree_builder_lexer : public data_node_serializer<NodeType>
00631 {
00632 public:
00633
00634 typedef NodeType node_type;
00635 typedef LexerSharingContext sharing_context;
00636
00637
00638
00639
00640
00641 explicit tree_builder_lexer( const std::string & lexerClassName )
00642 : m_impl(lexerClassName)
00643 {}
00644
00645 virtual ~tree_builder_lexer(){}
00646
00647
00648
00649
00650
00651
00652 virtual node_type * deserialize( std::istream & src )
00653 {
00654 return deserialize_lex_forwarder<
00655 node_type,
00656 sharing_context
00657 >( this->lexer_class(), src );
00658 }
00659
00660
00661
00662
00663
00664 std::string lexer_class() const { return this->m_impl; }
00665
00666
00667 protected:
00668
00669
00670
00671 void lexer_class( const std::string & classname )
00672 {
00673 this->m_impl = classname;
00674 }
00675
00676 private:
00677 std::string m_impl;
00678 };
00679
00680 }
00681 }
00682
00683 s11n_CLASSLOADER_ABSTRACT_BASE(s11n::io::tree_builder);
00684
00685 #endif // s11n_DATA_NODE_FORMAT_H_INCLUDED