/** * @file tobjstrm.h * * Turbo Vision - Version 2.0 * * Copyright (c) 1994 by Borland International * All Rights Reserved. * * Modified by Sergio Sigala * Modified by Max Okumoto */ #include #include #include #include /** * Undocumented. */ typedef unsigned P_id_type; /* ------------------------------------------------------------------------*/ /* class TStreamable */ /* */ /* This is the base class for all storable objects. It provides */ /* three member functions, streamableName(), read(), and write(), which */ /* must be overridden in every derived class. */ /* ------------------------------------------------------------------------*/ #if !defined( __fLink_def ) #define __fLink_def /** * Internal structure. * @short Internal structure */ struct fLink { /** * Undocumented. */ fLink *f; /** * Undocumented. */ class TStreamableClass *t; }; #endif #define __link( s ) \ extern TStreamableClass s; \ static fLink force ## s = \ { (fLink *)&force ## s, (TStreamableClass *)&s }; #if defined( Uses_TStreamable ) && !defined( __TStreamable ) #define __TStreamable /** * Gives the streamable property to a class. * * @ref TView has two base classes, @ref TObject and the abstract class * TStreamable. All the viewable classes, derived ultimately from @ref TView, * therefore also inherit from TStreamable. * * Several non-view classes, such as @ref TCollection, @ref TStrListMaker and * @ref TStringList, also have TStreamable as a base class. Such classes are * known as streamable, meaning that their objects can be written to and read * from streams using the TVision stream manager. * * If you want to develop your own streamable classes, make sure that * TStreamable is somewhere in their ancestry. Using an existing streamable * class as a base class, of course, is an obvious way of achieving this. * * Since TStreamable is an abstract class, no objects of this class can be * instantiated. Before a streamable class can be used with streams, the class * must override the three pure virtual functions @ref streamableName(), * @ref read(), and @ref write(). * @short Gives the streamable property to a class */ class TStreamable { friend class opstream; friend class ipstream; private: /** * Class TStreamable has no constructor. This function must be overridden * (or redeclared as pure virtual) by every derived class. Its purpose is * to return the name of the streamable class of the object that invokes * it. * * This name is used in the registering of streams by the stream manager. * The name returned must be a unique, 0-terminated string, so the safest * strategy is to use the name of the streamable class. */ virtual const char *streamableName() const = 0; protected: /** * This pure virtual function must be overridden (or redeclared as pure * virtual) in every derived class. The overriding read() function for * each streamable class must read the necessary data members from the * @ref ipstream object `is'. read() is usually implemented by calling * the base class's read() (if any), then extracting any additional data * members for the derived class. */ virtual void *read( ipstream& is ) = 0; /** * This pure virtual function must be overridden (or redeclared as pure * virtual) in every derived class. The overriding write() function for * each streamable class must write the necessary data members to the * @ref opstream object `os'. write() is usually implemented by calling * the base class's write() (if any), then inserting any additional data * members for the derived class. */ virtual void write( opstream& os ) = 0; }; #endif // Uses_TStreamable /* ------------------------------------------------------------------------*/ /* class TStreamableClass */ /* ------------------------------------------------------------------------*/ #if defined( Uses_TStreamableClass ) && !defined( __TStreamableClass ) #define __TStreamableClass /** * Undocumented. */ const P_id_type P_id_notFound = UINT_MAX; /** \enum BUILDER * Each streamable class has a builder function of type BUILDER. The builder * provides raw memory of the correct size and initializes the virtual table * pointers when objects are created by certain stream read operations. * The read() function of the streamable class reads data from the stream into * the raw object provided by the builder. * @see TStreamable::read */ typedef TStreamable *(*BUILDER)(); #define __DELTA( d ) ((int)(TStreamable*)(d*)1-1 ) /** * TStreamableClass is used by @ref TStreamableTypes and @ref pstream in the * registration of streamable classes. * @short TStreamableClass is used by TStreamableTypes and pstream in the * registration of streamable classes */ class TStreamableClass { friend class TStreamableTypes; friend class opstream; friend class ipstream; public: /** * Creates a TStreamable object with the given name and the given builder * function, then calls @ref pstream::registerTypes(). * * Each streamable class TClassName has a build member function. There are * also the familiar non-member overloaded >> and << operators for stream * I/O associated with each streamable class. * * For type-safe object-stream I/O, the stream manager needs to access the * names and the type information for each class. * * To ensure that the appropriate functions are linked into any * application using the stream manager, you must provide an extern * reference such as this: * *
     * extern TStreamableClass registerTClassName;
     * 
* * where TClassName is the name of the class for which objects need to be * streamed. @ref BUILDER is typedefed as follows: * *
     * typedef TStreamable *(*BUILDER)();
     * 
*/ TStreamableClass(const char *aName, BUILDER aBuild, int aDelta ); private: const char *name; BUILDER build; int delta; }; #endif // Uses_TStreamableClass /* ------------------------------------------------------------------------*/ /* class TStreamableTypes */ /* ------------------------------------------------------------------------*/ #if defined( Uses_TStreamableTypes ) && !defined( __TStreamableTypes ) #define __TStreamableTypes /** * TStreamableTypes, derived privately from @ref TNSSortedCollection, * maintains a database of all registered streamable types used in an * application. * * Classes @ref opstream and @ref ipstream use this database to determine the * correct @ref read() and @ref write() functions for particular objects. * Because of the private derivation, all the inherited members are private * within TStreamableTypes. * @short Maintains a database of all registered streamable types used in an * application */ class TStreamableTypes : private TNSSortedCollection { public: /** * Calls the base @ref TNSSortedCollection constructor to create a * TStreamableTypes collection. * @see TNSSortedCollection::TNSSortedCollection */ TStreamableTypes(); /** * Sets the collection @ref limit to 0 without destroying the collection * (since the @ref shouldDelete data member is set to False). */ ~TStreamableTypes(); /** * Registers the argument class by inserting `d' in the collection. */ void registerType(const TStreamableClass *d ); /** * Returns a pointer to the class in the collection corresponding to the * argument `name', or returns 0 if no match. */ const TStreamableClass *lookup(const char name[]); private: /** * Undocumented. */ virtual void *keyOf( void * ); /** * Undocumented. */ int compare( void *, void * ); }; #endif // Uses_TStreamableTypes /* ------------------------------------------------------------------------*/ /* class TPWrittenObjects */ /* ------------------------------------------------------------------------*/ #if defined( Uses_TPWrittenObjects ) && !defined( __TPWrittenObjects ) #define __TPWrittenObjects /** * TPWrittenObjects maintains a database of all objects that have been written * to the current object stream. This is used by @ref opstream when it writes a * pointer onto a stream. * @short Maintains a database of all objects that have been written to the * current object stream */ class TPWrittenObjects : public TNSSortedCollection { friend class opstream; public: /** * Undocumented. */ void removeAll() { curId = 0; TNSSortedCollection::freeAll(); } private: /** * This private constructor creates a non-streamable collection by calling * the base @ref TNSSortedCollection constructor. It is accessible only * by the member functions and friends. */ TPWrittenObjects(); /** * Sets the collection @ref limit to 0 without destroying the collection. */ ~TPWrittenObjects(); /** * Undocumented. */ void registerObject(const void *adr ); /** * Undocumented. */ P_id_type find(const void *adr ); /** * Undocumented. */ void *keyOf( void * ); /** * Undocumented. */ int compare( void *, void * ); /** * Undocumented. */ P_id_type curId; }; /* ------------------------------------------------------------------------*/ /* class TPWObj */ /* ------------------------------------------------------------------------*/ /** * TPWObj is used internally by @ref TPWrittenObjects. The class * TPWrittenObjects is a friend of TPWobj, so all its member functions can * access the private members of TPWObj. * @short Used internally by TPWrittenObjects */ class TPWObj { friend class TPWrittenObjects; private: TPWObj(const void *adr, P_id_type id ); const void *address; P_id_type ident; }; #endif // Uses_TPWrittenObjects /* ------------------------------------------------------------------------*/ /* class TPReadObjects */ /* ------------------------------------------------------------------------*/ #if defined( Uses_TPReadObjects ) && !defined( __TPReadObjects ) #define __TPReadObjects /** * TPReadObjects maintains a database of all objects that have been read from * the current object stream. This is used by @ref ipstream when it reads a * pointer from a stream to determine if other addresses for that objects * exist. * @short Maintains a database of all objects that have been read from the * current object stream */ class TPReadObjects : public TNSCollection { friend class ipstream; public: /** * Undocumented. */ void removeAll() { curId = 0; TNSCollection::removeAll(); } private: /** * This private constructor creates a non-streamable collection by calling * the base @ref TNSCollection constructor. It is accessible only by * member functions and friends. * @see TNSCollection::TNSCollection */ TPReadObjects(); /** * Sets the collection @ref limit to 0 without destroying the collection. */ ~TPReadObjects(); void registerObject(const void *adr ); const void *find( P_id_type id ); P_id_type curId; }; #endif // Uses_TPReadObjects /* ------------------------------------------------------------------------*/ /* class pstream */ /* ------------------------------------------------------------------------*/ #if defined( Uses_pstream ) && !defined( __pstream ) #define __pstream class TStreamableTypes; /** * pstream is the base class for handling streamable objects. * @short The base class for handling streamable objects */ class pstream { protected: /** * Pointer to the @ref TStreamableTypes data base of all registered types * in this application. */ static TStreamableTypes *types; public: pstream(); virtual ~pstream(); /** * Undocumented. */ enum StreamableError { peNotRegistered, peInvalidType }; /** * Undocumented. */ enum PointerTypes { ptNull, ptIndexed, ptObject }; void error(StreamableError); void error(StreamableError, const TStreamable &); static void initTypes(); static void registerType(TStreamableClass *ts); }; #endif // Uses_pstream /* ------------------------------------------------------------------------*/ /* class ipstream */ /* ------------------------------------------------------------------------*/ #if defined( Uses_ipstream ) && !defined( __ipstream ) #define __ipstream class TStreamableClass; /** * ipstream, a specialized input stream derivative of @ref pstream, is the * base class for reading (extracting) streamable objects. ipstream is * analogous to istream, defined in `iostream' for the standard C++ stream * library. ipstream is a friend class of @ref TPReadObjects. * * The overloaded operators >> extract (read) from the given ipstream object * to the given argument. A reference to the stream is returned, allowing you * to chain >> operations in the usual way. The data type of the argument * determines how the read is performed. For example, reading a signed char * is implemented using @ref readByte(). * * @see opstream * * @short The base class for reading (extracting) streamable objects from * streams */ class ipstream : virtual public pstream, public std::istream { private: TPReadObjects objs; protected: const TStreamableClass *readPrefix(); void *readData(const TStreamableClass *c, TStreamable *mem); void readSuffix(); const void *find(P_id_type id); void registerObject(const void *adr); ushort readWord(); ulong readLong(); public: ipstream(std::streambuf *buf); ~ipstream(); ipstream &seekg(std::streampos pos); ipstream &seekg(std::streamoff off, std::ios::seekdir dir); uchar readByte(); void readBytes(void *data, std::streamsize sz); char *readString(); char *readString(char *buf, unsigned maxLen); ipstream &operator>>(char &); ipstream &operator>>(signed char &); ipstream &operator>>(unsigned char &); ipstream &operator>>(signed short &); ipstream &operator>>(unsigned short &); ipstream &operator>>(signed int &); ipstream &operator>>(unsigned int &); ipstream &operator>>(signed long &); ipstream &operator>>(unsigned long &); ipstream &operator>>(float &); ipstream &operator>>(double &); ipstream &operator>>(long double &); ipstream &operator>>(TStreamable &); ipstream &operator>>(void *&); }; #endif // Uses_ipstream /* ------------------------------------------------------------------------*/ /* class opstream */ /* ------------------------------------------------------------------------*/ #if defined( Uses_opstream ) && !defined( __opstream ) #define __opstream class TStreamableClass; /** * opstream, a specialized output stream derivative of @ref pstream, is the * base class for writing (inserting) streamable objects. opstream is * analogous to ostream, defined in `iostream' for the standard C++ stream * library. opstream is a friend class of @ref TPWrittenObjects. * * The overloaded operators << insert (write) the given argument to the given * opstream object. A reference to the stream is returned, allowing you * to chain << operations in the usual way. The data type of the argument * determines the form of write operation employed. For example, writing a * signed char is implemented using @ref writeByte(). * * @see ipstream * * @short The base class for writing (inserting) streamable objects into * streams */ class opstream : virtual public pstream, public std::ostream { TPWrittenObjects objs; protected: void writePrefix(const TStreamable &); void writeData(TStreamable &); void writeSuffix(const TStreamable &); P_id_type find(const void *adr); void registerObject(const void *adr); public: opstream(std::streambuf *buf); ~opstream(); opstream& seekp(std::streampos pos); opstream& seekp(std::streamoff off, std::ios::seekdir dir); opstream& flush(); void writeByte(uchar ch); void writeBytes(const void *data, std::streamsize sz); void writeWord(ushort us); void writeString(const char *str); opstream &operator<<(char); opstream &operator<<(signed char); opstream &operator<<(unsigned char); opstream &operator<<(signed short); opstream &operator<<(unsigned short); opstream &operator<<(signed int); opstream &operator<<(unsigned int); opstream &operator<<(signed long); opstream &operator<<(unsigned long); opstream &operator<<(float); opstream &operator<<(double); opstream &operator<<(long double); opstream &operator<<(TStreamable &); opstream &operator<<(TStreamable *); }; #endif // Uses_opstream /* ------------------------------------------------------------------------*/ /* class iopstream */ /* ------------------------------------------------------------------------*/ #if defined( Uses_iopstream ) && !defined( __iopstream ) #define __iopstream /** * Class iopstream is a simple "mix" of its bases, @ref opstream and * @ref ipstream. It provides the base class for simultaneous writing and * reading streamable objects. * * @short The base class for simultaneous writing and reading streamable * objects to and from streams */ class iopstream : public ipstream, public opstream { public: iopstream(std::streambuf *buf); ~iopstream(); }; #endif // Uses_iopstream /* ------------------------------------------------------------------------*/ /* class ifpstream */ /* ------------------------------------------------------------------------*/ #if defined( Uses_ifpstream ) && !defined( __ifpstream ) #define __ifpstream /** * ifpstream provides the base class for reading (extracting) * streamable objects from file streams. * * @short The base class for reading (extracting) streamable objects * from file streams. */ class ifpstream : public ipstream { std::filebuf buf; public: ifpstream(); ifpstream(const char name[], std::ios::openmode omode = std::ios::in); ~ifpstream(); void open(const char name[], std::ios::openmode omode = std::ios::in); }; #endif // Uses_ifpstream /* ------------------------------------------------------------------------*/ /* class ofpstream */ /* ------------------------------------------------------------------------*/ #if defined( Uses_ofpstream ) && !defined( __ofpstream ) #define __ofpstream /** * ofpstream provides the base class for writing (inserting) * streamable objects to file streams. * * @short The base class for writing (inserting) streamable objects * to file streams. */ class ofpstream : public opstream { std::filebuf buf; public: ofpstream(); ofpstream(const char name[], std::ios::openmode omode = std::ios::out); ~ofpstream(); void open(const char name[], std::ios::openmode omode = std::ios::out); }; #endif // Uses_ofpstream /* ------------------------------------------------------------------------*/ /* class fpstream */ /* ------------------------------------------------------------------------*/ #if defined( Uses_fpstream ) && !defined( __fpstream ) #define __fpstream /** * fpstream provides the base class for simultaneous writing and * reading streamable objects to bidirectional file streams. * * @short The base class for simultaneous writing and reading * streamable objects to bidirectional file streams. */ class fpstream : public iopstream { std::filebuf buf; public: fpstream(); fpstream(const char name[], std::ios::openmode omode); ~fpstream(); void open(const char name[], std::ios::openmode omode); }; #endif // Uses_fpstream