Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members

map.h

00001 //////////////////////////////////////////////////////////////////////// 00002 // 00003 //////////////////////////////////////////////////////////////////////// 00004 #ifndef s11n_MAP_H_INCLUDED 00005 #define s11n_MAP_H_INCLUDED 1 00006 00007 #include <list> 00008 #include <iterator> // insert_iterator 00009 #include <algorithm> // for_each() 00010 #include <stdio.h> // snprintf() 00011 00012 #include <s11n/functor.h> // copy_if, same_name 00013 00014 #include <s11n/data_node_serialize.h> // core serialize funcs 00015 #include <s11n/data_node_functor.h> // data_node_child_serializer functor 00016 #include <s11n/data_node_algo.h> // dump_node_debug() 00017 #include <s11n/abstract_creator.h> // abstract_creator class 00018 00019 namespace s11n { 00020 /** 00021 The s11n::map namespace defines functors and algorithms for 00022 working with std::map and std::pair containers. 00023 */ 00024 namespace map { 00025 00026 00027 /** 00028 00029 serialize_streamable_map() is intended for use as a 00030 serialization proxy for the s11n framework. It 00031 de/serializes objects of type <tt>std::map&lt;X,Y&gt;</tt> 00032 into a destination node. 00033 00034 NodeType must support: 00035 00036 set( const std::string & key, const std::string & value ) 00037 00038 - MapType must conform to std::map conventions and 00039 it's key_type and mapped_type must both be Value Types 00040 which are i/ostreamable (this includes all PODs and 00041 std::string). Pointers as keys or values are not 00042 supported by this functor. 00043 00044 Returns the number of values serialized into dest. 00045 */ 00046 00047 template <typename NodeType, typename MapType> 00048 size_t serialize_streamable_map( NodeType & dest, const MapType & src ) 00049 { 00050 typedef typename MapType::value_type VT; 00051 typedef typename VT::first_type FT; 00052 typedef typename VT::second_type ST; 00053 VT p; 00054 size_t count=0; 00055 typename MapType::const_iterator it = src.begin(); 00056 for( ; src.end() != it; ++it ) 00057 { 00058 ++count; 00059 dest.set( 00060 s11n::to_string<FT>( (*it).first ), 00061 s11n::to_string<ST>( (*it).second ) 00062 ); 00063 } 00064 return count; 00065 } 00066 00067 /** 00068 Exactly like serialize_streamable_map(dest,src) except that a subnode, 00069 named subnodename, of dest is created to store the data. 00070 */ 00071 template <typename NodeType, typename MapType> 00072 size_t serialize_streamable_map( NodeType & dest, 00073 const std::string & subnodename, 00074 const MapType & src ) 00075 { 00076 return serialize_streamable_map( s11n::create_child( dest, subnodename ), src ); 00077 } 00078 00079 /** 00080 This is the converse of serialize_streamable_map(). It tries to 00081 read in all properties stored in src and stick them into 00082 dest. 00083 00084 NodeType must support begin() and end() and they must 00085 return iterators to pair&lt;X,Y&gt;, where X and Y must 00086 meet the same requirements as the key and value types for 00087 MapType in serialize_streamable_map(). MapType must support: 00088 00089 void insert( MapType::value_type ); 00090 00091 (Duh.) 00092 00093 Returns the number of values deserialized into dest. 00094 */ 00095 template <typename NodeType, typename MapType> 00096 size_t deserialize_streamable_map( const NodeType & src, MapType & dest ) 00097 { 00098 typedef typename MapType::value_type VT; // pair 00099 typedef typename VT::first_type T1; 00100 typedef typename VT::second_type T2; 00101 00102 const T1 default1 = T1(); 00103 const T2 default2 = T2(); 00104 size_t count=0; 00105 typename NodeType::const_iterator it = src.begin(); 00106 for( ; src.end() != it; ++it ) 00107 { 00108 ++count; 00109 dest.insert( std::make_pair( 00110 s11n::from_string( (*it).first, default1 ), 00111 s11n::from_string( (*it).second, default2 ) 00112 ) ); 00113 } 00114 return count; 00115 } 00116 00117 /** 00118 Exactly like deserialize_streamable_map(dest,src) except 00119 that a subnode of dest, named subnodename, is sought to 00120 pull the data from. 00121 00122 A return value of 0 indicates that either no child with 00123 the given name was found or that no deserializable items 00124 were in that node. 00125 */ 00126 template <typename NodeType, typename MapType> 00127 size_t deserialize_streamable_map( const NodeType & src, 00128 const std::string & subnodename, 00129 MapType & dest ) 00130 { 00131 const NodeType * ch = s11n::find_child_by_name( src, subnodename ); 00132 if( ! ch ) return 0; 00133 return deserialize_streamable_map<NodeType,MapType>( *ch, dest ); 00134 } 00135 00136 00137 /** 00138 Serializes a std::pair-compatible type into a "custom" 00139 format, suitable for saving pairs in standard XML 00140 (de/serialize_streamable_map() can't do this when keys are 00141 not valid XML keys, e.g., numeric). Use 00142 deserialize_streamable_pair() to decode the data. 00143 00144 The destination node gets these two properties: 00145 00146 - first = src.first 00147 00148 - second = src.second 00149 00150 PairType must comply with: 00151 00152 - first/second types must be i/o streamable (i.e., 00153 convertable to strings). 00154 00155 Returns true on success... and never fails. Honestly. It'll 00156 fail at compile-time if it's going to fail. 00157 00158 00159 use deserialize_streamable_pair() to convert them back to pairs, 00160 or fish out the "first" and "second" properties manually. 00161 */ 00162 template <typename NodeType, typename PairType> 00163 bool serialize_streamable_pair( NodeType & dest, const PairType & src ) 00164 { 00165 typedef typename PairType::first_type FT; 00166 typedef typename PairType::second_type ST; 00167 dest.set( "first", src.first ); 00168 dest.set( "second", src.second ); 00169 return true; 00170 } 00171 00172 /** 00173 The quasi-counterpart of serialize_streamable_pair(). It's 00174 non-conventional args and return type are a result of 00175 map::value_type having a const .first element, which 00176 prohibits us assigning to it. See deserialize_pair() for 00177 more info on that. 00178 */ 00179 template <typename PairType, typename NodeType> 00180 PairType deserialize_streamable_pair( const NodeType & src ) 00181 { 00182 typedef typename PairType::first_type T1; 00183 typedef typename PairType::second_type T2; 00184 T1 default1 = T1(); 00185 T2 default2 = T2(); 00186 return std::make_pair( src.get( "first", default1 ), 00187 src.get( "second", default2 ) 00188 ); 00189 } 00190 00191 00192 /** 00193 Similar to serialize_streamable_map(), but puts each key/value 00194 pair into it's own node, using serialize_streamable_pair(). The 00195 end effect is that it's output is more verbose, but may be 00196 compatible with more file formats, regardless of the actual 00197 key type. e.g., numeric keys are supported by standard XML 00198 (though they are by the s11n XML parsers), and this algorithm 00199 structures the data such that this is not a problem. 00200 00201 Returns the number of pairs stored. 00202 00203 MapType must meet these conditions: 00204 00205 value_type must be a pair containing i/ostreamable types 00206 (e.g. PODs/strings). 00207 00208 */ 00209 template <typename NodeType, typename MapType> 00210 size_t serialize_streamable_map_pairs( NodeType & dest, const MapType & src ) 00211 { 00212 // dest.impl_class( class_name_of_MapType ); 00213 typedef typename MapType::value_type VT; 00214 typedef typename VT::first_type FT; 00215 typedef typename VT::second_type ST; 00216 size_t count=0; 00217 typename MapType::const_iterator it = src.begin(); 00218 for( ; src.end() != it; ++it ) 00219 { 00220 ++count; 00221 serialize_streamable_pair( create_child( dest, "pair" ), *it ); 00222 } 00223 return count; 00224 } 00225 00226 /** 00227 The load-time counterpart to serialize_streamable_map_pairs(). 00228 */ 00229 template <typename NodeType, typename MapType> 00230 size_t deserialize_streamable_map_pairs( const NodeType & src, MapType & dest ) 00231 { 00232 typedef typename MapType::value_type VT; // pair 00233 typedef typename VT::first_type T1; 00234 typedef typename VT::second_type T2; 00235 typedef std::list<const NodeType *> ChList; 00236 typedef typename ChList::const_iterator ChIt; 00237 00238 static const T1 default1 = T1(); 00239 static const T2 default2 = T2(); 00240 00241 ChList namedch; 00242 if( 0 == s11n::find_children_by_name( src, "pair", namedch ) ) return 0; 00243 00244 size_t count=0; 00245 const NodeType * ch = 0; 00246 ChIt it = namedch.begin(); 00247 VT p = VT(default1,default2); 00248 for( ; namedch.end() != it; ++it ) 00249 { 00250 ++count; 00251 ch = *it; 00252 dest.insert( deserialize_streamable_pair<VT>( *ch ) ); 00253 } 00254 return count; 00255 } 00256 00257 00258 /** 00259 serialize_pair() can serialize any std::pair type which 00260 meets these conditions: 00261 00262 - PairType must be registed with s11n. 00263 00264 PairType's first_type and second_type types must: 00265 00266 - both be Serializables. They may be pointer or value 00267 types. 00268 00269 00270 ACHTUNG: never pass the same destination container to the 00271 operators more than once or you will get duplicate and/or 00272 incorrect data. 00273 */ 00274 template <typename NodeType, typename PairType> 00275 bool serialize_pair( NodeType & dest, const PairType & src ) 00276 { 00277 dest.impl_class( classname<PairType>() ); 00278 NodeType * ch = & create_child( dest, "first" ); 00279 if( ! serialize( *ch, src.first ) ) 00280 { 00281 CERR << "serialize_pair: first child failed serialize!\n"; 00282 return false; 00283 } 00284 ch = & create_child( dest, "second" ); 00285 if( ! serialize( *ch, src.second ) ) 00286 { 00287 CERR << "serialize_pair: second child failed serialize!\n"; 00288 return false; 00289 } 00290 return true; 00291 } 00292 00293 /** 00294 The counterpart to serialize_pair(). 00295 00296 Note: std::map&lt;X,Y&gt;::value_type is not the same as pair&lt;X,Y&gt;, 00297 but is pair&lt;const X,Y&gt;, so you cannot simply iterate over a map and 00298 pass each pair to this function, because this function cannot assign 00299 to the first element of such a pair. 00300 */ 00301 template <typename NodeType, typename PairType> 00302 bool deserialize_pair( const NodeType & src, PairType & dest ) 00303 { 00304 //CERR << "deserialize_pair: deserialize " << src.impl_class() << "\n"; 00305 typedef typename PairType::first_type FT; 00306 typedef typename PairType::second_type ST; 00307 const NodeType * ch = 0; 00308 typedef pointer_stripper<PairType> PS; 00309 00310 // Note: the abstract_creator code below is simply 00311 // to treat pointer and value types identically 00312 // with this same code base. See it's docs for what 00313 // it does (or doesn't do, in the case of reference 00314 // types). 00315 00316 typedef s11n::abstract_creator<FT> AC1st; 00317 typedef s11n::abstract_creator<ST> AC2nd; 00318 //////////////////////////////////////// .first 00319 ch = find_child_by_name( src, "first" ); 00320 if( ! ch ) 00321 { 00322 CERR << "deserialize_pair: deserialize: no 'first' node found!\n"; 00323 return false; 00324 } 00325 FT f; // value of .first 00326 if( ! AC1st::create( f, ch->impl_class() ) ) 00327 { 00328 CERR << "Internal error: could not create first element." 00329 <<"type='"<<ch->impl_class()<<"'!\n"; 00330 return false; 00331 } 00332 if( ! deserialize( *ch, f ) ) 00333 { 00334 CERR << "pair deserialize(..., first ) failed.\n"; 00335 AC1st::release( f ); 00336 return false; 00337 } 00338 //////////////////////////////////////// .second: 00339 ST s; // value of .second 00340 ch = find_child_by_name( src, "second" ); 00341 if( ! ch ) 00342 { 00343 CERR << "deserialize_pair: deserialize: no 'second' node found!\n"; 00344 AC1st::release( f ); 00345 return false; 00346 } 00347 if( ! AC2nd::create( s, ch->impl_class() ) ) 00348 { 00349 CERR << "Internal error: could not create second element." 00350 <<"type='"<<ch->impl_class()<<"'!\n"; 00351 AC1st::release( f ); 00352 return false; 00353 } 00354 if( ! deserialize( *ch, s ) ) 00355 { 00356 CERR << "deserialize_pair(): deserialize((..., second ) failed.\n"; 00357 AC1st::release( f ); 00358 AC2nd::release( s ); 00359 return false; 00360 } 00361 dest.first = f; 00362 dest.second = s; 00363 return true; 00364 } 00365 00366 00367 00368 /** 00369 pair_serializer_proxy is a Serializable Proxy for std::pairs. 00370 */ 00371 struct pair_serializer_proxy 00372 { 00373 /** 00374 See serialize_pair(). 00375 */ 00376 template <typename NodeType, typename PairType> 00377 bool operator()( NodeType & dest, const PairType & src ) const 00378 { 00379 return serialize_pair( dest, src ); 00380 } 00381 /** 00382 See deserialize_pair(). 00383 */ 00384 template <typename NodeType, typename PairType> 00385 bool operator()( const NodeType & src, PairType & dest ) const 00386 { 00387 return deserialize_pair( src, dest ); 00388 } 00389 }; 00390 00391 00392 00393 /** 00394 Serialize the given map into dest. MapType's pairs must be 00395 Serializable and must contain Serializable types, but their 00396 "pointerness" is irrelevant. 00397 00398 ACHTUNG: never pass the same destination container to the 00399 operators more than once or you will get duplicate and/or 00400 incorrect data. 00401 00402 See deserialize_map() for important info. 00403 00404 */ 00405 template <typename NodeType, typename MapType> 00406 bool serialize_map( NodeType & dest, const MapType & src ) 00407 { 00408 typedef typename MapType::const_iterator CIT; 00409 CIT b = src.begin(), e = src.end(); 00410 NodeType * ch = 0; 00411 for( ; e != b; ++b ) 00412 { 00413 ch = new NodeType; 00414 ch->name( "pair" ); 00415 if( ! serialize_pair( *ch, *b ) ) 00416 { 00417 delete( ch ); 00418 CERR << "map_serializer_proxy: child failed serialize.\n"; 00419 return false; 00420 } 00421 dest.children().push_back( ch ); 00422 } 00423 return true; 00424 } 00425 00426 /** 00427 Identical to the two-argument form, but creates a subnode of dest, 00428 named subnodename, and serializes to that node. 00429 */ 00430 template <typename NodeType, typename MapType> 00431 bool serialize_map( NodeType & dest, 00432 const std::string & subnodename, 00433 const MapType & src ) 00434 { 00435 NodeType * ch = new NodeType; 00436 if( ! serialize_map<NodeType,MapType>( *ch, src ) ) 00437 { 00438 delete( ch ); 00439 return false; 00440 } 00441 dest.children().push_back( ch ); 00442 return true; 00443 } 00444 00445 /** 00446 The counterpart of serializer_map(), deserializes src into the 00447 given map. MapType must be Serializable and contain pairs 00448 which themselves are Serializables... ad inifinitum.. 00449 00450 Minor caveat: 00451 00452 This operation will only work with maps containing std::pair 00453 types, not map-like classes which use a different pair 00454 type. :( The reason is that map&lt;X,Y&gt;::value_type is 00455 not a pair of (X,Y), but (const Y,Y), which means we cannot 00456 use the map's value_type for a deser operation because we 00457 cannot assign to it's .first element (i.e., can't 00458 deserialize it). To get around that we "manually" create a 00459 new std::pair type using map's key_type and mapped_type 00460 typedefs, which "loses" the constness for use so we can 00461 assign to the first_type during deserialization, and then 00462 insert that pair into the deserializing map. 00463 00464 00465 */ 00466 template <typename NodeType, typename MapType> 00467 bool deserialize_map( const NodeType & src, MapType & dest ) 00468 { 00469 typedef typename NodeType::child_list_type::const_iterator CIT; 00470 //typedef typename SerializableType::value_type VT; 00471 // ^^^ no, because VT::first_type is const! 00472 // Thus we hand-create a compatible pair type: 00473 typedef typename MapType::key_type KType; 00474 typedef typename MapType::mapped_type VType; 00475 typedef std::pair< KType, VType > PairType; 00476 PairType pair; 00477 CIT b = src.children().begin(), e = src.children().end(); 00478 const NodeType *ch = 0; 00479 for( ; e != b ; ++b ) 00480 { 00481 ch = *b; 00482 if( ! deserialize_pair( *ch, pair ) ) 00483 { 00484 CERR << "map_serializer_proxy: child failed deser.\n"; 00485 return false; 00486 } 00487 dest.insert( pair ); 00488 } 00489 return true; 00490 } 00491 00492 00493 /** 00494 Identical to the two-argument form, but tries to deserialize 00495 from a subnode of src named subnodename. If no such node is found 00496 then false is returned. 00497 */ 00498 template <typename NodeType, typename MapType> 00499 bool deserialize_map( const NodeType & src, 00500 const std::string & subnodename, 00501 MapType & dest ) 00502 { 00503 const NodeType * ch = s11n::find_child_by_name( src, subnodename ); 00504 if( ! ch ) return false; 00505 return deserialize_map<NodeType,MapType>( *ch, dest ); 00506 } 00507 00508 00509 /** 00510 A proxy which can serialize std::maps which contain Streamable 00511 Types. 00512 00513 It uses de/serialize_streamable_map(), so see those 00514 functions for details. 00515 */ 00516 struct streamable_map_serializer_proxy 00517 { 00518 /** 00519 Serializes src to dest. 00520 00521 ACHTUNG: never pass the same destination container 00522 to this operator more than once or you will get 00523 duplicate and/or incorrect data. 00524 */ 00525 template <typename NodeType, typename SerializableType> 00526 bool operator()( NodeType & dest , const SerializableType & src ) const 00527 { 00528 dest.impl_class( class_name<SerializableType>::name() ); 00529 //s11n::serialize_streamable_map_pairs( dest, src ); 00530 serialize_streamable_map( dest, src ); 00531 return true; 00532 } 00533 00534 /** 00535 Deserializes dest from src. 00536 */ 00537 template <typename NodeType, typename SerializableType> 00538 bool operator()( const NodeType & src , SerializableType & dest ) const 00539 { 00540 //s11n::deserialize_streamable_map_pairs( src, dest ); 00541 deserialize_streamable_map( src, dest ); 00542 return true; 00543 } 00544 }; 00545 00546 00547 00548 /** 00549 map_serializer_proxy is a Serialization Proxy for std::maps. 00550 00551 See de/serialize_map(): this functor simply wraps those. 00552 */ 00553 struct map_serializer_proxy 00554 { 00555 00556 /** 00557 Serializes src into dest. Returns true on success, 00558 false on error. Stops at the first child-serialize failure. 00559 */ 00560 template <typename NodeType, typename MapType> 00561 bool operator()( NodeType & dest , const MapType & src ) const 00562 { 00563 return serialize_map( dest, src ); 00564 } 00565 /** 00566 Deserializes src into dest. Returns true on success, 00567 false on error. Stops at the first child-deserialize failure. 00568 */ 00569 template <typename NodeType, typename MapType> 00570 bool operator()( const NodeType & src , MapType & dest ) const 00571 { 00572 return deserialize_map( src, dest ); 00573 } 00574 }; 00575 00576 00577 00578 00579 00580 } } // namespace s11n::map 00581 00582 00583 #endif // s11n_MAP_H_INCLUDED

Generated on Tue Jul 20 10:46:48 2004 for s11n by doxygen 1.3.7