All classes in the Library employ a uniform technology of storing their content in disk files and its subsequent retrieval. This allows for automatical reading/writing of arbitrary system of linked classes. If an application derives childs from Library's classes, it must provide for this technology, otherwise the file operations on classes will not work correctly.
In order to comply with the Library's system of class I/O, a class should provide for the following:CDerivedClass ( RPCStream Object );Both of them should fully initialize the class' data; parameter Object must be passed to the stream constructor of parent untouched (see example below).
void write ( RCFile f ); void read ( RCFile f );which, correspondingly, write and read the class' data using the file class CFile. These functions should also call the parent's write and read.
DefineClass(CDerivedClass) DefineStreamFunctions(CDerivedClass)
MakeStreamFunctions(CDerivedClass)
CFile f; CLibClass LC; f.assign ( FileName ); if (f.rewrite()) { LC.write ( f ); f.shut(); } else printf ( " can't open file for writting\n" );and CLibClass::read(RCFile f)
CFile f; CLibClass LC; f.assign ( FileName ); if (f.reset()) { LC.read ( f ); f.shut(); } else printf ( " can't open file for reading\n" );This method represents merely a uniform unsophisticated approach to streaming the classes, which does not actually involve creation of class instances -- and therefore the special stream constructor from above does not participate in this. However, the all rules listed above must be satisfied if CLibClass is to replace one of the Library classes and the Library is therefore expected to take care of all file operations on it. Method 2: use stream functions StreamWrite(RCFile f,RPCLibClass LC):
CFile f; PCLibClass LC; LC = new CLibClass(); . . . . . . . . . . f.assign ( FileName ); if (f.rewrite()) { StreamWrite ( f,LC ); f.shut(); } else printf ( " can't open file for writting\n" );and StreamRead(RCFile f,RPCLibClass LC)
CFile f; PCLibClass LC; LC = NULL; f.assign ( FileName ); if (f.reset()) { StreamRead ( f,LC ); f.shut(); } else printf ( " can't open file for reading\n" );This method will work even if class CLibClass is not found at the specified file position, in which case LC will be assigned NULL. This is a more general method of streaming the classes, which simplifies file operations on arbitrary dynamically-linked class hierarchies. Note that Method 1 and Method 2 cannot be mixed up, and that on each write/StreamWrite executed at writing the file, there should be exactly one call of read/StreamRead, correspondingly, at reading the file. EXAMPLE
DefineClass(CNewAtom) DefineStreamFunctions(CNewAtom) class CNewAtom : public CAtom { public : CNewAtom(); CNewAtom( RPCStream Object ); ~CNewAtom(); // destructor void write ( RCFile f ); void read ( RCFile f ); protected : int new_int_data; realtype new_real_data; pstr new_dynamical_string; void InitNewAtom(); // common initializer };
CNewAtom::CNewAtom() : CAtom() { InitNewAtom(); } CNewAtom::CNewAtom ( RPCStream Object ) : CAtom(Object) { InitNewAtom(); } CNewAtom~CNewAtom() { if (new_dynamical_string) delete new_dynamical_string; } void CNewAtom::InitNewAtom() { new_int_data = 1; new_real_data = 0.001; new_dynamical_string = NULL; CreateCopy ( new_dynamical_string,"new dynamical string" ); }
void CNewAtom::write ( RCFile f ) { CAtom::write ( f ); f.WriteInt ( &new_int_data ); f.WriteReal ( &new_real_data ); f.CreateWrite ( new_dynamical_string ); }
void CNewAtom::read ( RCFile f ) { // read() must strictly preserve the order of file operations // set in the corresponding write() function CAtom::read ( f ); f.ReadInt ( &new_int_data ); f.ReadReal ( &new_real_data ); f.CreateRead ( new_dynamical_string ); }
MakeStreamFunctions(CNewAtom)
Function | Purpose |
CLibClass::CLibClass | Default constructor for Library classes |
CLibClass::CLibClass | Stream constructor for Library classes. |
CLibClass::write | Writing the class data into a disk file. |
CLibClass::read | Reading the class data from disk file. |
StreamWrite | Writing a class into a disk file. |
StreamRead | Reading a class from a disk file. |
DefineClass | Macrodefinition of major types associated with the class. |
DefineStructure | Macrodefinition of major types associated with the structure.
|
DefineStreamFunctions | Macrodefinition of prototypes of stream functions
(StreamWrite and
StreamRead)
for a class.
|
MakeStreamFunctions | Macrogeneration of stream functions
(StreamWrite and
StreamRead)
for a class.
|
CLibClass::CLibClass ( |
) |
Default constructor performs initialization of class' data. All Library classes and classes derived from them must have the default constructor.
NOTE 1: Default constructors are used in Library's file operations on classes.
NOTE 2: All Library classes are derived from class CStream, which provides support for file operations on classes.
CLibClass::CLibClass() : CStream() {
CLibClassIntVariable = 0;
}
CLibClass::CLibClass ( |
RPCStream Object ) |
Stream constructor performs initialization of class' data and passes its argument to the parent class. All Library classes and classes derived from them must have the default constructor.
NOTE 1: Stream constructors are used in Library's file operations on classes.
NOTE 2: All Library classes are derived from class CStream, which provides support for file operations on classes.
CLibClass::CLibClass(RPCStream Object) : CStream(Object) {
CLibClassIntVariable = 0;
}
CLibClass::write ( |
RCFile f ) |
This virtual function, first defined in class CStream (file stream_.h), should provide for writing the class data into file given as the function's argument. The given file is already open; the function must not attempt to neither open nor close it, as well as change its current position by means other than normal output operations. It must not attempt to read from the file, either.
If the class is derived from another class, other than CStream, the write function must also call write function of the class' parent by placing statementCParentClass::write(f);(CParentClass stands for the name of parential class), where appropriate within the function body.
NOTE : It is crucially important that write and read functions of a class handle equal amount of bytes in strictly the same order.
See examples on the top of this page.
CLibClass::read ( |
RCFile f ) |
This virtual function, first defined in class CStream (file stream_.h), should provide for reading the class data from file given as the function's argument. The given file is already open; the function must not attempt to neither open nor close it, as well as change its current position by means other than normal input operations. It must not attempt to write into the file, either.
If the class is derived from another class, other than CStream, the read function must also call read function of the class' parent by placing statementCParentClass::read(f);(CParentClass stands for the name of parential class), where required within the function body.
NOTE : It is crucially important that write and read functions of a class handle equal amount of bytes in strictly the same order.
See examples on the top of this page.
void StreamWrite ( |
RCFile f, |
This function is part of the Library's technology of performing file operation on classes. Combined with StreamRead, it allows for automatical writing/reading an arbitrary dynamically linked hierarchy of classes.
The function writes the class data into disk file, preceeding it with a few bytes of auxilary information. It is perfectly Ok to give this function a NULL pointer for Object which is interpreted as "empty" class or "no class".NOTE 1: The function is generated automatically by macros DefineStreamFunctions and MakeStreamFunctions.
NOTE 2: For each call to StreamWrite made at writing a file, there must be exactly one call to StreamRead at reading it at strictly the same file position.
See examples on the top of this page.
void StreamRead ( |
RCFile f, |
This function is part of the Library's technology of performing file operation on classes. Combined with StreamWrite, it allows for automatical reading/writing an arbitrary dynamically linked hierarchy of classes.
If Object is set to NULL, the corresponding class will be allocated, initialized and read from the disk file; Object will then return pointer on it. If Object points to an existing instance of the class before being passed to StreamRead, the function will use that instance to stuff it with data from the file. If StreamWrite has placed an "empty" class at given position in the file, StreamRead will always return Object=NULL; in this case, if Object pointed to an allocated class before being passed to StreamRead, that class will be automatically disposed.NOTE 1: The function is generated automatically by macros DefineStreamFunctions and MakeStreamFunctions.
NOTE 2: For each call to StreamRead made at reading a file, there must be exactly one call to StreamWrite at writing it at strictly the same file position.
See examples on the top of this page.
DefineClass ( |
ClassName ) |
This macro defines the types of class pointer, class reference, pointer on pointer and reference to pointer. Each pointer is made by prefix "P", and each reference - by prefix "R". Thus
PClassName | - is pointer on class ClassName |
RClassName | - is reference to class ClassName |
PPClassName | - is pointer on PClassName |
RPClassName | - is reference to PClassName |
NOTE 1: These type definitions are used by macros DefineStreamFunctions and MakeStreamFunctions and through all the Library, therefore definition of each class should be prefaced with this macro.
NOTE 2: In the Library, the class names always start with capital "C". This however is not a requirement of any syntax or macrodefinition(s).
See example on the top of this page.
DefineStructure ( |
StructName ) |
This macro defines the types of structure pointer, structure reference, pointer on pointer and reference to pointer. Each pointer is made by prefix "P", and each reference - by prefix "R". Thus
PStructName | - is pointer on structure StructName |
RStructName | - is reference to structure StructName |
PPStructName | - is pointer on PStructName |
RPStructName | - is reference to PStructName |
NOTE : In the Library, the structure names always start with capital "S". This however is not a requirement of any syntax or macrodefinition(s).
DefineStreamFunctions ( |
ClassName ) |
This macro defines the prototypes of stream functions (StreamWrite and StreamRead) for class ClassName. These prototypes may be implicitely used by the Library, therefore always issue this macro.
NOTE 1: This macro will not work if DefineClass macro for that class was not issued before it.
NOTE 2: In the Library, the class names always start with capital "C". This however is not a requirement of any syntax or macrodefinition(s).
See example on the top of this page.
MakeStreamFunctions ( |
ClassName ) |
This macro generates stream functions StreamWrite and StreamRead for class ClassName.
NOTE 1: This macro will not work if DefineClass macro for that class was not issued before it.
NOTE 2: In the Library, the class names always start with capital "C". This however is not a requirement of any syntax or macrodefinition(s).
See example on the top of this page.