#include <UIOObj.h> // TIOObjectBase, TIOObject<T>
#include <cstring.h>
// global variables
fstream* pfstream; // disk file stream
// example "simple object classes"
struct X {
int i;
X (int _i = 0) : i(_i) {} // is also default ctor...
};
class Y {
public:
double d[2]; // C arrays are OK
};
class XY: public X, public Y {
public: XY(X _x=X(), Y _y=Y()): X(_x), Y(_y) {}
};
//---------------------------------------------------------------
// initialization
void init(char * filename)
{
// open file, ios::binary!
// ios::app to append new objects to existing file
pfstream = new fstream(filename,
ios::in | ios::app | ios::binary);
// clears registered classes, not really needed here,
// but good habit
TIOObjectBase::reset();
// "Register" ALL classes that MIGHT BE in FILE INPUT
TIOObject<X>::Register();
TIOObject<Y>::Register();
TIOObject<XY>::Register();
}
//---------------------------------------------------------------
void writeFile() // OUTPUTS OBJECTS TO DISK FILE
{
X x(10); // "detailed" way to write
TIOObject<X> ioo(x); // ctor
ioo.write(*pfstream); // and write. . .
TIOObject<X>(X(20)).write(*pfstream); // "all in one"
// construct and write
Y y = { {1.2, 3.4} };
TIOObject<Y>(y).write(*pfstream);
x.i = 30;
TIOObject<X>(x).write(*pfstream);
TIOObject<XY> (XY(x,y)).write(*pfstream);
}
//--------------------------------------------------------------------
// OBJECT INPUT AND USEvoid useFile()
{
// go file begin
pfstream->rdbuf()->seekoff(0, ios::beg, ios::in);
TIOObjectBase* pIOObjectBase; // holds file input
// the read-process loop
while(true) { // exits on end of file or exception
try { // Enclose input in try catch block !
pIOObjectBase =
TIOObjectBase::Create(*pfstream);
}
catch (const TIOObjectBase::EEof* ) // OK, end of file
{
cout << "End of Data" << endl;
return;
}
// probably class name not registered?
catch (const TIOObjectBase::EUnknownClass* e)
{
cout << "error: " << e->mess.c_str() // offending name
<< " is unknown object type" // is displayed
<< endl;
return;
}
// *** bad news ***
catch (const TIOObjectBase::exception* e) {
cout << "error: " << e->mess.c_str() << endl
<< "file, line: "
<< __throwFileName << ", " << __throwLineNumber
<< endl;
return;
}
// *** worse news ***
catch (...) {
cout << "error: unknown exception thrown at " << endl
<< __throwFileName << ", " << __throwLineNumber
<< endl;
return;
}
// pIOObjectBase has valid object, find type and process
// T* TIOObject<T>::PtrData(TIOObjectBase*) returns:
// 0 if pIOObjectBase is not a TIOObject<T>*
// a T* if OK
if ( X* p = TIOObject<X>::PtrData(pIOObjectBase) ) {
cout << "read an X. i = " << p->i << endl;
}
if ( Y* p = TIOObject<Y>::PtrData(pIOObjectBase) ) {
cout << "read a Y. d[0], d[1] = "
<< p->d[0] <<", "<< p->d[1] << endl;
}
if ( XY* p = TIOObject <XY>::PtrData(pIOObjectBase) ) {
cout << "read a " << pIOObjectBase->name()
<< " d[0], d[1] = " << p->d[0] <<", "
<< p->d[1] << endl;
}
delete pIOObjectBase;
} // end while(true);
} // end useFile()
//---------------------------------------------------------------
// MAIN
//---------------------------------------------------------------
// usage dbstruct filename r|w|rw
// r for read, w write or rw for write and read
int main (int argc, char* argv[])
{
char c[1];
if (argc < 3) {
cout << "usage filename r|w|rw" << endl;
cin.getline(c, 2);
return 0;
}
else
init(argv[1]); // initialize
if ( (strcmp(argv[2], "w")==0) || (strcmp(argv[2], "rw")==0) )
writeFile(); // write objects to disk file
if ( (strcmp(argv[2], "r")==0) || (strcmp(argv[2], "rw") == 0))
useFile(); // read and use objects in file
// CLOSING PROGRAM
delete pfstream;
TIOObjectBase::reset(); // don't forget, memory leak...
cout << "end of program, press newline ";
cin.getline(c, 2);
return 1;
}
//End of File