00001 #ifndef s11n_s11nlite_SERIALIZABLE_BASE_HPP_INCLUDED 00002 #define s11n_s11nlite_SERIALIZABLE_BASE_HPP_INCLUDED 00003 #include <string> 00004 #include <iostream> 00005 namespace s11nlite { 00006 /** 00007 A convenience base type for polymorphic serializable types. 00008 It provides easy access to load/save support for polymorphic 00009 Serializables which subclass it. It has no public constructor 00010 and can only be used via subclassing. 00011 00012 Subclasses must reimplement the protected virtual functions 00013 s11n_serialize() and s11n_deserialize(). They may optionally 00014 override the other protected members, but do not need to. 00015 */ 00016 class serializable_base 00017 { 00018 public: 00019 /** The s11n-compliant serialization node type. */ 00020 typedef s11nlite::node_type node_type; 00021 /** The s11n-compliant serialization node traits type. */ 00022 typedef ::s11nlite::node_traits node_traits; 00023 /** Frees internal resources. */ 00024 virtual ~serializable_base(); 00025 /** See the protected member s11n_serialize(). */ 00026 bool serialize( node_type & dest ) const; 00027 /** 00028 See the protected member s11n_deserialize(). 00029 */ 00030 bool deserialize( node_type const & src ); 00031 /** 00032 Returns the class name of this type as used by 00033 the de/serialization process. See the protected 00034 setter for more information. 00035 */ 00036 char const * s11n_class() const; 00037 00038 /** 00039 See the protected member s11n_load(). 00040 */ 00041 bool load( std::string const & ); 00042 /** 00043 Convenience overload. 00044 */ 00045 bool load( std::istream & ); 00046 /** 00047 See the protected member s11n_save(). 00048 */ 00049 bool save( std::string const & ) const; 00050 /** 00051 Convenience overload. 00052 */ 00053 bool save( std::ostream & ) const; 00054 /** 00055 Returns the file extension associated with this type. 00056 If you need it permanently, copy it, because 00057 any call to the setter overload of this func will 00058 invalidate it. 00059 */ 00060 char const * s11n_file_extension(); 00061 00062 /** 00063 Returns true if the given file name has a trailing suffix 00064 equal to s11n_file_extension(). The function may be 00065 reimplemented to check against varying extensions, to 00066 return true for other filename types (e.g. URLs) handled by 00067 subclasses, etc. 00068 00069 The intention is that client applications can ask an object 00070 if it knows how to handle a specific file before attempting 00071 to deserialize it. It's just a half-ass check, as a file 00072 extension doesn't have to map to a specific file type, but 00073 it's useful in some cases. 00074 00075 Note that it does a case-sensitive check. 00076 */ 00077 virtual bool filename_matches( std::string const & ) const; 00078 00079 protected: 00080 /** Serializes this object to dest. Subclasses must reimplement 00081 this to serialize any data they want. They must call 00082 this implementation before starting, as this sets 00083 the proper polymorphic class name in dest. 00084 */ 00085 virtual bool s11n_serialize( node_type & dest ) const; 00086 /** 00087 Deserializes src to this object. 00088 00089 If src does not contain data for the same polymorphic type 00090 as this object (as determined by comparing s11n_class() to 00091 node_traits::class_name(src)), deserialization will fail and 00092 an s11n_exception is thrown. 00093 00094 Subclasses should call this implementation first, to allow 00095 it to do its error checking. If this routine fails, 00096 the subclass should pass on the error. 00097 */ 00098 virtual bool s11n_deserialize( node_type const & src ); 00099 00100 /** 00101 Tries to deserialize the contents of the given file into 00102 this object using the deserialize() member. 00103 00104 Returns true on success, false on error. 00105 */ 00106 virtual bool s11n_load( std::string const & ); 00107 /** See s11n_load(std::string). This functions identically but 00108 accepts a stream instead of a string. */ 00109 virtual bool s11n_load( std::istream & ); 00110 /** 00111 Serializes this object's state to the given file. If a 00112 s11n_file_extension() has been set, it is automatically 00113 appended to the name if the name doesn't have that 00114 extension already. It is serialized by calling the 00115 serialize() member function. 00116 00117 Returns true on success, false on error. 00118 */ 00119 virtual bool s11n_save( std::string const & ) const; 00120 00121 /** See s11n_save(std::string). This functions identically but 00122 accepts a stream instead of a string. */ 00123 virtual bool s11n_save( std::ostream & ) const; 00124 00125 /** Sets s11n class name (to be used for de/serialization) and 00126 sets s11n_file_extension() to cn prefixed by a 00127 '.'. e.g. if cn=="MyType" then s11n_file_extension(".MyType") 00128 is set. 00129 00130 Note that className gets copied by this object, so it 00131 need not be a static string. 00132 00133 Subclasses must set className to ensure that polymorphic 00134 deserialization works properly. The name must stay 00135 constant for the life of the serialized data. Changing 00136 this value for a given subclass may break loading of older 00137 serialized data. 00138 */ 00139 explicit serializable_base(char const * className ); 00140 00141 /** 00142 Sets the file extension for this type. When 00143 save() is called, that file extension is 00144 appended to the filename automatically 00145 if needed. The extension may be 0. 00146 00147 Note that the "dot" part of the extension must be 00148 explicit. e.g. use s11n_file_extension(".foo") instead of 00149 s11n_file_extension("foo"). 00150 00151 This routine makes a copy of the extension string. 00152 */ 00153 void s11n_file_extension( std::string const & ); 00154 00155 private: 00156 std::string m_cname; 00157 std::string m_ext; 00158 00159 }; 00160 struct serializable_base_s11n 00161 { 00162 /** Returns src.serialize(dest). */ 00163 bool operator()( node_type & dest, serializable_base const & src ) const; 00164 /** Returns dest.deserialize(src). */ 00165 bool operator()( node_type const & src, serializable_base & dest ) const; 00166 }; 00167 } // namespace 00168 // Register serializable_base with s11n: 00169 #define S11N_TYPE s11nlite::serializable_base 00170 #define S11N_TYPE_NAME "serializable_base" 00171 #define S11N_SERIALIZE_FUNCTOR s11nlite::serializable_base_s11n 00172 #define S11N_ABSTRACT_BASE 00173 #include <s11n.net/s11n/reg_s11n_traits.hpp> 00174 #endif // s11n_s11nlite_SERIALIZABLE_BASE_HPP_INCLUDED