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 Oct 26 18:25:59 2004 for s11n by  doxygen 1.3.9.1