home *** CD-ROM | disk | FTP | other *** search
- // Borland C++ - (C) Copyright 1992 by Borland International
-
- /*------------------------------------------------------------*/
- /* filename - objstrm.cpp */
- /* */
- /* function(s) */
- /* Member function(s) of following classes: */
- /* TStreamable */
- /* TStreamableClass */
- /* TStreamableTypes */
- /* TPWrittenObjects */
- /* TPReadObjects */
- /* pstream */
- /* ipstream */
- /* opstream */
- /* iopstream */
- /* fpbase */
- /* ifpstream */
- /* ofpstream */
- /* fpstream */
- /*------------------------------------------------------------*/
-
- #if !defined( __OBJSTRM_H )
- #include <objstrm.h>
- #endif // __OBJSTRM_H
-
- #if !defined( __STRING_H )
- #include <string.h>
- #endif // __STRING_H
-
- #if !defined( __FSTREAM_H )
- #include <fstream.h>
- #endif // __FSTREAM_H
-
- #if !defined( __IO_H )
- #include <io.h>
- #endif // __IO_H
-
- #if !defined( __STAT_H )
- #include <sys\Stat.h>
- #endif // __STAT_H
-
- #if !defined( __FCNTL_H )
- #include <fcntl.h>
- #endif // __FCNTL_H
-
- #if !defined( __ASSERT_H )
- #include <assert.h>
- #endif // __ASSERT_H
-
- #if !defined(__ALLOC_H)
- #include <alloc.h>
- #endif // __ALLOC_H
-
-
-
-
-
-
-
-
-
-
- #if !defined(__APPLICAT_H)
- #include <applicat.h>
- #endif
-
- #if !defined(__WINDOBJ_H)
- #include <windobj.h>
- #endif
-
- #if defined(__DLL__)
- extern "C"
- unsigned _WinAllocFlag;
- #endif
-
- TStreamableTypes *pstream::types;
-
- #if defined(__DLL__)
-
- static unsigned short GetSegmentLimit(Pvoid pMem)
- {
- unsigned short Temp = FP_SEG(pMem); // Temp = selector
- asm lsl ax, Temp; // ax = segment limit
- asm mov Temp, ax; // Temp = segment limit
- return Temp;
- }
-
- static unsigned short GetChecksum(Pvoid pMem, unsigned short SegmentLimit)
- {
- unsigned long TempChecksum = 0; // intialize checksum
-
- SegmentLimit -= FP_OFF(pMem); // adjust for starting offset
-
- // Use either 64 bytes (32 words) or the segment limit, whichever
- // is smaller
- int ChecksumLimit = (SegmentLimit < 64) ? (SegmentLimit>>1) : 32;
-
- unsigned short _FAR *p = (unsigned short _FAR *)pMem;
-
- for (int i = 0; i < ChecksumLimit; i++)
- TempChecksum += *p++;
-
- return (unsigned short)TempChecksum;
- }
-
- TObjStrmRegRecord::TObjStrmRegRecord(PTStreamableClass pTStreamableClass)
- {
- this->pTStreamableClass = pTStreamableClass;
- SegmentLimit = GetSegmentLimit(pTStreamableClass->build);
- Checksum = GetChecksum(pTStreamableClass->build, SegmentLimit);
- }
-
- Pvoid TObjStrmRegRecord::operator new (size_t s)
- {
- return (Pvoid)LocalLock(LocalAlloc(LPTR, s));
- }
-
- void TObjStrmRegRecord::operator delete(Pvoid ptr)
- {
- HANDLE hMem =
- #ifdef STRICT
- LocalHandle( (void NEAR *)FP_OFF( ptr ) );
- #else
- LocalHandle( FP_OFF( ptr ) );
- #endif
- if (LocalUnlock(hMem))
- LocalFree(hMem);
- }
-
- int TObjStrmRegRecord::Validate()
- {
- WORD Temp = FP_SEG(pTStreamableClass);
- asm lar ax, Temp; // get access rights
- asm jnz invalid; // invalid segment
-
- asm and ax, 0x0800; // code or data?
- asm jnz invalid; // code, invalid
-
- // We can access the pTStreamableClass pointer. See if segment is
- // big enough to contain a TStreamableClass object.
-
- long TempSegmentLimit = GetSegmentLimit(pTStreamableClass);
- if (TempSegmentLimit-FP_OFF(pTStreamableClass) <=
- sizeof(TStreamableClass)-1)
- return 0;
-
- // We can access the TStreamableClass object and the segment in
- // which it resides is big enough to hold a TStreamableClass
-
- Temp = FP_SEG(pTStreamableClass->build);
- asm lar ax, Temp; // get access rights
- asm jnz invalid; // invalid selector
-
- asm and ax, 0x0800; // code or data
- asm jz invalid; // data, invalid
-
- unsigned short ActualSegmentLimit =
- GetSegmentLimit(pTStreamableClass->build);
-
- if (ActualSegmentLimit != SegmentLimit)
- {
- invalid:
- return 0;
- }
- else
- return (GetChecksum(pTStreamableClass->build,
- ActualSegmentLimit) == Checksum);
- }
-
- #endif // __DLL__
-
- TStreamableClass::TStreamableClass( const char *n, BUILDER b, int d ) :
- name( n ),
- build( b ),
- delta( d )
- {
- pstream::initTypes();
-
- #if defined(__DLL__)
-
- TObjStrmRegRecord * pTObjStrmRegRecord =
- new TObjStrmRegRecord(this);
-
- pstream::types->registerType(pTObjStrmRegRecord);
- #else
- pstream::types->registerType(this);
- #endif
- }
-
- #if defined(__DLL__)
- void TStreamableTypes::registerType(TObjStrmRegRecord *pTObjStrmRegRecord)
- {
- unsigned SavedWinAllocFlag = _WinAllocFlag;
- _WinAllocFlag |= GMEM_DDESHARE;
-
- insert((void *)pTObjStrmRegRecord);
-
- _WinAllocFlag = SavedWinAllocFlag;
- }
- #endif
-
- Boolean TStreamableTypes::search( void *key, ccIndex& index )
- {
- ccIndex l = 0;
- ccIndex h = count - 1;
- while( l <= h )
- {
- ccIndex i = (l + h) >> 1;
- // i is our midpoint
- #if defined(__DLL__)
-
- TObjStrmRegRecord * pTObjStrmRegRecord =
- (TObjStrmRegRecord *)items[i];
-
- if (!(pTObjStrmRegRecord->Validate()))
- {
- // remove this entry
- count--;
- memmove(&items[i], &items[i+1], (count-i)*sizeof(void *));
- h--;
- continue; // do the while again
- }
- #endif
- ccIndex c = compare( keyOf( items[i] ), key );
- if (c < 0)
- l = i + 1;
- else if (c > 0)
- h = i - 1;
- else
- {
- index = i;
- return True;
- }
- }
- index = l;
- return False;
- }
-
- const TStreamableClass *TStreamableTypes::lookup( const char *name )
- {
- ccIndex loc;
-
- if (!search((void *)name, loc))
- return NULL;
-
- #if defined(__DLL__)
- return ((TObjStrmRegRecord *)at(loc))->pTStreamableClass;
- #else
- return (PTStreamableClass)at(loc);
- #endif
- }
-
- Pvoid TStreamableTypes::keyOf(Pvoid d)
- {
- #if defined(__DLL__)
- TObjStrmRegRecord * pTObjStrmRegRecord = (TObjStrmRegRecord *)d;
- return (void *)((pTObjStrmRegRecord->pTStreamableClass)->name);
- #else
- return (void *)((PTStreamableClass)d)->name;
- #endif
- }
-
- int TStreamableTypes::compare( void *d1, void *d2 )
- {
- return strcmp( (char *)d1, (char *)d2 );
- }
-
- void TPWrittenObjects::registerObject( const void *adr )
- {
- TPWObj *o = new TPWObj( adr, curId++ );
- insert( o );
- }
-
- P_id_type TPWrittenObjects::find( const void *d )
- {
- ccIndex loc;
- if( search( Pvoid( d ), loc ) )
- return ((TPWObj *)at( loc ))->ident;
- else
- return 0;
- }
-
- int TPWrittenObjects::compare( void *o1, void *o2 )
- {
- if( o1 == o2 )
- return 0;
- else if( (void huge *)o1 < (void huge *)o2 )
- return -1;
- else
- return 1;
- }
-
- void TPReadObjects::registerObject( const void *adr )
- {
- ccIndex loc = insert( Pvoid( adr ));
- assert( loc == curId++ ); // to be sure that TNSCollection
- // continues to work the way
- // it does now...
- }
-
- void _Cdecl pstream::error( StreamableError errorcondition )
- {
- setstate( errorcondition );
-
- if(errorcondition == peNotRegistered)
- MessageBox(
- GetApplicationObject()->MainWindow->HWindow,
- "Type Not Registered", "PStream Error Condition",
- MB_OK | MB_ICONEXCLAMATION);
- else
- {
- assert(errorcondition == peInvalidType);
- MessageBox(
- GetApplicationObject()->MainWindow->HWindow,
- "Invalid Type Encountered", "PStream Error Condition",
- MB_OK | MB_ICONEXCLAMATION);
- }
-
- clear(ios::badbit);
- }
-
- void _Cdecl pstream::error( StreamableError errorcondition, RCTStreamable )
- {
- error( errorcondition );
- }
-
- void pstream::initTypes()
- {
- if( types == NULL )
- {
- #if defined(__DLL__)
- unsigned SavedWinAllocFlag = _WinAllocFlag;
- _WinAllocFlag |= GMEM_DDESHARE;
- #endif
-
- types = new TStreamableTypes;
-
- #if defined(__DLL__)
- _WinAllocFlag = SavedWinAllocFlag;
- #endif
- }
- }
-
- ipstream& ipstream::seekg( streampos pos )
- {
- objs.removeAll();
- objs.insert( new TPWObj( 0, 0 ));
- bp->seekoff( pos, ios::beg );
- return *this;
- }
-
- ipstream& ipstream::seekg( streamoff off, ios::seek_dir dir )
- {
- objs.removeAll();
- objs.insert( new TPWObj( 0, 0 ));
- bp->seekoff( off, dir );
- return *this;
- }
-
- ushort ipstream::readWord()
- {
- ushort temp;
- bp->sgetn( (char *)&temp, sizeof( ushort ) );
- return temp;
- }
-
- void ipstream::freadBytes( void far *data, size_t sz )
- {
- if (sz > 0)
- {
- char *buf = new char[sz+1];
-
- bp->sgetn( (char *)buf, sz );
- _fstrncpy((char far *)data, buf, sz);
-
- delete buf;
- }
- }
-
- char *ipstream::readString()
- {
- uchar len = readByte();
-
- char *buf = new char[len+1];
-
- if( buf != 0 )
- {
- readBytes( buf, len );
- buf[len] = EOS;
- }
- return buf;
- }
-
- char *ipstream::readString( char *buf, unsigned maxLen )
- {
- assert( buf != 0 );
-
- uchar len = readByte();
-
- if( len > maxLen-1 )
- len = maxLen; // but see buf[len] = EOS;
-
- readBytes( buf, len );
- buf[len] = EOS;
- return buf;
- }
-
- char far *ipstream::freadString( char far *buf, unsigned maxLen )
- {
- assert (buf != 0 );
-
- uchar len = readByte();
-
- if( len > maxLen-1 )
- len = maxLen; // but see buf[len] = EOS;
-
- freadBytes( buf, len);
- buf[len] = EOS;
- return buf;
- }
-
- char far *ipstream::freadString()
- {
- uchar len = readByte();
-
- char far *buf = (char far *)farmalloc(len+1);
-
- freadBytes(buf, len);
- buf[len] = EOS;
- return buf;
- }
-
- ipstream& operator >> ( ipstream& ps, signed char &ch )
- {
- ch = ps.readByte();
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, unsigned char &ch )
- {
- ch = ps.readByte();
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, signed short &sh )
- {
- sh = ps.readWord();
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, unsigned short &sh )
- {
- sh = ps.readWord();
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, signed int &i )
- {
- i = ps.readWord();
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, unsigned int &i )
- {
- i = ps.readWord();
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, signed long &l )
- {
- ps.readBytes( &l, sizeof(l) );
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, unsigned long &l )
- {
- ps.readBytes( &l, sizeof(l) );
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, float &l )
- {
- ps.readBytes( &l, sizeof(l) );
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, double &l )
- {
- ps.readBytes( &l, sizeof(l) );
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, long double &l )
- {
- ps.readBytes( &l, sizeof(l) );
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, TStreamable& t )
- {
- const TStreamableClass *pc;
-
- if((pc = ps.readPrefix()) == NULL)
- ps.error(pstream::peInvalidType );
- ps.readData( pc, &t );
- ps.readSuffix();
- return ps;
- }
-
- ipstream& operator >> ( ipstream& ps, void *&t )
- {
- char ch = ps.readByte();
- switch( ch )
- {
- case pstream::ptNull:
- t = 0;
- break;
- case pstream::ptIndexed:
- {
- P_id_type index = ps.readWord();
- t = Pvoid( ps.find( index ) );
- assert( t != 0 );
- break;
- }
- case pstream::ptObject:
- {
- const TStreamableClass *pc;
-
- if((pc = ps.readPrefix()) == NULL)
- ps.error( pstream::peInvalidType );
-
- t = ps.readData( pc, 0 );
- ps.readSuffix();
- break;
- }
- default:
- ps.error( pstream::peInvalidType );
- break;
- }
- return ps;
- }
-
- const TStreamableClass *ipstream::readPrefix()
- {
- char ch = readByte();
-
- assert( ch == '[' ); // don't combine this with the previous line!
- // We must always do the read, even if we're
- // not checking assertions
-
- char name[125];
- readString( name, sizeof name );
- return types->lookup( name );
- }
-
- void *ipstream::readData( const TStreamableClass *c, TStreamable *mem )
- {
- if( mem == 0 )
- mem = c->build();
-
- registerObject( (char *)mem - c->delta ); // register the actual address
- // of the object, not the address
- // of the TStreamable sub-object
- return mem->read( *this );
- }
-
- void ipstream::readSuffix()
- {
- char ch = readByte();
-
- assert( ch == ']' ); // don't combine this with the previous line!
- // We must always do the write, even if we're
- // not checking assertions
- }
-
- opstream& opstream::seekp( streampos pos )
- {
- objs.removeAll();
- objs.insert( new TPWObj( 0, 0 ));
- bp->seekoff( pos, ios::beg );
- return *this;
- }
-
- opstream& opstream::seekp( streamoff pos, ios::seek_dir dir )
- {
- objs.removeAll();
- objs.insert( new TPWObj( 0, 0 ));
- bp->seekoff( pos, dir );
- return *this;
- }
-
- opstream& opstream::flush()
- {
- bp->sync();
- return *this;
- }
-
- void opstream::fwriteBytes( const void far *data, size_t sz )
- {
- if (sz > 0)
- {
- char *buf = new char[sz+1];
-
- _fstrcpy(buf, (char far *)data);
- bp->sputn( (char *)buf, sz );
-
- delete buf;
- }
- }
-
- void opstream::writeString( const char *str )
- {
- int len = strlen( str );
- writeByte( (uchar)len );
- writeBytes( str, len );
- }
-
- void opstream::fwriteString( const char far * str )
- {
- int len = _fstrlen( str );
- writeByte( (uchar)len );
- fwriteBytes(str, len);
- }
-
- opstream& operator << ( opstream& ps, signed char ch )
- {
- ps.writeByte( ch );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, unsigned char ch )
- {
- ps.writeByte( ch );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, signed short sh )
- {
- ps.writeWord( sh );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, unsigned short sh )
- {
- ps.writeWord( sh );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, signed int i )
- {
- ps.writeWord( i );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, unsigned int i )
- {
- ps.writeWord( i );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, signed long l )
- {
- ps.writeBytes( &l, sizeof(l) );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, unsigned long l )
- {
- ps.writeBytes( &l, sizeof(l) );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, float l )
- {
- ps.writeBytes( &l, sizeof(l) );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, double l )
- {
- ps.writeBytes( &l, sizeof(l) );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, long double l )
- {
- ps.writeBytes( &l, sizeof(l) );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, TStreamable& t )
- {
- ps.writePrefix( t );
- ps.writeData( t );
- ps.writeSuffix( t );
- return ps;
- }
-
- opstream& operator << ( opstream& ps, TStreamable *t )
- {
- P_id_type index;
- if( t == 0 )
- ps.writeByte( pstream::ptNull );
- else if( (index = ps.find( t )) != 0 )
- {
- ps.writeByte( pstream::ptIndexed );
- ps.writeWord( index );
- }
- else
- {
- ps.writeByte( pstream::ptObject );
- ps << *t;
- }
- return ps;
- }
-
- void opstream::writePrefix( const TStreamable& t )
- {
- writeByte( '[' );
- writeString( t.streamableName() );
- }
-
- void opstream::writeData( TStreamable& t )
- {
- if ( types->lookup( t.streamableName() ) == NULL )
- error( peNotRegistered, t );
- else
- {
- registerObject( &t );
- t.write( *this );
- }
- }
-
- fpbase::fpbase( const char *name, int omode, int prot )
- {
- pstream::init( &buf );
- open( name, omode, prot );
- }
-
- void fpbase::open( const char *b, int m, int prot )
- {
- if( buf.is_open() )
- clear(ios::failbit); // fail - already open
- else if( buf.open(b, m, prot) )
- {
- clear(ios::goodbit);
- }
- else
- clear(ios::badbit); // open failed
- }
-
- void fpbase::attach( int f )
- {
- if( buf.is_open() )
- setstate(ios::failbit);
- else if( buf.attach(f) )
- clear(ios::goodbit);
- else
- clear(ios::badbit);
- }
-
- void fpbase::close()
- {
- if( buf.close() )
- clear(ios::goodbit);
- else
- setstate(ios::failbit);
- }
-
- void fpbase::setbuf(char* b, int len)
- {
- if( buf.setbuf(b, len) )
- clear(ios::goodbit);
- else
- setstate(ios::failbit);
- }
-
- ifpstream::ifpstream( const char* name, int omode, int prot ) :
- fpbase( name, omode | ios::in | ios::binary, prot )
- {
- }
-
- void ifpstream::open( const char _FAR *name, int omode, int prot )
- {
- fpbase::open( name, omode | ios::in | ios::binary, prot );
- }
-
- ofpstream::ofpstream( const char* name, int omode, int prot ) :
- fpbase( name, omode | ios::out | ios::binary, prot )
- {
- }
-
- void ofpstream::open( const char _FAR *name, int omode, int prot )
- {
- fpbase::open( name, omode | ios::out | ios::binary, prot );
- }
-
- fpstream::fpstream( const char* name, int omode, int prot ) :
- fpbase( name, omode | ios::out | ios::binary, prot )
- {
- }
-
- void fpstream::open( const char _FAR *name, int omode, int prot )
- {
- fpbase::open( name, omode | ios::in | ios::out | ios::binary, prot );
- }
-
-
-
-