00001 /** 00002 * \file serializ.h <mi32/serializ.h> 00003 * \brief SERIALIZER class definition 00004 * 00005 * \if NODOC 00006 * $Id: serializ.h_v 1.34 2003/11/12 20:54:05 mju Exp $ 00007 * 00008 * $Log: serializ.h_v $ 00009 * Revision 1.34 2003/11/12 20:54:05 mju 00010 * Add logging methods. 00011 * 00012 * Revision 1.33 2003/09/26 19:36:41 scowan 00013 * Removed use of include file. 00014 * 00015 * Revision 1.32 2003/09/15 13:49:56 fileserver!dwilliss 00016 * Doxygen 00017 * 00018 * Revision 1.31 2003/09/09 16:22:57 mju 00019 * Add GetFilePath. 00020 * 00021 * Revision 1.30 2003/03/10 15:43:14 mju 00022 * nc. 00023 * 00024 * Revision 1.29 2002/09/11 18:00:39 mju 00025 * Add ITEM_RVCOBJITEM... 00026 * 00027 * Revision 1.28 2002/08/21 20:40:04 scowan 00028 * Deprecate old object name define. 00029 * 00030 * Revision 1.27 2002/04/04 18:36:24 mju 00031 * Remove vararg method as not used. 00032 * 00033 * Revision 1.26 2002/04/04 18:25:12 mju 00034 * Add TYPE_RVCOBJECTNAME. 00035 * Deprecate varargs method. 00036 * 00037 * Revision 1.25 2002/03/26 21:12:56 mju 00038 * Remove deprecated methods. 00039 * 00040 * Revision 1.24 2002/03/05 14:37:01 mju 00041 * Make PutItem methods public. 00042 * 00043 * Revision 1.23 2002/03/04 18:45:39 mju 00044 * Add Open() using objitem. 00045 * 00046 * Revision 1.22 2001/12/28 21:35:49 mju 00047 * SerialWrite and related methods now const. 00048 * 00049 * Revision 1.21 2001/07/12 17:30:32 dwilliss 00050 * Allow for new TYPE_StringMLRaw -- When writing to text file, don't muck 00051 * with the encoding. It's just a raw one-byte-character string who's encoding 00052 * is only known by the caller. Can't assume it's UTF8 00053 * 00054 * Revision 1.20 2001/07/12 15:55:19 dwilliss 00055 * Made PutStr() methods public (just the Unicode ones). There was a comment 00056 * on the (char*) ones to make them go away, so I left them private. All the 00057 * PutDouble, PutInt, PutUnsigned methods were already public, so why not 00058 * the string ones? 00059 * 00060 * Revision 1.19 2001/06/07 16:09:36 mju 00061 * Add details for SERIALIZABLE. 00062 * Remove unnecessary SERIALIZABLE methods. 00063 * Add TYPE_SERIALIZABLE/PTR. 00064 * 00065 * Revision 1.18 2001/03/05 21:43:59 mju 00066 * Add StatusTextUpdate. 00067 * 00068 * Revision 1.17 2000/11/30 20:36:04 mju 00069 * Add Rewind(). 00070 * 00071 * Revision 1.16 2000/11/13 15:00:31 mju 00072 * Change formula layer to use new geoformula class. 00073 * 00074 * Revision 1.14 2000/09/20 14:05:03 mju 00075 * Add flag to not prompt for missing linked file. 00076 * 00077 * Revision 1.13 2000/08/23 22:19:16 dwilliss 00078 * MISTRING? 00079 * 00080 * Revision 1.12 2000/08/18 20:08:09 dwilliss 00081 * Added LPOINT2D/LRECT2D support 00082 * 00083 * Revision 1.9 2000/03/08 18:28:05 mju 00084 * Add GetIgnoreSkippable() method. 00085 * 00086 * Revision 1.8 2000/03/03 15:03:07 mju 00087 * Add FLAG_AddOffsetCB. 00088 * 00089 * Revision 1.7 2000/02/15 14:21:46 mju 00090 * Make SkipStruct public. 00091 * 00092 * Revision 1.6 2000/01/27 15:33:40 mju 00093 * Add GetObjectName(). 00094 * 00095 * Revision 1.5 2000/01/19 18:50:49 mju 00096 * Allow FILEPATH for Make/Open. 00097 * 00098 * Revision 1.4 2000/01/19 14:22:29 mju 00099 * Make PutDouble/PutInt public. 00100 * Add GetItemValue(). 00101 * 00102 * Revision 1.3 1999/12/10 23:07:25 mju 00103 * Make SERIALIZABLE pure virtual. 00104 * 00105 * Revision 1.1 1999/12/02 23:21:26 mju 00106 * Initial revision 00107 * 00108 * \endif 00109 **/ 00110 00111 #ifndef INC_MI32_SERIALIZ_H 00112 #define INC_MI32_SERIALIZ_H 00113 00114 #ifndef INC_MI32_STDDEFNS_H 00115 #include <mi32/stddefns.h> 00116 #endif 00117 00118 #ifndef INC_MI32_RVCDEFNS_H 00119 #include <mi32/rvcdefns.h> 00120 #endif 00121 00122 #ifndef INC_MI32_MSTATUS_H 00123 #include <mi32/mstatus.h> 00124 #endif 00125 00126 //! Forward declarations 00127 00128 class SERIALIZABLE; 00129 struct RVCPARMINFO; 00130 struct MAPPROJPARM; 00131 struct COLOR; 00132 struct DPOINT2D; 00133 struct DPOINT3D; 00134 struct DRECT2D; 00135 00136 //----------------------------------------------------------------------------- 00137 // SERIALIZER class 00138 //----------------------------------------------------------------------------- 00139 00140 //! Class for storing object instances to file. 00141 //! The SERIALIZER class provides methods to write object instances to a text 00142 //! file/object and read those instances back into memory later. The design 00143 //! allows for the object structure to change while maintaining compatibility 00144 //! with previously existing files. 00145 00146 class SERIALIZER { 00147 public: 00148 00149 //! Item definition for single member of structure or class. 00150 class ITEMDEF { 00151 public: 00152 00153 //! Item types. 00154 enum TYPE { 00155 TYPE_End = 0, 00156 00157 //! Scalars 00158 TYPE_UINT8 = 1, 00159 TYPE_INT8 = 2, 00160 TYPE_UINT16 = 3, 00161 TYPE_INT16 = 4, 00162 TYPE_UINT32 = 5, 00163 TYPE_INT32 = 6, 00164 TYPE_BitUINT32 = 7, //!< Bit value in UINT32, bit specified in .extra 00165 TYPE_UInt = 8, //!< unsigned int 00166 TYPE_Int = 9, //!< int 00167 TYPE_Float = 10, //!< float 00168 TYPE_Double = 11, //!< double 00169 TYPE_Bool = 12, //!< bool 00170 TYPE_UINT8_Array = 13, 00171 TYPE_Enum = 14, //!< enum, size specified in .extra 00172 00173 //! Strings 00174 TYPE_StringU = 20, //!< UNICODE string (.extra contains size) 00175 TYPE_MISTRING = 21, //!< MISTRING 00176 TYPE_MISTRING_ML = 22, //!< Multi-line MISTRING 00177 TYPE_StringMLU = 23, //!< Multi-line Unicode string 00178 TYPE_StringPtrU = 24, //!< Pointer to Unicode string 00179 TYPE_StringA = 25, //!< ASCII string (.extra contains size) 00180 TYPE_StringMLA = 26, //!< Multi-line ASCII string (pointer) 00181 TYPE_StringPtrA = 27, //!< Multi-line Unicode String (pointer) 00182 TYPE_StringMLRaw = 28, //!< Multi-line raw (char*) string (pointer) 00183 00184 //! Files and objects 00185 TYPE_FileName = 30, //!< UNICODE filename 00186 TYPE_FILEPATH = 31, 00187 TYPE_Object = 32, //!< RVC object, type stored in ITEMDEF.extra 00188 TYPE_SubObject = 33, //!< Subobject, use previous TYPE_Object as parent 00189 TYPE_RVCOBJECTNAME = 34, //!< RVC::OBJECTNAME 00190 TYPE_RVCOBJITEMFILE = 35, //!< FilePath portion of RVC::OBJITEM 00191 TYPE_RVCOBJITEMOBJECT = 36, //!< Object portion of RVC::OBJITEM, type stored in ITEMDEF.extra 00192 00193 //! Generic 00194 TYPE_Special = 40, //!< Use cbfunc to do read and write 00195 TYPE_SpecialPtr = 41, //!< Use cbfunc to do read and write 00196 TYPE_Struct = 42, //!< Structure/class 00197 TYPE_StructPtr = 43, //!< Structure/class pointer, will be allocated if 0, .extra contains size 00198 TYPE_StructPtrArray = 44, //!< Array of structure pointers, .extra contain size 00199 00200 //! Built-in structures 00201 TYPE_COLOR = 50, //!< COLOR 00202 TYPE_DRECT2D = 51, //!< DRECT2D 00203 TYPE_DPOINT2D = 52, //!< DPOINT2D 00204 TYPE_DPOINT3D = 53, //!< DPOINT3D 00205 TYPE_MAPPROJPARM = 54, //!< MAPPROJPARM 00206 TYPE_POINTSTYLE = 55, //!< POINTSTYLE 00207 TYPE_LINESTYLE = 56, //!< LINESTYLE 00208 TYPE_POLYSTYLE = 57, //!< POLYSTYLE 00209 TYPE_TEXTSTYLE = 58, //!< TEXTSTYLE 00210 TYPE_LPOINT2D = 59, //!< LPOINT2D 00211 TYPE_LRECT2D = 60, //!< LRECT2D 00212 00213 TYPE_SERIALIZABLE = 90, //!< SERIALIZABLE object 00214 TYPE_SERIALIZABLEPTR = 91, //!< Pointer to SERIALIZABLE object 00215 00216 TYPE_InternalSer = 998, 00217 TYPE_Start = 999 //!< Used internally to start new structure 00218 }; 00219 00220 enum FLAGS { 00221 FLAG_None = 0x0000, 00222 FLAG_NoWrite0 = 0x0001, //!< Don't write value if not set 00223 FLAG_NoWrite = 0x0002, //!< Don't write this item 00224 FLAG_NoRead = 0x0004, //!< Don't read this item 00225 FLAG_FileNoExist0 = 0x0008, //!< When reading PARMITEM_FileName zero string if file doesn't exist 00226 FLAG_Skippable = 0x0020, //!< Item will be ignored if "IgnoreSkippable" set 00227 FLAG_AddOffsetCB = 0x0040, //!< Add offset to pointer when passing to callback function 00228 FLAG_FindFileImmed = 0x0080, //!< Search for file immediately instead of waiting until looking for object 00229 FLAG_DontAskLinkFile = 0x0100 //!< Don't prompt user if can't find linked file 00230 }; 00231 00232 enum ACTION { 00233 ACTION_None = 0x0000, 00234 ACTION_ReadBegin = 0x0001, 00235 ACTION_ReadEnd = 0x0002, 00236 ACTION_WriteBegin = 0x0004, 00237 ACTION_WriteEnd = 0x0008, 00238 ACTION_Read = 0x0010, 00239 ACTION_Write = 0x0020 00240 }; 00241 00242 typedef ERRVALUE (*CBFUNC)(SERIALIZER&, const ITEMDEF*, void *data, ACTION action); 00243 00244 char *name; //!< Name of the item, 0 to terminate array, not case-sensitive 00245 TYPE type; //!< Item type 00246 int offset; //!< Offset into class/struct 00247 int extra; //!< Extra type-specific data, see below 00248 const ITEMDEF *substruct; //!< Sub-structure definition for TYPE_Struct/StructPtr 00249 FLAGS flags; //!< Flags 00250 CBFUNC cbfunc; //!< Callback function for this item 00251 00252 //! The meaning of the "extra" field is dependent on the "type" field: 00253 //! 00254 //! "type" 00255 //! UINT8_Array Number of array entries 00256 //! StringA, StringU Number of bytes in entry (use membersize in definition) 00257 //! Object, SubObject Object type (0 for OTYPE_ALL) 00258 //! BitUINT32 Bit number to use, 0 = lowest 00259 //! StructPtr, StructPtrArray Size of structure to allocate 00260 //! Enum Size of member 00261 00262 //! When handling TYPE_Special items, the cbfunc will be called with ACTION_Read or 00263 //! ACTION_Write. The cbfunc is responsible for actually reading and writing the data 00264 //! using the SERIALIZER class reference provided. 00265 00266 }; 00267 00268 //! Merge two item definition arrays. 00269 //! This is useful when inheriting from a class which already uses an item definition array. 00270 static ITEMDEF* MergeItemDef ( 00271 const ITEMDEF *def1, //!< First definition array 00272 const ITEMDEF *def2 //!< Second definition array 00273 ); //! Returns new allocated definition array 00274 00275 //! Default constructor. 00276 SERIALIZER ( 00277 ); 00278 00279 //! Destructor. 00280 virtual ~SERIALIZER ( 00281 ); 00282 00283 //! Close the serializer, will be done in destructor. 00284 void Close ( 00285 ); 00286 00287 //! Get path to serialization file. 00288 const FILEPATH& GetFilePath ( 00289 ) const { return (m_filepath); } 00290 00291 //! Determine if ignoring "skippable" items. 00292 bool GetIgnoreSkippable ( 00293 ) const { return (m_IgnoreSkippable); } 00294 00295 //! Get name of current item being read/written. 00296 const char* GetItemName ( 00297 ) const { return (m_itemname); } 00298 00299 //! Get value for current item being read. 00300 const UNICODE* GetItemValue ( 00301 ) const { return (m_parmvalue); } 00302 00303 // Get log text. 00304 const MISTRING& GetLog ( 00305 ) const { return (m_Log); } 00306 00307 // Get log text (non-const). 00308 MISTRING& GetLog ( 00309 ) { return (m_Log); } 00310 00311 //! Get name of object, will be blank if text file. 00312 const UNICODE* GetObjectName ( 00313 ) const { return (m_objname); } 00314 00315 //! Get list of missing files/objects after scan, also clears the list. 00316 FNAMEINODEUC* GetScanListMissing ( 00317 ) { 00318 FNAMEINODEUC *temp = m_ScanFileObjListMissing; 00319 m_ScanFileObjListMissing = NULL; 00320 return (temp); 00321 } 00322 00323 //! Get list of "used" files/objects after scan, also clears the list. 00324 FNAMEINODEUC* GetScanListUsed ( 00325 ) { 00326 FNAMEINODEUC *temp = m_ScanFileObjListUsed; 00327 m_ScanFileObjListUsed = NULL; 00328 return (temp); 00329 } 00330 00331 //! Get current version setting. 00332 UINT16 GetVersion ( 00333 ) const { return (m_Version[m_depth]); } 00334 00335 //! Check if scanning serialization only. 00336 bool IsScanOnly ( 00337 ) const { return (m_ScanOnly); } 00338 00339 //! Clear serialization log. 00340 void LogClear ( 00341 ) { m_Log.Clear(); } 00342 00343 //! Add error message to log. 00344 //! Will insert newline before and after error text. 00345 void LogError ( 00346 ERRVALUE err 00347 ); 00348 00349 //! Add text to log. 00350 void LogText ( 00351 const MISTRING& text 00352 ) { m_Log << text; } 00353 00354 //! Create object to contain serialization. 00355 ERRVALUE Make ( 00356 const FILEPATH& filepath, //!< RVC file path 00357 RVCPARMINFO& objinfo //!< New or existing object header 00358 ); 00359 00360 //! Create object to contain serialization. 00361 ERRVALUE Make ( 00362 int fhandle, //!< RVC file handle 00363 RVCPARMINFO& objinfo //!< New or existing object header 00364 ); 00365 00366 //! Create text file to contain serialization. 00367 ERRVALUE Make ( 00368 const FILEPATH& filepath, //!< Text file path 00369 int version = 1 //!< Version to write 00370 ); 00371 00372 //! Open object containing serialization to read. 00373 ERRVALUE Open ( 00374 const RVC::OBJITEM& objitem //!< RVC object item reference 00375 ); 00376 00377 //! Open object containing serialization to read. 00378 ERRVALUE Open ( 00379 const FILEPATH& filepath, //!< RVC file path 00380 INT32 inode, //!< RVC object inode 00381 RVCPARMINFO& objinfo //!< Object header returned 00382 ); 00383 00384 //! Open object containing serialization to read. 00385 ERRVALUE Open ( 00386 int fhandle, //!< Open RVC file handle 00387 INT32 inode, //!< RVC object inode 00388 RVCPARMINFO& objinfo //!< Object header returned 00389 ); 00390 00391 //! Open text file containing serialization to read. 00392 ERRVALUE Open ( 00393 const FILEPATH& filepath //!< Text file path 00394 ); 00395 00396 //! Write beginning tag for starting a component. 00397 ERRVALUE PutBegin ( 00398 const char *tagname, //!< Tag name to write 00399 UINT16 version = 0 //!< Optional version 00400 ); 00401 00402 //! Write floating-point value. 00403 ERRVALUE PutDouble ( 00404 const char *tagname, //!< Tag name 00405 double value //!< Value to write 00406 ); 00407 00408 //! Write ending tag at end of a component. 00409 ERRVALUE PutEnd ( 00410 ); 00411 00412 //! Write integer value. 00413 ERRVALUE PutInt ( 00414 const char *tagname, //!< Tag name to write 00415 int value //!< Value to write 00416 ); 00417 00418 //! Write COLOR item. 00419 ERRVALUE PutItem ( 00420 const char *tagname, //!< Tag name to write 00421 const COLOR& color //!< Item value 00422 ); 00423 00424 //! Write DPOINT2D item. 00425 ERRVALUE PutItem ( 00426 const char *tagname, //!< Tag name to write 00427 const DPOINT2D& point2d //!< Item value 00428 ); 00429 00430 //! Write DPOINT3D item. 00431 ERRVALUE PutItem ( 00432 const char *tagname, //!< Tag name to write 00433 const DPOINT3D& point3d //!< Item value 00434 ); 00435 00436 //! Write DRECT2D item. 00437 ERRVALUE PutItem ( 00438 const char *tagname, //!< Tag name to write 00439 const DRECT2D& rect //!< Item value 00440 ); 00441 00442 //! Write LPOINT2D item. 00443 ERRVALUE PutItem ( 00444 const char *tagname, //!< Tag name to write 00445 const LPOINT2D& point2d //!< Item value 00446 ); 00447 00448 //! Write LRECT2D item. 00449 ERRVALUE PutItem ( 00450 const char *tagname, //!< Tag name to write 00451 const LRECT2D& rect //!< Item value 00452 ); 00453 00454 //! Write a single-line Unicode string 00455 ERRVALUE PutStr ( 00456 const char *tagname, //!< Tag name to write 00457 const UNICODE *str //!< String 00458 ); 00459 00460 //! Write a Multi-line Unicode String 00461 ERRVALUE PutStrML ( 00462 const char *tagname, //!< Tag name to write 00463 const UNICODE *str //!< String 00464 ); 00465 00466 //! Write unsigned integer value. 00467 ERRVALUE PutUnsigned ( 00468 const char *tagname, //!< Tag name to write 00469 unsigned int value //!< Item value 00470 ); 00471 00472 //! Read SERIALIZABLE object. 00473 inline ERRVALUE Read ( 00474 SERIALIZABLE& object //!< Object to read 00475 ); 00476 00477 //! Read SERIALIZABLE object. 00478 ERRVALUE Read ( 00479 const char *tagname, //!< Tag name to match 00480 SERIALIZABLE& object //!< Object to read 00481 ); 00482 00483 //! Read items from serialization. 00484 ERRVALUE Read ( 00485 const ITEMDEF *itemdef, //!< Item definition array 00486 void *data //!< Serialization data 00487 ); 00488 00489 //! Read items from serialization. 00490 ERRVALUE Read ( 00491 const char *tagname, //!< Tag name to match 00492 const ITEMDEF *itemdef, //!< Item definition array 00493 void *data //!< Serialization data 00494 ); 00495 00496 //! Rewind file to beginning. 00497 ERRVALUE Rewind ( 00498 ); 00499 00500 //! Set whether to ignore "skippable" items. 00501 void SetIgnoreSkippable ( 00502 bool IgnoreSkippable = true //!< Ignore skippable mode 00503 ) { m_IgnoreSkippable = IgnoreSkippable; } 00504 00505 //! Set scan-only mode. 00506 void SetScanOnly ( 00507 bool ScanOnly //!< Scan only mode 00508 ) { m_ScanOnly = ScanOnly; } 00509 00510 //! Set version (for overriding). 00511 void SetVersion ( 00512 UINT16 Version //!< Version 00513 ) { m_Version[m_depth] = Version; } 00514 00515 //! Skip remainder of current structure (for use in item callback). 00516 ERRVALUE SkipStruct ( 00517 ); 00518 00519 //! Update status text from Unicode string. 00520 ERRVALUE StatusTextUpdate ( 00521 const UNICODE *string 00522 ) { return (MstatusTextUpdateString(m_StatusContext,0,string)); } 00523 00524 //! Write items without begin/end tags. 00525 ERRVALUE Write ( 00526 const ITEMDEF *itemdef, //!< Item definition array 00527 const void *data //!< Data to write 00528 ); 00529 00530 //! Write items to serialized output. 00531 ERRVALUE Write ( 00532 const char *tagname, //!< Name to tag object with 00533 const ITEMDEF *itemdef, //!< Item definition array 00534 const void *data, //!< Data to write 00535 UINT16 version = 0 //!< Version to set if top level object 00536 ); 00537 00538 //! Write SERIALIZABLE object. 00539 inline ERRVALUE Write ( 00540 const SERIALIZABLE& object, //!< Object to write 00541 const char *tagname = 0 //!< Name to tag object with 00542 ); 00543 00544 private: 00545 #ifndef GENERATING_DOXYGEN_OUTPUT 00546 00547 FILEPATH m_filepath; //!< Path to file 00548 RVC::OBJECTNAME m_objname; //!< Name of object if in RVC file 00549 FILE *m_fp; //!< Text file handle if non-RVC 00550 int m_fhandle; //!< RVC file handle if Text object 00551 int m_ohandle; //!< RVC object handle for Text object 00552 int m_depth; //!< Current depth 00553 UINT16 m_Version[128]; //!< Version at current depth 00554 char m_itemname[128]; 00555 UNICODE m_parmvalue[2048]; //!< Last parameter value 00556 MSTATUSCONTEXT m_StatusContext; 00557 INT32 m_filesize; //!< Size of file/object being read for status update 00558 INT32 m_filepos; //!< Position in file/object for status update 00559 bool m_IgnoreSkippable; 00560 bool m_ScanOnly; 00561 FNAMEINODEUC *m_ScanFileObjListUsed; 00562 FNAMEINODEUC *m_ScanFileObjListMissing; 00563 MISTRING m_Log; 00564 00565 //! Call callback for item if necessary. 00566 ERRVALUE CallItemCB ( 00567 const ITEMDEF *itemdef, 00568 void *data, //!< Callback data 00569 ITEMDEF::ACTION action //!< Callback action 00570 ); 00571 00572 //! Find link file, add to missing file list if can't find it. 00573 ERRVALUE FindLinkFile ( 00574 const ITEMDEF *parmdp, 00575 const UINT8* data, 00576 FILEPATH& linkfilepath, 00577 UINT32 findflags = 0 00578 ); 00579 00580 //! Find object. 00581 int FindObject ( 00582 const ITEMDEF *parmdp, 00583 const ITEMDEF *startdp, 00584 UINT8 *data 00585 ); 00586 00587 //! Find subobject. 00588 int FindSubObject ( 00589 const ITEMDEF *parmdp, 00590 const ITEMDEF *startdp, 00591 UINT8 *data 00592 ); 00593 00594 //! Get multi-line string (Unicode). 00595 ERRVALUE GetStrML ( 00596 UNICODE **str //!< XXX change to MISTRING& 00597 ); 00598 00599 //! Get multi-line string (ASCII or RAW). 00600 ERRVALUE GetStrML ( 00601 char **str, 00602 bool raw = false 00603 ); 00604 00605 //! 00606 ERRVALUE PutObjName ( 00607 const ITEMDEF *parmdp, 00608 const ITEMDEF *startdp, 00609 const UINT8 *data 00610 ); 00611 00612 //! 00613 ERRVALUE PutStr ( 00614 const char *tagname, 00615 const char *str //!< XXX eliminate 00616 ); 00617 00618 00619 //! 00620 ERRVALUE PutStrML ( 00621 const char *tagname, 00622 const char *str 00623 ); 00624 00625 //! 00626 ERRVALUE PutSubObjName ( 00627 const ITEMDEF *parmdp, 00628 const ITEMDEF *startdp, 00629 const UINT8 *data 00630 ); 00631 00632 //! 00633 ERRVALUE ReadLine ( 00634 UNICODE *buf, //!< XXX change to MISTRING& 00635 int bufsize, 00636 bool raw = false 00637 ); 00638 00639 //! Write single-line UNICODE string. 00640 ERRVALUE WriteText ( 00641 const UNICODE *str //!< String to write 00642 ); 00643 00644 //! Write ASCII string. 00645 ERRVALUE WriteText ( 00646 const char *str //!< String to write 00647 ); 00648 00649 SERIALIZER (const SERIALIZER&); 00650 SERIALIZER& operator= (const SERIALIZER&); 00651 #endif // GENERATING_DOXYGEN_OUTPUT 00652 }; 00653 00654 DEFINE_ENUM_OPERATORS(SERIALIZER::ITEMDEF::FLAGS); 00655 DEFINE_ENUM_OPERATORS(SERIALIZER::ITEMDEF::ACTION); 00656 00657 00658 //----------------------------------------------------------------------------- 00659 // SERIALIZABLE interface definition 00660 //----------------------------------------------------------------------------- 00661 00662 //! Interface class for making object serializable. 00663 //! Objects may be serialized without inheriting from this interface provided 00664 //! they are serialized as part of a container object. In general there are two 00665 //! reasons to inherit from SERIALIZABLE. 00666 //! 00667 //! 1. If the object will be a top-level item in the serialization. This 00668 //! makes it easy to read and write the object via the SERIALIZER Read() 00669 //! and Write() methods pertaining to SERIALIZABLE objects. Simple 00670 //! objects which may be represented by an ITEMDEF array do not need to 00671 //! be made serializable as there are Read/Write methods which may use 00672 //! this array. The GRE_LAYOUT and GRE_GROUP classes are examples. 00673 //! 00674 //! 2. If an object is contained within another object and has complicated 00675 //! serialization which must be implemented via functions rather than 00676 //! using and ITEMDEF array. This allows use of TYPE_SERIALIZABLE and 00677 //! TYPE_SERIALIZABLEPTR in the containing object's ITEMDEF array, thus 00678 //! simplifying its definition. The GRE_LAYER::DISPPARM class is an 00679 //! example of this case. 00680 //! 00681 //! By convention, if an object implements SerialRead and/or SerialWrite() the 00682 //! method signatures should match those used in SERIALIZABLE even if the class 00683 //! does not actually implement the SERIALIZABLE interface. This allows easy 00684 //! modification should it become necessary to implement the interface in the 00685 //! future. The GRE_LAYER class is an example of this case in that it defines 00686 //! both SerialRead() and SerialWrite() methods but does not specifically 00687 //! inherit from SERIALIZABLE. 00688 00689 class SERIALIZABLE { 00690 //! This is an "interface" class and must therefore 00691 //! only have virtual methods and no members. 00692 00693 public: 00694 00695 //! Read component from serialization. 00696 //! This method must be called only after the tag name has been read and 00697 //! is responsible for determining how to deserialize the component 00698 //! elements. When beginning a deserialization, usually the 00699 //! SERIALIZER::Read(tagname,object) method should be used to match 00700 //! the desired tag name which was used in writing. 00701 //! A default implementation is not possible due to multiple inheritance 00702 //! resulting in a different "this" pointer being passed than the actual 00703 //! object, which causes the offset values in the ITEMDEF arrays to be wrong. 00704 virtual ERRVALUE SerialRead ( 00705 SERIALIZER& serializer 00706 ) = 0; 00707 00708 //! Write object to serialization. 00709 //! This method must write the tag name provided, using SERIALIZER::PutBegin(). 00710 //! If the tagname is 0 (default) then it must determine the proper tag name to 00711 //! write. After writing the object this method must write the ending tag using 00712 //! SERIALIZER::PutEnd(). 00713 //! When inheriting this interface, the default value of 0 for the tag name 00714 //! must NOT be redefined. (See Meyers, Effective C++, item #38) 00715 //! A default implementation is not possible due to multiple inheritance 00716 //! resulting in a different "this" pointer being passed than the actual 00717 //! object, which causes the offset values in the ITEMDEF arrays to be wrong. 00718 virtual ERRVALUE SerialWrite ( 00719 SERIALIZER& serializer, 00720 const char *tagname = 0 00721 ) const = 0; 00722 }; 00723 00724 00725 //----------------------------------------------------------------------------- 00726 //! Inline methods 00727 //----------------------------------------------------------------------------- 00728 00729 #ifndef GENERATING_DOXYGEN_OUTPUT 00730 00731 inline ERRVALUE SERIALIZER::Read ( 00732 SERIALIZABLE& object 00733 ) { 00734 return (object.SerialRead(*this)); 00735 } 00736 00737 inline ERRVALUE SERIALIZER::Write ( 00738 const SERIALIZABLE& object, 00739 const char *tagname 00740 ) { 00741 return (object.SerialWrite(*this,tagname)); 00742 } 00743 00744 #endif //!< GENERATING_DOXYGEN_OUTPUT 00745 00746 #endif //!< INC_MI32_SERIALIZ_H
1.3.4-20031026