serialize.hpp

Go to the documentation of this file.
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

Generated on Wed Jun 4 21:45:18 2008 for libs11n by  doxygen 1.5.3