00001 /*---------------------------------------------------------------------* 00002 | Library QgarLib, graphics analysis and recognition | 00003 | Copyright (C) 2004 Qgar Project, LORIA | 00004 | | 00005 | This library is free software; you can redistribute it and/or | 00006 | modify it under the terms of the GNU Lesser General Public | 00007 | License version 2.1, as published by the Free Software Foundation. | 00008 | | 00009 | This library is distributed in the hope that it will be useful, | 00010 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 00011 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 00012 | See the GNU Lesser General Public License for more details. | 00013 | | 00014 | The GNU Lesser General Public License is included in the file | 00015 | LICENSE.LGPL, in the root directory of the Qgar packaging. See | 00016 | http://www.gnu.org/licenses/lgpl.html for the terms of the license. | 00017 | To receive a paper copy, write to the Free Software Foundation, | 00018 | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 00019 | | 00020 | Contact Project Qgar for any information: | 00021 | LORIA - équipe Qgar | 00022 | B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France | 00023 | email: qgar-contact@loria.fr | 00024 | http://www.qgar.org/ | 00025 *---------------------------------------------------------------------*/ 00026 00027 00028 #ifndef __ISERIALIZABLE_H_INCLUDED__ 00029 #define __ISERIALIZABLE_H_INCLUDED__ 00030 00031 00032 /** 00033 * @file ISerializable.H 00034 * @brief Header file of class qgar::ISerializable. 00035 * 00036 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Jan Rendek">Jan Rendek</a> 00037 * @date June 28, 2004 14:34 00038 * @since Qgar 2.2 00039 */ 00040 00041 00042 // For RCS/CVS use: Do not delete 00043 /* $Id: ISerializable.H,v 1.8 2005/10/14 17:05:47 masini Exp $ */ 00044 00045 00046 00047 // STD 00048 #include <iosfwd> // Avoid including classes when not necessary 00049 #include <sstream> 00050 #include <string> 00051 // QGAR 00052 #include <qgarlib/QgarErrorIO.H> 00053 00054 00055 00056 namespace qgar 00057 { 00058 00059 /** 00060 * @page serialization Object serialization 00061 * 00062 * An object of class <b>Example</b> can be serialized and deserialized using 00063 * operators '>>' and '<<', on condition that: 00064 * 00065 * <ul> 00066 * <li> 00067 * <p> Class <b>Example</b> inherits from class <b>ISerializable</b></p> 00068 * </li> 00069 * 00070 * <li> 00071 * <p>Class <b>Example</b> is provided with appropriate implementations of 00072 * functions <b>read</b> and <b>write</b>.</p> 00073 * </li> 00074 * </ul> 00075 * 00076 * Operators '>>' and '<<' also apply to file streams, as <b>ifstream 00077 * (resp. ifstream)</b> derives from <b>istream (resp. ostream)</b>. 00078 * 00079 * See class qgar::GenQgarSegment for an example. 00080 * 00081 * A serialized object conforms to the following pattern: 00082 @code 00083 CLASS-NAME(DATA_1) ... (DATA_N) 00084 @endcode 00085 * 00086 * The source code of functions <b>read</b> and <b>write</b>, to respectively 00087 * deserialize and serialize an object of class <b>Example</b>, should typically 00088 * conform to the following patterns. 00089 * <b>Warning: Values of data members must be read and written in the same order.</b> 00090 * 00091 @code 00092 // DESERIALIZATION 00093 00094 std::istream& 00095 Example::read(std::istream& anInStream) 00096 { 00097 qgReadObjName(anInStream, "Example"); // Get class name 00098 00099 qgReadObjData(anInStream, this->_data_1); // Get first data member 00100 ... 00101 qgReadObjData(anInStream, this->_data_N); // Get last data member 00102 00103 return anInStream; 00104 } 00105 00106 // SERIALIZATION 00107 // data_1() is supposed to be the access function 00108 // of data member Example::data_1 00109 00110 std::ostream& 00111 Example::write(std::ostream& anOutStream) 00112 { 00113 anOutStream << "Example" 00114 << '(' << this->_data_1() << ')' // First data member 00115 ... 00116 << '(' << this->_data_N() << ')'; // Last data member 00117 00118 return anOutStream; 00119 } 00120 @endcode 00121 */ 00122 00123 00124 // ------------------------------------------------------------------- 00125 // D E S E R I A L I Z A T I O N 00126 // ------------------------------------------------------------------- 00127 00128 00129 /** 00130 * @name Global functions for object deserialization 00131 * @ingroup IO_SERIAL 00132 */ 00133 //@{ 00134 00135 /** 00136 * @brief Read the name part of an object. 00137 * @param anIStream input stream to read from 00138 * @param aClassName name of the object class 00139 * 00140 * @exception qgar::QgarErrorIO (error in input stream) 00141 */ 00142 void qgReadObjName(std::istream& anIStream, const char* aClassName) 00143 throw(qgar::QgarErrorIO); 00144 00145 00146 /** 00147 * @brief Read a data member of class <b>T</b>. 00148 * @param anIStream input stream to read from 00149 * @param anObject object to be deserialized 00150 * 00151 * @exception qgar::QgarErrorIO (error in input stream) 00152 */ 00153 template <class T> 00154 void qgReadObjData(std::istream& anIStream, T& anObject) 00155 00156 throw(qgar::QgarErrorIO) 00157 00158 { 00159 char c; 00160 do 00161 { 00162 anIStream.get(c); 00163 } 00164 while (isspace(c)); 00165 00166 if (c != '(') 00167 { 00168 anIStream.putback(c); 00169 throw qgar::QgarErrorIO(__FILE__, __LINE__, 00170 "template <class T> void qgar::qgReadObjData(std::istream&, T&)", 00171 "Error in input stream: '(' expected."); 00172 } 00173 00174 anIStream >> anObject; 00175 do 00176 { 00177 anIStream.get(c); 00178 } 00179 while (isspace(c)); 00180 00181 if (c != ')') 00182 { 00183 anIStream.putback(c); 00184 throw qgar::QgarErrorIO(__FILE__, __LINE__, 00185 "template <class T> void qgar::qgReadObjData(std::istream&, T&)", 00186 "Error in input stream: ')' expected."); 00187 } 00188 } 00189 00190 //@} 00191 00192 // ------------------------------------------------------------------- 00193 00194 00195 00196 00197 /** 00198 * @class ISerializable ISerializable.H "qgarlib/ISerializable.H" 00199 * @ingroup IO_SERIAL 00200 * @brief Base interface of all serializable objects. 00201 * 00202 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Jan Rendek">Jan Rendek</a> 00203 * @date June 28, 2004 14:34 00204 * @since Qgar 2.1.1 00205 */ 00206 class ISerializable 00207 { 00208 // ------------------------------------------------------------------- 00209 // P U B L I C M E M B E R S 00210 // ------------------------------------------------------------------- 00211 public: 00212 00213 /** 00214 * @brief Deserializes the current object (from an input stream). 00215 * 00216 * @param anInStream the input stream 00217 */ 00218 virtual std::istream& read(std::istream& anInStream) = 0; 00219 00220 00221 /** 00222 * @brief Serializes the current object (to an input stream). 00223 * 00224 * @param anOutStream the output stream 00225 */ 00226 virtual std::ostream& write(std::ostream& anOutStream) const = 0; 00227 00228 00229 /** @name Destructor */ 00230 // ========== 00231 //@{ 00232 /** 00233 * @brief Virtual destructor. 00234 */ 00235 virtual ~ISerializable() 00236 { 00237 /* EMPTY */ 00238 } 00239 //@} 00240 00241 // ------------------------------------------------------------------- 00242 }; // class ISerializable 00243 00244 00245 00246 00247 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00248 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00249 // GLOBAL STREAM OPERATORS TO SERIALIZE/DESERIALIZE OBJECTS 00250 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00251 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00252 00253 00254 /** 00255 * @name Stream operators for object serialization/deserialization */ 00256 // ========================================================= 00257 //@{ 00258 00259 /** 00260 * @brief Reads a serializable object from and input stream. 00261 * 00262 * @param anInStream the input stream to read an object from 00263 * @param aSerial an object implementing 00264 * the qgar::ISerializable interface 00265 * 00266 * @ingroup IO_SERIAL 00267 */ 00268 inline std::istream& operator>>(std::istream& anInStream, 00269 ISerializable& aSerial) 00270 { 00271 return aSerial.read(anInStream); 00272 } 00273 00274 00275 /** 00276 * @brief Writes a serializable object to an output stream. 00277 * 00278 * @param anOutStream the output stream to write an object to 00279 * @param aSerial an object implementing 00280 * the qgar::ISerializable interface 00281 * 00282 * @ingroup IO_SERIAL 00283 */ 00284 inline std::ostream& operator<<(std::ostream& anOutStream, 00285 const ISerializable& aSerial) 00286 { 00287 return aSerial.write(anOutStream); 00288 } 00289 00290 //@} 00291 00292 00293 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00294 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00295 00296 00297 } // namespace qgar 00298 00299 00300 #endif /* __ISERIALIZABLE_H_INCLUDED__ */