00001 #ifndef s11n_SERIALIZE_HPP_INCLUDED 00002 #define s11n_SERIALIZE_HPP_INCLUDED 00003 //////////////////////////////////////////////////////////////////////// 00004 // serialize.hpp: 00005 // 00006 // Defines the core de/serialize() functions (and close friends). 00007 // 00008 // License: Public Domain 00009 // Author: stephan@s11n.net 00010 //////////////////////////////////////////////////////////////////////// 00011 00012 //////////////////////////////////////////////////////////////////////////////// 00013 // NO DEPS ON s11n_node.hpp ALLOWED! 00014 //////////////////////////////////////////////////////////////////////////////// 00015 #include <s11n.net/s11n/memory.hpp> // cleanup stuff 00016 00017 namespace s11n { 00018 00019 00020 namespace Detail { 00021 /*** 00022 s11n_api_marshaler is the internal API marshaller 00023 for s11n. See the lib manual for full 00024 details. Client code is not expected to use or 00025 specialize this class, but theoretically some 00026 cases may call for doing so. In s11n versions 00027 prior to 1.0.x, specializing this type was 00028 sometimes useful for handling client-side 00029 template types, but this is no longer necessary 00030 nor encouraged. 00031 00032 In the default implementation, s11n_traits<NodeT,SerializableT> 00033 is used to marshal the de/serialize() calls. 00034 00035 Changed in 1.1.3: 00036 00037 - NodeType template param was moved from the static 00038 functions to the class. 00039 00040 - Moved class from anonymous namespace into s11n::Detail. 00041 */ 00042 template <typename NodeType,typename SerializableT> 00043 struct s11n_api_marshaler 00044 { 00045 /** 00046 Same as SerializableT. 00047 */ 00048 typedef SerializableT serializable_type; 00049 00050 /** Same as the NodeType template parameter. */ 00051 typedef NodeType node_type; 00052 00053 /** 00054 Returns s11n_traits<serializable_type>::serialize_functor()( dest, src ). 00055 00056 This implementation sets dest's class name to 00057 s11n_traits<SerializableT>::class_name(&src), which 00058 is only guaranteed to work properly for monomorphic 00059 types and base-most types of Serialization 00060 hierarchies (i.e., the registered 00061 bases). Polymorphic Serializable subtypes should 00062 set this class name themselves, or via their 00063 s11n_traits::class_name() specialization, both 00064 described in the library manual. 00065 00066 */ 00067 static bool serialize( node_type &dest, const serializable_type & src ); 00068 00069 /** 00070 Returns s11n_traits<SerializableT>::deserialize_functor()(src,dest). 00071 */ 00072 static bool deserialize( const node_type & src, serializable_type & dest ); 00073 }; 00074 00075 /** 00076 A specialization to handle pointer types the same as 00077 reference/value types. It simply translates the pointers 00078 into references. 00079 */ 00080 template <typename NodeType,typename SerializableT> 00081 struct s11n_api_marshaler<NodeType,SerializableT *> 00082 { 00083 /** 00084 The SerializableT templatized type, minus any 00085 pointer part. 00086 */ 00087 typedef SerializableT serializable_type; 00088 00089 /** Same as the NodeType template parameter. */ 00090 typedef NodeType node_type; 00091 00092 /** 00093 Convenience typedef: this class' quasi-parent type. 00094 */ 00095 typedef s11n_api_marshaler<node_type,serializable_type> parent_type; 00096 00097 /** 00098 Returns parent_type::serialize( dest, *src ); 00099 00100 src must be a valid pointer, else false is returned. 00101 */ 00102 static bool serialize( node_type &dest, const serializable_type * const & src ); 00103 00104 /** 00105 Returns parent_type::deserialize( src, *dest ); 00106 00107 dest must be a valid pointer, else false is returned. 00108 00109 Reminder to self: if we dupe the code from 00110 deserialize(const N&,ST *&), we could 00111 potentially provide support for passing a 00112 reference to a null pointer here. No need, 00113 though, since the public s11n API already 00114 provides that. 00115 */ 00116 static bool deserialize( const node_type & src, serializable_type * & dest ); 00117 }; 00118 } // namespace Detail 00119 00120 00121 /** 00122 Serializes src to target using the default API marshaling 00123 mechanism. 00124 00125 On success it always returns true, else false. 00126 00127 If a the underlying operation throws, it will pass on the 00128 exception. 00129 */ 00130 template <typename DataNodeType, typename SerializableT> 00131 bool serialize( DataNodeType & target, const SerializableT & src ); 00132 00133 00134 00135 /** 00136 Deserializes target from src using the default API marshaling 00137 mechanism. Returns true on success. 00138 00139 On error it returns false or passes on an exception. In 00140 either case, target might be in an undefined state, and may 00141 need manual interaction to free up resources (e.g., a list 00142 of pointers might have some pointers which need to be 00143 cleaned up during exception handling). The exact definition 00144 of its state after a failure is specified by the algorithm 00145 which deserializes the target (as defined via 00146 s11n_traits<DeserializableT>::deserialize_functor). 00147 */ 00148 template <typename DataNodeType, typename DeserializableT> 00149 bool deserialize( const DataNodeType & src, DeserializableT & target ); 00150 00151 00152 /** 00153 Like the standard form of deserialize(), but if passed a 00154 null pointer, it attempts to classload the class and assign 00155 the passed-in pointer to it. If passed a non-null target 00156 then it behaves as if target were a reference, simply 00157 passing on the target after dereferencing it. 00158 00159 For example: 00160 00161 <pre> 00162 T * t = 0; 00163 deserialize<NodeType,T>( mynode, t ); 00164 // t will be non-0 if it worked. 00165 00166 T * x = new X; 00167 if( deserialize<NodeType,T>( mynode, x ) ) 00168 { 00169 // x is now populated exactly as if we had called: 00170 // deserialize<NodeType,T>( mynode, *x ); 00171 } 00172 </pre> 00173 00174 To get the class name, the algorithm first tries 00175 node_traits<DataNodeType>::class_name(src). If it cannot 00176 load a class using that name, it tries 00177 s11n_traits<DeserializableT>::class_name(target). 00178 00179 Underlying calls to s11n::cl::classload() and serialization 00180 proxies may throw. If they do, the exception is passed on 00181 to the caller. 00182 00183 If passed a null pointer and this function fails, target is 00184 not modified. If deserialization fails, any 00185 internally-created (DeserializableT*) is deallocated using 00186 cleanup_serializable(). If passed a non-null pointer and 00187 the function fails, behaviour is as for the non-pointer 00188 variant of deserialize() - target may or may not be in a 00189 defined state, as defined by the specific proxy algorithm. 00190 00191 00192 Added in s11n version 1.1.3. 00193 00194 */ 00195 template <typename DataNodeType, typename DeserializableT> 00196 bool deserialize( const DataNodeType & src, DeserializableT * & target ); 00197 00198 /** 00199 Identical to deserialize(const 00200 DataNodeType&,DeserializableT*&) except that it works on a 00201 cleanup_ptr<>. The target may be empty (pointing to zero): 00202 if it is then dynamic loading is attempted, as described 00203 in the docs for the non-cleanup_ptr variant of this 00204 function. 00205 00206 Returns true if deserialization to the target succeeds, 00207 else false. If it returns false, target.get() still points 00208 to the same object it did when function was called (which 00209 may be 0). Whether or not the contained object is modified 00210 on deserialization failure depends on the underlying 00211 algorithm used to deserialize it. 00212 */ 00213 template <typename DataNodeType, typename DeserializableT> 00214 bool deserialize( const DataNodeType & src, cleanup_ptr<DeserializableT> & target ); 00215 00216 /** 00217 Tries to deserialize a DeserializableT from src, using 00218 <code>s11n_traits<DeserializableT>::factory_type()(node_traits<DataNodeType>::class_name(src))</code> 00219 to create a new DeserializableT. 00220 00221 DeserializableT may not be a pointer-qualified type. 00222 00223 On error it returns 0 or propagates on an exception, 00224 otherwise returns a pointer to a new object, which the 00225 caller takes ownership of. 00226 00227 As of 1.1.3, this function relies on 00228 s11n::cleanup_serializable() in order to be able to specify 00229 what happens to the internally allocated object if 00230 deserialization fails. That function is called on the 00231 object before this function returns if deserialization 00232 fails. 00233 00234 Prior to 1.1.3 this function would leak if this function 00235 failed and if DeserializableT contained unmanaged pointers 00236 (even indirectly, via sub-containment), such as in 00237 list<int*> or list<map<int,string*>>. 00238 */ 00239 template <typename DataNodeType, typename DeserializableT> 00240 DeserializableT * deserialize( const DataNodeType & src ); 00241 00242 00243 /** 00244 Clones an arbitrary SerializableType using its 00245 DataNodeType serialization implementation. 00246 00247 Returns a clone of tocp, or returns 0 on error. 00248 The caller owns the returned pointer. 00249 00250 This copy is polymorphism-safe as long as all participating 00251 Serializables (re)implement the appropriate de/serialize 00252 operations, similarly to as they would do for a copy ctor 00253 or classical Clone() member function. 00254 00255 Tip: s11n_clone() is a convenient way to test new 00256 de/serialize functions, e.g., for new Serializables, 00257 because if it works then deserializing from streams/files 00258 will also work. This function takes SerializableType 00259 through the whole de/serialize process except for i/o, 00260 including classloading. 00261 00262 This function was renamed from clone() in version 1.1. 00263 00264 Exceptions and errors: 00265 00266 This function may return 0 or throw on an error, as 00267 dictated by serialize() and then deserialize() (in that 00268 order). Thus safety guarantees are defined in terms 00269 of those operations. 00270 */ 00271 template <typename DataNodeType, typename SerializableType> 00272 SerializableType * s11n_clone( const SerializableType & tocp ); 00273 00274 /** 00275 "Casts" t1 to t2 using serialization. This will work 00276 whenever t1 and t2 are "semantically compatible", whatever 00277 that really means. It can be used, e.g., to copy a 00278 list<int> to a vector<double>, provided both 00279 types have been proxied. In practice, this means: if Type1 00280 and Type2 both use the same, or compatible, de/ser 00281 algorithms, they are s11n_cast-able to one another. 00282 00283 Note that in the case of containers, the pointerness of the 00284 contained types is irrelevant: this works on both, thus 00285 a list<int> can be "cast" to a vector<double*>. 00286 00287 As usual for a failed deserialization, if it returns false 00288 then t2 may be in an undefined state. There is no guaranty, 00289 however, that t2's deserialize operator will ever be 00290 called, as the serialization of t1 must first succeed 00291 for that to happen. 00292 00293 Type2 may not currently be a pointer type, but Type1 may 00294 be. This will be fixed someday (when someone complains). 00295 00296 Exceptions and errors: 00297 00298 On error this function will return false or propagate 00299 an exception, as dictated by serialize() and then 00300 deserialize() (in that order). 00301 00302 If Type1 and Type2 are not guaranteed to be monomorphic or 00303 base-most Serializable types, then it is good practice to 00304 explicitely specify them as templatized parameters, and not 00305 rely on implicit type selection, which might choose the 00306 wrong type (not the base-most one, which is what s11n is 00307 "keyed" to), which will mean that s11n "can't find" the 00308 registration code for the type. What that means is, if t1 00309 or t2 may be polymorphic types, then it is best to 00310 explicitly specify their base-most s11n-registered common 00311 ancestor as the template parameters for Type1 and/or Type2. 00312 e.g.: 00313 00314 \code 00315 BaseT * lhs = new SubT; 00316 ... populate lhs ... 00317 BaseT * rhs = new SubT; 00318 s11n_cast<s11n_node,BaseT,BaseT>( *lhs, *rhs ); 00319 \endcode 00320 00321 */ 00322 template <typename NodeType, typename Type1, typename Type2> 00323 bool s11n_cast( const Type1 & t1, Type2 & t2 ); 00324 00325 00326 } // namespace s11n 00327 00328 #include <s11n.net/s11n/serialize.tpp> // implementations for above-declared code 00329 00330 00331 #endif // s11n_SERIALIZE_HPP_INCLUDED