home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / CLASSINC.PAK / OBJSTRM.H < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  56.6 KB  |  1,547 lines

  1. //----------------------------------------------------------------------------
  2. // Borland Class Library
  3. // Copyright (c) 1992, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   5.15  $
  6. //
  7. //----------------------------------------------------------------------------
  8. #if !defined(CLASSLIB_OBJSTRM_H)
  9. #define CLASSLIB_OBJSTRM_H
  10.  
  11. #if !defined(CLASSLIB_DEFS_H)
  12. # include <classlib/defs.h>
  13. #endif
  14. #if !defined(SERVICES_CHECKS_H)
  15. # include <services/checks.h>
  16. #endif
  17. #if !defined(CLASSLIB_STREAMBL_H)
  18. # include <classlib/streambl.h>
  19. #endif
  20. #if !defined(CLASSLIB_VECTIMP_H)
  21. # include <classlib/vectimp.h>
  22. #endif
  23. #if !defined(__IOSTREAM_H) && !defined(_INC_IOSTREAM)
  24. # include <iostream.h>
  25. #endif
  26. #if !defined(__FSTREAM_H) && !defined(_INC_FSTREAM)
  27. # include <fstream.h>
  28. #endif
  29. #if !defined(BI_NO_RTTI) && !defined(__TYPEINFO_H) && !defined(_INC_TYPEINFO)
  30. # include <typeinfo.h>
  31. #endif
  32. #if !defined (__TCHAR_H)
  33. # include <tchar.h>
  34. #endif
  35.  
  36. #if defined( BI_CLASSLIB_NO_po )
  37. # pragma option -po-
  38. #endif
  39.  
  40. #if defined(BI_NAMESPACE)
  41. namespace ClassLib {
  42. #endif
  43.  
  44. /*------------------------------------------------------------------------*/
  45. /*                                                                        */
  46. /*  The __link() macro forces the compiler to link in a static instance   */
  47. /*  of class TStreamableClass, which in turn registers its associated     */
  48. /*  TStreamable object with the stream manager.  Applications that do     */
  49. /*  not use streaming won't use __link(), and that will reduce the amount */
  50. /*  of code that is linked into the application.                          */
  51. /*                                                                        */
  52. /*------------------------------------------------------------------------*/
  53.  
  54. struct fLink
  55. {
  56.     struct fLink *f;
  57.     class TStreamableClass *t;
  58. };
  59.  
  60. #define __link( s )             \
  61.   extern TStreamableClass s;    \
  62.   static fLink force ## s =     \
  63.     { (fLink *)&force ## s, (TStreamableClass *)&s };
  64.  
  65. typedef unsigned P_id_type;
  66.  
  67. class _BIDSCLASS _RTTI TStreamable;
  68. class _BIDSCLASS TStreamableTypes;
  69. class _BIDSCLASS opstream;
  70. class _BIDSCLASS ipstream;
  71.  
  72. #if defined(BI_NAMESPACE)
  73. }     // namespace ClassLib
  74. #endif
  75.  
  76. class _EXPCLASS string;
  77.  
  78. #if defined(BI_NAMESPACE)
  79. namespace ClassLib {
  80. #endif
  81.  
  82. ipstream _BIDSFAR& _BIDSENTRY _BIDSFUNC operator >> ( ipstream _BIDSFAR& is,
  83.                                                       string _BIDSFAR& str );
  84.  
  85. opstream _BIDSFAR& _BIDSENTRY _BIDSFUNC operator << ( opstream _BIDSFAR& os,
  86.                                                       const string _BIDSFAR& str );
  87.  
  88. /* -----------------------------------------------------------------------*/
  89. /*                                                                        */
  90. /*  _TYPENAME(obj) provides a macro for getting the type name from a      */
  91. /*  pointer to an object. If runtime type information is available, this  */
  92. /*  macro uses the typeid of the object to get its name. If runtime type  */
  93. /*  information is not available, it uses the CastableID() for the object.*/
  94. /*                                                                        */
  95. /* -----------------------------------------------------------------------*/
  96.  
  97. #if defined( BI_NO_RTTI )
  98. #   define _TYPENAME(obj) (obj)->CastableID()
  99. #else
  100. #   define _TYPENAME(obj) typeid(*obj).name()
  101. #endif
  102.  
  103. /* -----------------------------------------------------------------------*/
  104. /*                                                                        */
  105. /*  class TStreamable                                                     */
  106. /*                                                                        */
  107. /*  This is the base class from which all streamable objects must be      */
  108. /*  derived.                                                              */
  109. /*                                                                        */
  110. /* -----------------------------------------------------------------------*/
  111.  
  112. enum StreamableInit { streamableInit };
  113.  
  114. class _BIDSCLASS _RTTI TStreamableBase
  115. {
  116.  
  117. public:
  118.  
  119.     virtual _BIDSCTOR ~TStreamableBase();
  120.  
  121. #if defined( BI_NO_RTTI )
  122.     typedef const _TCHAR * /*_BIDSENTRY*/ Type_id;
  123.     virtual void * /*_BIDSENTRY*/ FindBase( Type_id id ) const;
  124.  
  125. public:
  126.  
  127.     virtual Type_id /*_BIDSENTRY*/ CastableID() const = 0;
  128.     virtual void * /*_BIDSENTRY*/ MostDerived() const = 0;
  129. #endif
  130. };
  131.  
  132. class _BIDSCLASS _RTTI TStreamable : public TStreamableBase
  133. {
  134.  
  135.     friend class _BIDSCLASS _RTTI TOldStreamer;
  136.  
  137. protected:
  138.  
  139.     virtual const _TCHAR * _BIDSENTRY streamableName() const = 0;
  140.  
  141.     virtual void * _BIDSENTRY read( ipstream& );
  142.     virtual void _BIDSENTRY write( opstream& );
  143.  
  144. #if defined( BI_NO_RTTI )
  145. public:
  146.     virtual void * /*_BIDSENTRY*/ FindBase( Type_id id ) const;
  147. protected:
  148.     virtual Type_id /*_BIDSENTRY*/ CastableID() const { return streamableName(); }
  149.     virtual void * /*_BIDSENTRY*/ MostDerived() const { return 0; }
  150. #endif
  151. };
  152.  
  153. class _BIDSCLASS _RTTI TStreamer
  154. {
  155.  
  156.     friend class ipstream;
  157.     friend class opstream;
  158.  
  159. public:
  160.  
  161.     TStreamableBase * _BIDSENTRY GetObject() const { return object; }
  162.  
  163. protected:
  164.  
  165.     TStreamer( TStreamableBase *obj ) : object(obj) {}
  166.  
  167.     virtual const _TCHAR * _BIDSENTRY StreamableName() const = 0;
  168.  
  169.     virtual void * _BIDSENTRY Read( ipstream&, uint32 ) const = 0;
  170.     virtual void _BIDSENTRY Write( opstream& ) const = 0;
  171.  
  172. private:
  173.  
  174.     virtual uint32 _BIDSENTRY ClassVersion() const = 0;
  175.  
  176.     TStreamableBase *object;
  177.  
  178. };
  179.  
  180. class _BIDSCLASS _RTTI TOldStreamer : public TStreamer
  181. {
  182.  
  183. public:
  184.  
  185.     _BIDSCTOR TOldStreamer( TStreamable *obj ) : TStreamer(obj) {};
  186.  
  187. protected:
  188.  
  189.     virtual const _TCHAR * _BIDSENTRY StreamableName() const
  190.         {
  191.         return STATIC_CAST(TStreamable *,GetObject())->streamableName();
  192.         }
  193.  
  194.     virtual void * _BIDSENTRY Read( ipstream& is, uint32 ) const
  195.         {
  196.         return STATIC_CAST(TStreamable *,GetObject())->read( is );
  197.         }
  198.  
  199.     virtual void _BIDSENTRY Write( opstream& os ) const
  200.         {
  201.         STATIC_CAST(TStreamable *,GetObject())->write( os );
  202.         }
  203.  
  204. private:
  205.  
  206.     virtual uint32 _BIDSENTRY ClassVersion() const
  207.         {
  208.         return 0;
  209.         }
  210.  
  211. };
  212.  
  213. class _BIDSCLASS _RTTI TNewStreamer : public TStreamer
  214. {
  215.  
  216. public:
  217.  
  218.     _BIDSCTOR TNewStreamer( TStreamableBase *obj ) : TStreamer(obj) {};
  219.  
  220. protected:
  221.  
  222.     virtual const _TCHAR * _BIDSENTRY StreamableName() const
  223.         {
  224.         return _TYPENAME(GetObject());
  225.         }
  226.  
  227. };
  228.  
  229. /* ------------------------------------------------------------------------*/
  230. /*                                                                         */
  231. /*   class TPWrittenObjects                                                */
  232. /*                                                                         */
  233. /*   Maintains a database of all objects that have been written to the     */
  234. /*   current persistent stream.                                            */
  235. /*                                                                         */
  236. /*   Used by opstream when it writes a pointer from a stream to save the   */
  237. /*   address and ID of the object being written.                           */
  238. /*                                                                         */
  239. /* ------------------------------------------------------------------------*/
  240.  
  241. class _BIDSCLASS TPWrittenObjects
  242. {
  243.  
  244.     friend opstream;
  245.  
  246. public:
  247.  
  248.     void _BIDSENTRY RemoveAll();
  249.  
  250.     class _BIDSCLASS TPWObj
  251.     {
  252.     public:
  253.  
  254.         _BIDSCTOR TPWObj() : Address(0), Ident(0) {}
  255.         _BIDSCTOR TPWObj( const void *adr, P_id_type id ) :
  256.             Address(adr), Ident(id) {}
  257.  
  258.         friend int _BIDSENTRY operator == ( const TPWObj& o1, const TPWObj& o2 )
  259.             { return TAddrInt(o1.Address) == TAddrInt(o2.Address); }
  260.  
  261.         friend int _BIDSENTRY operator < ( const TPWObj& o1, const TPWObj& o2 )
  262.             { return TAddrInt(o1.Address) < TAddrInt(o2.Address); }
  263.  
  264.         const void *Address;
  265.         P_id_type Ident;
  266. #if defined(BI_DATA_NEAR)
  267.         typedef uint16 TAddrInt;
  268. #else
  269.         typedef uint32 TAddrInt;
  270. #endif
  271.     };
  272.  
  273. private:
  274.  
  275.     _BIDSCTOR TPWrittenObjects();
  276.  
  277.     void _BIDSENTRY RegisterObject( TStreamableBase *adr );
  278.     void _BIDSENTRY RegisterVB( const TStreamableBase *adr );
  279.     P_id_type _BIDSENTRY FindObject( TStreamableBase *adr );
  280.     P_id_type _BIDSENTRY FindVB( TStreamableBase *adr );
  281.  
  282.     P_id_type CurId;
  283.  
  284.     TSVectorImp<TPWObj> Data;
  285. };
  286.  
  287. /* ------------------------------------------------------------------------*/
  288. /*                                                                         */
  289. /*   class TPReadObjects                                                   */
  290. /*                                                                         */
  291. /*   Maintains a database of all objects that have been read from the      */
  292. /*   current persistent stream.                                            */
  293. /*                                                                         */
  294. /*   Used by ipstream when it reads a pointer from a stream to determine   */
  295. /*   the address of the object being referred to.                          */
  296. /*                                                                         */
  297. /* ------------------------------------------------------------------------*/
  298.  
  299. class _BIDSCLASS TPReadObjects
  300. {
  301.     friend ipstream;
  302.  
  303. public:
  304.  
  305.     void _BIDSENTRY RemoveAll();
  306.  
  307. private:
  308.  
  309.     _BIDSCTOR TPReadObjects();
  310.  
  311.     void _BIDSENTRY RegisterObject( TStreamableBase *adr );
  312.     TStreamableBase * _BIDSENTRY Find( P_id_type id );
  313.  
  314.     TCVectorImp<TStreamableBase *> Data;
  315. };
  316.  
  317. /* ------------------------------------------------------------------------*/
  318. /*                                                                         */
  319. /*   class pstream                                                         */
  320. /*                                                                         */
  321. /*   Base class for handling streamable objects.                           */
  322. /*                                                                         */
  323. /* ------------------------------------------------------------------------*/
  324.  
  325. class _BIDSCLASS pstream
  326. {
  327.     friend TStreamableTypes;
  328.     friend TStreamableClass;
  329.  
  330. public:
  331.  
  332.     enum PointerTypes { ptNull, ptIndexed, ptObject };
  333.  
  334.     _BIDSCTOR pstream( streambuf _BIDSFAR * );
  335.     virtual _BIDSCTOR ~pstream();
  336.  
  337.     int _BIDSENTRY rdstate() const;
  338.     int _BIDSENTRY eof() const;
  339.     int _BIDSENTRY fail() const;
  340.     int _BIDSENTRY bad() const;
  341.     int _BIDSENTRY good() const;
  342.     void _BIDSENTRY clear( int = 0 );
  343.     _BIDSENTRY operator void *() const;
  344.     int _BIDSENTRY operator ! () const;
  345.  
  346.     streambuf _BIDSFAR * _BIDSENTRY rdbuf() const;
  347.  
  348.     static void _BIDSENTRY initTypes();
  349.     static void _BIDSENTRY releaseTypes();
  350.  
  351.     static void _BIDSENTRY registerType( TStreamableClass *ts );
  352.  
  353. protected:
  354.  
  355.     _BIDSCTOR pstream();
  356.  
  357.     streambuf _BIDSFAR *bp;
  358.     int state;
  359.  
  360.     void _BIDSENTRY init( streambuf _BIDSFAR * );
  361.     void _BIDSENTRY setstate( int );
  362.  
  363.     static TStreamableTypes *types;
  364. };
  365.  
  366. /* ------------------------------------------------------------------------*/
  367. /*                                                                         */
  368. /*   class ipstream                                                        */
  369. /*                                                                         */
  370. /*   Base class for reading streamable objects                             */
  371. /*                                                                         */
  372. /* ------------------------------------------------------------------------*/
  373.  
  374. class _BIDSCLASS ipstream : virtual public pstream
  375. {
  376.     friend class TStreamableClass;
  377.  
  378. public:
  379.  
  380.     _BIDSCTOR ipstream( streambuf _BIDSFAR * );
  381.  
  382.     streampos _BIDSENTRY tellg();
  383.     ipstream& _BIDSENTRY seekg( streampos );
  384.     ipstream& _BIDSENTRY seekg( streamoff, ios::seek_dir );
  385.  
  386.     uint8 _BIDSENTRY readByte();
  387.     void _BIDSENTRY readBytes( void _BIDSFAR *, size_t );
  388.     void _BIDSENTRY freadBytes( void _BIDSFARDATA *data, size_t sz );
  389.  
  390.     uint32 _BIDSENTRY readWord();
  391.     uint16 _BIDSENTRY readWord16();
  392.     uint32 _BIDSENTRY readWord32();
  393.  
  394.     _TCHAR _BIDSFAR * _BIDSENTRY readString();
  395.     _TCHAR _BIDSFAR * _BIDSENTRY readString( _TCHAR _BIDSFAR *, unsigned );
  396.     _TCHAR _BIDSFARDATA * _BIDSENTRY freadString();
  397.     _TCHAR _BIDSFARDATA * _BIDSENTRY freadString( _TCHAR _BIDSFARDATA *buf,
  398.                                             unsigned maxLen );
  399.  
  400.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, _TSCHAR& );
  401.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, _TUCHAR& );
  402.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, _TCHAR& );
  403.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, signed short& );
  404.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, unsigned short& );
  405.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, signed int& );
  406.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, unsigned int& );
  407. #if defined(BI_UNIQUE_BOOL)
  408.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, bool& );
  409. #endif
  410.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, signed long& );
  411.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, unsigned long& );
  412.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, float& );
  413.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, double& );
  414.     friend ipstream& _BIDSENTRY operator >> ( ipstream&, long double& );
  415.  
  416.     friend ipstream _BIDSFAR& _BIDSENTRY _BIDSFUNC
  417.             operator >> ( ipstream _BIDSFAR& is, string _BIDSFAR& str );
  418.  
  419.     uint32 _BIDSENTRY getVersion() const;
  420.  
  421.     TStreamableBase _BIDSFAR * _BIDSENTRY readObject( TStreamableBase _BIDSFAR *&mem, ModuleId mid = GetModuleId() );
  422.     TStreamableBase _BIDSFAR * _BIDSENTRY readObjectPointer( TStreamableBase _BIDSFAR *&mem, ModuleId mid = GetModuleId() );
  423.  
  424.     TStreamableBase _BIDSFAR * _BIDSENTRY find( P_id_type );
  425.     void _BIDSENTRY registerObject( TStreamableBase _BIDSFAR *adr );
  426.  
  427. protected:
  428.  
  429.     _BIDSCTOR ipstream();
  430.  
  431.     const ObjectBuilder _BIDSFAR * _BIDSENTRY readPrefix( ModuleId mid );
  432.     void _BIDSENTRY readData( const ObjectBuilder _BIDSFAR *,
  433.                           TStreamableBase _BIDSFAR *& );
  434.     void _BIDSENTRY readSuffix();
  435.  
  436.     void _BIDSENTRY readVersion();
  437.  
  438. private:
  439.  
  440.     uint32 readStringLength();
  441.     TPReadObjects objs;
  442.     uint32 version;
  443. };
  444.  
  445. /* ------------------------------------------------------------------------*/
  446. /*                                                                         */
  447. /*   class opstream                                                        */
  448. /*                                                                         */
  449. /*   Base class for writing streamable objects                             */
  450. /*                                                                         */
  451. /* ------------------------------------------------------------------------*/
  452.  
  453. class _BIDSCLASS opstream : virtual public pstream
  454. {
  455. public:
  456.  
  457.     _BIDSCTOR opstream( streambuf _BIDSFAR * );
  458.     _BIDSCTOR ~opstream();
  459.  
  460.     streampos _BIDSENTRY tellp();
  461.     opstream& _BIDSENTRY seekp( streampos );
  462.     opstream& _BIDSENTRY seekp( streamoff, ios::seek_dir );
  463.     opstream& _BIDSENTRY flush();
  464.  
  465.     void _BIDSENTRY writeByte( uint8 );
  466.     void _BIDSENTRY writeBytes( const void _BIDSFAR *, size_t );
  467.     void _BIDSENTRY fwriteBytes( const void _BIDSFARDATA *data, size_t sz );
  468.  
  469.     void _BIDSENTRY writeWord( uint32 );
  470.     void _BIDSENTRY writeWord16( uint16 );
  471.     void _BIDSENTRY writeWord32( uint32 );
  472.  
  473.     void _BIDSENTRY writeString( const _TCHAR _BIDSFAR * );
  474.     void _BIDSENTRY fwriteString( const _TCHAR _BIDSFARDATA * str );
  475.  
  476.     friend opstream& _BIDSENTRY operator << ( opstream&, signed _TCHAR );
  477.     friend opstream& _BIDSENTRY operator << ( opstream&, unsigned _TCHAR );
  478.     friend opstream& _BIDSENTRY operator << ( opstream&, _TCHAR );
  479.     friend opstream& _BIDSENTRY operator << ( opstream&, signed short );
  480.     friend opstream& _BIDSENTRY operator << ( opstream&, unsigned short );
  481.     friend opstream& _BIDSENTRY operator << ( opstream&, signed int );
  482.     friend opstream& _BIDSENTRY operator << ( opstream&, unsigned int );
  483. #if defined(BI_UNIQUE_BOOL)
  484.     friend opstream& _BIDSENTRY operator << ( opstream&, bool );
  485. #endif
  486.     friend opstream& _BIDSENTRY operator << ( opstream&, signed long );
  487.     friend opstream& _BIDSENTRY operator << ( opstream&, unsigned long );
  488.     friend opstream& _BIDSENTRY operator << ( opstream&, float );
  489.     friend opstream& _BIDSENTRY operator << ( opstream&, double );
  490.     friend opstream& _BIDSENTRY operator << ( opstream&, long double );
  491.  
  492.     void _BIDSENTRY writeObject( const TStreamableBase _BIDSFAR *t, int isPtr = 0, ModuleId mid = GetModuleId() );
  493.     void _BIDSENTRY writeObjectPointer( const TStreamableBase _BIDSFAR *t, ModuleId mid = GetModuleId() );
  494.  
  495.     P_id_type _BIDSENTRY findObject( TStreamableBase _BIDSFAR *adr );
  496.     void _BIDSENTRY registerObject( TStreamableBase _BIDSFAR *adr );
  497.  
  498.     P_id_type _BIDSENTRY findVB( TStreamableBase _BIDSFAR *adr );
  499.     void _BIDSENTRY registerVB( TStreamableBase _BIDSFAR *adr );
  500.  
  501. protected:
  502.  
  503.     _BIDSCTOR opstream();
  504.  
  505.     void _BIDSENTRY writePrefix( const TStreamableBase _BIDSFAR * );
  506.     void _BIDSENTRY writeData( const TStreamableBase _BIDSFAR *, ModuleId mid );
  507.     void _BIDSENTRY writeSuffix( const TStreamableBase _BIDSFAR * );
  508.  
  509. private:
  510.  
  511.     void _BIDSENTRY writeVersion();
  512.  
  513.     TPWrittenObjects *objs;
  514. };
  515.  
  516. /* ------------------------------------------------------------------------*/
  517. /*                                                                         */
  518. /*   class fpbase                                                          */
  519. /*                                                                         */
  520. /*   Base class for handling streamable objects on file streams            */
  521. /*                                                                         */
  522. /* ------------------------------------------------------------------------*/
  523.  
  524. class _BIDSCLASS fpbase : virtual public pstream
  525. {
  526. public:
  527.  
  528.     _BIDSCTOR fpbase();
  529.     _BIDSCTOR fpbase( const _TCHAR _BIDSFAR *, int, int = filebuf::openprot );
  530.     _BIDSCTOR fpbase( int );
  531.     _BIDSCTOR fpbase( int, _TCHAR _BIDSFAR *, int );
  532.  
  533.     void _BIDSENTRY open( const _TCHAR _BIDSFAR *, int, int = filebuf::openprot );
  534.     void _BIDSENTRY attach( int );
  535.     void _BIDSENTRY close();
  536.     void _BIDSENTRY setbuf( _TCHAR _BIDSFAR *, int );
  537.     filebuf _BIDSFAR * _BIDSENTRY rdbuf();
  538.  
  539. private:
  540.  
  541.     filebuf buf;
  542. };
  543.  
  544. /* ------------------------------------------------------------------------*/
  545. /*                                                                         */
  546. /*   class ifpstream                                                       */
  547. /*                                                                         */
  548. /*   Base class for reading streamable objects from file streams           */
  549. /*                                                                         */
  550. /* ------------------------------------------------------------------------*/
  551.  
  552. class _BIDSCLASS ifpstream : public fpbase, public ipstream
  553. {
  554. public:
  555.  
  556.     _BIDSCTOR ifpstream();
  557.     _BIDSCTOR ifpstream( const _TCHAR _BIDSFAR *,
  558.                       int = ios::in,
  559.                       int = filebuf::openprot
  560.                     );
  561.     _BIDSCTOR ifpstream( int );
  562.     _BIDSCTOR ifpstream( int, _TCHAR _BIDSFAR *, int );
  563.  
  564.     filebuf _BIDSFAR * _BIDSENTRY rdbuf();
  565.     void _BIDSENTRY open( const _TCHAR _BIDSFAR *,
  566.                       int = ios::in,
  567.                       int = filebuf::openprot
  568.                     );
  569. };
  570.  
  571. /* ------------------------------------------------------------------------*/
  572. /*                                                                         */
  573. /*   class ofpstream                                                       */
  574. /*                                                                         */
  575. /*   Base class for writing streamable objects to file streams             */
  576. /*                                                                         */
  577. /* ------------------------------------------------------------------------*/
  578.  
  579. class _BIDSCLASS ofpstream : public fpbase, public opstream
  580. {
  581.  
  582. public:
  583.  
  584.     _BIDSCTOR ofpstream();
  585.     _BIDSCTOR ofpstream( const _TCHAR _BIDSFAR *,
  586.                       int = ios::out,
  587.                       int = filebuf::openprot
  588.                     );
  589.     _BIDSCTOR ofpstream( int );
  590.     _BIDSCTOR ofpstream( int, _TCHAR _BIDSFAR *, int );
  591.  
  592.     filebuf _BIDSFAR * _BIDSENTRY rdbuf();
  593.     void _BIDSENTRY open( const _TCHAR _BIDSFAR *,
  594.                       int = ios::out,
  595.                       int = filebuf::openprot
  596.                     );
  597. };
  598.  
  599. /* ------------------------------------------------------------------------*/
  600. /*                                                                         */
  601. /*   Inline functions                                                      */
  602. /*                                                                         */
  603. /* ------------------------------------------------------------------------*/
  604.  
  605. inline _BIDSCTOR pstream::pstream( streambuf _BIDSFAR *sb )
  606. {
  607.     init( sb );
  608. }
  609.  
  610. inline int _BIDSENTRY pstream::rdstate() const
  611. {
  612.     return state;
  613. }
  614.  
  615. inline int _BIDSENTRY pstream::eof() const
  616. {
  617.     return state & ios::eofbit;
  618. }
  619.  
  620. #if defined(BI_COMP_MSC)
  621. # define hardfail    goodbit   // MSC ios does not support hardfail, use goodbit (0)
  622. #endif
  623.  
  624. inline int _BIDSENTRY pstream::fail() const
  625. {
  626.     return state & (ios::failbit | ios::badbit | ios::hardfail);
  627. }
  628.  
  629. inline int _BIDSENTRY pstream::bad() const
  630. {
  631.     return state & (ios::badbit | ios::hardfail);
  632. }
  633.  
  634. inline int _BIDSENTRY pstream::good() const
  635. {
  636.     return state == 0;
  637. }
  638.  
  639. inline void _BIDSENTRY pstream::clear( int i )
  640. {
  641.     state = (i & 0xFF) | (state & ios::hardfail);
  642. }
  643.  
  644. #if defined(BI_COMP_MSC)
  645. # undef hardfail
  646. #endif
  647.  
  648. inline _BIDSENTRY pstream::operator void _BIDSFAR *() const
  649. {
  650.     return fail() ? 0 : (void *)this;
  651. }
  652.  
  653. inline int _BIDSENTRY pstream::operator! () const
  654. {
  655.     return fail();
  656. }
  657.  
  658. inline streambuf _BIDSFAR * _BIDSENTRY pstream::rdbuf() const
  659. {
  660.     return bp;
  661. }
  662.  
  663. inline _BIDSCTOR pstream::pstream()
  664. {
  665. }
  666.  
  667. inline void _BIDSENTRY pstream::init( streambuf *sbp )
  668. {
  669.     state = 0;
  670.     bp = sbp;
  671. }
  672.  
  673. inline void _BIDSENTRY pstream::setstate( int b )
  674. {
  675.     state |= (b&0xFF);
  676. }
  677.  
  678. inline _BIDSCTOR ipstream::ipstream( streambuf _BIDSFAR *sb )
  679. {
  680.     pstream::init( sb );
  681.     readVersion();
  682. }
  683.  
  684. inline _BIDSCTOR ipstream::ipstream()
  685. {
  686.     if( bp != 0 )
  687.         readVersion();
  688. }
  689.  
  690. inline TStreamableBase * _BIDSENTRY ipstream::find( P_id_type id )
  691. {
  692.     return objs.Find( id );
  693. }
  694.  
  695. inline void _BIDSENTRY ipstream::registerObject( TStreamableBase *adr )
  696. {
  697.     objs.RegisterObject( adr );
  698. }
  699.  
  700. inline uint32 _BIDSENTRY ipstream::getVersion() const
  701. {
  702.     return version;
  703. }
  704.  
  705. inline void _BIDSENTRY pstream::registerType( TStreamableClass *ts )
  706. {
  707.     types->RegisterType( GetModuleId(), *ts );
  708. }
  709.  
  710. inline _BIDSCTOR opstream::~opstream()
  711. {
  712.     delete objs;
  713. }
  714.  
  715. inline void _BIDSENTRY opstream::writeWord( uint32 word32 )
  716. {
  717.     writeWord32( word32 );
  718. }
  719.  
  720. inline void _BIDSENTRY opstream::writeSuffix( const TStreamableBase * )
  721. {
  722.     writeByte( ']' );
  723. }
  724.  
  725. inline P_id_type _BIDSENTRY opstream::findObject( TStreamableBase *adr )
  726. {
  727.     return objs->FindObject( adr );
  728. }
  729.  
  730. inline void _BIDSENTRY opstream::registerObject( TStreamableBase *adr )
  731. {
  732.     objs->RegisterObject( adr );
  733. }
  734.  
  735. inline P_id_type _BIDSENTRY opstream::findVB( TStreamableBase *adr )
  736. {
  737.     return objs->FindVB( adr );
  738. }
  739.  
  740. inline void _BIDSENTRY opstream::registerVB( TStreamableBase *adr )
  741. {
  742.     objs->RegisterVB( adr );
  743. }
  744.  
  745. inline _BIDSCTOR fpbase::fpbase()
  746. {
  747.     pstream::init( &buf );
  748. }
  749.  
  750. inline _BIDSCTOR fpbase::fpbase( const _TCHAR *name, int omode, int prot )
  751. {
  752.     pstream::init( &buf );
  753.     open( name, omode, prot );
  754. }
  755.  
  756. inline _BIDSCTOR fpbase::fpbase( int f ) : buf( f )
  757. {
  758.     pstream::init( &buf );
  759. }
  760.  
  761. inline _BIDSCTOR fpbase::fpbase( int f, _TCHAR *b, int len ) : buf( f, b, len )
  762. {
  763.     pstream::init( &buf );
  764. }
  765.  
  766. inline filebuf * _BIDSENTRY fpbase::rdbuf()
  767. {
  768.     return &buf;
  769. }
  770.  
  771. inline _BIDSCTOR ifpstream::ifpstream()
  772. {
  773. }
  774.  
  775. inline _BIDSCTOR ifpstream::ifpstream( const _TCHAR* name, int omode, int prot ) :
  776.     fpbase( name, omode | ios::in | ios::binary, prot )
  777. {
  778. }
  779.  
  780. inline _BIDSCTOR ifpstream::ifpstream( int f ) : fpbase( f )
  781. {
  782. }
  783.  
  784. inline _BIDSCTOR ifpstream::ifpstream(int f, _TCHAR* b, int len) : fpbase(f, b, len)
  785. {
  786. }
  787.  
  788. inline filebuf * _BIDSENTRY ifpstream::rdbuf()
  789. {
  790.     return fpbase::rdbuf();
  791. }
  792.  
  793. inline void _BIDSENTRY ifpstream::open( const _TCHAR _BIDSFAR *name,
  794.                                     int omode,
  795.                                     int prot )
  796. {
  797.     fpbase::open( name, omode | ios::in | ios::binary, prot );
  798.     readVersion();
  799. }
  800.  
  801. inline _BIDSCTOR ofpstream::ofpstream()
  802. {
  803. }
  804.  
  805. inline _BIDSCTOR ofpstream::ofpstream( const _TCHAR* name, int omode, int prot ) :
  806.     fpbase( name, omode | ios::out | ios::binary, prot )
  807. {
  808. }
  809.  
  810. inline _BIDSCTOR ofpstream::ofpstream( int f ) : fpbase( f )
  811. {
  812. }
  813.  
  814. inline _BIDSCTOR ofpstream::ofpstream(int f, _TCHAR* b, int len) :
  815.     fpbase(f, b, len)
  816. {
  817. }
  818.  
  819. inline filebuf * _BIDSENTRY ofpstream::rdbuf()
  820. {
  821.     return fpbase::rdbuf();
  822. }
  823.  
  824. inline void _BIDSENTRY ofpstream::open( const _TCHAR _BIDSFAR *name,
  825.                                     int omode,
  826.                                     int prot )
  827. {
  828.     fpbase::open( name, omode | ios::out | ios::binary, prot );
  829. }
  830.  
  831. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, _TSCHAR &ch )
  832. {
  833.     ch = ps.readByte();
  834.     return ps;
  835. }
  836.  
  837. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, _TUCHAR &ch )
  838. {
  839.     ch = ps.readByte();
  840.     return ps;
  841. }
  842.  
  843. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, _TCHAR &ch )
  844. {
  845.     ch = ps.readByte();
  846.     return ps;
  847. }
  848.  
  849. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, signed short &sh )
  850. {
  851.     sh = ps.readWord16();
  852.     return ps;
  853. }
  854.  
  855. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, unsigned short &sh )
  856. {
  857.     sh = ps.readWord16();
  858.     return ps;
  859. }
  860.  
  861. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, signed int &i )
  862. {
  863.     i = (int)(ps.readWord());
  864.     return ps;
  865. }
  866.  
  867. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, unsigned int &i )
  868. {
  869.     i = (unsigned int)(ps.readWord());
  870.     return ps;
  871. }
  872.  
  873. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, signed long &l )
  874. {
  875.     ps.readBytes( &l, sizeof(l) );
  876.     return ps;
  877. }
  878.  
  879. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, unsigned long &l )
  880. {
  881.     ps.readBytes( &l, sizeof(l) );
  882.     return ps;
  883. }
  884.  
  885. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, float &f )
  886. {
  887.     ps.readBytes( &f, sizeof(f) );
  888.     return ps;
  889. }
  890.  
  891. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, double &d )
  892. {
  893.     ps.readBytes( &d, sizeof(d) );
  894.     return ps;
  895. }
  896.  
  897. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, long double &l )
  898. {
  899.     ps.readBytes( &l, sizeof(l) );
  900.     return ps;
  901. }
  902.  
  903. #if defined(BI_UNIQUE_BOOL)
  904. inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, bool &b )
  905. {
  906.     b = static_cast<bool>(ps.readWord32());
  907.     return ps;
  908. }
  909. #endif
  910.  
  911. inline opstream& _BIDSENTRY operator << ( opstream& ps, _TSCHAR ch )
  912. {
  913.     ps.writeByte( ch );
  914.     return ps;
  915. }
  916.  
  917. inline opstream& _BIDSENTRY operator << ( opstream& ps, _TUCHAR ch )
  918. {
  919.     ps.writeByte( ch );
  920.     return ps;
  921. }
  922.  
  923. inline opstream& _BIDSENTRY operator << ( opstream& ps, _TCHAR ch )
  924. {
  925.     ps.writeByte( ch );
  926.     return ps;
  927. }
  928.  
  929. inline opstream& _BIDSENTRY operator << ( opstream& ps, signed short sh )
  930. {
  931.     ps.writeWord16( sh );
  932.     return ps;
  933. }
  934.  
  935. inline opstream& _BIDSENTRY operator << ( opstream& ps, unsigned short sh )
  936. {
  937.     ps.writeWord16( sh );
  938.     return ps;
  939. }
  940.  
  941. inline opstream& _BIDSENTRY operator << ( opstream& ps, signed int i )
  942. {
  943.     ps.writeWord32( i );
  944.     return ps;
  945. }
  946.  
  947. inline opstream& _BIDSENTRY operator << ( opstream& ps, unsigned int i )
  948. {
  949.     ps.writeWord32( i );
  950.     return ps;
  951. }
  952.  
  953. inline opstream& _BIDSENTRY operator << ( opstream& ps, signed long l )
  954. {
  955.     ps.writeBytes( &l, sizeof(l) );
  956.     return ps;
  957. }
  958.  
  959. inline opstream& _BIDSENTRY operator << ( opstream& ps, unsigned long l )
  960. {
  961.     ps.writeBytes( &l, sizeof(l) );
  962.     return ps;
  963. }
  964.  
  965. inline opstream& _BIDSENTRY operator << ( opstream& ps, float f )
  966. {
  967.     ps.writeBytes( &f, sizeof(f) );
  968.     return ps;
  969. }
  970.  
  971. inline opstream& _BIDSENTRY operator << ( opstream& ps, double d )
  972. {
  973.     ps.writeBytes( &d, sizeof(d) );
  974.     return ps;
  975. }
  976.  
  977. inline opstream& _BIDSENTRY operator << ( opstream& ps, long double l )
  978. {
  979.     ps.writeBytes( &l, sizeof(l) );
  980.     return ps;
  981. }
  982.  
  983. #if defined(BI_UNIQUE_BOOL)
  984. inline opstream& _BIDSENTRY operator << ( opstream& ps, bool b )
  985. {
  986.     ps.writeWord32( b );
  987.     return ps;
  988. }
  989. #endif
  990.  
  991. template <class Base> void WriteBaseObject( Base *base, opstream& out )
  992. {
  993.     Base::Streamer strmr(base);
  994.     out << strmr.ClassVersion();
  995.     strmr.Write( out );
  996. }
  997.  
  998. template <class Base> void ReadBaseObject( Base *base, ipstream& in )
  999. {
  1000.     uint32 version = 0;
  1001.     if( in.getVersion() > 0 )
  1002.         in >> version;
  1003.     Base::Streamer(base).Read( in, version );
  1004. }
  1005.  
  1006. template <class Base> void WriteVirtualBase( Base *base, opstream& out )
  1007. {
  1008.     if( !out.good() )
  1009.         return;
  1010.     if( out.findVB( base ) != 0 )
  1011.         {
  1012.         out.writeByte( pstream::ptIndexed );    // use ptIndexed to indicate
  1013.                                                 // that we've already seen
  1014.                                                 // this virtual base. Don't
  1015.                                                 // need to actually write it.
  1016.         }
  1017.     else
  1018.         {
  1019.         Base::Streamer strmr(base);
  1020.         out.registerObject( (TStreamableBase *)((_TCHAR *)base + 1) );
  1021.         out.writeByte( pstream::ptObject );
  1022.         out.writeWord32( strmr.ClassVersion() );
  1023.         strmr.Write( out );
  1024.         }
  1025. }
  1026.  
  1027. template <class Base> void ReadVirtualBase( Base *base, ipstream& in )
  1028. {
  1029.     _TCHAR ch;
  1030.     in >> ch;
  1031.     switch( ch )
  1032.         {
  1033.         case pstream::ptIndexed:
  1034.             {
  1035.             break;      // We've already read this virtual base
  1036.             }
  1037.         case pstream::ptObject:
  1038.             {
  1039.             uint32 ver = 0;
  1040.             if( in.getVersion() > 0 )
  1041.                 ver = in.readWord32();
  1042.             Base::Streamer strmr(base);
  1043.             // register the address
  1044.             in.registerObject(strmr.GetObject());
  1045.             strmr.Read( in, ver );
  1046.             break;
  1047.             }
  1048.         }
  1049. }
  1050.  
  1051. //
  1052. //  Individual Components for Streamable Declarations
  1053. //
  1054.  
  1055. // When using namespaces, the friend declarations need to name
  1056. // their scope explicitly.
  1057. //
  1058.  
  1059. // Used to paste tokens when one argument is itself a macro
  1060. // that needs to be processed before the ## operation
  1061. //
  1062. #define INNER_PASTE(a,b) a ## b
  1063. #define PASTE(a, b) INNER_PASTE(a,b)
  1064.  
  1065. #if defined(BI_NAMESPACE)
  1066. # define CLASSLIB_ ClassLib::
  1067. #else
  1068. # define CLASSLIB_
  1069. #endif
  1070.  
  1071. #define DECLARE_STREAMER( exp, cls, ver )                           \
  1072. public:                                                             \
  1073.     class exp Streamer : public TNewStreamer                        \
  1074.         {                                                           \
  1075.         public:                                                     \
  1076.                                                                     \
  1077.         Streamer( TStreamableBase *obj );                           \
  1078.                                                                     \
  1079.         virtual uint32 ClassVersion() const                         \
  1080.             { return ver; }                                         \
  1081.                                                                     \
  1082.         virtual void Write( opstream& ) const;                      \
  1083.         virtual void *Read( ipstream&, uint32 ) const;              \
  1084.                                                                     \
  1085.         cls *GetObject() const                                      \
  1086.             {                                                       \
  1087.             return object;                                          \
  1088.             }                                                       \
  1089.                                                                     \
  1090.         static TStreamer *Build( TStreamableBase *obj )             \
  1091.             {                                                       \
  1092.             return new Streamer( obj ? obj : new cls(streamableInit) ); \
  1093.             }                                                       \
  1094.                                                                     \
  1095.         private:                                                    \
  1096.             cls *object;                                            \
  1097.                                                                     \
  1098.         };                                                          \
  1099.     friend Streamer;                                                \
  1100.     friend void PASTE(CLASSLIB_, ReadBaseObject)( cls *, ipstream& );   \
  1101.     friend void PASTE(CLASSLIB_, WriteBaseObject)( cls *, opstream& );  \
  1102.     friend void PASTE(CLASSLIB_, ReadVirtualBase)( cls *, ipstream& );  \
  1103.     friend void PASTE(CLASSLIB_, WriteVirtualBase)( cls *, opstream& )
  1104.  
  1105. #define DECLARE_STREAMER_FROM_BASE( exp, cls, base )                \
  1106. public:                                                             \
  1107.     class exp Streamer : public base::Streamer                      \
  1108.         {                                                           \
  1109.         public:                                                     \
  1110.                                                                     \
  1111.         Streamer( TStreamableBase *obj ) : base::Streamer(obj){}    \
  1112.                                                                     \
  1113.         cls *GetObject() const                                      \
  1114.             {                                                       \
  1115.             return object;                                          \
  1116.             }                                                       \
  1117.                                                                     \
  1118.         static TStreamer *Build( TStreamableBase *obj )             \
  1119.             {                                                       \
  1120.             return new Streamer( obj ? obj : new cls(streamableInit) ); \
  1121.             }                                                       \
  1122.                                                                     \
  1123.         private:                                                    \
  1124.             cls *object;                                            \
  1125.                                                                     \
  1126.         };                                                          \
  1127.     friend Streamer;                                                \
  1128.     friend void PASTE(CLASSLIB_, ReadBaseObject)( cls *, ipstream& );   \
  1129.     friend void PASTE(CLASSLIB_, WriteBaseObject)( cls *, opstream& );  \
  1130.     friend void PASTE(CLASSLIB_, ReadVirtualBase)( cls *, ipstream& );  \
  1131.     friend void PASTE(CLASSLIB_, WriteVirtualBase)( cls *, opstream& )
  1132.  
  1133. #define DECLARE_ABSTRACT_STREAMER( exp, cls, ver )                  \
  1134. public:                                                             \
  1135.     class exp Streamer : public TNewStreamer                        \
  1136.         {                                                           \
  1137.         public:                                                     \
  1138.                                                                     \
  1139.         Streamer( TStreamableBase *obj );                           \
  1140.                                                                     \
  1141.         virtual uint32 ClassVersion() const                         \
  1142.             { return ver; }                                         \
  1143.                                                                     \
  1144.         virtual void Write( opstream& ) const;                      \
  1145.         virtual void *Read( ipstream&, uint32 ) const;              \
  1146.                                                                     \
  1147.         cls *GetObject() const                                      \
  1148.             {                                                       \
  1149.             return object;                                          \
  1150.             }                                                       \
  1151.                                                                     \
  1152.         private:                                                    \
  1153.             cls *object;                                            \
  1154.                                                                     \
  1155.         };                                                          \
  1156.     friend Streamer;                                                \
  1157.     friend void PASTE(CLASSLIB_, ReadBaseObject)( cls *, ipstream& );   \
  1158.     friend void PASTE(CLASSLIB_, WriteBaseObject)( cls *, opstream& );  \
  1159.     friend void PASTE(CLASSLIB_, ReadVirtualBase)( cls *, ipstream& );  \
  1160.     friend void PASTE(CLASSLIB_, WriteVirtualBase)( cls *, opstream& )
  1161.  
  1162. #define DECLARE_STREAMABLE_OPS( cls )                               \
  1163. static ipstream& readRef( ipstream& is, cls& cl );                  \
  1164. friend inline ipstream& operator >> ( ipstream& is, cls& cl )       \
  1165.     { return cls::readRef( is, cl ); }                              \
  1166. static ipstream& readPtr( ipstream& is, cls*& cl );                 \
  1167. friend inline ipstream& operator >> ( ipstream& is, cls*& cl )      \
  1168.     { return cls::readPtr( is, cl ); }                              \
  1169. static opstream& writeRef( opstream& is, const cls& cl );           \
  1170. friend inline opstream& operator << ( opstream& os, const cls& cl ) \
  1171.     { return cls::writeRef( os, cl ); }                             \
  1172. static opstream& writePtr( opstream& is, const cls* cl );           \
  1173. friend inline opstream& operator << ( opstream& os, const cls* cl ) \
  1174.     { return cls::writePtr( os, cl ); }
  1175.  
  1176. #define DECLARE_STREAMABLE_CTOR( cls )                              \
  1177. public:                                                             \
  1178.     cls ( StreamableInit )
  1179.  
  1180.  
  1181. //
  1182. // Castable declaration macros
  1183. //
  1184. #if defined( BI_NO_RTTI )
  1185. # define DECLARE_CASTABLE                                           \
  1186. public:                                                             \
  1187.     virtual void *FindBase( Type_id id ) const;                     \
  1188. public:                                                             \
  1189.     virtual Type_id CastableID() const;                             \
  1190.     virtual void *MostDerived() const { return (void *)this; }      \
  1191.     static Type_id CastableIdent
  1192. #else
  1193. # define DECLARE_CASTABLE friend class typeinfo
  1194. #endif
  1195.  
  1196. //
  1197. // Streamable declaration macros
  1198. //
  1199. #if !defined(BI_NO_OBJ_STREAMING)
  1200.  
  1201. #define DECLARE_STREAMABLE( exp, cls, ver )                         \
  1202.     DECLARE_CASTABLE ;                                               \
  1203.     DECLARE_STREAMER( exp, cls, ver );                              \
  1204.     DECLARE_STREAMABLE_OPS( cls );                                  \
  1205.     DECLARE_STREAMABLE_CTOR( cls )
  1206.  
  1207. #define DECLARE_STREAMABLE_FROM_BASE( exp, cls, base )              \
  1208.     DECLARE_CASTABLE;                                               \
  1209.     DECLARE_STREAMER_FROM_BASE( exp, cls, base );                   \
  1210.     DECLARE_STREAMABLE_OPS( cls );                                  \
  1211.     DECLARE_STREAMABLE_CTOR( cls )
  1212.  
  1213. #define DECLARE_ABSTRACT_STREAMABLE( exp, cls, ver )                \
  1214.     DECLARE_CASTABLE;                                               \
  1215.     DECLARE_ABSTRACT_STREAMER( exp, cls, ver );                     \
  1216.     DECLARE_STREAMABLE_OPS( cls );                                  \
  1217.     DECLARE_STREAMABLE_CTOR( cls )
  1218.  
  1219. #else  // if BI_NO_OBJ_STREAMING
  1220.  
  1221. #define DECLARE_STREAMABLE( exp, cls, ver )                         \
  1222.     DECLARE_CASTABLE
  1223.  
  1224. #define DECLARE_STREAMABLE_FROM_BASE( exp, cls, base )              \
  1225.     DECLARE_CASTABLE
  1226.  
  1227. #define DECLARE_ABSTRACT_STREAMABLE( exp, cls, ver )                \
  1228.     DECLARE_CASTABLE
  1229.  
  1230. #endif  // if/else BI_NO_OBJ_STREAMING
  1231.  
  1232. //
  1233. // Castable implementation macros
  1234. //
  1235. #if !defined( BI_NO_RTTI )
  1236.  
  1237. #define IMPLEMENT_CASTABLE( cls )
  1238. #define IMPLEMENT_CASTABLE1( cls, base1 )
  1239. #define IMPLEMENT_CASTABLE2( cls, base1, base2 )
  1240. #define IMPLEMENT_CASTABLE3( cls, base1, base2, base3 )
  1241. #define IMPLEMENT_CASTABLE4( cls, base1, base2, base3, base4 )
  1242. #define IMPLEMENT_CASTABLE5( cls, base1, base2, base3, base4, base5 )
  1243.  
  1244. #else   // BI_NO_RTTI
  1245.  
  1246. #define IMPLEMENT_CASTABLE_ID( cls )                                \
  1247. TStreamableBase::Type_id cls::CastableIdent = #cls;                 \
  1248. TStreamableBase::Type_id cls::CastableID() const                    \
  1249. {                                                                   \
  1250.     return cls::CastableIdent;                                      \
  1251. }                                                                   \
  1252.  
  1253. #define IMPLEMENT_CASTABLE( cls )                                   \
  1254. IMPLEMENT_CASTABLE_ID( cls );                                       \
  1255. void *cls::FindBase( Type_id id ) const                             \
  1256. {                                                                   \
  1257.     return (_tcscmp( id, CastableIdent ) == 0) ? (void *)this : 0;   \
  1258. }                                                                   \
  1259.  
  1260.                                                                     \
  1261. #define IMPLEMENT_CASTABLE1( cls, base1 )                           \
  1262. IMPLEMENT_CASTABLE_ID( cls );                                       \
  1263. void *cls::FindBase( Type_id id ) const                             \
  1264. {                                                                   \
  1265.     if(_tcscmp( id, CastableIdent ) == 0)                            \
  1266.         return (void *)this;                                        \
  1267.     else                                                            \
  1268.         return base1::FindBase(id);                                 \
  1269. }                                                                   \
  1270.  
  1271. #define IMPLEMENT_CASTABLE2( cls, base1, base2 )                    \
  1272. IMPLEMENT_CASTABLE_ID( cls );                                       \
  1273. void *cls::FindBase( Type_id id ) const                             \
  1274. {                                                                   \
  1275.     void *res = 0;                                                  \
  1276.     if(_tcscmp( id, CastableIdent ) == 0)                            \
  1277.         return (void *)this;                                        \
  1278.     else if( (res = base1::FindBase(id)) != 0 )                     \
  1279.         return res;                                                 \
  1280.     else if( (res = base2::FindBase(id)) != 0 )                     \
  1281.         return res;                                                 \
  1282.     else                                                            \
  1283.         return 0;                                                   \
  1284. }                                                                   \
  1285.  
  1286. #define IMPLEMENT_CASTABLE3( cls, base1, base2, base3 )             \
  1287. IMPLEMENT_CASTABLE_ID( cls );                                       \
  1288. void *cls::FindBase( Type_id id ) const                             \
  1289. {                                                                   \
  1290.     void *res = 0;                                                  \
  1291.     if(_tcscmp( id, CastableIdent ) == 0)                            \
  1292.         return (void *)this;                                        \
  1293.     else if( (res = base1::FindBase(id)) != 0 )                     \
  1294.         return res;                                                 \
  1295.     else if( (res = base2::FindBase(id)) != 0 )                     \
  1296.         return res;                                                 \
  1297.     else if( (res = base3::FindBase(id)) != 0 )                     \
  1298.         return res;                                                 \
  1299.     else                                                            \
  1300.         return 0;                                                   \
  1301. }                                                                   \
  1302.  
  1303. #define IMPLEMENT_CASTABLE4( cls, base1, base2, base3, base4 )      \
  1304. IMPLEMENT_CASTABLE_ID( cls );                                       \
  1305. void *cls::FindBase( Type_id id ) const                             \
  1306. {                                                                   \
  1307.     void *res = 0;                                                  \
  1308.     if(_tcscmp( id, CastableIdent ) == 0)                            \
  1309.         return (void *)this;                                        \
  1310.     else if( (res = base1::FindBase(id)) != 0 )                     \
  1311.         return res;                                                 \
  1312.     else if( (res = base2::FindBase(id)) != 0 )                     \
  1313.         return res;                                                 \
  1314.     else if( (res = base3::FindBase(id)) != 0 )                     \
  1315.         return res;                                                 \
  1316.     else if( (res = base4::FindBase(id)) != 0 )                     \
  1317.         return res;                                                 \
  1318.     else                                                            \
  1319.         return 0;                                                   \
  1320. }                                                                   \
  1321.  
  1322. #define IMPLEMENT_CASTABLE5( cls, base1, base2, base3, base4, base5 )\
  1323. IMPLEMENT_CASTABLE_ID( cls );                                       \
  1324. void *cls::FindBase( Type_id id ) const                             \
  1325. {                                                                   \
  1326.     void *res = 0;                                                  \
  1327.     if(_tcscmp( id, CastableIdent ) == 0)                            \
  1328.         return (void *)this;                                        \
  1329.     else if( (res = base1::FindBase(id)) != 0 )                     \
  1330.         return res;                                                 \
  1331.     else if( (res = base2::FindBase(id)) != 0 )                     \
  1332.         return res;                                                 \
  1333.     else if( (res = base3::FindBase(id)) != 0 )                     \
  1334.         return res;                                                 \
  1335.     else if( (res = base4::FindBase(id)) != 0 )                     \
  1336.         return res;                                                 \
  1337.     else if( (res = base5::FindBase(id)) != 0 )                     \
  1338.         return res;                                                 \
  1339.     else                                                            \
  1340.         return 0;                                                   \
  1341. }                                                                   \
  1342.  
  1343. #endif  // BI_NO_RTTI
  1344.  
  1345. //
  1346. // Streamable implementation mactos
  1347. //
  1348. #if !defined(BI_NO_OBJ_STREAMING)
  1349. # if defined( BI_NO_RTTI )
  1350. #   define IMPLEMENT_STREAMABLE_CLASS( cls )    \
  1351.     TStreamableClass r ## cls( cls::CastableIdent, &cls::Streamer::Build )
  1352. # else
  1353. #   define IMPLEMENT_STREAMABLE_CLASS( cls )    \
  1354.     TStreamableClass r ## cls( typeid(cls).name(), &cls::Streamer::Build )
  1355. # endif
  1356. #else
  1357. # define IMPLEMENT_STREAMABLE_CLASS( cls )
  1358. #endif
  1359.  
  1360. #if !defined(BI_NO_OBJ_STREAMING)
  1361. #define IMPLEMENT_STREAMABLE_POINTER( cls )                         \
  1362. ipstream& cls::readPtr( ipstream& is, cls*& cl )                    \
  1363.     {                                                               \
  1364.     TStreamableBase *temp = 0;                                      \
  1365.     is.readObjectPointer( temp );                                   \
  1366.     cl = TYPESAFE_DOWNCAST(temp,cls);                               \
  1367.     return is;                                                      \
  1368.     }                                                               \
  1369. ipstream& cls::readRef( ipstream& is, cls& cl )                     \
  1370.     {                                                               \
  1371.     TStreamableBase *ptr = &cl;                                     \
  1372.     is.readObject( ptr );                                           \
  1373.     return is;                                                      \
  1374.     }                                                               \
  1375. opstream& cls::writeRef( opstream& os, const cls& cl )              \
  1376.     {                                                               \
  1377.     os.writeObject( &cl );                                          \
  1378.     return os;                                                      \
  1379.     }                                                               \
  1380. opstream& cls::writePtr( opstream& os, const cls* cl )              \
  1381.     {                                                               \
  1382.     os.writeObjectPointer( cl );                                    \
  1383.     return os;                                                      \
  1384.     }
  1385. #else
  1386. #define IMPLEMENT_STREAMABLE_POINTER( cls )
  1387. #endif
  1388.  
  1389. #if !defined(BI_NO_OBJ_STREAMING)
  1390.  
  1391. #define IMPLEMENT_STREAMER( cls )                                   \
  1392. cls::Streamer::Streamer( TStreamableBase *obj ) :                   \
  1393.     TNewStreamer(obj), object(TYPESAFE_DOWNCAST(obj,cls)){}
  1394.  
  1395. #define IMPLEMENT_STREAMABLE_CTOR( cls )                            \
  1396. cls::cls ( StreamableInit ) {}
  1397.  
  1398. #define IMPLEMENT_STREAMABLE_CTOR1( cls, base1 )                    \
  1399. cls::cls ( StreamableInit ) : base1( streamableInit ) {}
  1400.  
  1401. #define IMPLEMENT_STREAMABLE_CTOR2( cls, base1, base2 )             \
  1402. cls::cls ( StreamableInit ) :                                       \
  1403.     base1 ( streamableInit ),                                       \
  1404.     base2 ( streamableInit ) {}
  1405.  
  1406. #define IMPLEMENT_STREAMABLE_CTOR3( cls, base1, base2, base3 )      \
  1407. cls::cls ( StreamableInit ) :                                       \
  1408.     base1 ( streamableInit ),                                       \
  1409.     base2 ( streamableInit ),                                       \
  1410.     base3 ( streamableInit ) {}
  1411.  
  1412. #define IMPLEMENT_STREAMABLE_CTOR4( cls, base1, base2, base3, base4 )\
  1413. cls::cls ( StreamableInit ) :                                       \
  1414.     base1 ( streamableInit ),                                       \
  1415.     base2 ( streamableInit ),                                       \
  1416.     base3 ( streamableInit ),                                       \
  1417.     base4 ( streamableInit ) {}
  1418.  
  1419. #define IMPLEMENT_STREAMABLE_CTOR5( cls, base1,base2,base3,base4,base5)\
  1420. cls::cls ( StreamableInit ) :                                       \
  1421.     base1 ( streamableInit ),                                       \
  1422.     base2 ( streamableInit ),                                       \
  1423.     base3 ( streamableInit ),                                       \
  1424.     base4 ( streamableInit ),                                       \
  1425.     base5 ( streamableInit ) {}
  1426.  
  1427. #else  // if !defined(BI_NO_OBJ_STREAMING)
  1428. # define IMPLEMENT_STREAMER( cls )
  1429. # define IMPLEMENT_STREAMABLE_CTOR( cls )
  1430. # define IMPLEMENT_STREAMABLE_CTOR1( cls, base1 )
  1431. # define IMPLEMENT_STREAMABLE_CTOR2( cls, base1, base2 )
  1432. # define IMPLEMENT_STREAMABLE_CTOR3( cls, base1, base2, base3 )
  1433. # define IMPLEMENT_STREAMABLE_CTOR4( cls, base1, base2, base3, base4 )
  1434. # define IMPLEMENT_STREAMABLE_CTOR5( cls, base1,base2,base3,base4,base5)
  1435. #endif
  1436.                                                                     \
  1437.  
  1438. //
  1439. //  Standard Combinations of Streamable Implementations
  1440. //
  1441.  
  1442. #if !defined(BI_NO_OBJ_STREAMING)
  1443. #define IMPLEMENT_ABSTRACT_STREAMABLE( cls )                        \
  1444. IMPLEMENT_CASTABLE( cls );                                          \
  1445. IMPLEMENT_STREAMER( cls );                                          \
  1446. IMPLEMENT_STREAMABLE_CTOR( cls );                                   \
  1447. IMPLEMENT_STREAMABLE_POINTER( cls )
  1448.  
  1449. #define IMPLEMENT_ABSTRACT_STREAMABLE1( cls, base1 )                \
  1450. IMPLEMENT_CASTABLE1( cls, base1 );                                  \
  1451. IMPLEMENT_STREAMER( cls );                                          \
  1452. IMPLEMENT_STREAMABLE_CTOR1( cls, base1 );                           \
  1453. IMPLEMENT_STREAMABLE_POINTER( cls )
  1454.  
  1455. #define IMPLEMENT_ABSTRACT_STREAMABLE2( cls, base1, base2 )         \
  1456. IMPLEMENT_CASTABLE2( cls, base1, base2 );                    \
  1457. IMPLEMENT_STREAMER( cls );                                          \
  1458. IMPLEMENT_STREAMABLE_CTOR2( cls, base1, base2 );                    \
  1459. IMPLEMENT_STREAMABLE_POINTER( cls )
  1460.  
  1461. #define IMPLEMENT_ABSTRACT_STREAMABLE3( cls, base1, base2, base3 )  \
  1462. IMPLEMENT_CASTABLE3( cls, base1, base2, base3 );                    \
  1463. IMPLEMENT_STREAMER( cls );                                          \
  1464. IMPLEMENT_STREAMABLE_CTOR3( cls, base1, base2, base3 );             \
  1465. IMPLEMENT_STREAMABLE_POINTER( cls )
  1466.  
  1467. #define IMPLEMENT_ABSTRACT_STREAMABLE4( cls, base1, base2, base3, base4 )\
  1468. IMPLEMENT_CASTABLE4( cls, base1, base2, base3, base4 );             \
  1469. IMPLEMENT_STREAMER( cls );                                          \
  1470. IMPLEMENT_STREAMABLE_CTOR4( cls, base1, base2, base3, base4 );      \
  1471. IMPLEMENT_STREAMABLE_POINTER( cls )
  1472.  
  1473. #define IMPLEMENT_ABSTRACT_STREAMABLE5( cls, base1, base2, base3, base4, base5 )\
  1474. IMPLEMENT_CASTABLE5( cls, base1, base2, base3, base4, base5 );      \
  1475. IMPLEMENT_STREAMER( cls );                                          \
  1476. IMPLEMENT_STREAMABLE_CTOR5( cls, base1, base2, base3, base4, base5 );\
  1477. IMPLEMENT_STREAMABLE_POINTER( cls )
  1478.  
  1479. #define IMPLEMENT_STREAMABLE( cls )                                 \
  1480. IMPLEMENT_STREAMABLE_CLASS( cls );                                  \
  1481. IMPLEMENT_ABSTRACT_STREAMABLE( cls )
  1482.  
  1483. #define IMPLEMENT_STREAMABLE1( cls, base1 )                         \
  1484. IMPLEMENT_STREAMABLE_CLASS( cls );                                  \
  1485. IMPLEMENT_ABSTRACT_STREAMABLE1( cls, base1 )
  1486.  
  1487. #define IMPLEMENT_STREAMABLE2( cls, base1, base2 )                  \
  1488. IMPLEMENT_STREAMABLE_CLASS( cls );                                  \
  1489. IMPLEMENT_ABSTRACT_STREAMABLE2( cls, base1, base2 )
  1490.  
  1491. #define IMPLEMENT_STREAMABLE3( cls, base1, base2, base3 )           \
  1492. IMPLEMENT_STREAMABLE_CLASS( cls );                                  \
  1493. IMPLEMENT_ABSTRACT_STREAMABLE3( cls, base1, base2, base3 )
  1494.  
  1495. #define IMPLEMENT_STREAMABLE4( cls, base1, base2, base3, base4 )    \
  1496. IMPLEMENT_STREAMABLE_CLASS( cls );                                  \
  1497. IMPLEMENT_ABSTRACT_STREAMABLE4( cls, base1, base2, base3, base4 )
  1498.  
  1499. #define IMPLEMENT_STREAMABLE5( cls, base1, base2, base3, base4, base5 )\
  1500. IMPLEMENT_STREAMABLE_CLASS( cls );                                  \
  1501. IMPLEMENT_ABSTRACT_STREAMABLE5( cls, base1, base2, base3, base4, base5 )
  1502.  
  1503. #define IMPLEMENT_STREAMABLE_FROM_BASE( cls, base1 )                \
  1504. IMPLEMENT_STREAMABLE_CLASS( cls );                                  \
  1505. IMPLEMENT_STREAMABLE_CTOR1( cls, base1 );                           \
  1506. IMPLEMENT_STREAMABLE_POINTER( cls )
  1507.  
  1508. #else  // if BI_NO_OBJ_STREAMING
  1509.  
  1510. #define IMPLEMENT_ABSTRACT_STREAMABLE( cls )                        \
  1511. IMPLEMENT_CASTABLE( cls );
  1512. #define IMPLEMENT_ABSTRACT_STREAMABLE1( cls, base1 )                \
  1513. IMPLEMENT_CASTABLE1( cls, base1 );
  1514. #define IMPLEMENT_ABSTRACT_STREAMABLE2( cls, base1, base2 )         \
  1515. IMPLEMENT_CASTABLE2( cls, base1, base2 )
  1516. #define IMPLEMENT_ABSTRACT_STREAMABLE3( cls, base1, base2, base3 )  \
  1517. IMPLEMENT_CASTABLE3( cls, base1, base2, base3 );
  1518. #define IMPLEMENT_ABSTRACT_STREAMABLE4( cls, base1, base2, base3, base4 ) \
  1519. IMPLEMENT_CASTABLE4( cls, base1, base2, base3, base4 );
  1520. #define IMPLEMENT_ABSTRACT_STREAMABLE5( cls, base1, base2, base3, base4, base5 ) \
  1521. IMPLEMENT_CASTABLE5( cls, base1, base2, base3, base4, base5 );
  1522. #define IMPLEMENT_STREAMABLE( cls )                                \
  1523. IMPLEMENT_CASTABLE( cls );
  1524. #define IMPLEMENT_STREAMABLE1( cls, base1 )                        \
  1525. IMPLEMENT_CASTABLE1( cls, base1 );
  1526. #define IMPLEMENT_STREAMABLE2( cls, base1, base2 )                 \
  1527. IMPLEMENT_CASTABLE2( cls, base1, base2 )
  1528. #define IMPLEMENT_STREAMABLE3( cls, base1, base2, base3 )          \
  1529. IMPLEMENT_CASTABLE3( cls, base1, base2, base3 );
  1530. #define IMPLEMENT_STREAMABLE4( cls, base1, base2, base3, base4 )   \
  1531. IMPLEMENT_CASTABLE4( cls, base1, base2, base3, base4 );
  1532. #define IMPLEMENT_STREAMABLE5( cls, base1, base2, base3, base4, base5 ) \
  1533. IMPLEMENT_CASTABLE5( cls, base1, base2, base3, base4, base5 );
  1534. #define IMPLEMENT_STREAMABLE_FROM_BASE( cls, base1 )
  1535.  
  1536. #endif  // if/else BI_NO_OBJ_STREAMING
  1537.  
  1538. #if defined(BI_NAMESPACE)
  1539. }   // namespace ClassLib
  1540. #endif
  1541.  
  1542. #if defined(BI_CLASSLIB_NO_po)
  1543. # pragma option -po.
  1544. #endif
  1545.  
  1546. #endif  // CLASSLIB_OBJSTRM_H
  1547.