Listing 3: UIOObj.CPP — Implements object creation functions

#pragma hdrstop

#include "UIOObj.h"

TIOObjectBase::CreateMap* TIOObjectBase::pCreateMap = 0;

//---------------------------------------------------------------
void TIOObjectBase::write(ostrstream & ostr)
{
   string _name(name());
   size_t nameSize = _name.length()+1;
   ostr.write((char*)&nameSize, sizeof nameSize);
   ostr.write(_name.c_str(), _name.length()+1);
   ostr.write((char*)dataStart(), dataSize());
}

//---------------------------------------------------------------
void TIOObjectBase::write(fstream& fstr)//(fstream* pfstream)
{
   ostrstream ostr;
   write(ostr);
   fstr.write(ostr.str(), ostr.pcount());
   ostr.rdbuf()->freeze(0);
}

//---------------------------------------------------------------
// returns the class name from  stream, AND
// positions stream to end of name, => begin of structure,
// for any calling method to use
string TIOObjectBase::readClassName(strstream & str) // * str)
        throw (TIOObjectBase::exception*)
{
   int nameSize=0;
   str.read((char*)&nameSize, sizeof nameSize);
   char  buf[MAX_NAME_SIZE];
   str.read( buf, nameSize);
   if (str.gcount() != nameSize  )  // something wrong?
      throw new exception("invalid size");
   str.seekg(sizeof nameSize + nameSize);  // for calling
   return string(buf);
}

//---------------------------------------------------------------
// as above, for file stream
string TIOObjectBase::readClassName(fstream & fstr) //* pfstream)
          throw (TIOObjectBase::exception*, TIOObjectBase::EEof*)
{
   int nameSize=0;
   fstr.read((char*)&nameSize, sizeof nameSize);
   if (fstr.eof())
      throw new EEof;
   if (nameSize > MAX_NAME_SIZE)     // some protection
      throw new exception("invalid name size");
   char  buf[MAX_NAME_SIZE];
   fstr.read( buf, nameSize);
   if (fstr.gcount() != nameSize  ) // some protection
      throw new exception("invalid read");
   return string(buf);
}

//---------------------------------------------------------------
TIOObjectBase* TIOObjectBase::Create(fstream& fstr)
   throw (TIOObjectBase::exception*, TIOObjectBase::EUnknownClass*)
{
  if (!pCreateMap)
     throw new exception("no classes registered!");
  string name = readClassName(fstr);
  if (name == string(""))
     throw new exception("empty class name");
  CreateMap::const_iterator it = pCreateMap->find(name);
  TIOObjectBase* pIOObjectBase=0;
  if (it != pCreateMap->end())            // class name in map, 
                                          // call create
     pIOObjectBase = (*it).second(fstr);  // indexed by name
  else                                    // OOPS!!!
     throw new EUnknownClass(name.c_str());
  return pIOObjectBase;
}

//---------------------------------------------------------------
void TIOObjectBase::reset()
{
   if (pCreateMap)
      delete pCreateMap;
}

//End of File