00001
00002
00003
00004 #ifndef s11n_LIST_H_INCLUDED
00005 #define s11n_LIST_H_INCLUDED 1
00006
00007 #include <list>
00008 #include <iterator>
00009 #include <algorithm>
00010 #include <stdio.h>
00011
00012 #include <s11n/functor.h>
00013
00014 #include <s11n/data_node_serialize.h>
00015 #include <s11n/data_node_functor.h>
00016 #include <s11n/data_node_algo.h>
00017 #include <s11n/abstract_creator.h>
00018
00019 namespace s11n {
00020
00021
00022
00023
00024 namespace list {
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 template <typename NodeT, typename ListType>
00047 bool serialize_pointer_list( NodeT & dest,
00048 const std::string & subnodename,
00049 const ListType & src )
00050 {
00051 return std::for_each( src.begin(),
00052 src.end(),
00053 s11n::data_node_child_serializer<NodeT>( dest, subnodename )
00054 ).result;
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 template <typename NodeT, typename ListType>
00075 bool deserialize_pointer_list( const NodeT & src,
00076 const std::string & subnodename,
00077 ListType & dest )
00078 {
00079
00080 typedef std::list<const NodeT *> MatchList;
00081 MatchList li;
00082 s11n::copy_if( src.children().begin(),
00083 src.children().end(),
00084 std::insert_iterator<MatchList>( li, li.begin() ),
00085 s11n::same_name<NodeT>( subnodename )
00086 );
00087
00088 if( ! li.size() ) return false;
00089 bool b = std::for_each( li.begin(),
00090 li.end(),
00091 s11n::data_node_child_deserializer<ListType>( dest )
00092 ).result;
00093
00094 return b;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 template <typename NodeType, typename SerType>
00134 bool serialize_list( NodeType & dest, const SerType & src )
00135 {
00136 dest.impl_class( class_name<SerType>::name() );
00137 typename SerType::const_iterator it = src.begin();
00138
00139
00140
00141 for( ; src.end() != it; ++it )
00142 {
00143 NodeType * ch = new NodeType;
00144 if( ! serialize( *ch, *it ) )
00145 {
00146 CERR << "serialize_list: a child failed to serialize: " << ch->name() << " @ " << std::hex << ch << "\n";
00147 s11n::dump_node_debug( *ch, std::cerr );
00148 delete( ch );
00149 return false;
00150 }
00151 dest.children().push_back( ch );
00152 }
00153 return true;
00154 }
00155
00156
00157
00158
00159
00160 template <typename NodeType, typename SerType>
00161 bool serialize_list( NodeType & dest,
00162 const std::string & subnodename,
00163 const SerType & src )
00164 {
00165 NodeType * ch = new NodeType;
00166 if( ! serialize_list<NodeType,SerType>( *ch, src ) )
00167 {
00168 delete( ch );
00169 return false;
00170 }
00171 dest.children().push_back( ch );
00172 return true;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 template <typename NodeType, typename SerType>
00196 bool deserialize_list( const NodeType & src, SerType & dest )
00197 {
00198
00199
00200 typedef typename SerType::value_type VT;
00201 typedef s11n::abstract_creator<VT> ACVT;
00202 typedef typename NodeType::child_list_type::const_iterator CHIT;
00203 const NodeType * nch = 0;
00204 CHIT it = src.children().begin();
00205 CHIT et = src.children().end();
00206 s11n::object_reference_wrapper<SerType> dwrap(dest);
00207 VT ser;
00208 for( ; et != it; ++it )
00209 {
00210 nch = *it;
00211 if( ! ACVT::create( ser,nch->impl_class() ) )
00212 {
00213 CERR << "Internal error: abstract_creator<> "
00214 << "could not create a new object of type '"
00215 << nch->impl_class()<<"'!\n";
00216 return false;
00217 }
00218 if( ! deserialize( *nch, ser ) )
00219 {
00220 CERR << "deserialize_list(): deser of a child failed!\n";
00221 CERR << "name="<< nch->name()<< ". implclass="<< nch->impl_class()<<" @ " << std::hex<<nch <<"\n";
00222 s11n::dump_node_debug( *nch, std::cerr );
00223 ACVT::release( ser );
00224 return false;
00225 }
00226 dwrap().insert( dwrap().end(), ser );
00227 }
00228 return true;
00229 }
00230
00231
00232
00233
00234
00235
00236 template <typename NodeType, typename SerType>
00237 bool deserialize_list( const NodeType & src,
00238 const std::string & subnodename,
00239 SerType & dest )
00240 {
00241 const NodeType * ch = s11n::find_child_by_name( src, subnodename );
00242 if( ! ch ) return false;
00243 return deserialize_list<NodeType,SerType>( *ch, dest );
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 template <typename NodeType, typename ListType>
00278 size_t serialize_streamable_list( NodeType & dest, const ListType & src )
00279 {
00280 typedef typename ListType::const_iterator CIT;
00281 CIT it = src.begin();
00282 size_t i = 0;
00283
00284
00285
00286
00287
00288 static const int bsize = 10;
00289 char num[bsize];
00290 char fmt[bsize];
00291 size_t sz = src.size();
00292 int places = 1;
00293 for( ; sz >= 0x0f; sz = (size_t)(sz/0x0f)) { ++places; }
00294 snprintf( fmt, bsize, "x%%0%dx", places );
00295 for( ; src.end() != it; ++it )
00296 {
00297 snprintf( num, bsize, fmt, i );
00298 ++i;
00299 dest.set( num, (*it) );
00300 }
00301 return i;
00302 }
00303
00304
00305
00306
00307
00308
00309
00310 template <typename NodeType, typename ListType>
00311 size_t serialize_streamable_list( NodeType & dest,
00312 const std::string & subnodename,
00313 const ListType & src )
00314 {
00315 NodeType & n = s11n::create_child( dest, subnodename );
00316 return serialize_streamable_list<NodeType,ListType>( n, src );
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 template <typename NodeType, typename ListType>
00331 size_t deserialize_streamable_list( const NodeType & src, ListType & dest )
00332 {
00333 typedef typename ListType::value_type VT;
00334 typename NodeType::const_iterator it = src.begin();
00335 size_t i = 0;
00336 VT defaultval;
00337 for( ; src.end() != it; ++it )
00338 {
00339 ++i;
00340 dest.insert( dest.end(),
00341 s11n::from_string<VT>( (*it).second, defaultval ) );
00342 }
00343 return i;
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353 template <typename NodeType, typename ListType>
00354 size_t deserialize_streamable_list( const NodeType & src,
00355 const std::string & subnodename,
00356 ListType & dest )
00357 {
00358 const NodeType * ch = s11n::find_child_by_name( src, subnodename );
00359 if( ! ch ) return 0;
00360 return deserialize_streamable_list<NodeType,ListType>( *ch, dest );
00361 }
00362
00363
00364
00365
00366
00367
00368
00369 class list_serializer_proxy
00370 {
00371 public:
00372 list_serializer_proxy()
00373 {}
00374
00375
00376
00377
00378
00379 template <typename NodeType, typename SerType>
00380 bool operator()( NodeType & dest, const SerType & src ) const
00381 {
00382 return serialize_list( dest, src );
00383 }
00384
00385
00386 template <typename NodeType, typename SerType>
00387 bool operator()( const NodeType & src, SerType & dest ) const
00388 {
00389 return deserialize_list( src, dest );
00390 }
00391 };
00392
00393
00394
00395 } }
00396
00397
00398 #endif // s11n_LIST_H_INCLUDED