00001 #ifndef s11n_S11N_TRAITS_HPP_INCLUDED 00002 #define s11n_S11N_TRAITS_HPP_INCLUDED 1 00003 00004 00005 #include <vector> 00006 #include <map> 00007 00008 #include <s11n.net/s11n/classload.hpp> // default classloader/factory implementation. 00009 #include <s11n.net/s11n/export.hpp> // S11N_EXPORT_API 00010 #include <s11n.net/s11n/type_traits.hpp> 00011 00012 namespace s11n { 00013 00014 /** 00015 node_traits encapsulates information relevant to Data 00016 Nodes, much in the same way that std::char_traits 00017 encapsulates character type information. 00018 00019 The default implementation works with 00020 s11n::s11n_node or API-compatible 00021 types. Specializations may be defined to work with 00022 other node types. 00023 00024 By using node_traits, instead of directly accessing a 00025 Node's API, client code may remain blissfully ignorant of 00026 the underlying node type. 00027 00028 All API docs for this class which do not explicitely say 00029 "this implementation" (or similar) apply to all 00030 specializations of this type. They act as the "requirements 00031 document" for implementors of specializations. 00032 00033 Changes from 1.0.x to 1.1.x: 00034 00035 - Removed begin() and end(), because they are just as 00036 easily accessed via children().begin/end(), and it was not 00037 easy to remember if they returned iterators to the children 00038 or the properties. 00039 00040 - Removed iterator typedefs, as they are (almost) as easily 00041 accessed via the appropriate container's typedefs. Again, this 00042 was to avoid confusion between the properties and children 00043 iterator types. 00044 */ 00045 template <typename NodeT> 00046 struct S11N_EXPORT_API node_traits 00047 { 00048 public: 00049 /** 00050 The same as NodeT. 00051 */ 00052 typedef NodeT node_type; 00053 00054 /** 00055 The type uses to store properties for node_type 00056 objects. 00057 */ 00058 typedef typename node_type::map_type property_map_type; 00059 00060 00061 /** 00062 The type used to store children of node_type 00063 objects. 00064 */ 00065 typedef typename node_type::child_list_type child_list_type; 00066 00067 00068 00069 00070 /** 00071 Returns a new node_type. The caller owns the 00072 returned pointer. 00073 00074 It is illegal for this function to return 0. If it 00075 cannot create a node for some reason, it must throw 00076 an exception. 00077 */ 00078 static node_type * create() 00079 { 00080 return new node_type; 00081 } 00082 00083 /** 00084 Returns a new node_type with the given name. The 00085 caller owns the returned pointer. 00086 00087 See create() for the no-null-return rule. 00088 */ 00089 static node_type * create( const std::string & nodename ) 00090 { 00091 node_type * n = create(); 00092 name( *n, nodename ); 00093 return n; 00094 } 00095 00096 00097 /** 00098 Sets the property key to the given value in 00099 the given node. 00100 00101 ValueT must support complementary ostream<< and 00102 istream>> operators. 00103 */ 00104 template <typename ValueT> 00105 static void set( node_type & node, 00106 const std::string & key, 00107 const ValueT & value ) 00108 { 00109 node.set( key, value ); 00110 } 00111 00112 /** 00113 Unsets (removes) the given property from node. It 00114 is not an error to unset an non-existing key. 00115 */ 00116 static void unset( node_type & node, 00117 const std::string & key ) 00118 { 00119 node.unset( key ); 00120 } 00121 00122 /** 00123 Returns true if node contains a property 00124 named key, else returns false. 00125 */ 00126 static bool is_set( const node_type & node, 00127 const std::string & key ) 00128 { 00129 return node.is_set( key ); 00130 } 00131 00132 00133 /** 00134 Returns an immutable reference to the node's map of properties. 00135 */ 00136 static const property_map_type & properties( const node_type & node ) 00137 { 00138 return node.properties(); 00139 } 00140 00141 /** 00142 Returns a mutable reference to the node's map of properties. 00143 */ 00144 static property_map_type & properties( node_type & node ) 00145 { 00146 return node.properties(); 00147 } 00148 00149 /** 00150 Returns the value of the property with the given 00151 key, or default_value if that property does not 00152 exist or cannot be lexically cast to type ValueT. 00153 00154 ValueT must support complementary ostream<< and 00155 istream>> operators. 00156 */ 00157 template <typename ValueT> 00158 static ValueT 00159 get( const node_type & node, 00160 const std::string & key, 00161 const ValueT & default_value ) 00162 { 00163 return node.template get<ValueT>( key, default_value ); 00164 } 00165 00166 /** 00167 Returns a mutable list of children 00168 belonging to node. 00169 */ 00170 static child_list_type & children( node_type & node ) 00171 { 00172 return node.children(); 00173 } 00174 00175 /** 00176 Returns an immutable list of children 00177 belonging to node. 00178 */ 00179 static const child_list_type & children( const node_type & node ) 00180 { 00181 return node.children(); 00182 } 00183 00184 /** 00185 Sets the class name of the type for which node 00186 holds serialized data. 00187 */ 00188 static void class_name( node_type & node, const std::string & classname ) 00189 { 00190 node.class_name( classname ); 00191 } 00192 00193 00194 /** 00195 Returns the class name of the type for which node 00196 holds serialized data. 00197 */ 00198 static std::string class_name( const node_type & node ) 00199 { 00200 return node.class_name(); 00201 } 00202 00203 /** 00204 Sets node's name. See the s11n lib manual for what 00205 conventions to follow. In short: the "variable name" 00206 rules from most programming languages are a good 00207 guideline. 00208 */ 00209 static void name( node_type & node, const std::string & name ) 00210 { 00211 node.name( name ); 00212 } 00213 00214 00215 /** 00216 Returns node's name. 00217 */ 00218 static std::string name( const node_type & node ) 00219 { 00220 return node.name(); 00221 } 00222 00223 /** 00224 Removes all children and properties from node, 00225 freeing up their resources. Whether the node's 00226 name() and class_name() are cleared is 00227 implementation-defined. In practice, those are 00228 overwritten by algos as needed, so it has not been 00229 a concern. 00230 */ 00231 static void clear( node_type & node ) 00232 { 00233 node.clear(); 00234 } 00235 00236 /** 00237 Returns true if this object has no properties 00238 and no children. The name() and class_name() 00239 are *not* considered. 00240 00241 Added in version 1.1.3. 00242 */ 00243 static bool empty( const node_type & node ) 00244 { 00245 return node.empty(); 00246 } 00247 00248 /** 00249 Swaps all publically-visible internal state of lhs 00250 with that of rhs. This includes: 00251 00252 - class_name() 00253 00254 - name() 00255 00256 - children() 00257 00258 - properties() 00259 00260 Added in version 1.1.3. 00261 */ 00262 static void swap( node_type & lhs, node_type & rhs ) 00263 { 00264 return lhs.swap( rhs ); 00265 } 00266 00267 }; // end node_traits<> 00268 00269 00270 // /** 00271 // An unfortunate necessity. 00272 // */ 00273 // template <typename NodeT> 00274 // struct S11N_EXPORT_API node_traits<NodeT const> : node_traits<NodeT> {}; 00275 00276 00277 /** 00278 A default serialization proxy, which simply 00279 forwards de/serialize calls to an interface 00280 implemented as two overloaded member functions 00281 SerializableType::operator()( NodeT ). 00282 */ 00283 struct S11N_EXPORT_API default_serialize_functor 00284 { 00285 /** 00286 Serialize src to dest using src.operator()( dest ). 00287 00288 The serialize operator must look like: 00289 00290 bool operator()( NodeT & ) const; 00291 00292 It may be virtual or a function template. 00293 */ 00294 template <typename NodeT, typename SerializableType> 00295 bool operator()( NodeT & dest, const SerializableType & src ) const 00296 { 00297 return src.operator()( dest ); 00298 } 00299 00300 /** 00301 Deserialize dest from src using dest.operator()( src ). 00302 00303 The deserialize operator must look like: 00304 00305 bool operator()( const NodeT & ); 00306 00307 It may be virtual or a function template. 00308 */ 00309 template <typename NodeT, typename DeserializableType> 00310 bool operator()( const NodeT & src, DeserializableType & dest ) const 00311 { 00312 return dest.operator()( src ); 00313 } 00314 }; 00315 00316 00317 /** 00318 A default implementation for 00319 s11n_traits::cleanup_functor. Compatible implementations 00320 and specializations must follow the conventions defined for 00321 this class. 00322 00323 This implementation is only suitable for cleaning up types 00324 which manage any child pointers which are assigned to them 00325 during deserialization. For example, std:: containers do 00326 not own their pointers, and therefor require a 00327 specialization of this type to clean them up. 00328 00329 SerializableType must be a Serializable and may be 00330 pointer-qualified. 00331 00332 The library manual goes into more detail about what this 00333 type is for. 00334 00335 The operations of this class are declared as throw() because 00336 of their logical role in the destruction process, and destructors 00337 are not generally allowed to throw. 00338 */ 00339 template <typename SerializableType> 00340 struct default_cleanup_functor 00341 { 00342 typedef typename type_traits<SerializableType>::type serializable_type; 00343 00344 /** 00345 Default implementation does nothing, though we 00346 should arguably assign to a default-constructed 00347 object. 00348 00349 Specializations must do any cleanup they need to 00350 here. For example, container specializations must 00351 a) deallocate any heap-based entries and b) empty 00352 the list. Specializations are free to do a 00353 default-assign, as mentioned above, but are not 00354 required to. Specializations for containers must 00355 recursively use s11n_trait::cleanup_functor for 00356 the contained types, to ensure that they can properly 00357 clean up containers holding other containers. 00358 */ 00359 void operator()( serializable_type & ) const throw() 00360 { 00361 } 00362 00363 }; 00364 00365 /** 00366 s11n_traits encapsulates information about what 00367 type(s) are responsible for handling de/serialize 00368 operations for a given type, plus the factory for 00369 that type. It should be specialized to define 00370 various aspects of serialization for a given type. 00371 00372 The interface shown here is the bare minimum which 00373 s11n_traits specializations must implement. 00374 Specializations may optionally add to the 00375 interface, but client code is discouraged from 00376 relying on any extensions. 00377 00378 This type is stateless, and specializations are 00379 expected to be stateless (at least, they will 00380 be treated as if they are). 00381 00382 Client code is not expected to need to use this 00383 type directly, except for purposes of plugging in 00384 their types into the s11n framework. More 00385 specifically, it is not expected that Serializables 00386 will use this type. 00387 00388 Parameterized on: 00389 00390 SerializableT: the base-most Serializable 00391 type. This is the base-most point of reference for 00392 classloading and "template typing". Subclasses of 00393 SerializableT are assumed to be handleable via the 00394 same de/serialize interface as SerializableT. 00395 00396 Changes from 1.0.x to 1.1.x: 00397 00398 - Added class_name() member to replace the ::classname() 00399 family of code in 1.1.0. 00400 00401 - cleanup_functor added in 1.1.3. 00402 00403 */ 00404 template <typename SerializableT> 00405 struct S11N_EXPORT_API s11n_traits 00406 { 00407 /** 00408 The s11n framework instantiates an s11n_traits 00409 object at some points to allow the traits object 00410 to do things like factory registration. 00411 */ 00412 s11n_traits(){} 00413 ~s11n_traits(){} 00414 00415 /** 00416 The type of object we want to [de]serialize. 00417 */ 00418 typedef SerializableT serializable_type; 00419 00420 /** 00421 Type which will be used to instantiate new objects 00422 of serializable_type. It must implement: 00423 00424 serializable_type * operator()( const std::string & classname ) const; 00425 00426 It is expected to return, polymorphically if 00427 possible, a new serializable_type on success or 0 00428 on failure. 00429 00430 The default factory_type works with types 00431 registered via the s11n::cl::classload() 00432 family of functions. 00433 */ 00434 typedef ::s11n::cl::object_factory<serializable_type> factory_type; 00435 00436 /** 00437 Functor type implementing serialize code. 00438 00439 Must implement: 00440 00441 bool operator()( SomeNodeType & dest, const base_type & src ) const; 00442 00443 */ 00444 typedef ::s11n::default_serialize_functor serialize_functor; 00445 00446 /** 00447 Functor type implementing deserialize code. 00448 00449 Must implement: 00450 00451 bool operator()( const SomeNodeType & src, base_type & dest ) const; 00452 */ 00453 typedef ::s11n::default_serialize_functor deserialize_functor; 00454 00455 /** 00456 This type is used to clean up a partial deserialized object 00457 on error. If this functor, and all specializations it calls, 00458 do their part, we can make much better exception guarantees, 00459 theoretically avoiding any leaks due to exceptions thrown 00460 during deserialization. 00461 00462 cleanup_functor must follow the conventions laid out by 00463 s11n::default_cleanup_functor<serializable_type>. 00464 */ 00465 typedef ::s11n::default_cleanup_functor<serializable_type> cleanup_functor; 00466 00467 /** 00468 As of s11n 1.1, specializations must define the 00469 class_name() function. This implementation returns 00470 a useless, unspecified class name. Specializations 00471 must return the class name of serializable_type, 00472 preferably polymorphically (polymorphic naming is 00473 unfortunately not possible without some client-side 00474 help). 00475 00476 instance_hint is a HINT to this class as to the 00477 actual instance we want the name for, and may be 00478 0. It is provided so that class hierarchies which 00479 have virtual functions like className() can make 00480 those available to the core library via s11n_traits 00481 specializations. 00482 00483 Specializations MUST accept 0 as a valid 00484 instance_hint value are are NEVER REQUIRED to pay 00485 any attention to instance_hint. The default 00486 implementation does nothing with it. 00487 00488 Design notes: 00489 00490 - It really should take a default value of 0 for 00491 instance_hint, but the idea of relying on a default 00492 value, considering things like how template 00493 specializations should define them and subclassing 00494 (though that is not an issue *here*), gives me the 00495 willies. Too much room for error there. 00496 00497 - Also, we could probably argue that it should 00498 return a const string. 00499 00500 - We could argue that it should return an empty string 00501 instead of a useless one. i don't want to to generate 00502 output which might break parsers, though. 00503 00504 */ 00505 static const std::string class_name( const serializable_type * /* instance_hint */ ) 00506 { 00507 return "unknown"; 00508 } 00509 00510 }; // end s11n_traits<> 00511 00512 00513 /** 00514 A general specialization to treat (T*) as (T) for s11n_traits 00515 purposes. This is necessary for some template argument resolution 00516 to work as desired. 00517 00518 Added in 1.1.3. 00519 */ 00520 template <typename T> 00521 struct S11N_EXPORT_API s11n_traits<T *> : public s11n_traits<T> {}; 00522 00523 00524 } // namespace s11n 00525 00526 00527 #endif // s11n_S11N_TRAITS_HPP_INCLUDED