home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / classinc.pak / OBJSTRM.H < prev    next >
C/C++ Source or Header  |  1997-07-23  |  54KB  |  1,427 lines

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