data_node_io.hpp
Go to the documentation of this file.00001 #ifndef s11n_DATA_NODE_IO_H_INCLUDED
00002 #define s11n_DATA_NODE_IO_H_INCLUDED
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <string>
00013 #include <sstream>
00014 #include <list>
00015 #include <map>
00016 #include <deque>
00017 #include <iostream>
00018 #include <memory>
00019
00020 #include <cassert>
00021 #include <typeinfo>
00022
00023
00024
00025
00026
00027 #include <s11n.net/s11n/phoenix.hpp>
00028
00029 #include <s11n.net/s11n/exception.hpp>
00030 #include <s11n.net/s11n/s11n_debuggering_macros.hpp>
00031 #include <s11n.net/s11n/classload.hpp>
00032 #include <s11n.net/s11n/serialize.hpp>
00033 #include <s11n.net/s11n/traits.hpp>
00034
00035 #include <s11n.net/s11n/export.hpp>
00036
00037
00038
00039
00040
00041
00042 #define s11n_SERIALIZER_ENABLE_INTERACTIVE 0
00043
00044 namespace s11n {
00045
00046 namespace io {
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 std::ostream * get_ostream( const std::string name );
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 std::istream * get_istream( const std::string name, bool ExternalData = true );
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 std::string get_magic_cookie( const std::string & src, bool ExternalData = true );
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 std::string get_magic_cookie( std::istream & is );
00107
00108 #if s11n_SERIALIZER_ENABLE_INTERACTIVE
00109 struct progress_reporter
00110 {
00111 progress_reporter() {}
00112 virtual ~progress_reporter() {}
00113 virtual void operator()( size_t pos, size_t total ) = 0;
00114 };
00115 #endif // s11n_SERIALIZER_ENABLE_INTERACTIVE
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 template <typename NodeT>
00155 class S11N_EXPORT_API data_node_serializer
00156 {
00157 public:
00158
00159
00160
00161
00162 typedef NodeT node_type;
00163
00164
00165 data_node_serializer()
00166 {
00167 this->magic_cookie( "WARNING: magic_cookie() not set!" );
00168
00169 typedef ::s11n::node_traits<node_type> NTR;
00170 NTR::name( this->metadata(), "serializer_metadata" );
00171
00172 using namespace s11n::debug;
00173 S11N_TRACE(TRACE_CTOR) << "data_node_serialier()\n";
00174
00175 };
00176 virtual ~data_node_serializer()
00177 {
00178 using namespace s11n::debug;
00179 S11N_TRACE(TRACE_DTOR) << "~data_node_serialier() ["<<this->magic_cookie()<<"]\n";
00180 }
00181
00182
00183
00184
00185
00186 typedef std::map<std::string,std::string> translation_map;
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 virtual const translation_map & entity_translations() const
00202 {
00203 typedef ::s11n::Detail::phoenix<translation_map,data_node_serializer<node_type> > TMap;
00204 return TMap::instance();
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 virtual bool serialize( const node_type & , std::ostream & )
00221 {
00222 return false;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 virtual bool serialize( const node_type & src, const std::string & destfile )
00251 {
00252 if( destfile.empty() ) return false;
00253 std::auto_ptr<std::ostream> os( ::s11n::io::get_ostream( destfile ) );
00254 if( ! os.get() ) return false;
00255 bool b = this->serialize( src, *os );
00256 return b;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 virtual node_type * deserialize( std::istream & )
00281 {
00282 return 0;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 virtual node_type * deserialize( const std::string & src )
00297 {
00298 typedef std::auto_ptr<std::istream> AP;
00299 AP is = AP( ::s11n::io::get_istream( src ) );
00300 if( ! is.get() ) return 0;
00301 return this->deserialize( *is );
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 std::string magic_cookie() const
00313 {
00314 return this->m_cookie;
00315 }
00316
00317
00318 #if s11n_SERIALIZER_ENABLE_INTERACTIVE
00319 bool is_cancelled() const { return m_cancelled; }
00320 void cancel() { this->m_cancelled = true; }
00321
00322 node_type * deserialize( std::string const & src, progress_reporter & p )
00323 {
00324 this->m_prog = &p;
00325 node_type * n = 0;
00326 try
00327 {
00328 n = this->deserialize( src );
00329 this->m_prog = 0;
00330 }
00331 catch(...)
00332 {
00333 this->m_prog = 0;
00334 throw;
00335 }
00336 return n;
00337 }
00338
00339 node_type * deserialize( std::istream & src, progress_reporter & p )
00340 {
00341 this->m_prog = &p;
00342 node_type * n = 0;
00343 try
00344 {
00345 n = this->deserialize( src );
00346 this->m_prog = 0;
00347 }
00348 catch(...)
00349 {
00350 this->m_prog = 0;
00351 throw;
00352 }
00353 return n;
00354 }
00355
00356 bool serialize( const node_type & src, std::ostream & dest, progress_reporter & p )
00357 {
00358 this->m_prog = &p;
00359 bool b = false;
00360 try
00361 {
00362 b = this->serialize( src, dest );
00363 this->m_prog = 0;
00364 }
00365 catch(...)
00366 {
00367 this->m_prog = 0;
00368 throw;
00369 }
00370 return b;
00371 }
00372
00373 bool serialize( const node_type & src, std::string const & dest, progress_reporter & p )
00374 {
00375 this->m_prog = &p;
00376 bool b = false;
00377 try
00378 {
00379 b = this->serialize( src, dest );
00380 this->m_prog = 0;
00381 }
00382 catch(...)
00383 {
00384 this->m_prog = 0;
00385 throw;
00386 }
00387 return b;
00388 }
00389 #endif // s11n_SERIALIZER_ENABLE_INTERACTIVE
00390
00391 protected:
00392
00393
00394
00395 void magic_cookie( const std::string & c )
00396 {
00397 this->m_cookie = c;
00398 }
00399
00400
00401
00402
00403
00404
00405
00406 node_type & metadata()
00407 { return this->m_meta; }
00408
00409
00410
00411 const node_type & metadata() const
00412 { return this->m_meta;}
00413
00414 #if s11n_SERIALIZER_ENABLE_INTERACTIVE
00415 void progress( size_t pos, size_t total )
00416 {
00417 if( this->m_prog )
00418 {
00419 this->m_prog->operator()( pos, total );
00420 }
00421 }
00422 void clear_cancel() { this->m_cancelled = false; }
00423 void assert_not_cancelled()
00424 {
00425 if( this->is_cancelled() )
00426 {
00427 throw ::s11n::s11n_exception("Serializer operation was cancelled.");
00428 }
00429 }
00430 #endif // s11n_SERIALIZER_ENABLE_INTERACTIVE
00431
00432 private:
00433 std::string m_cookie;
00434 node_type m_meta;
00435 #if s11n_SERIALIZER_ENABLE_INTERACTIVE
00436 bool m_cancelled;
00437 progress_reporter * m_prog;
00438 #endif
00439 };
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 template <typename NodeType>
00473 data_node_serializer<NodeType> * guess_serializer( std::istream & is )
00474 {
00475 typedef data_node_serializer<NodeType> ST;
00476 ST * ser = 0;
00477 std::string cookie;
00478
00479 cookie = get_magic_cookie( is );
00480 if( cookie.empty() ) return 0;
00481 std::string opencmd = "#s11n::io::serializer ";
00482 std::string::size_type at = cookie.find( opencmd );
00483 if( std::string::npos == at )
00484 {
00485 opencmd = "#!/s11n/io/serializer ";
00486 at = cookie.find( opencmd );
00487 }
00488
00489 if( 0 == at )
00490 {
00491 std::string dll = cookie.substr( opencmd.size() );
00492 ser = ::s11n::cl::classload<ST>( dll );
00493 }
00494 else
00495 {
00496 ser = ::s11n::cl::classload<ST>( cookie );
00497 }
00498 return ser;
00499 }
00500
00501
00502
00503
00504
00505
00506 template <typename NodeType>
00507 data_node_serializer<NodeType> * guess_serializer( std::string const & infile )
00508 {
00509 std::auto_ptr<std::istream> is( get_istream( infile.c_str() ) );
00510 return is.get()
00511 ? guess_serializer<NodeType>( *is )
00512 : 0;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 template <typename NodeType>
00534 NodeType *
00535 load_node_classload_serializer( std::istream & is )
00536 {
00537 try
00538 {
00539 typedef data_node_serializer<NodeType> ST;
00540 std::auto_ptr<ST> ser( guess_serializer<NodeType>( is ) );
00541 return ser.get()
00542 ? ser->deserialize( is )
00543 : 0;
00544 }
00545 catch( const s11n_exception & sex )
00546 {
00547 throw sex;
00548 }
00549 catch( const std::exception & ex )
00550 {
00551 throw ::s11n::io_exception( "%s:%d: forwarded exception: %s",
00552 __FILE__, __LINE__, ex.what() );
00553 }
00554 catch( ... )
00555 {
00556 throw ::s11n::io_exception( "%s:%d: Stream-level deserialization failed for unknown reason.",
00557 __FILE__, __LINE__ );
00558 }
00559 return 0;
00560 }
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 template <typename NodeType>
00572 NodeType *
00573 load_node_classload_serializer( std::string const & src )
00574 {
00575 try
00576 {
00577 typedef data_node_serializer<NodeType> ST;
00578 std::auto_ptr<ST> ser( guess_serializer<NodeType>( src ) );
00579 return ser.get()
00580 ? ser->deserialize( src )
00581 : 0;
00582 }
00583 catch( const s11n_exception & sex )
00584 {
00585 throw sex;
00586 }
00587 catch( const std::exception & ex )
00588 {
00589 throw ::s11n::io_exception( "%s:%d: forwarded exception: %s",
00590 __FILE__, __LINE__, ex.what() );
00591 }
00592 catch( ... )
00593 {
00594 throw ::s11n::io_exception( "%s:%d: Stream-level deserialization failed for unknown reason.",
00595 __FILE__, __LINE__ );
00596 }
00597 return 0;
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608 template <typename NodeType>
00609 NodeType * load_node( std::istream & is )
00610 {
00611 return load_node_classload_serializer< NodeType >( is );
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 template <typename NodeType>
00635 NodeType * load_node( const std::string & src, bool ExternalData = true )
00636 {
00637 if( ! ExternalData )
00638 {
00639 typedef std::auto_ptr<std::istream> AP;
00640 AP is( ::s11n::io::get_istream( src, ExternalData ) );
00641 if( ! is.get() ) return 0;
00642 return load_node<NodeType>( *is );
00643 }
00644 return load_node_classload_serializer<NodeType>( src );
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 template <typename NodeT,typename SerializableT>
00656 SerializableT * load_serializable( std::istream & src )
00657 {
00658 typedef std::auto_ptr<NodeT> AP;
00659 AP node( load_node<NodeT>( src ) );
00660 if( ! node.get() )
00661 {
00662 CERR << "load_serializable<>(istream) Could not load a root node from the input.\n";
00663 return 0;
00664 }
00665 return ::s11n::deserialize<NodeT,SerializableT>( *node );
00666 }
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 template <typename NodeT,typename SerializableT>
00682 SerializableT * load_serializable( const std::string & src, bool ExternalData = true )
00683 {
00684 if( ! ExternalData )
00685 {
00686 typedef std::auto_ptr<std::istream> AP;
00687 AP is( ::s11n::io::get_istream( src, ExternalData ) );
00688 if( ! is.get() )
00689 {
00690
00691 return 0;
00692 }
00693 return load_serializable<NodeT,SerializableT>( *is );
00694 }
00695 typedef std::auto_ptr<NodeT> AP;
00696 AP node( load_node<NodeT>( src ) );
00697 if( ! node.get() )
00698 {
00699
00700 return 0;
00701 }
00702 return ::s11n::deserialize<NodeT,SerializableT>( *node );
00703 }
00704
00705 }
00706
00707 }
00708
00709 #endif // s11n_DATA_NODE_IO_H_INCLUDED