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 };
00173 virtual ~data_node_serializer(){};
00174
00175
00176
00177
00178
00179 typedef std::map<std::string,std::string> translation_map;
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 virtual const translation_map & entity_translations() const
00195 {
00196 typedef ::s11n::Detail::phoenix<translation_map,data_node_serializer<node_type> > TMap;
00197 return TMap::instance();
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 virtual bool serialize( const node_type & , std::ostream & )
00214 {
00215 return false;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 virtual bool serialize( const node_type & src, const std::string & destfile )
00241 {
00242 if( destfile.empty() ) return false;
00243 std::ostream * os = ::s11n::io::get_ostream( destfile );
00244 if( ! os ) return false;
00245 bool b = this->serialize( src, *os );
00246 delete( os );
00247 return b;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 virtual node_type * deserialize( std::istream & )
00272 {
00273 return 0;
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 virtual node_type * deserialize( const std::string & src )
00288 {
00289 typedef std::auto_ptr<std::istream> AP;
00290 AP is = AP( ::s11n::io::get_istream( src ) );
00291 if( ! is.get() ) return 0;
00292 return this->deserialize( *is );
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 std::string magic_cookie() const
00304 {
00305 return this->m_cookie;
00306 }
00307
00308
00309 #if s11n_SERIALIZER_ENABLE_INTERACTIVE
00310 bool is_cancelled() const { return m_cancelled; }
00311 void cancel() { this->m_cancelled = true; }
00312
00313 node_type * deserialize( std::string const & src, progress_reporter & p )
00314 {
00315 this->m_prog = &p;
00316 node_type * n = 0;
00317 try
00318 {
00319 n = this->deserialize( src );
00320 this->m_prog = 0;
00321 }
00322 catch(...)
00323 {
00324 this->m_prog = 0;
00325 throw;
00326 }
00327 return n;
00328 }
00329
00330 node_type * deserialize( std::istream & src, progress_reporter & p )
00331 {
00332 this->m_prog = &p;
00333 node_type * n = 0;
00334 try
00335 {
00336 n = this->deserialize( src );
00337 this->m_prog = 0;
00338 }
00339 catch(...)
00340 {
00341 this->m_prog = 0;
00342 throw;
00343 }
00344 return n;
00345 }
00346
00347 bool serialize( const node_type & src, std::ostream & dest, progress_reporter & p )
00348 {
00349 this->m_prog = &p;
00350 bool b = false;
00351 try
00352 {
00353 b = this->serialize( src, dest );
00354 this->m_prog = 0;
00355 }
00356 catch(...)
00357 {
00358 this->m_prog = 0;
00359 throw;
00360 }
00361 return b;
00362 }
00363
00364 bool serialize( const node_type & src, std::string const & dest, progress_reporter & p )
00365 {
00366 this->m_prog = &p;
00367 bool b = false;
00368 try
00369 {
00370 b = this->serialize( src, dest );
00371 this->m_prog = 0;
00372 }
00373 catch(...)
00374 {
00375 this->m_prog = 0;
00376 throw;
00377 }
00378 return b;
00379 }
00380 #endif // s11n_SERIALIZER_ENABLE_INTERACTIVE
00381
00382 protected:
00383
00384
00385
00386 void magic_cookie( const std::string & c )
00387 {
00388 this->m_cookie = c;
00389 }
00390
00391
00392
00393
00394
00395
00396
00397 node_type & metadata()
00398 { return this->m_meta; }
00399
00400
00401
00402 const node_type & metadata() const
00403 { return this->m_meta;}
00404
00405 #if s11n_SERIALIZER_ENABLE_INTERACTIVE
00406 void progress( size_t pos, size_t total )
00407 {
00408 if( this->m_prog )
00409 {
00410 this->m_prog->operator()( pos, total );
00411 }
00412 }
00413 void clear_cancel() { this->m_cancelled = false; }
00414 void assert_not_cancelled()
00415 {
00416 if( this->is_cancelled() )
00417 {
00418 throw ::s11n::s11n_exception("Serializer operation was cancelled.");
00419 }
00420 }
00421 #endif // s11n_SERIALIZER_ENABLE_INTERACTIVE
00422
00423 private:
00424 std::string m_cookie;
00425 node_type m_meta;
00426 #if s11n_SERIALIZER_ENABLE_INTERACTIVE
00427 bool m_cancelled;
00428 progress_reporter * m_prog;
00429 #endif
00430 };
00431
00432
00433
00434
00435
00436
00437
00438
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 template <typename NodeType>
00464 data_node_serializer<NodeType> * guess_serializer( std::istream & is )
00465 {
00466 typedef data_node_serializer<NodeType> ST;
00467 ST * ser = 0;
00468 std::string cookie;
00469
00470 cookie = get_magic_cookie( is );
00471 if( cookie.empty() ) return 0;
00472 std::string opencmd = "#s11n::io::serializer ";
00473 std::string::size_type at = cookie.find( opencmd );
00474 if( std::string::npos == at )
00475 {
00476 opencmd = "#!/s11n/io/serializer ";
00477 at = cookie.find( opencmd );
00478 }
00479
00480 if( 0 == at )
00481 {
00482 std::string dll = cookie.substr( opencmd.size() );
00483 ser = ::s11n::cl::classload<ST>( dll );
00484 }
00485 else
00486 {
00487 ser = ::s11n::cl::classload<ST>( cookie );
00488 }
00489 return ser;
00490 }
00491
00492
00493
00494
00495
00496
00497 template <typename NodeType>
00498 data_node_serializer<NodeType> * guess_serializer( std::string const & infile )
00499 {
00500 std::auto_ptr<std::istream> is( get_istream( infile.c_str() ) );
00501 return is.get()
00502 ? guess_serializer<NodeType>( *is )
00503 : 0;
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 template <typename NodeType>
00525 NodeType *
00526 load_node_classload_serializer( std::istream & is )
00527 {
00528 try
00529 {
00530 typedef data_node_serializer<NodeType> ST;
00531 std::auto_ptr<ST> ser( guess_serializer<NodeType>( is ) );
00532 return ser.get()
00533 ? ser->deserialize( is )
00534 : 0;
00535 }
00536 catch( const s11n_exception & sex )
00537 {
00538 throw sex;
00539 }
00540 catch( const std::exception & ex )
00541 {
00542 throw ::s11n::io_exception( ex.what(), __FILE__, __LINE__ );
00543 }
00544 catch( ... )
00545 {
00546 throw ::s11n::io_exception( std::string("Stream-level deserialization failed for unknown reason."),
00547 __FILE__, __LINE__ );
00548 }
00549 return 0;
00550 }
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 template <typename NodeType>
00562 NodeType *
00563 load_node_classload_serializer( std::string const & src )
00564 {
00565 typedef data_node_serializer<NodeType> ST;
00566 ST * ser = guess_serializer<NodeType>( src );
00567 if( ! ser ) return 0;
00568 try
00569 {
00570 return ser->deserialize( src );
00571 }
00572 catch( const s11n_exception & sex )
00573 {
00574 throw sex;
00575 }
00576 catch( const std::exception & ex )
00577 {
00578 throw ::s11n::io_exception( ex.what(), __FILE__, __LINE__ );
00579 }
00580 catch( ... )
00581 {
00582 throw ::s11n::io_exception( std::string("Stream-level deserialization failed for unknown reason."),
00583 __FILE__, __LINE__ );
00584 }
00585 return 0;
00586 }
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 template <typename NodeType>
00597 NodeType * load_node( std::istream & is )
00598 {
00599 return load_node_classload_serializer< NodeType >( is );
00600 }
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 template <typename NodeType>
00623 NodeType * load_node( const std::string & src, bool ExternalData = true )
00624 {
00625 if( ! ExternalData )
00626 {
00627 typedef std::auto_ptr<std::istream> AP;
00628 AP is( ::s11n::io::get_istream( src, ExternalData ) );
00629 if( ! is.get() ) return 0;
00630 return load_node<NodeType>( *is );
00631 }
00632 return load_node_classload_serializer<NodeType>( src );
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643 template <typename NodeT,typename SerializableT>
00644 SerializableT * load_serializable( std::istream & src )
00645 {
00646 typedef std::auto_ptr<NodeT> AP;
00647 AP node( load_node<NodeT>( src ) );
00648 if( ! node.get() )
00649 {
00650 CERR << "load_serializable<>(istream) Could not load a root node from the input.\n";
00651 return 0;
00652 }
00653 return ::s11n::deserialize<NodeT,SerializableT>( *node );
00654 }
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 template <typename NodeT,typename SerializableT>
00670 SerializableT * load_serializable( const std::string & src, bool ExternalData = true )
00671 {
00672 if( ! ExternalData )
00673 {
00674 typedef std::auto_ptr<std::istream> AP;
00675 AP is( ::s11n::io::get_istream( src, ExternalData ) );
00676 if( ! is.get() )
00677 {
00678
00679 return 0;
00680 }
00681 return load_serializable<NodeT,SerializableT>( *is );
00682 }
00683 typedef std::auto_ptr<NodeT> AP;
00684 AP node( load_node<NodeT>( src ) );
00685 if( ! node.get() )
00686 {
00687
00688 return 0;
00689 }
00690 return ::s11n::deserialize<NodeT,SerializableT>( *node );
00691 }
00692
00693 }
00694
00695 }
00696
00697 #endif // s11n_DATA_NODE_IO_H_INCLUDED