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