s11nlite.hpp

Go to the documentation of this file.
00001 #ifndef S11N_LITE_H_INCLUDED
00002 #define S11N_LITE_H_INCLUDED 1
00003 
00004 ////////////////////////////////////////////////////////////////////////
00005 // headers which want to check for s11nlite's inclusion should check
00006 // for:
00007 #define s11n_S11NLITE_INCLUDED 1
00008 // That's "the official way" to know if s11nlite is avaliable.
00009 ////////////////////////////////////////////////////////////////////////
00010 
00011 /**
00012    s11nlite is a simplified subset of the s11n interface, combining
00013    the APIs from the core and the s11n::io namespace into a single
00014    API. It refines the s11n interface to almost-minimal, while still
00015    leaving the full power of the underlying framework at clients'
00016    disposals if they need it. It also provides a binding to the
00017    default i/o implementation (the s11n::io-related Serializers),
00018    meaning that clients don't have to deal with file formats at all,
00019    and almost never even need to deal with the Serializer interface.
00020 
00021    It is completely compatible with the core s11n framework, but
00022    directly provides only a subset of the interface: those operations
00023    common to most client-side use-cases, and those functions where
00024    s11nlite can eliminate one of the required template parameters
00025    (s11n's conventional NodeType argument, which s11nlite hard-codes
00026    in its note_type typedef).
00027 
00028    This implementation can easily be used as a basis for writing
00029    custom client-side, s11n-based serialization frameworks.
00030 
00031    Suggestions for including specific features into this interface are
00032    of course welcomed.
00033 
00034    Common conventions concerning this API:
00035 
00036    - node_type must conform to s11n's S11n Node conventions.
00037 
00038    - node_traits is equivalent to s11n::node_traits<node_type>.
00039 
00040    - Serializers usable by this framework must be classloadable via
00041      the serializer_interface classloader (including all that this
00042      implies).
00043 
00044 
00045      As of version 1.1, s11nlite is primarily a wrapper around the
00046      type s11nlite::client_api<>. Many of s11nlite's functions
00047      internally use a client_api instance to do their work. This
00048      allows clients to swap out most of the s11nlite implementation
00049      with their own at runtime, while still allowing all s11nlite
00050      clients to use the same front-end API.
00051 
00052 
00053      License: Do As You Damned Well Please
00054 
00055      Author: stephan@s11n.net
00056 */
00057 namespace s11nlite { /** here to please doxygen :( */ }
00058 
00059 #include <memory> // auto_ptr
00060 #include <iterator> // insert_interator<>
00061 
00062 #include <s11n.net/s11n/s11n.hpp> // the core s11n framework
00063 #include <s11n.net/s11n/io/data_node_io.hpp> // s11n::io::data_node_serializer class
00064 #include <s11n.net/s11n/client_api.hpp> // the "real" implementation for most of s11nlite.
00065 
00066 
00067 namespace s11nlite {
00068 
00069 
00070 
00071     /**
00072        client_interface defines the interface used/returned by the
00073        instance() functions. By subclassing this type and
00074        reimplmenting the appropriate virtual functions, a client-supplied
00075        instance of this type can be plugged in as the primary s11nlite API
00076        handler. This allows, for example, transparently adding compression
00077        or network support to s11nlite.
00078     */
00079     typedef client_api<s11n::s11n_node> client_interface;
00080 
00081         /**
00082            node_type is the type used to store/load a Serializable
00083            object's data.
00084         */
00085         typedef client_interface::node_type node_type;
00086 
00087         /** The s11n::node_traits type for node_type. */
00088         typedef client_interface::node_traits node_traits;
00089 
00090         /**
00091            This is the base-most type of the serializers used by s11nlite.
00092         */
00093         typedef client_interface::serializer_interface serializer_interface;
00094 
00095     /**
00096        Returns the client_interface object used by the s11nlite
00097        API. This is guaranteed to return *some* object, except
00098        possibly post-main() (where all bets are off).
00099 
00100        See instance(client_interface*) for more details.
00101     */
00102     client_interface & instance();
00103 
00104     /**
00105        Sets the client_interface object used by the s11nlite
00106        API. Ownership of newinstance IS NOT transfered. Passing
00107        NULL will cause it to revert to the default instance.
00108        newinstance must live as long as any client is using
00109        s11nlite, and when newinstance is destroyed, 0 must be
00110        passed to this function to disassociate the object from the
00111        library.
00112     */
00113     void instance( client_interface * newinstance );
00114 
00115         /**
00116            Returns a new instance of the default serializer class.
00117 
00118            The caller owns the returned pointer.
00119 
00120          */
00121         serializer_interface * create_serializer();
00122 
00123         /**
00124            Returns a new instance of the given serializer class, or 0
00125            if one could not be loaded. classname must represent a subtype
00126            of serializer_interface.
00127 
00128            The caller owns the returned pointer.
00129 
00130            You can also pass a serializer's cookie here, and that
00131            should return the same thing as its class name would.
00132 
00133            The internally-supported serializers all support a "friendly
00134            form" of the name, an alias registered with their
00135            classloader. Passing either this name or the cookie of the
00136            Serializer should return the same thing as the classname
00137            itself would.
00138 
00139            Short-form names of internally-supported Serializers:
00140 
00141            - compact (also called 51191011)
00142            - expat (IF s11n was built with libexpat support)
00143            - funtxt
00144            - funxml
00145            - parens
00146            - simplexml
00147            - wesnoth
00148 
00149            Note that the short-form name is always the same as that of
00150            the underlying Serializer class, minus the _serializer
00151            suffix. This is purely a convention, and not a rule. This command
00152        will use s11n::plugin support, if available, to dynamically
00153        load new serializers. Simply name the DLL the same as the class,
00154        without any namespace part in the filename, and your platform-specific
00155        DLL file extension (e.g. .dll, .so, or .dylib).
00156          */
00157         serializer_interface *
00158         create_serializer( const std::string & classname );
00159 
00160 
00161         /**
00162            Sets the current Serializer class used by s11nlite's
00163            create_serializer(). Pass it a class name, or one of the
00164            convenience names listed in create_serializer(string).
00165         */
00166         void serializer_class( const std::string & );
00167 
00168         /**
00169            Gets the name of the current Serializer type.
00170         */
00171         std::string serializer_class();
00172 
00173 
00174         /**
00175            A non-const overload. Ownership is not modified by calling
00176            this function: normally the parent node owns it.
00177         */
00178         node_type *
00179         find_child( node_type & parent,
00180                     const std::string subnodename );
00181 
00182         /**
00183            Equivalent to s11n::find_child_by_name( parent, subnodename ).
00184         */
00185         const node_type *
00186         find_child( const node_type & parent,
00187                     const std::string subnodename );
00188 
00189         /**
00190            See s11n::serialize().
00191         */
00192         template <typename SerializableType>
00193         bool serialize( node_type & dest,
00194                         const SerializableType & src )
00195         {
00196                 return instance().template serialize<SerializableType>( dest, src );
00197         }
00198 
00199         /**
00200            See s11n::serialize().
00201         */
00202         template <typename SerializableType>
00203         bool serialize_subnode( node_type & dest,
00204                                 const std::string & subnodename,
00205                                 const SerializableType & src )
00206         {
00207         return instance().template serialize_subnode<SerializableType>( dest, subnodename, src );
00208         }
00209 
00210        
00211         /**
00212         Saves the given node to the given ostream using the default
00213         serializer type.
00214 
00215         Returns true on success, false on error.
00216 
00217         ONLY use this for saving root nodes!
00218         */
00219         bool save( const node_type & src, std::ostream & dest );
00220 
00221         /**
00222         Saves the given node to the given filename using the default
00223         serializer type.
00224 
00225         Returns true on success, false on error.
00226 
00227         ONLY use this for saving root nodes!
00228         */
00229         bool save( const node_type & src, const std::string & filename );
00230 
00231         /**
00232         Saves the given Serializable to the given ostream using the default
00233         serializer type.
00234 
00235         Returns true on success, false on error.
00236 
00237         ONLY use this for saving root nodes!
00238         */
00239         template <typename SerializableType>
00240         bool save( const SerializableType & src, std::ostream & dest )
00241         {
00242         return instance().template save<SerializableType>( src, dest );
00243         }
00244         /**
00245         Saves the given Serializable to the given filename using the default
00246         serializer type.
00247         
00248         Returns true on success, false on error.
00249 
00250         ONLY use this for saving root nodes!
00251         */
00252         template <typename SerializableType>
00253         bool save( const SerializableType & src, const std::string & dest )
00254         {
00255         return instance().template save<SerializableType>(src,dest);
00256         }
00257 
00258         /**
00259            Tries to load a node from the given filename.
00260 
00261            The caller owns the returned pointer.
00262 
00263            Only usable for loading ROOT nodes.
00264          */        
00265         node_type * load_node( const std::string & src );
00266 
00267         /**
00268            Tries to load a node from the given input stream.
00269 
00270            The caller owns the returned pointer.
00271 
00272            Only usable for loading ROOT nodes.
00273          */        
00274         node_type * load_node( std::istream & src );
00275 
00276 
00277         /**
00278        See s11n::deserialize().
00279 
00280            ACHTUNG: if you are using both s11n and s11nlite
00281            namespaces this function will be ambiguous with one provided
00282            in the namespace s11n. You must then qualify it
00283            with the namespace of the one you wish to use.
00284         */
00285         template <typename SerializableType>
00286         SerializableType * deserialize( const node_type & src )
00287         {
00288                 return instance().template deserialize<SerializableType>( src );
00289         }
00290 
00291 
00292 
00293         /**
00294            Tries to deserialize src into target. Returns true on
00295            success. If false is returned then target is not guaranteed
00296            to be in a useful state: this depends entirely on the
00297            object (but, it could be argued, if it was in a useful
00298            state then its deserialize operator would have returned
00299            true!).
00300 
00301        DO NOT PASS A POINTER TYPE TO THIS FUNCTION. It will not do
00302        what you want it to, and it will likely cause a leak. If
00303        you want to directly deserialize to a pointer, use the
00304        s11n::deserialize<>() overload which takes a reference to a
00305        pointer.
00306         */
00307         template <typename DeserializableT>
00308         bool deserialize( const node_type & src, DeserializableT & target )
00309         {
00310                 return instance().template deserialize<DeserializableT>( src, target );
00311         }
00312 
00313 
00314         /**
00315            Exactly like deserialize(), but operates on a subnode of
00316            src named subnodename. Returns false if no such file is
00317            found.
00318          */
00319         template <typename DeserializableT>
00320         bool deserialize_subnode( const node_type & src,
00321                                   const std::string & subnodename,
00322                                   DeserializableT & target )
00323         {
00324                 return instance().template deserialize_subnode<DeserializableT>( src, subnodename, target );
00325         }
00326 
00327         /**
00328            Exactly like deserialize(), but operates on a subnode of
00329            src named subnodename. Returns 0 if no such subnode is
00330            found.
00331          */
00332         template <typename DeserializableT>
00333         DeserializableT * deserialize_subnode( const node_type & src,
00334                                                const std::string & subnodename )
00335         {
00336                 return instance().template deserialize_subnode<DeserializableT>( src, subnodename );
00337         }
00338 
00339 
00340         /**
00341            Tries to load an S11nNode from src, then deserialize that
00342            to a SerializableType.
00343         */
00344         template <typename SerializableType>
00345         SerializableType * load_serializable( std::istream & src )
00346         {
00347         return instance().template load_serializable<SerializableType>( src );
00348         }
00349 
00350         /**
00351            Overloaded form which takes a file name.
00352 
00353        1.1.3: removed the never-used 2nd parameter.
00354         */
00355         template <typename SerializableType>
00356         SerializableType * load_serializable( const std::string & src )
00357         {
00358         return instance().template load_serializable<SerializableType>( src );
00359         }
00360 
00361         /**
00362            See s11n::s11n_clone().
00363 
00364        This function was renamed from clone() in version 1.1.
00365         */
00366         template <typename SerializableType>
00367         SerializableType * s11n_clone( const SerializableType & tocp )
00368         {
00369         return instance().template clone<SerializableType>( tocp );
00370         }
00371 
00372         /**
00373            See s11n::s11n_cast().
00374         */
00375         template <typename Type1, typename Type2>
00376         bool s11n_cast( const Type1 & t1, Type2 & t2 )
00377         {
00378         return instance().template cast<Type1,Type2>(t1,t2);
00379         }
00380 
00381 
00382 
00383     /**
00384        A binary functor to save s-nodes and Serializables
00385        using s11nlite::save().
00386 
00387        Added in version 1.1.3.
00388     */
00389     struct save_binary_f
00390     {
00391         typedef ::s11nlite::node_type node_type;
00392 
00393         /**
00394            Returns save(src,dest).
00395         */
00396         inline bool operator()( node_type const & src, std::string const & dest ) const
00397         {
00398             return ::s11nlite::save( src, dest );
00399         }
00400 
00401         /**
00402            Returns save(src,dest).
00403         */
00404         inline bool operator()( node_type const & src, std::ostream & dest ) const
00405         {
00406             return ::s11nlite::save( src, dest );
00407         }
00408 
00409         /**
00410            Returns save(src,dest).
00411         */
00412         template <typename SerT>
00413         inline bool operator()( SerT const & src, std::string const & dest ) const
00414         {
00415             return ::s11nlite::save( src, dest );
00416         }
00417 
00418         /**
00419            Returns save(src,dest).
00420         */
00421         template <typename SerT>
00422         inline bool operator()( SerT const & src, std::ostream  & dest ) const
00423         {
00424             return ::s11nlite::save( src, dest );
00425         }
00426 
00427 
00428     };
00429 
00430     /**
00431        A functor which forwards to s11nlite::save(node_type,string).
00432 
00433        See save_stream_unary_f for notes about the parent classes.
00434        Those same notes apply here.
00435 
00436        Added in version 1.1.3.
00437     */
00438     struct save_string_unary_f : ::s11n::serialize_unary_serializable_f_tag,
00439                      ::s11n::serialize_unary_node_f_tag
00440     {
00441         typedef ::s11nlite::node_type node_type;
00442         const std::string destination;
00443         /**
00444            Specifies that operator() should send output to the
00445            given resource name (normally, but not always, a
00446            filename).
00447         */
00448         explicit save_string_unary_f( std::string const & s ) : destination(s)
00449         {}
00450 
00451         /**
00452            Returns s11nlite::save( src, this->destination ).
00453         */
00454         bool operator()( node_type const & src ) const
00455         {
00456             return ::s11nlite::save( src, this->destination );
00457         }
00458 
00459         /**
00460            Returns s11nlite::save( src, this->destination ).
00461         */
00462         template <typename SerT>
00463         bool operator()( SerT const & src ) const
00464         {
00465             return ::s11nlite::save( src, this->destination );
00466         }
00467     };
00468 
00469 
00470     /**
00471        A unary functor which forwards to
00472        s11nlite::save(node_type|SerializableT,ostream).
00473 
00474        Note that while this type conforms to two s11n-standard
00475        tags (its parent classes), it is not *really* intended to
00476        be used as a normal part of a serialization algorithm. That
00477        said, that approach may indeed turn out to have some
00478        interesting uses. It certainly has some pitfalls, in any
00479        case, so don't blythely do it.
00480 
00481        Added in version 1.1.3.
00482     */
00483     struct save_stream_unary_f : ::s11n::serialize_unary_serializable_f_tag,
00484                      ::s11n::serialize_unary_node_f_tag
00485     {
00486         typedef ::s11nlite::node_type node_type;
00487         std::ostream & stream;
00488         /**
00489            Specifies that operator() should send output to the
00490            given stream.
00491         */
00492         explicit save_stream_unary_f( std::ostream & os ) : stream(os)
00493         {}
00494 
00495         /**
00496            Returns s11nlite::save( src, this->stream ).
00497         */
00498         bool operator()( node_type const & src ) const
00499         {
00500             return ::s11nlite::save( src, this->stream );
00501         }
00502 
00503         /**
00504            Returns s11nlite::save( src, this->stream ).
00505         */
00506         template <typename SerT>
00507         bool operator()( SerT const & src ) const
00508         {
00509             return ::s11nlite::save( src, this->stream );
00510         }
00511     };
00512 
00513 
00514     /**
00515        An "implementation detail" nullary functor type to simplify
00516        implementations of save_xxx_nullary_f. It is not intended
00517        for standalone use, but as a base type for
00518        save_xxx_nullary_f functors.
00519 
00520        T must be one of:
00521 
00522        - A non-cvp (const/volatile/pointer) qualified
00523        s11nlite::node_type
00524 
00525        - A non-cvp qualified Serializable type.
00526 
00527        OutputT is expected to be one of:
00528 
00529        - [const] std::string. NOT a reference, because we're
00530        lazily evaluating and don't want to step on a dead
00531        temporary.
00532 
00533        - (std::ostream &)
00534 
00535        If s11nlite::save() is ever overloaded, e.g., to take your
00536        own custom output destination type, then that type will
00537        also theoretically work here
00538 
00539        See save() for important notes about when you should NOT
00540        use this. In particular, this functor should not normally
00541        be used with std::for_each(), as save() expects to store
00542        ONE object in each target. Loading objects saved this way
00543        won't work: only the first one is likely to be read by
00544        load-time. Exceptions to this caveat include network
00545        streams or debug channels.
00546 
00547        Added in version 1.1.3.
00548 
00549     */
00550     template <typename T,typename OutputT>
00551     struct save_nullary_base_f
00552     {
00553         T const & source;
00554         OutputT destination;
00555         /**
00556            Both src and dest are expected to outlive this
00557            object, unless of source OutputT is a value type,
00558            in which case we copy dest at ctor time, instead of
00559            taking a (const &), to avoid us accidentally storing
00560            a reference to a temporary which probably won't
00561            exist when operator() is called.
00562         */
00563         save_nullary_base_f( T const & src, OutputT dest )
00564             : source(src), destination(dest)
00565         {}
00566         /**
00567            Returns ::s11nlite::save( this->source, this->destination ).
00568         */
00569         inline bool operator()() const
00570         {
00571             return ::s11nlite::save( this->source, this->destination );
00572         }
00573     };
00574 
00575     /**
00576        A nullary functor forwarding to s11nlite::save(node,string).
00577     */
00578     struct save_node_string_nullary_f : save_nullary_base_f< ::s11nlite::node_type, const std::string >
00579     {
00580         typedef save_nullary_base_f< ::s11nlite::node_type, const std::string > parent_t;
00581         typedef ::s11nlite::node_type node_type;
00582         /**
00583            See the notes in the base type API for requirements
00584            of src and dest.
00585         */
00586         save_node_string_nullary_f( node_type const & src, std::string const & dest )
00587             : parent_t( src, dest )
00588         {}
00589 
00590     };
00591 
00592     /**
00593        A nullary functor forwarding to s11nlite::save(node,string).
00594     */
00595     struct save_node_stream_nullary_f : save_nullary_base_f< ::s11nlite::node_type, std::ostream & >
00596     {
00597         typedef save_nullary_base_f< ::s11nlite::node_type, std::ostream & > parent_t;
00598         typedef ::s11nlite::node_type node_type;
00599         /**
00600            See the notes in the base type API for requirements
00601            of src and dest.
00602         */
00603         save_node_stream_nullary_f( node_type const & src, std::ostream & dest )
00604             : parent_t( src, dest )
00605         {}
00606     };
00607 
00608     /**
00609        A nullary functor forwarding to s11nlite::save(SerT,string).
00610     */
00611     template <typename SerT>
00612     struct save_serializable_string_nullary_f : save_nullary_base_f< SerT, const std::string >
00613     {
00614         typedef save_nullary_base_f< SerT, const std::string > parent_t;
00615         /**
00616            See the notes in the base type API for requirements
00617            of src and dest.
00618         */
00619         save_serializable_string_nullary_f( SerT const & src, std::string const & dest )
00620             : parent_t( src, dest )
00621         {}
00622     };
00623 
00624     /**
00625        A nullary functor forwarding to s11nlite::save(Serializable,ostream).
00626     */
00627     template <typename SerT>
00628     struct save_serializable_stream_nullary_f : save_nullary_base_f< SerT, std::ostream & >
00629     {
00630         /**
00631            See the notes in the base type API for requirements
00632            of src and dest.
00633         */
00634         typedef save_nullary_base_f< SerT, std::ostream & > parent_t;
00635         save_serializable_stream_nullary_f( SerT const & src, std::ostream & dest )
00636             : parent_t( src, dest )
00637         {}
00638     };
00639 
00640 
00641     /**
00642        Returns save_serializable_string_nullary_f<SerT>( src, dest ).
00643     */
00644     template <typename SerT>
00645     inline save_serializable_string_nullary_f<SerT>
00646     save_nullary_f( SerT const & src, std::string const & dest )
00647     {
00648         return save_serializable_string_nullary_f<SerT>( src, dest );
00649     }
00650 
00651     /**
00652        Returns save_serializable_stream_nullary_f<SerT>( src, dest ).
00653     */
00654     template <typename SerT>
00655     inline save_serializable_stream_nullary_f<SerT>
00656     save_nullary_f( SerT const & src, std::ostream & dest )
00657     {
00658         return save_serializable_stream_nullary_f<SerT>( src, dest );
00659     }
00660 
00661     /**
00662        Returns save_node_string_nullary_f( src, dest ).
00663     */
00664     inline save_node_string_nullary_f
00665     save_nullary_f( node_type const & src, std::string const & dest )
00666     {
00667         return save_node_string_nullary_f( src, dest );
00668     }
00669     /**
00670        Returns save_node_stream_nullary_f( src, dest ).
00671     */
00672     inline save_node_stream_nullary_f
00673     save_nullary_f( node_type const & src, std::ostream & dest )
00674     {
00675         return save_node_stream_nullary_f( src, dest );
00676     }
00677 
00678 
00679 
00680 
00681     /**
00682        A nullary functor to call s11nlite::load_node(istream&).
00683 
00684        Added in version 1.1.3.
00685     */
00686     struct load_node_stream_nullary_f
00687     {
00688         std::istream & stream;
00689         typedef ::s11nlite::node_type node_type;
00690         /**
00691            Specifies that operator() should fetch input from the
00692            given stream.
00693         */
00694         explicit load_node_stream_nullary_f( std::istream & s ) : stream(s)
00695         {}
00696 
00697         /**
00698            Returns s11nlite::load_node( this->stream ),
00699 
00700            Caller owns the returned object, which may be 0.
00701         */
00702         inline node_type * operator()() const
00703         {
00704             return ::s11nlite::load_node( this->stream );
00705         }
00706     };
00707 
00708     /**
00709        A nullary functor to call s11nlite::load_node(string).
00710     */
00711     struct load_node_nullary_string_f
00712     {
00713         typedef ::s11nlite::node_type node_type;
00714         const std::string resource;
00715         /**
00716            Specifies that operator() should fetch input from
00717            the given resource name (normally, but not always,
00718            a filename).
00719         */
00720         explicit load_node_nullary_string_f( std::string const & s ) : resource(s)
00721         {}
00722 
00723         /**
00724            Returns s11nlite::load_node( this->resource ).
00725 
00726            Caller owns the returned object, which may be 0.
00727         */
00728         inline node_type * operator()() const
00729         {
00730             return ::s11nlite::load_node( this->resource );
00731         }
00732     };
00733 
00734 
00735     /**
00736        Returns load_node_nullary_string_f(s).
00737     */
00738     inline load_node_nullary_string_f
00739     load_node_nullary_f( std::string const & s )
00740     {
00741         return load_node_nullary_string_f(s);
00742     }
00743 
00744     /**
00745        Returns load_node_stream_nullary_f(s).
00746     */
00747     inline load_node_stream_nullary_f
00748     load_node_nullary_f( std::istream & s )
00749     {
00750         return load_node_stream_nullary_f(s);
00751     }
00752     
00753 
00754     /**
00755        A unary functor to call s11nlite::load_node(string|stream).
00756     */
00757     struct load_node_unary_f
00758     {
00759 
00760         /**
00761            Returns s11nlite::load_node( src ).
00762         */
00763         inline bool operator()( std::string const & src ) const
00764         {
00765             return ::s11nlite::load_node( src );
00766         }
00767 
00768         /**
00769            Returns s11nlite::load_node( src ).
00770         */
00771         inline bool operator()( std::istream & src ) const
00772         {
00773             return ::s11nlite::load_node( src );
00774         }
00775     };
00776 
00777 
00778 } // namespace s11nlite
00779 
00780 #endif // S11N_LITE_H_INCLUDED

Generated on Sun Apr 27 13:16:04 2008 for libs11n by  doxygen 1.5.3