Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | 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 Tue Jul 20 10:46:48 2004 for s11n by doxygen 1.3.7