// ObjStream.hpp #ifndef ObjStream_H #define ObjStream_H // ObjStream is a wrapper around standard ostream's and istream's // which defines a format so that data written out with one type of // ObjStream may be read back in with the same type. Associations // between objects are preserved. // // Supported data are restricted to atomic types (int, double, bool and // string) and pointers to objects inheriting from ObjectType. // These may be either bare pointers or shared management pointers // (ObjPtr). // // When an object is read in, it is constructed and stored in ObjTable // and the object name is returned. The object may be retrieved from // the table using this name. // // Objects are assigned a name when they are written out. Objects may be // written by reference or by shared delete pointer. In the latter case // the objects are inserted in ObjTable if not already present. // // A references to another object appear as the referenced object name in // the stream. On output, C++ addressses are converted to names. On // input, the reverse takes place. In both cases, the conversion is made // using ObjTable. The referenced object must already be present in the // table when the referencer is written or read. // // This class is an abtract base. Subclasses define the format of the // stream. // // The stream is organized into blocks which begin with a header // and end with a trailer. The subclass is expected to write or read past // the header in its constructor and write or read past the trailer in its // destructor. #include #include #include #include "ObjName.hpp" #include "ObjTable.hpp" #include "ObjException.hpp" using std::string; using std::set; using std::istream; using std::ostream; using std::ios; class ObjStream { private: // typedefs // List of object names. typedef set ObjList; // Input stream. istream* _pistream; // Output stream. ostream* _postream; private: // Data. // List of objects which have been written to the stream. ObjList _saved_objects; private: // Hidden methods. // Hide copy constructor. ObjStream(const ObjStream&); // Hide assignment. ObjStream& operator=(const ObjStream&); public: // Constructors. // Construct for an input stream. ObjStream(istream& stream); // Construct for an output stream. ObjStream(ostream& stream); // Destructor. virtual ~ObjStream(); // Read a data object from the stream into the table. // Returns the name of the object. virtual string read_data() =0; // Write a data object to the stream. virtual void write_data(string name, const ObjData& data) =0; protected: // Methods to access streams. // Return the input stream. // Throws ObjUndefinedInputStream if the input stream is undefined. const istream& in_stream() const; istream& in_stream(); // Return the output stream. // Throws ObjUndefinedOutputStream if the input stream is undefined. const ostream& out_stream() const; ostream& out_stream(); // Return the list of saved objects. const ObjList& saved_objects() const { return _saved_objects; } public: // Methods to examine stream states. // Return whether input is enabled. bool in_enabled() const { return _pistream != 0; } // Return whether output is enabled. bool out_enabled() const { return _postream != 0; } // Return the state of the input stream. // Throws ObjUndefinedInputStream if the input stream is undefined. ios::iostate in_state() const; // Return the state of the output stream. // Throws ObjUndefinedOutputStream if the input stream is undefined. ios::iostate out_state() const; // Return whether the input stream is at the end of file. // Throws ObjUndefinedInputStream if the input stream is undefined. bool eof() const; // Return whether an object has already been written to an output // stream. bool has_been_written(ObjName name) const; public: // Read and write. // Read the next object in the stream. // The object name is returned. // Throw ObjReadError if operation fails. string read_object(); // Read all objects and return the number read. int read_all_objects(); // Write an object (with data) to the stream. // Take no action and return false if the name already appears in // the stream. bool write_object(string name, const ObjType& obj); // Register an object with ObjTable if not already registered and // then write it to the stream. If the name already appears in the // stram then the last step is skipped and false is returned. bool write_object(string name, const ObjPtr& obj); }; //********************************************************************** // Exceptions. //********************************************************************** // Thrown when a requested input stream does not exist. class ObjUndefinedInputStream : public ObjException { }; // Thrown when a requested Output stream does not exist. class ObjUndefinedOutputStream : public ObjException { }; // Thrown when a name and address are insconsistent with ObjTable. class ObjNameAddressMismatch : public ObjException { }; //********************************************************************** #endif