home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 May
/
Pcwk5b98.iso
/
Borland
/
Cplus45
/
BC45
/
CLASSINC.PAK
/
OBJSTRM.H
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-29
|
54KB
|
1,427 lines
/*------------------------------------------------------------------------*/
/* */
/* OBJSTRM.H */
/* */
/* Copyright (c) 1992, 1994 Borland International */
/* All Rights Reserved */
/* */
/*------------------------------------------------------------------------*/
#if !defined( CLASSLIB_OBJSTRM_H )
#define CLASSLIB_OBJSTRM_H
#if !defined( __IOSTREAM_H )
#include <iostream.h>
#endif
#if !defined( __FSTREAM_H )
#include <fstream.h>
#endif
#if !defined( __SYSTYPES_H )
#include <systypes.h>
#endif
#if !defined( __TYPEINFO_H ) && !defined(BI_NO_RTTI)
#include <typeinfo.h>
#endif
#if !defined( __CHECKS_H )
#include <checks.h>
#endif
#if !defined( CLASSLIB_DEFS_H )
#include <classlib/defs.h>
#endif
#if !defined( CLASSLIB_STREAMBL_H )
#include <classlib/streambl.h>
#endif
#if !defined( CLASSLIB_VECTIMP_H )
#include <classlib/vectimp.h>
#endif
#if defined( BI_CLASSLIB_NO_po )
#pragma option -po-
#endif
/*------------------------------------------------------------------------*/
/* */
/* The __link() macro forces the compiler to link in a static instance */
/* of class TStreamableClass, which in turn registers its associated */
/* TStreamable object with the stream manager. Applications that do */
/* not use streaming won't use __link(), and that will reduce the amount */
/* of code that is linked into the application. */
/* */
/*------------------------------------------------------------------------*/
struct fLink
{
struct fLink *f;
class TStreamableClass *t;
};
#define __link( s ) \
extern TStreamableClass s; \
static fLink force ## s = \
{ (fLink *)&force ## s, (TStreamableClass *)&s };
typedef unsigned P_id_type;
class _BIDSCLASS _RTTI TStreamable;
class _BIDSCLASS TStreamableTypes;
class _BIDSCLASS opstream;
class _BIDSCLASS ipstream;
class _EXPCLASS string;
ipstream _BIDSFAR& _BIDSENTRY _BIDSFUNC operator >> ( ipstream _BIDSFAR& is,
string _BIDSFAR& str );
opstream _BIDSFAR& _BIDSENTRY _BIDSFUNC operator << ( opstream _BIDSFAR& os,
const string _BIDSFAR& str );
/* -----------------------------------------------------------------------*/
/* */
/* _TYPENAME(obj) provides a macro for getting the type name from a */
/* pointer to an object. If runtime type information is available, this */
/* macro uses the typeid of the object to get its name. If runtime type */
/* information is not available, it uses the CastableID() for the object.*/
/* */
/* -----------------------------------------------------------------------*/
#if defined( BI_NO_RTTI )
# define _TYPENAME(obj) (obj)->CastableID()
#else
# define _TYPENAME(obj) typeid(*obj).name()
#endif
/* -----------------------------------------------------------------------*/
/* */
/* class TStreamable */
/* */
/* This is the base class from which all streamable objects must be */
/* derived. */
/* */
/* -----------------------------------------------------------------------*/
enum StreamableInit { streamableInit };
class _BIDSCLASS _RTTI TStreamableBase
{
public:
virtual _BIDSENTRY ~TStreamableBase();
#if defined( BI_NO_RTTI )
typedef const char * _BIDSENTRY Type_id;
virtual void * _BIDSENTRY FindBase( Type_id id ) const;
public:
virtual Type_id _BIDSENTRY CastableID() const = 0;
virtual void * _BIDSENTRY MostDerived() const = 0;
#endif // BI_NO_RTTI
};
class _BIDSCLASS _RTTI TStreamable : public TStreamableBase
{
friend class _BIDSCLASS _RTTI TOldStreamer;
protected:
virtual const char * _BIDSENTRY streamableName() const = 0;
virtual void * _BIDSENTRY read( ipstream& );
virtual void _BIDSENTRY write( opstream& );
#if defined( BI_NO_RTTI )
public:
virtual void * _BIDSENTRY FindBase( Type_id id ) const;
protected:
virtual Type_id _BIDSENTRY CastableID() const { return streamableName(); }
virtual void * _BIDSENTRY MostDerived() const { return 0; }
#endif
};
class _BIDSCLASS _RTTI TStreamer
{
friend class ipstream;
friend class opstream;
public:
TStreamableBase * _BIDSENTRY GetObject() const { return object; }
protected:
_BIDSENTRY TStreamer( TStreamableBase *obj ) : object(obj) {}
virtual const char * _BIDSENTRY StreamableName() const = 0;
virtual void * _BIDSENTRY Read( ipstream&, uint32 ) const = 0;
virtual void _BIDSENTRY Write( opstream& ) const = 0;
private:
virtual uint32 _BIDSENTRY ClassVersion() const = 0;
TStreamableBase *object;
};
class _BIDSCLASS _RTTI TOldStreamer : public TStreamer
{
public:
_BIDSENTRY TOldStreamer( TStreamable *obj ) : TStreamer(obj) {};
protected:
virtual const char * _BIDSENTRY StreamableName() const
{
return STATIC_CAST(TStreamable *,GetObject())->streamableName();
}
virtual void * _BIDSENTRY Read( ipstream& is, uint32 ) const
{
return STATIC_CAST(TStreamable *,GetObject())->read( is );
}
virtual void _BIDSENTRY Write( opstream& os ) const
{
STATIC_CAST(TStreamable *,GetObject())->write( os );
}
private:
virtual uint32 _BIDSENTRY ClassVersion() const
{
return 0;
}
};
class _BIDSCLASS _RTTI TNewStreamer : public TStreamer
{
public:
_BIDSENTRY TNewStreamer( TStreamableBase *obj ) : TStreamer(obj) {};
protected:
virtual const char * _BIDSENTRY StreamableName() const
{
return _TYPENAME(GetObject());
}
};
/* ------------------------------------------------------------------------*/
/* */
/* class TPWrittenObjects */
/* */
/* Maintains a database of all objects that have been written to the */
/* current persistent stream. */
/* */
/* Used by opstream when it writes a pointer from a stream to save the */
/* address and ID of the object being written. */
/* */
/* ------------------------------------------------------------------------*/
class _BIDSCLASS TPWrittenObjects
{
friend opstream;
public:
void _BIDSENTRY RemoveAll();
class _BIDSCLASS TPWObj
{
public:
_BIDSENTRY TPWObj() : Address(0), Ident(0) {}
_BIDSENTRY TPWObj( const void *adr, P_id_type id ) :
Address(adr), Ident(id) {}
friend int _BIDSENTRY operator == ( const TPWObj& o1, const TPWObj& o2 )
{ return o1.Address == o2.Address; }
friend int _BIDSENTRY operator < ( const TPWObj& o1, const TPWObj& o2 )
{ return o1.Address < o2.Address; }
const void *Address;
P_id_type Ident;
};
private:
_BIDSENTRY TPWrittenObjects();
void _BIDSENTRY RegisterObject( TStreamableBase *adr );
void _BIDSENTRY RegisterVB( const TStreamableBase *adr );
P_id_type _BIDSENTRY FindObject( TStreamableBase *adr );
P_id_type _BIDSENTRY FindVB( TStreamableBase *adr );
P_id_type CurId;
TSVectorImp<TPWObj> Data;
};
/* ------------------------------------------------------------------------*/
/* */
/* class TPReadObjects */
/* */
/* Maintains a database of all objects that have been read from the */
/* current persistent stream. */
/* */
/* Used by ipstream when it reads a pointer from a stream to determine */
/* the address of the object being referred to. */
/* */
/* ------------------------------------------------------------------------*/
class _BIDSCLASS TPReadObjects
{
friend ipstream;
public:
void _BIDSENTRY RemoveAll();
private:
_BIDSENTRY TPReadObjects();
void _BIDSENTRY RegisterObject( TStreamableBase *adr );
TStreamableBase * _BIDSENTRY Find( P_id_type id );
TCVectorImp<TStreamableBase *> Data;
};
/* ------------------------------------------------------------------------*/
/* */
/* class pstream */
/* */
/* Base class for handling streamable objects. */
/* */
/* ------------------------------------------------------------------------*/
class _BIDSCLASS pstream
{
friend TStreamableTypes;
friend TStreamableClass;
public:
enum PointerTypes { ptNull, ptIndexed, ptObject };
_BIDSENTRY pstream( streambuf _BIDSFAR * );
virtual _BIDSENTRY ~pstream();
int _BIDSENTRY rdstate() const;
int _BIDSENTRY eof() const;
int _BIDSENTRY fail() const;
int _BIDSENTRY bad() const;
int _BIDSENTRY good() const;
void _BIDSENTRY clear( int = 0 );
_BIDSENTRY operator void *() const;
int _BIDSENTRY operator ! () const;
streambuf _BIDSFAR * _BIDSENTRY rdbuf() const;
static void _BIDSENTRY initTypes();
static void _BIDSENTRY releaseTypes();
static void _BIDSENTRY registerType( TStreamableClass *ts );
protected:
_BIDSENTRY pstream();
streambuf _BIDSFAR *bp;
int state;
void _BIDSENTRY init( streambuf _BIDSFAR * );
void _BIDSENTRY setstate( int );
static TStreamableTypes *types;
};
/* ------------------------------------------------------------------------*/
/* */
/* class ipstream */
/* */
/* Base class for reading streamable objects */
/* */
/* ------------------------------------------------------------------------*/
class _BIDSCLASS ipstream : virtual public pstream
{
friend class TStreamableClass;
public:
_BIDSENTRY ipstream( streambuf _BIDSFAR * );
streampos _BIDSENTRY tellg();
ipstream& _BIDSENTRY seekg( streampos );
ipstream& _BIDSENTRY seekg( streamoff, ios::seek_dir );
uint8 _BIDSENTRY readByte();
void _BIDSENTRY readBytes( void _BIDSFAR *, size_t );
void _BIDSENTRY freadBytes( void _BIDSFARDATA *data, size_t sz );
uint32 _BIDSENTRY readWord();
uint16 _BIDSENTRY readWord16();
uint32 _BIDSENTRY readWord32();
char _BIDSFAR * _BIDSENTRY readString();
char _BIDSFAR * _BIDSENTRY readString( char _BIDSFAR *, unsigned );
char _BIDSFARDATA * _BIDSENTRY freadString();
char _BIDSFARDATA * _BIDSENTRY freadString( char _BIDSFARDATA *buf,
unsigned maxLen );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, signed char& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, unsigned char& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, char& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, signed short& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, unsigned short& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, signed int& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, unsigned int& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, signed long& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, unsigned long& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, float& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, double& );
friend ipstream& _BIDSENTRY operator >> ( ipstream&, long double& );
friend ipstream _BIDSFAR& _BIDSENTRY _BIDSFUNC
operator >> ( ipstream _BIDSFAR& is, string _BIDSFAR& str );
uint32 _BIDSENTRY getVersion() const;
TStreamableBase _BIDSFAR * _BIDSENTRY readObject( TStreamableBase _BIDSFAR *&mem, ModuleId mid = GetModuleId() );
TStreamableBase _BIDSFAR * _BIDSENTRY readObjectPointer( TStreamableBase _BIDSFAR *&mem, ModuleId mid = GetModuleId() );
TStreamableBase _BIDSFAR * _BIDSENTRY find( P_id_type );
void _BIDSENTRY registerObject( TStreamableBase _BIDSFAR *adr );
protected:
_BIDSENTRY ipstream();
const ObjectBuilder _BIDSFAR * _BIDSENTRY readPrefix( ModuleId mid );
void _BIDSENTRY readData( const ObjectBuilder _BIDSFAR *,
TStreamableBase _BIDSFAR *& );
void _BIDSENTRY readSuffix();
void _BIDSENTRY readVersion();
private:
uint32 readStringLength();
TPReadObjects objs;
uint32 version;
};
/* ------------------------------------------------------------------------*/
/* */
/* class opstream */
/* */
/* Base class for writing streamable objects */
/* */
/* ------------------------------------------------------------------------*/
class _BIDSCLASS opstream : virtual public pstream
{
public:
_BIDSENTRY opstream( streambuf _BIDSFAR * );
_BIDSENTRY ~opstream();
streampos _BIDSENTRY tellp();
opstream& _BIDSENTRY seekp( streampos );
opstream& _BIDSENTRY seekp( streamoff, ios::seek_dir );
opstream& _BIDSENTRY flush();
void _BIDSENTRY writeByte( uint8 );
void _BIDSENTRY writeBytes( const void _BIDSFAR *, size_t );
void _BIDSENTRY fwriteBytes( const void _BIDSFARDATA *data, size_t sz );
void _BIDSENTRY writeWord( uint32 );
void _BIDSENTRY writeWord16( uint16 );
void _BIDSENTRY writeWord32( uint32 );
void _BIDSENTRY writeString( const char _BIDSFAR * );
void _BIDSENTRY fwriteString( const char _BIDSFARDATA * str );
friend opstream& _BIDSENTRY operator << ( opstream&, signed char );
friend opstream& _BIDSENTRY operator << ( opstream&, unsigned char );
friend opstream& _BIDSENTRY operator << ( opstream&, char );
friend opstream& _BIDSENTRY operator << ( opstream&, signed short );
friend opstream& _BIDSENTRY operator << ( opstream&, unsigned short );
friend opstream& _BIDSENTRY operator << ( opstream&, signed int );
friend opstream& _BIDSENTRY operator << ( opstream&, unsigned int );
friend opstream& _BIDSENTRY operator << ( opstream&, signed long );
friend opstream& _BIDSENTRY operator << ( opstream&, unsigned long );
friend opstream& _BIDSENTRY operator << ( opstream&, float );
friend opstream& _BIDSENTRY operator << ( opstream&, double );
friend opstream& _BIDSENTRY operator << ( opstream&, long double );
void _BIDSENTRY writeObject( const TStreamableBase _BIDSFAR *t, int isPtr = 0, ModuleId mid = GetModuleId() );
void _BIDSENTRY writeObjectPointer( const TStreamableBase _BIDSFAR *t, ModuleId mid = GetModuleId() );
P_id_type _BIDSENTRY findObject( TStreamableBase _BIDSFAR *adr );
void _BIDSENTRY registerObject( TStreamableBase _BIDSFAR *adr );
P_id_type _BIDSENTRY findVB( TStreamableBase _BIDSFAR *adr );
void _BIDSENTRY registerVB( TStreamableBase _BIDSFAR *adr );
protected:
_BIDSENTRY opstream();
void _BIDSENTRY writePrefix( const TStreamableBase _BIDSFAR * );
void _BIDSENTRY writeData( const TStreamableBase _BIDSFAR *, ModuleId mid );
void _BIDSENTRY writeSuffix( const TStreamableBase _BIDSFAR * );
private:
void _BIDSENTRY writeVersion();
TPWrittenObjects *objs;
};
/* ------------------------------------------------------------------------*/
/* */
/* class fpbase */
/* */
/* Base class for handling streamable objects on file streams */
/* */
/* ------------------------------------------------------------------------*/
class _BIDSCLASS fpbase : virtual public pstream
{
public:
_BIDSENTRY fpbase();
_BIDSENTRY fpbase( const char _BIDSFAR *, int, int = filebuf::openprot );
_BIDSENTRY fpbase( int );
_BIDSENTRY fpbase( int, char _BIDSFAR *, int );
void _BIDSENTRY open( const char _BIDSFAR *, int, int = filebuf::openprot );
void _BIDSENTRY attach( int );
void _BIDSENTRY close();
void _BIDSENTRY setbuf( char _BIDSFAR *, int );
filebuf _BIDSFAR * _BIDSENTRY rdbuf();
private:
filebuf buf;
};
/* ------------------------------------------------------------------------*/
/* */
/* class ifpstream */
/* */
/* Base class for reading streamable objects from file streams */
/* */
/* ------------------------------------------------------------------------*/
class _BIDSCLASS ifpstream : public fpbase, public ipstream
{
public:
_BIDSENTRY ifpstream();
_BIDSENTRY ifpstream( const char _BIDSFAR *,
int = ios::in,
int = filebuf::openprot
);
_BIDSENTRY ifpstream( int );
_BIDSENTRY ifpstream( int, char _BIDSFAR *, int );
filebuf _BIDSFAR * _BIDSENTRY rdbuf();
void _BIDSENTRY open( const char _BIDSFAR *,
int = ios::in,
int = filebuf::openprot
);
};
/* ------------------------------------------------------------------------*/
/* */
/* class ofpstream */
/* */
/* Base class for writing streamable objects to file streams */
/* */
/* ------------------------------------------------------------------------*/
class _BIDSCLASS ofpstream : public fpbase, public opstream
{
public:
_BIDSENTRY ofpstream();
_BIDSENTRY ofpstream( const char _BIDSFAR *,
int = ios::out,
int = filebuf::openprot
);
_BIDSENTRY ofpstream( int );
_BIDSENTRY ofpstream( int, char _BIDSFAR *, int );
filebuf _BIDSFAR * _BIDSENTRY rdbuf();
void _BIDSENTRY open( const char _BIDSFAR *,
int = ios::out,
int = filebuf::openprot
);
};
/* ------------------------------------------------------------------------*/
/* */
/* Inline functions */
/* */
/* ------------------------------------------------------------------------*/
inline _BIDSENTRY pstream::pstream( streambuf _BIDSFAR *sb )
{
init( sb );
}
inline int _BIDSENTRY pstream::rdstate() const
{
return state;
}
inline int _BIDSENTRY pstream::eof() const
{
return state & ios::eofbit;
}
inline int _BIDSENTRY pstream::fail() const
{
return state & (ios::failbit | ios::badbit | ios::hardfail);
}
inline int _BIDSENTRY pstream::bad() const
{
return state & (ios::badbit | ios::hardfail);
}
inline int _BIDSENTRY pstream::good() const
{
return state == 0;
}
inline void _BIDSENTRY pstream::clear( int i )
{
state = (i & 0xFF) | (state & ios::hardfail);
}
inline _BIDSENTRY pstream::operator void _BIDSFAR *() const
{
return fail() ? 0 : (void *)this;
}
inline int _BIDSENTRY pstream::operator! () const
{
return fail();
}
inline streambuf _BIDSFAR * _BIDSENTRY pstream::rdbuf() const
{
return bp;
}
inline _BIDSENTRY pstream::pstream()
{
}
inline void _BIDSENTRY pstream::init( streambuf *sbp )
{
state = 0;
bp = sbp;
}
inline void _BIDSENTRY pstream::setstate( int b )
{
state |= (b&0xFF);
}
inline _BIDSENTRY ipstream::ipstream( streambuf _BIDSFAR *sb )
{
pstream::init( sb );
readVersion();
}
inline _BIDSENTRY ipstream::ipstream()
{
if( bp != 0 )
readVersion();
}
inline TStreamableBase * _BIDSENTRY ipstream::find( P_id_type id )
{
return objs.Find( id );
}
inline void _BIDSENTRY ipstream::registerObject( TStreamableBase *adr )
{
objs.RegisterObject( adr );
}
inline uint32 _BIDSENTRY ipstream::getVersion() const
{
return version;
}
inline void _BIDSENTRY pstream::registerType( TStreamableClass *ts )
{
types->RegisterType( GetModuleId(), *ts );
}
inline _BIDSENTRY opstream::~opstream()
{
delete objs;
}
inline void _BIDSENTRY opstream::writeWord( uint32 word32 )
{
writeWord32( word32 );
}
inline void _BIDSENTRY opstream::writeSuffix( const TStreamableBase * )
{
writeByte( ']' );
}
inline P_id_type _BIDSENTRY opstream::findObject( TStreamableBase *adr )
{
return objs->FindObject( adr );
}
inline void _BIDSENTRY opstream::registerObject( TStreamableBase *adr )
{
objs->RegisterObject( adr );
}
inline P_id_type _BIDSENTRY opstream::findVB( TStreamableBase *adr )
{
return objs->FindVB( adr );
}
inline void _BIDSENTRY opstream::registerVB( TStreamableBase *adr )
{
objs->RegisterVB( adr );
}
inline _BIDSENTRY fpbase::fpbase()
{
pstream::init( &buf );
}
inline _BIDSENTRY fpbase::fpbase( const char *name, int omode, int prot )
{
pstream::init( &buf );
open( name, omode, prot );
}
inline _BIDSENTRY fpbase::fpbase( int f ) : buf( f )
{
pstream::init( &buf );
}
inline _BIDSENTRY fpbase::fpbase( int f, char *b, int len ) : buf( f, b, len )
{
pstream::init( &buf );
}
inline filebuf * _BIDSENTRY fpbase::rdbuf()
{
return &buf;
}
inline _BIDSENTRY ifpstream::ifpstream()
{
}
inline _BIDSENTRY ifpstream::ifpstream( const char* name, int omode, int prot ) :
fpbase( name, omode | ios::in | ios::binary, prot )
{
}
inline _BIDSENTRY ifpstream::ifpstream( int f ) : fpbase( f )
{
}
inline _BIDSENTRY ifpstream::ifpstream(int f, char* b, int len) : fpbase(f, b, len)
{
}
inline filebuf * _BIDSENTRY ifpstream::rdbuf()
{
return fpbase::rdbuf();
}
inline void _BIDSENTRY ifpstream::open( const char _BIDSFAR *name,
int omode,
int prot )
{
fpbase::open( name, omode | ios::in | ios::binary, prot );
readVersion();
}
inline _BIDSENTRY ofpstream::ofpstream()
{
}
inline _BIDSENTRY ofpstream::ofpstream( const char* name, int omode, int prot ) :
fpbase( name, omode | ios::out | ios::binary, prot )
{
}
inline _BIDSENTRY ofpstream::ofpstream( int f ) : fpbase( f )
{
}
inline _BIDSENTRY ofpstream::ofpstream(int f, char* b, int len) :
fpbase(f, b, len)
{
}
inline filebuf * _BIDSENTRY ofpstream::rdbuf()
{
return fpbase::rdbuf();
}
inline void _BIDSENTRY ofpstream::open( const char _BIDSFAR *name,
int omode,
int prot )
{
fpbase::open( name, omode | ios::out | ios::binary, prot );
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, signed char &ch )
{
ch = ps.readByte();
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, unsigned char &ch )
{
ch = ps.readByte();
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, char &ch )
{
ch = ps.readByte();
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, signed short &sh )
{
sh = ps.readWord16();
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, unsigned short &sh )
{
sh = ps.readWord16();
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, signed int &i )
{
i = (int)(ps.readWord32());
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, unsigned int &i )
{
i = (unsigned int)(ps.readWord32());
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, signed long &l )
{
ps.readBytes( &l, sizeof(l) );
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, unsigned long &l )
{
ps.readBytes( &l, sizeof(l) );
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, float &f )
{
ps.readBytes( &f, sizeof(f) );
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, double &d )
{
ps.readBytes( &d, sizeof(d) );
return ps;
}
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, long double &l )
{
ps.readBytes( &l, sizeof(l) );
return ps;
}
#if defined( UNIQUE_BOOL )
inline ipstream& _BIDSENTRY operator >> ( ipstream& ps, bool &b )
{
b = static_cast<bool>(ps.readWord32());
return ps;
}
#endif
inline opstream& _BIDSENTRY operator << ( opstream& ps, signed char ch )
{
ps.writeByte( ch );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, unsigned char ch )
{
ps.writeByte( ch );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, char ch )
{
ps.writeByte( ch );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, signed short sh )
{
ps.writeWord16( sh );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, unsigned short sh )
{
ps.writeWord16( sh );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, signed int i )
{
ps.writeWord32( i );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, unsigned int i )
{
ps.writeWord32( i );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, signed long l )
{
ps.writeBytes( &l, sizeof(l) );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, unsigned long l )
{
ps.writeBytes( &l, sizeof(l) );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, float f )
{
ps.writeBytes( &f, sizeof(f) );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, double d )
{
ps.writeBytes( &d, sizeof(d) );
return ps;
}
inline opstream& _BIDSENTRY operator << ( opstream& ps, long double l )
{
ps.writeBytes( &l, sizeof(l) );
return ps;
}
template <class Base> void WriteBaseObject( Base *base, opstream& out )
{
Base::Streamer strmr(base);
out << strmr.ClassVersion();
strmr.Write( out );
}
template <class Base> void ReadBaseObject( Base *base, ipstream& in )
{
uint32 version = 0;
if( in.getVersion() > 0 )
in >> version;
Base::Streamer(base).Read( in, version );
}
template <class Base> void WriteVirtualBase( Base *base, opstream& out )
{
if( !out.good() )
return;
if( out.findVB( base ) != 0 )
{
out.writeByte( pstream::ptIndexed ); // use ptIndexed to indicate
// that we've already seen
// this virtual base. Don't
// need to actually write it.
}
else
{
Base::Streamer strmr(base);
out.registerObject( (TStreamableBase *)((char *)base + 1) );
out.writeByte( pstream::ptObject );
out.writeWord32( strmr.ClassVersion() );
strmr.Write( out );
}
}
template <class Base> void ReadVirtualBase( Base *base, ipstream& in )
{
char ch;
in >> ch;
switch( ch )
{
case pstream::ptIndexed:
{
break; // We've already read this virtual base
}
case pstream::ptObject:
{
uint32 ver = 0;
if( in.getVersion() > 0 )
ver = in.readWord32();
Base::Streamer strmr(base);
// register the address
in.registerObject(strmr.GetObject());
strmr.Read( in, ver );
break;
}
}
}
/* Individual Components for Streamable Declarations */
#define DECLARE_STREAMER( exp, cls, ver ) \
public: \
class exp Streamer : public TNewStreamer \
{ \
public: \
\
Streamer( TStreamableBase *obj ); \
\
virtual uint32 ClassVersion() const \
{ return ver; } \
\
virtual void Write( opstream& ) const; \
virtual void *Read( ipstream&, uint32 ) const; \
\
cls *GetObject() const \
{ \
return object; \
} \
\
static TStreamer *Build( TStreamableBase *obj ) \
{ \
return new Streamer( obj ? obj : new cls(streamableInit) ); \
} \
\
private: \
cls *object; \
\
}; \
friend Streamer; \
friend void ReadBaseObject( cls *, ipstream& ); \
friend void WriteBaseObject( cls *, opstream& ); \
friend void ReadVirtualBase( cls *, ipstream& ); \
friend void WriteVirtualBase( cls *, opstream& )
#define DECLARE_STREAMER_FROM_BASE( exp, cls, base ) \
public: \
class exp Streamer : public base::Streamer \
{ \
public: \
\
Streamer( TStreamableBase *obj ) : base::Streamer(obj){} \
\
cls *GetObject() const \
{ \
return object; \
} \
\
static TStreamer *Build( TStreamableBase *obj ) \
{ \
return new Streamer( obj ? obj : new cls(streamableInit) ); \
} \
\
private: \
cls *object; \
\
}; \
friend Streamer; \
friend void ReadBaseObject( cls *, ipstream& ); \
friend void WriteBaseObject( cls *, opstream& ); \
friend void ReadVirtualBase( cls *, ipstream& ); \
friend void WriteVirtualBase( cls *, opstream& )
#define DECLARE_ABSTRACT_STREAMER( exp, cls, ver ) \
public: \
class exp Streamer : public TNewStreamer \
{ \
public: \
\
Streamer( TStreamableBase *obj ); \
\
virtual uint32 ClassVersion() const \
{ return ver; } \
\
virtual void Write( opstream& ) const; \
virtual void *Read( ipstream&, uint32 ) const; \
\
cls *GetObject() const \
{ \
return object; \
} \
\
private: \
cls *object; \
\
}; \
friend Streamer; \
friend void ReadBaseObject( cls *, ipstream& ); \
friend void WriteBaseObject( cls *, opstream& ); \
friend void ReadVirtualBase( cls *, ipstream& ); \
friend void WriteVirtualBase( cls *, opstream& )
#define DECLARE_STREAMABLE_OPS( cls ) \
static ipstream& readRef( ipstream& is, cls& cl ); \
friend inline ipstream& operator >> ( ipstream& is, cls& cl ) \
{ return cls::readRef( is, cl ); } \
static ipstream& readPtr( ipstream& is, cls*& cl ); \
friend inline ipstream& operator >> ( ipstream& is, cls*& cl ) \
{ return cls::readPtr( is, cl ); } \
static opstream& writeRef( opstream& is, const cls& cl ); \
friend inline opstream& operator << ( opstream& os, const cls& cl ) \
{ return cls::writeRef( os, cl ); } \
static opstream& writePtr( opstream& is, const cls* cl ); \
friend inline opstream& operator << ( opstream& os, const cls* cl ) \
{ return cls::writePtr( os, cl ); }
#define DECLARE_STREAMABLE_CTOR( cls ) \
public: \
cls ( StreamableInit )
#if defined( BI_NO_RTTI )
#define DECLARE_CASTABLE \
public: \
virtual void *FindBase( Type_id id ) const; \
public: \
virtual Type_id CastableID() const; \
virtual void *MostDerived() const { return (void *)this; } \
static Type_id CastableIdent
#else
#define DECLARE_CASTABLE friend class typeinfo
#endif
#define DECLARE_STREAMABLE( exp, cls, ver ) \
DECLARE_CASTABLE; \
DECLARE_STREAMER( exp, cls, ver ); \
DECLARE_STREAMABLE_OPS( cls ); \
DECLARE_STREAMABLE_CTOR( cls )
#define DECLARE_STREAMABLE_FROM_BASE( exp, cls, base ) \
DECLARE_CASTABLE; \
DECLARE_STREAMER_FROM_BASE( exp, cls, base ); \
DECLARE_STREAMABLE_OPS( cls ); \
DECLARE_STREAMABLE_CTOR( cls )
#define DECLARE_ABSTRACT_STREAMABLE( exp, cls, ver ) \
DECLARE_CASTABLE; \
DECLARE_ABSTRACT_STREAMER( exp, cls, ver ); \
DECLARE_STREAMABLE_OPS( cls ); \
DECLARE_STREAMABLE_CTOR( cls )
#if !defined( BI_NO_RTTI )
#define IMPLEMENT_CASTABLE( cls )
#define IMPLEMENT_CASTABLE1( cls, base1 )
#define IMPLEMENT_CASTABLE2( cls, base1, base2 )
#define IMPLEMENT_CASTABLE3( cls, base1, base2, base3 )
#define IMPLEMENT_CASTABLE4( cls, base1, base2, base3, base4 )
#define IMPLEMENT_CASTABLE5( cls, base1, base2, base3, base4, base5 )
#else // BI_NO_RTTI
#define IMPLEMENT_CASTABLE_ID( cls ) \
TStreamableBase::Type_id cls::CastableIdent = #cls; \
TStreamableBase::Type_id cls::CastableID() const \
{ \
return cls::CastableIdent; \
} \
#define IMPLEMENT_CASTABLE( cls ) \
IMPLEMENT_CASTABLE_ID( cls ); \
void *cls::FindBase( Type_id id ) const \
{ \
return (strcmp( id, CastableIdent ) == 0) ? (void *)this : 0; \
} \
\
#define IMPLEMENT_CASTABLE1( cls, base1 ) \
IMPLEMENT_CASTABLE_ID( cls ); \
void *cls::FindBase( Type_id id ) const \
{ \
if(strcmp( id, CastableIdent ) == 0) \
return (void *)this; \
else \
return base1::FindBase(id); \
} \
#define IMPLEMENT_CASTABLE2( cls, base1, base2 ) \
IMPLEMENT_CASTABLE_ID( cls ); \
void *cls::FindBase( Type_id id ) const \
{ \
void *res = 0; \
if(strcmp( id, CastableIdent ) == 0) \
return (void *)this; \
else if( (res = base1::FindBase(id)) != 0 ) \
return res; \
else if( (res = base2::FindBase(id)) != 0 ) \
return res; \
else \
return 0; \
} \
#define IMPLEMENT_CASTABLE3( cls, base1, base2, base3 ) \
IMPLEMENT_CASTABLE_ID( cls ); \
void *cls::FindBase( Type_id id ) const \
{ \
void *res = 0; \
if(strcmp( id, CastableIdent ) == 0) \
return (void *)this; \
else if( (res = base1::FindBase(id)) != 0 ) \
return res; \
else if( (res = base2::FindBase(id)) != 0 ) \
return res; \
else if( (res = base3::FindBase(id)) != 0 ) \
return res; \
else \
return 0; \
} \
#define IMPLEMENT_CASTABLE4( cls, base1, base2, base3, base4 ) \
IMPLEMENT_CASTABLE_ID( cls ); \
void *cls::FindBase( Type_id id ) const \
{ \
void *res = 0; \
if(strcmp( id, CastableIdent ) == 0) \
return (void *)this; \
else if( (res = base1::FindBase(id)) != 0 ) \
return res; \
else if( (res = base2::FindBase(id)) != 0 ) \
return res; \
else if( (res = base3::FindBase(id)) != 0 ) \
return res; \
else if( (res = base4::FindBase(id)) != 0 ) \
return res; \
else \
return 0; \
} \
#define IMPLEMENT_CASTABLE5( cls, base1, base2, base3, base4, base5 )\
IMPLEMENT_CASTABLE_ID( cls ); \
void *cls::FindBase( Type_id id ) const \
{ \
void *res = 0; \
if(strcmp( id, CastableIdent ) == 0) \
return (void *)this; \
else if( (res = base1::FindBase(id)) != 0 ) \
return res; \
else if( (res = base2::FindBase(id)) != 0 ) \
return res; \
else if( (res = base3::FindBase(id)) != 0 ) \
return res; \
else if( (res = base4::FindBase(id)) != 0 ) \
return res; \
else if( (res = base5::FindBase(id)) != 0 ) \
return res; \
else \
return 0; \
} \
#endif // BI_NO_RTTI
#if defined( BI_NO_RTTI )
# define IMPLEMENT_STREAMABLE_CLASS( cls ) \
TStreamableClass r ## cls( cls::CastableIdent, &cls::Streamer::Build )
#else
# define IMPLEMENT_STREAMABLE_CLASS( cls ) \
TStreamableClass r ## cls( typeid(cls).name(), &cls::Streamer::Build )
#endif
#define IMPLEMENT_STREAMABLE_POINTER( cls ) \
ipstream& cls::readPtr( ipstream& is, cls*& cl ) \
{ \
TStreamableBase *temp = 0; \
is.readObjectPointer( temp ); \
cl = TYPESAFE_DOWNCAST(temp,cls); \
return is; \
} \
ipstream& cls::readRef( ipstream& is, cls& cl ) \
{ \
TStreamableBase *ptr = &cl; \
is.readObject( ptr ); \
return is; \
} \
opstream& cls::writeRef( opstream& os, const cls& cl ) \
{ \
os.writeObject( &cl ); \
return os; \
} \
opstream& cls::writePtr( opstream& os, const cls* cl ) \
{ \
os.writeObjectPointer( cl ); \
return os; \
}
#define IMPLEMENT_STREAMER( cls ) \
cls::Streamer::Streamer( TStreamableBase *obj ) : \
TNewStreamer(obj), object(TYPESAFE_DOWNCAST(obj,cls)){}
\
#define IMPLEMENT_STREAMABLE_CTOR( cls ) \
cls::cls ( StreamableInit ) {}
#define IMPLEMENT_STREAMABLE_CTOR1( cls, base1 ) \
cls::cls ( StreamableInit ) : base1( streamableInit ) {}
#define IMPLEMENT_STREAMABLE_CTOR2( cls, base1, base2 ) \
cls::cls ( StreamableInit ) : \
base1 ( streamableInit ), \
base2 ( streamableInit ) {}
#define IMPLEMENT_STREAMABLE_CTOR3( cls, base1, base2, base3 ) \
cls::cls ( StreamableInit ) : \
base1 ( streamableInit ), \
base2 ( streamableInit ), \
base3 ( streamableInit ) {}
#define IMPLEMENT_STREAMABLE_CTOR4( cls, base1, base2, base3, base4 )\
cls::cls ( StreamableInit ) : \
base1 ( streamableInit ), \
base2 ( streamableInit ), \
base3 ( streamableInit ), \
base4 ( streamableInit ) {}
#define IMPLEMENT_STREAMABLE_CTOR5( cls, base1,base2,base3,base4,base5)\
cls::cls ( StreamableInit ) : \
base1 ( streamableInit ), \
base2 ( streamableInit ), \
base3 ( streamableInit ), \
base4 ( streamableInit ), \
base5 ( streamableInit ) {}
/* Standard Combinations of Streamable Implementations */
#define IMPLEMENT_ABSTRACT_STREAMABLE( cls ) \
IMPLEMENT_STREAMER( cls ); \
IMPLEMENT_STREAMABLE_CTOR( cls ); \
IMPLEMENT_STREAMABLE_POINTER( cls )
#define IMPLEMENT_ABSTRACT_STREAMABLE1( cls, base1 ) \
IMPLEMENT_STREAMER( cls ); \
IMPLEMENT_STREAMABLE_CTOR1( cls, base1 ); \
IMPLEMENT_STREAMABLE_POINTER( cls )
#define IMPLEMENT_ABSTRACT_STREAMABLE2( cls, base1, base2 ) \
IMPLEMENT_STREAMER( cls ); \
IMPLEMENT_STREAMABLE_CTOR2( cls, base1, base2 ); \
IMPLEMENT_STREAMABLE_POINTER( cls )
#define IMPLEMENT_ABSTRACT_STREAMABLE3( cls, base1, base2, base3 ) \
IMPLEMENT_STREAMER( cls ); \
IMPLEMENT_STREAMABLE_CTOR3( cls, base1, base2, base3 ); \
IMPLEMENT_STREAMABLE_POINTER( cls )
#define IMPLEMENT_ABSTRACT_STREAMABLE4( cls, base1, base2, base3, base4 )\
IMPLEMENT_STREAMER( cls ); \
IMPLEMENT_STREAMABLE_CTOR4( cls, base1, base2, base3, base4 ); \
IMPLEMENT_STREAMABLE_POINTER( cls )
#define IMPLEMENT_ABSTRACT_STREAMABLE5( cls, base1, base2, base3, base4, base5 )\
IMPLEMENT_STREAMER( cls ); \
IMPLEMENT_STREAMABLE_CTOR5( cls, base1, base2, base3, base4, base5 );\
IMPLEMENT_STREAMABLE_POINTER( cls )
#define IMPLEMENT_STREAMABLE( cls ) \
IMPLEMENT_STREAMABLE_CLASS( cls ); \
IMPLEMENT_ABSTRACT_STREAMABLE( cls )
#define IMPLEMENT_STREAMABLE1( cls, base1 ) \
IMPLEMENT_STREAMABLE_CLASS( cls ); \
IMPLEMENT_ABSTRACT_STREAMABLE1( cls, base1 )
#define IMPLEMENT_STREAMABLE2( cls, base1, base2 ) \
IMPLEMENT_STREAMABLE_CLASS( cls ); \
IMPLEMENT_ABSTRACT_STREAMABLE2( cls, base1, base2 )
#define IMPLEMENT_STREAMABLE3( cls, base1, base2, base3 ) \
IMPLEMENT_STREAMABLE_CLASS( cls ); \
IMPLEMENT_ABSTRACT_STREAMABLE3( cls, base1, base2, base3 )
#define IMPLEMENT_STREAMABLE4( cls, base1, base2, base3, base4 ) \
IMPLEMENT_STREAMABLE_CLASS( cls ); \
IMPLEMENT_ABSTRACT_STREAMABLE4( cls, base1, base2, base3, base4 )
#define IMPLEMENT_STREAMABLE5( cls, base1, base2, base3, base4, base5 )\
IMPLEMENT_STREAMABLE_CLASS( cls ); \
IMPLEMENT_ABSTRACT_STREAMABLE5( cls, base1, base2, base3, base4, base5 )
#define IMPLEMENT_STREAMABLE_FROM_BASE( cls, base1 ) \
IMPLEMENT_STREAMABLE_CLASS( cls ); \
IMPLEMENT_STREAMABLE_CTOR1( cls, base1 ); \
IMPLEMENT_STREAMABLE_POINTER( cls )
#if defined( BI_CLASSLIB_NO_po )
#pragma option -po.
#endif
#endif // CLASSLIB_OBJSTRM_H