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

s11nlite.h

00001 #ifndef S11N_LITE_H_INCLUDED 00002 #define S11N_LITE_H_INCLUDED 1 00003 00004 //////////////////////////////////////////////////////////////////////// 00005 // s11nlite.h 00006 // Defines a subset of the s11n interface, intended to: 00007 // a) Cover "most common client-side operations." 00008 // b) provide a reference/sample for writing custom client-side 00009 // interfaces on top of the s11n core. 00010 // c) simplify many of the template-based operations needed 00011 // when working directly with the core. 00012 // 00013 // License: Do As You Damned Well Please 00014 // Author: stephan@s11n.net 00015 //////////////////////////////////////////////////////////////////////// 00016 00017 #include <memory> // auto_ptr 00018 #include <iterator> // insert_interator<> 00019 #include <functional> // for_each 00020 00021 #if HAVE_CONFIG_H 00022 # include "config.h" 00023 #endif 00024 00025 00026 00027 #include <s11n/s11n.h> // the whole s11n framework 00028 00029 //////////////////////////////////////////////////////////////////////////////// 00030 // CLIENT-SIDE MACROS: 00031 //////////////////////////////////////////////////////////////////////////////// 00032 00033 00034 //////////////////////////////////////////////////////////////////////// 00035 // define these two macros before including this header to set the 00036 // Serializer type used by s11nlite. 00037 //////////////////// base-most Serializer type (normally no need to change this) 00038 #ifndef S11NLITE_DEFAULT_SERIALIZER_BASE_TYPE 00039 # define S11NLITE_DEFAULT_SERIALIZER_BASE_TYPE \ 00040 s11n::io::data_node_serializer<s11nlite::node_type> 00041 #endif 00042 //////////////////// must be of the base type listed above: 00043 #ifndef S11NLITE_DEFAULT_SERIALIZER_TYPE 00044 # define S11NLITE_DEFAULT_SERIALIZER_TYPE \ 00045 s11n::io::funxml_serializer<s11nlite::node_type> 00046 #endif 00047 // Note that setting that macro when compiling client code does not 00048 // affect the lib's default build-time Serializer, and thus 00049 // clients will need to call serializer_class() to set the class they 00050 // want. (Sorry!) 00051 //////////////////////////////////////////////////////////////////////// 00052 00053 //////////////////////////////////////////////////////////////////////////////// 00054 // END CLIENT-SIDE MACROS 00055 //////////////////////////////////////////////////////////////////////////////// 00056 00057 00058 00059 00060 /************************************************************************ 00061 s11nlite is a simplified subset of the s11n interface. It refines 00062 the s11n interface to it's bare minimum (or pretty close), while 00063 still leaving the full power of the underlying framework at the 00064 clients' disposals if they need it. 00065 00066 It is completely compatible with the core s11n framework, but 00067 directly provides only a subset of the interface: those operations 00068 common to most client-side use-cases, and those functions where 00069 s11nlite can eliminate one of the required template parameters 00070 (s11n's conventional NodeType argument, which s11nlite hard-codes 00071 in it's note_type typedef). 00072 00073 Many of the functors and proxies in the s11n namespace are directly 00074 usable with s11nlite without having to fight with template parameters. 00075 00076 This implementation can easily be used as a basis for writing 00077 custom client-side, s11n-based serialization frameworks. 00078 00079 Suggestions for including specific features into this interface are 00080 of course welcomed. 00081 00082 Common conventions concerning this API: 00083 00084 - node_type must conform to s11n::data_node conventions. 00085 00086 - MapType templatized types must conform to "some" std::map 00087 conventions. 00088 00089 00090 ************************************************************************/ 00091 namespace s11nlite { 00092 00093 00094 00095 /** 00096 The sharing namespace contains "sharing context" classes. 00097 */ 00098 namespace sharing { 00099 /** 00100 Internal marker class. 00101 */ 00102 struct sharing_context; 00103 } 00104 00105 /** 00106 node_type is the type used to store/load a Serializable object's data. 00107 */ 00108 typedef s11n::data_node node_type; 00109 00110 /** 00111 This is the base-most type of the serializers used by s11nlite. 00112 00113 This can be set at compile-time by defining 00114 S11NLITE_DEFAULT_SERIALIZER_BASE_TYPE to the fully-qualified 00115 class name of the base-most Serializer type. 00116 */ 00117 typedef S11NLITE_DEFAULT_SERIALIZER_BASE_TYPE serializer_base_type; 00118 00119 /** Short-form name of the base serializer type for s11n::data_node. */ 00120 typedef s11n::io::data_node_serializer<node_type> base_serializer; 00121 /** Short-form name of the compact_serializer for s11n::data_node. */ 00122 typedef s11n::io::compact_serializer<node_type> compact; 00123 /** Short-form name of the funtxt_serializer for s11n::data_node. */ 00124 typedef s11n::io::funtxt_serializer<node_type> funtxt; 00125 /** Short-form name of the funxml_serializer for s11n::data_node. */ 00126 typedef s11n::io::funxml_serializer<node_type> funxml; 00127 /** Short-form name of the parens_serializer for s11n::data_node. */ 00128 typedef s11n::io::parens_serializer<node_type> parens; 00129 /** Short-form name of the simplexml_serializer for s11n::data_node. */ 00130 typedef s11n::io::simplexml_serializer<node_type> simplexml; 00131 00132 00133 /** 00134 This is the default serializer used by s11nlite. 00135 00136 This can be set at compile-time by defining 00137 S11NLITE_DEFAULT_SERIALIZER_TYPE to the fully-qualified 00138 class name of the deserializer. The type is 00139 restricted to a subtype of S11NLITE_DEFAULT_SERIALIZER_BASE_TYPE. 00140 00141 The exact type of the default implementation is not defined 00142 by the s11nlite interface. 00143 */ 00144 typedef S11NLITE_DEFAULT_SERIALIZER_TYPE default_serializer_type; 00145 00146 00147 00148 /** 00149 Returns a new instance of the default serializer class. 00150 00151 The caller owns the returned pointer. 00152 00153 */ 00154 serializer_base_type * create_serializer(); 00155 00156 /** 00157 Returns a new instance of the given serializer class, or 0 00158 if one could not be loaded. classname must represent a subtype 00159 of serializer_base_type. 00160 00161 The caller owns the returned pointer. 00162 00163 You can also pass a serializer's cookie here, and that 00164 should return the same thing as it's class name would. 00165 00166 The internally-supported serializes all support a "friendly 00167 form" of the name, an alias registered with their 00168 classloader. Passing either this name or the cookie of the 00169 Serializer should return the same thing as the classname 00170 itself would. 00171 00172 Short-form names of internally-supported Serializers: 00173 00174 - compact 00175 - funtxt, text, txt 00176 - funxml, xml 00177 - parens 00178 - simplexml 00179 00180 Note that the short-form name is always the same as that of 00181 the underlying Serializer class, minus the _serializer 00182 suffix. This is purely a convention, and a rule. 00183 00184 */ 00185 serializer_base_type * 00186 create_serializer( const std::string & classname ); 00187 00188 00189 /** 00190 Sets the current Serializer class used by s11nlite's 00191 create_serializer(). Pass it a class name, or one of 00192 the convenience names: 00193 00194 compact, funtxt, funxml, simplexml, parens 00195 */ 00196 void serializer_class( const std::string & ); 00197 00198 /** 00199 Gets the name of the current Serializer type. 00200 */ 00201 std::string serializer_class(); 00202 00203 00204 /** 00205 A non-const overload. Ownership is not modified by calling 00206 this function: normally the parent node owns it. 00207 */ 00208 node_type * 00209 find_child( node_type & parent, 00210 const std::string subnodename ); 00211 00212 /** 00213 Equivalent to s11n::find_child_by_name( parent, subnodename ). 00214 */ 00215 const node_type * 00216 find_child( const node_type & parent, 00217 const std::string subnodename ); 00218 00219 /** 00220 See s11n::serialize(). 00221 */ 00222 template <typename SerializableType> 00223 bool serialize( node_type & dest, 00224 const SerializableType & src ) 00225 { 00226 return s11n::serialize<node_type,SerializableType>( dest, src ); 00227 } 00228 00229 /** 00230 See s11n::serialize(). 00231 */ 00232 template <typename SerializableType> 00233 bool serialize_subnode( node_type & dest, 00234 const std::string & subnodename, 00235 const SerializableType & src ) 00236 { 00237 node_type * n = new node_type; 00238 n->name( subnodename ); 00239 if( serialize<SerializableType>( *n, src ) ) 00240 { 00241 dest.children().push_back( n ); 00242 } 00243 else 00244 { 00245 delete( n ); 00246 n = 0; 00247 } 00248 return n != 0; 00249 } 00250 00251 /** 00252 Saves the given node to the given ostream using the default 00253 serializer type. 00254 00255 Returns true on success, false on error. 00256 00257 ONLY use this for saving root nodes! 00258 */ 00259 bool save( const node_type & src, std::ostream & dest ); 00260 00261 /** 00262 Saves the given node to the given filename using the default 00263 serializer type. 00264 00265 Returns true on success, false on error. 00266 00267 ONLY use this for saving root nodes! 00268 */ 00269 bool save( const node_type & src, const std::string & filename ); 00270 00271 /** 00272 Saves the given Serializable to the given ostream using the default 00273 serializer type. 00274 00275 Returns true on success, false on error. 00276 00277 ONLY use this for saving root nodes! 00278 */ 00279 template <typename SerializableType> 00280 bool save( const SerializableType & src, std::ostream & dest ) 00281 { 00282 node_type n; 00283 if( ! serialize( n, src ) ) return false; 00284 return save( n, dest ); 00285 } 00286 00287 /** 00288 Saves the given Serializable to the given filename using the default 00289 serializer type. 00290 00291 Returns true on success, false on error. 00292 00293 ONLY use this for saving root nodes! 00294 */ 00295 template <typename SerializableType> 00296 bool save( const SerializableType & src, const std::string & dest ) 00297 { 00298 typedef std::auto_ptr<std::ostream> AP; 00299 AP os = AP( s11n::get_ostream( dest ) ); 00300 if( ! os.get() ) return 0; 00301 return save( src, *os ); 00302 } 00303 00304 /** 00305 Tries to load a node from the given filename. 00306 00307 The caller owns the returned pointer. 00308 */ 00309 node_type * load_node( const std::string & src ); 00310 00311 /** 00312 Tries to load a node from the given input stream. 00313 00314 The caller owns the returned pointer. 00315 00316 Only usable for loading ROOT nodes. 00317 */ 00318 node_type * load_node( std::istream & src ); 00319 00320 00321 00322 00323 00324 /** 00325 deserializer is a functor for deserializing 00326 SerializableType objects from node_type objects. 00327 00328 Sometimes this may be more convenient to use than 00329 deserialize(), e.g., when deserializing multiple 00330 objects of the same type. 00331 00332 Sample usage: 00333 <pre> 00334 typedef deserializer<MyBaseType> Deser; 00335 Deser d; 00336 MyBaseType * obj = d( my_data_node ); 00337 </pre> 00338 00339 */ 00340 template <typename SerializableType> 00341 struct node_deserializer 00342 { 00343 typedef SerializableType serializable_type; 00344 serializable_type * operator()( const node_type & src ) 00345 { 00346 return s11n::deserialize<node_type,serializable_type>( src ); 00347 } 00348 }; 00349 00350 /** 00351 A free-function equivalent to deserializer<>. 00352 00353 It is implemented in terms of deserializer<>, 00354 so that specializations of that class will 00355 be picked up by calls to this function, allowing 00356 clients to selectively replace certain ones. 00357 00358 ACHTUNG: if you are using both s11n and s11nlite 00359 namespaces this function will be ambiguous with one provided 00360 in the namespace s11n. You must then qualify it 00361 with the namespace of the one you wish to use. 00362 */ 00363 template <typename SerializableType> 00364 SerializableType * deserialize( const node_type & src ) 00365 { 00366 return s11n::deserialize<node_type,SerializableType>( src ); 00367 } 00368 00369 00370 00371 /** 00372 Tries to find a subnode of src named subnodename. If it finds 00373 it, it tries to deserialize<SerializableT>( thenode 00374 ). Returns the result of deserialize( thenode ), or 0 if no 00375 such child could be found. 00376 */ 00377 template <typename SerializableType> 00378 SerializableType * deserialize( const node_type & src, const std::string & subnodename ) 00379 { 00380 const node_type * ch = s11n::find_child_by_name( src, subnodename ); 00381 if( ! ch ) return 0; 00382 return deserialize<SerializableType>( *ch ); 00383 } 00384 00385 /** 00386 Tries to deserialize src into target. Returns true on 00387 success. If false is returned then target is not guaranteed 00388 to be in a useful state: this depends entirely on the 00389 object (but, it could be argued, it it was in a useful 00390 state it's deserialize operator would have returned true!). 00391 */ 00392 template <typename DeserializableT> 00393 bool deserialize( const node_type & src, DeserializableT & target ) 00394 { 00395 return s11n::deserialize<node_type,DeserializableT>( src, target ); 00396 } 00397 00398 /** 00399 Exactly like deserialize(), but operates on a subnode of 00400 src named subnodename. Returns false if no such file is 00401 found. 00402 */ 00403 template <typename DeserializableT> 00404 bool deserialize_subnode( const node_type & src, 00405 const std::string & subnodename, 00406 DeserializableT & target ) 00407 { 00408 return s11n::deserialize_subnode< 00409 node_type, 00410 DeserializableT>( src, subnodename, target ); 00411 } 00412 00413 /** 00414 Exactly like deserialize(), but operates on a subnode of 00415 src named subnodename. Returns false if no such file is 00416 found. 00417 */ 00418 template <typename DeserializableT> 00419 DeserializableT * deserialize_subnode( const node_type & src, 00420 const std::string & subnodename ) 00421 { 00422 return s11n::deserialize_subnode< 00423 node_type, 00424 DataNodeType>( src, subnodename ); 00425 } 00426 00427 00428 /** 00429 Tries to load a data_node from src, then deserialize that 00430 to a SerializableType. 00431 */ 00432 template <typename SerializableType> 00433 SerializableType * load_serializable( std::istream & src ) 00434 { 00435 typedef std::auto_ptr<node_type> AP; 00436 AP n = AP( load_node( src ) ); 00437 if( ! n.get() ) return 0; 00438 return deserialize<SerializableType>( *n ); 00439 } 00440 00441 /** 00442 Overloaded form which takes a file name. 00443 00444 See get_istream() for a description of the AsFile 00445 parameter. 00446 */ 00447 template <typename SerializableType> 00448 SerializableType * load_serializable( const std::string & src, bool AsFile = true ) 00449 { 00450 typedef std::auto_ptr<std::istream> AP; 00451 AP is = AP( s11n::get_istream( src, AsFile ) ); 00452 if( ! is.get() ) return 0; 00453 return load_serializable<SerializableType>( *is ); 00454 } 00455 00456 /** 00457 See s11n::clone(). 00458 */ 00459 template <typename SerializableType> 00460 SerializableType * clone( const SerializableType & tocp ) 00461 { 00462 node_type node; 00463 if( ! serialize( node, tocp ) ) return 0; 00464 return deserialize<SerializableType>( node ); 00465 } 00466 00467 /** 00468 See s11n::s11n_cast(). 00469 */ 00470 template <typename Type1, typename Type2> 00471 bool s11n_cast( const Type1 & t1, Type2 & t2 ) 00472 { 00473 node_type n; 00474 return serialize( n, t1 ) && deserialize( n, t2 ); 00475 } 00476 00477 00478 00479 } // namespace s11nlite 00480 00481 #undef S11NLITE_NODE_TYPE 00482 #undef S11NLITE_DEFAULT_SERIALIZER_BASE_TYPE 00483 #undef S11NLITE_DEFAULT_SERIALIZER 00484 00485 #endif // S11N_LITE_H_INCLUDED

Generated on Tue Jul 20 10:46:48 2004 for s11n by doxygen 1.3.7