Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | 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                         DeserializableT>( 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 Thu Jun 16 16:18:12 2005 for s11n by  doxygen 1.4.3-20050530