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

data_node_serialize.h

00001 #ifndef s11n_DATA_SERIALIZE_H_INCLUDED
00002 #define s11n_DATA_SERIALIZE_H_INCLUDED
00003 ////////////////////////////////////////////////////////////////////////
00004 // data_node_serialize.h:
00005 //
00006 // Defines the core de/serialize() functions (and close friends).
00007 //
00008 // License: Public Domain
00009 // Author: stephan@s11n.net
00010 ////////////////////////////////////////////////////////////////////////
00011 
00012 #include <string>
00013 #include <list>
00014 #include <map>
00015 #include <deque>
00016 
00017 #include <cassert>
00018 #include <typeinfo>
00019 
00020 #include <s11n/debuggering_macros.h> // COUT/CERR
00021 #include <s11n/s11n_core.h> // classload()
00022 #include <s11n/pointer_stripper.h>
00023 #include <s11n/functor.h> // several useful functors.
00024 
00025 #define NODEERR if(0) CERR
00026 
00027 ////////////////////////////////////////////////////////////////////////////////
00028 // NO DEPS ON data_node.h ALLOWED!
00029 ////////////////////////////////////////////////////////////////////////////////
00030 
00031 
00032 namespace { // anon namespace important for linking reasons, to avoid ODR violations.
00033 
00034         /***
00035             Specializations of s11n_api_marshaler may
00036             marshall calls to local serialization APIs.
00037 
00038             This is the newer form of s11n_api_adapter&lt;&gt;, and it
00039             will eventually replace that type.
00040 
00041             For the default implementation, SerializableT must support
00042             these two operations:
00043 
00044            <b>Serialize:</b>
00045 
00046 <pre>
00047 bool operator()( serialize_node_type & dest ) const;
00048 </pre>
00049 
00050            <b>Deserialize:</b>
00051 
00052 <pre>
00053 bool operator()( const serialize_node_type & src );
00054 </pre>
00055 
00056        If these conditions are not met a compile-time error will occur.
00057 
00058            Normally specializations are created by using one of these macros:
00059 
00060            - s11n_SERIALIZABLE_BASE()
00061 
00062            - s11n_SERIALIZABLE_PROXY()
00063 
00064            - s11n_SERIALIZABLE_SUBTYPE()
00065 
00066        but specializations must be hand-written if the macro
00067        arguments contain commas (e.g., class template names)
00068        because those break the macros. Specializations may, in any
00069        case, be hand-written to implement arbitrary
00070        customizations.
00071         */
00072         template <typename SerializableT>
00073         struct s11n_api_marshaler
00074         {
00075                 typedef SerializableT serializable_type;
00076 
00077                 /**
00078                    Returns src.operator()( dest ). Specializations are free to reimplement
00079                    this call as they see fit.
00080                 */
00081                 template <typename NodeType>
00082                 static bool serialize( NodeType &dest, const serializable_type & src )
00083                 {
00084                         NODEERR << "Unspecialized serialize-via-self.\n";
00085                         dest.impl_class( ::classname<serializable_type>() ); // only good for monomorphs
00086                         return src( dest );
00087                 }
00088 
00089                 /**
00090                    Returns dest.operator()( src ). Specializations are free to reimplement
00091                    this call as they see fit.
00092                 */
00093                 template <typename NodeType>
00094                 static bool deserialize( const NodeType & src, serializable_type & dest )
00095                 {
00096                         NODEERR << "Unspecialized deserialize-via-self.\n";
00097                         return dest( src );
00098                 }
00099 
00100 //                 template <typename NodeType>
00101 //                 bool operator()( NodeType &dest, const serializable_type & src ) const
00102 //                 {
00103 //                         return serialize<NodeType>( dest, src );
00104 //                 }
00105 //                 template <typename NodeType>
00106 //                 bool operator()( const NodeType & src, serializable_type & dest )
00107 //                 {
00108 //                         return deserialize<NodeType>( src, dest );
00109 //                 }
00110         };
00111 
00112         /**
00113            A specialization to handle pointer types the same as
00114            reference/value types. It simply translates the pointers
00115            into references.
00116         */
00117         template <typename SerializableT>
00118         struct s11n_api_marshaler<SerializableT *>
00119         {
00120                 /**
00121                    The SerializableT templatized type, minus any
00122                    pointer part.
00123                 */
00124                 typedef SerializableT serializable_type;
00125 
00126                 /**
00127                    Convenience typedef: this class' parent type.
00128                  */
00129                 typedef s11n_api_marshaler<serializable_type> parent_type;
00130 
00131                 /**
00132                    Returns parent_type::serialize( dest, *src );
00133                 */
00134                 template <typename NodeType>
00135                 static bool serialize( NodeType &dest, const serializable_type * src )
00136                 {
00137                         if( ! src ) return false;
00138                         NODEERR << "Unspecialized pointer-type serialize via-non-pointer-parent-type handler.\n";
00139                         return parent_type::serialize( dest, *src );
00140                 }
00141 
00142                 /**
00143                    Returns parent_type::deserialize( src, *dest );
00144                 */
00145                 template <typename NodeType>
00146                 static bool deserialize( const NodeType & src, serializable_type * dest )
00147                 {
00148                         if( ! dest ) return false;
00149                         NODEERR << "Unspecialized pointer-type deserialize via-non-pointer-parent-type handler.\n";
00150                         return parent_type::deserialize( src, *dest );
00151                 }
00152 
00153 //                 template <typename NodeType>
00154 //                 bool operator()( NodeType &dest, const serializable_type * src ) const
00155 //                 {
00156 //                         return serialize<NodeType>( dest, src );
00157 //                 }
00158 //                 template <typename NodeType>
00159 //                 bool operator()( const NodeType & src, serializable_type * dest )
00160 //                 {
00161 //                         return deserialize<NodeType>( src, dest );
00162 //                 }
00163 
00164         };
00165 
00166 
00167 
00168 } // anon namespace
00169 
00170 
00171 /**********************************************************************
00172 
00173 General Conventions:
00174 
00175     NodeType should conform to the conventions laid out
00176     by s11n::data_node.
00177 
00178 
00179     SerializableTypes/BaseTypes:
00180 
00181     -BaseT must have the following in it's interface:
00182 
00183     - bool SerializeFunction( NodeType & dest ) const;
00184 
00185     - bool DeserializeFunction( const NodeType & dest );
00186 
00187     SerializeFunction/DeserializeFunction need not be virtual,
00188     though they should be unless your BaseT has a way of getting
00189     the stringified class NAME of it's subtypes (the Qt lib, e.g.,
00190     supports such a feature).
00191     
00192 
00193     Proxy functors:
00194 
00195     Serialization functor must have:
00196 
00197     bool operator()( NodeType & dest, const BaseT & src ) const;
00198 
00199     Derialization functor must have:
00200 
00201     bool operator()( const NodeType & src, BaseT & dest ) const;
00202 
00203     They may be the same functor type - const resolution will
00204     determine which s11n uses. Sometimes this causes ambiguity,
00205     and may require 2 functors.
00206 
00207     These signatures apply for all functors designed to work as
00208     de/serializers.
00209 
00210 
00211 
00212 **********************************************************************/
00213 
00214 
00215 namespace s11n {
00216 
00217 
00218 
00219 //         /**
00220 //            Returns func( target, src ).
00221 //         */
00222 //         template <typename DataNodeType,typename SerializableT, typename SerializerFunctorT>
00223 //         bool serialize( DataNodeType & target, const SerializableT & src, const SerializerFunctorT & func )
00224 //         {
00225 //                 NODEERR << "serialize<>(DataNodeType,SerializableT,SerializerFunctorT) forwarding to functor.\n";
00226 //                 return func( target, src );
00227 //         }
00228 
00229 
00230         /**
00231            Serializes src to target using a default API marshaling mechanism.
00232         */
00233         template <typename DataNodeType, typename SerializableT>
00234         bool serialize( DataNodeType & target, const SerializableT & src )
00235         {
00236                 NODEERR << "serialize<>(DataNodeType,SerializableT): using default API-marshaling functor.\n";
00237                 //return serialize( target, src, serialize_marshaler_selector<SerializableT>() );
00238                 //return serialize( target, src, s11n_api_marshaler<SerializableT>() );
00239                 return s11n_api_marshaler<SerializableT>::serialize( target, src );
00240         }
00241 
00242 
00243 //         /**
00244 //            Returns func( src, target ).
00245 //         */
00246 //         template <typename DataNodeType, typename DeserializableT, typename DeserializerFunctorT>
00247 //         bool deserialize( const DataNodeType & src, DeserializableT & target, const DeserializerFunctorT & func )
00248 //         {
00249 //                 return func( src, target );
00250 //         }
00251 
00252         /**
00253            Deserializes target from src using a default API marshaling
00254            mechanism.
00255         */
00256         template <typename DataNodeType, typename DeserializableT>
00257         bool deserialize( const DataNodeType & src, DeserializableT & target )
00258         {
00259                 NODEERR << "deserialize(DataNodeType,SerializableT): using default API marshaler.\n";
00260                 return s11n_api_marshaler<DeserializableT>::deserialize( src, target );
00261         }
00262 
00263 
00264         /**
00265            Tries to deserialize a DeserializableT from src, using
00266            <code>classload<DeserializableT>()</code> to load
00267            DeserializableT. Returns 0 on error, otherwise returns a
00268            pointer to a new object, which the caller takes ownership
00269            of.
00270         */
00271         template <typename DataNodeType, typename DeserializableT>
00272         DeserializableT * deserialize( const DataNodeType & src )
00273         {
00274                 NODEERR << "DeserializableT * deserialize(DataNodeType)\n";
00275                 DeserializableT * ret = classload<DeserializableT>( src.impl_class() );
00276                 if( ! ret )
00277                 {
00278                         NODEERR << "deserialize<>(): impl class '"
00279                                 << src.impl_class()<<"' classload failed.\n"
00280                                 << "It is probably not registered with it's base classloader.\n";
00281                         return 0;
00282                 }
00283                 if( ! deserialize( src, *ret ) )
00284                 {
00285                         NODEERR << "deserialize(): failed for unknown reason.\n";
00286                         delete( ret );
00287                         ret = 0;
00288                 }
00289                 return ret;
00290         }
00291 
00292 
00293 //         /**
00294 //            Serializes src to as a subnode of target, named
00295 //            nodename. Except for the addition of a subnode, it is
00296 //            identical to serialize( target, src, func ).
00297 //            The given functor is responsible for the serialization.
00298 //            The target node becomes the owner of any created pointer.
00299 //            This is a convenience function: not part of the s11n kernel.
00300 //         */
00301 //         template <typename DataNodeType, typename SerializableT, typename SerializerFunctorT>
00302 //         bool serialize_subnode( DataNodeType & target,
00303 //                                 const::std::string & nodename,
00304 //                                 const SerializableT & src,
00305 //                                 const SerializerFunctorT & func )
00306 //         {
00307 //                 NODEERR << "serialize_subnode<>(DataNodeType, '"<<nodename<<"', SerializableT, SerializerFunctorT)\n";
00308 //                 DataNodeType * sub = new DataNodeType();
00309 //                 sub->name( nodename );
00310 //                 if( ! serialize( *sub, src, func ) )
00311 //                 {
00312 //                         delete( sub );
00313 //                         sub = 0;
00314 //                 }
00315 //                 else
00316 //                 {
00317 //                         target.children().push_back( sub );
00318 //                 }
00319 //                 return sub != 0;
00320 //         }
00321 
00322 
00323 
00324 
00325         /**
00326            Serializes src to as a subnode of target, named
00327            nodename. Except for the addition of a subnode, it is
00328            identical to serialize( target, src ).
00329 
00330            This is a convenience function: not part of the s11n kernel.
00331         */
00332         template <typename DataNodeType, typename SerializableT >
00333         bool serialize_subnode( DataNodeType & target,
00334                                 const std::string & nodename,
00335                                 const SerializableT & src )
00336         {
00337                 NODEERR << "serialize_subnode<>(DataNodeType, '"<<nodename<<"', SerializableT)\n";
00338                 DataNodeType * sub = new DataNodeType();
00339                 sub->name( nodename );
00340                 if( ! serialize<DataNodeType,SerializableT>( *sub, src ) )
00341                 {
00342                         delete( sub );
00343                         sub = 0;
00344                 }
00345                 else
00346                 {
00347                         target.children().push_back( sub );
00348                 }
00349                 return sub != 0;
00350         }
00351 
00352 
00353 //         /**
00354 //            Looks for a subode of src named subnodename. If it does not
00355 //            find one it returns false, otherwise it returns the result of
00356 //            deserialize( child, target, func ).
00357 
00358 //            This is a convenience function: not part of the s11n kernel.
00359 //         */
00360 //         template <typename DataNodeType,
00361 //                   typename DeserializableT,
00362 //                   typename DeserializerFunctorT>
00363 //         bool deserialize_subnode( const DataNodeType & src,
00364 //                                   const std::string & subnodename,
00365 //                                   DeserializableT & target,
00366 //                                   const DeserializerFunctorT & func )
00367 //         {
00368 //                 const DataNodeType * ch = find_child_by_name( src, subnodename );
00369 //                 if( ! ch ) return false;
00370 //                 return deserialize<
00371 //                         DataNodeType,
00372 //                         DeserializableT,
00373 //                         DeserializerFunctorT
00374 //                         >( *ch, target, func );
00375 //         }
00376 
00377 
00378         /**
00379            If a child named subnodename is found in src then this function
00380            returns deserialize( child, target ) and returns it's result, otherwise
00381            it returns 0.
00382 
00383            This is a convenience function: not part of the s11n kernel.
00384         */
00385         template <typename DataNodeType, typename DeserializableT>
00386         bool deserialize_subnode( const DataNodeType & src,
00387                                   const std::string & subnodename,
00388                                   DeserializableT & target )
00389         {
00390                 const DataNodeType * ch = find_child_by_name( src, subnodename );
00391                 if( ! ch ) return false;
00392                 return deserialize<DataNodeType,DeserializableT>( *ch, target );
00393 
00394         }
00395 
00396         /**
00397            If a child named subnodename is found in src then this function
00398            returns the result of deserialize(child), otherwise
00399            it returns 0.
00400 
00401            This is a convenience function: not part of the s11n kernel.
00402         */
00403         template <typename DataNodeType, typename DeserializableT>
00404         DeserializableT * deserialize_subnode( const DataNodeType & src,
00405                                                const std::string & subnodename )
00406         {
00407                 const DataNodeType * ch = find_child_by_name( src, subnodename );
00408                 if( ! ch ) return false;
00409                 return deserialize<DataNodeType,DeserializableT>( *ch );
00410         }
00411 
00412 
00413         /**
00414            Clones an arbitrary SerializableType using it's
00415            DataNodeType serializable implementation.
00416 
00417            Returns a clone of tocp, or returns 0 on error.
00418            The caller owns the returned pointer.
00419 
00420            This copy is polymorphism-safe as long as all participating
00421            Serializables (re)implement the appropriate de/serialize
00422            operations, similarly to as they would do for a copy ctor
00423            or classical Clone() member function.
00424 
00425            Tip: clone() is a convenient way to test new de/serialize
00426            functions, e.g., for new Serializables, because if it works
00427            then deserializng from streams/files will also work. This
00428            function takes SerializableType through the whole
00429            de/serialize process, including classloading.
00430         */
00431         template <typename DataNodeType, typename SerializableType>
00432         SerializableType * clone( const SerializableType & tocp )
00433         {
00434                 DataNodeType node;
00435                 if( ! serialize( node, tocp ) ) return 0;
00436                 return deserialize<DataNodeType,SerializableType>( node );
00437         }
00438 
00439 
00440 
00441         /**
00442            "Casts" t1 to t2 using serialization. This will work
00443            whenever t1 and t2 are "compatible", whatever that really
00444            means. It can be used, e.g., to copy a list&lt;int&gt;
00445            to a vector&lt;double&gt;, provided both types have
00446            been proxied.
00447 
00448            Note that in the case of containers, the pointerness of the
00449            contained types is irrelevant: this works on both, thus
00450            a list&lt;int&gt; can be "cast" to a vector&lt;double*&gt;!
00451 
00452            As usual for a failed deserialization, if it returns false
00453            then t2 may be in an undefined state. There is no guaranty,
00454            however, that t2's deserialize operator will ever be
00455            called, as the serialization of t1 must first succeed
00456            for that to happen.
00457         */
00458 
00459         template <typename NodeType, typename Type1, typename Type2>
00460         bool s11n_cast( const Type1 & t1, Type2 & t2 )
00461         {
00462                 NodeType n;
00463                 return serialize( n, t1 ) && deserialize( n, t2 );
00464         }
00465 
00466 
00467 
00468 
00469 } // namespace s11n
00470 
00471 #undef NODEERR
00472 
00473 #endif // s11n_DATA_SERIALIZE_H_INCLUDED

Generated on Thu Jun 16 16:18:12 2005 for s11n by  doxygen 1.4.3-20050530