home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 9.ddi / TVSRC.ZIP / TOBJSTRM.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  17.1 KB  |  866 lines

  1. /*------------------------------------------------------------*/
  2. /* filename -       tobjstrm.cpp                              */
  3. /*                                                            */
  4. /* function(s)                                                */
  5. /*                  Member function(s) of following classes:  */
  6. /*                     TParamText                             */
  7. /*                     TStreamable                            */
  8. /*                     TStreamableClass                       */
  9. /*                     TStreamableTypes                       */
  10. /*                     TPWrittenObjects                       */
  11. /*                     TPReadObjects                          */
  12. /*                     pstream                                */
  13. /*                     ipstream                               */
  14. /*                     opstream                               */
  15. /*                     iopstream                              */
  16. /*                     fpbase                                 */
  17. /*                     ifpstream                              */
  18. /*                     ofpstream                              */
  19. /*                     fpstream                               */
  20. /*------------------------------------------------------------*/
  21.  
  22. /*------------------------------------------------------------*/
  23. /*                                                            */
  24. /*    Turbo Vision -  Version 1.0                             */
  25. /*                                                            */
  26. /*                                                            */
  27. /*    Copyright (c) 1991 by Borland International             */
  28. /*    All Rights Reserved.                                    */
  29. /*                                                            */
  30. /*------------------------------------------------------------*/
  31.  
  32. #define Uses_TStreamable
  33. #define Uses_TStreamableClass
  34. #define Uses_TStreamableTypes
  35. #define Uses_TPWrittenObjects
  36. #define Uses_TPReadObjects
  37. #define Uses_pstream
  38. #define Uses_ipstream
  39. #define Uses_opstream
  40. #define Uses_iopstream
  41. #define Uses_fpbase
  42. #define Uses_ifpstream
  43. #define Uses_ofpstream
  44. #define Uses_fpstream
  45. #include <tv.h>
  46.  
  47. #if !defined( __LIMITS_H )
  48. #include <Limits.h>
  49. #endif  // __LIMITS_H
  50.  
  51. #if !defined( __STRING_H )
  52. #include <String.h>
  53. #endif  // __STRING_H
  54.  
  55. #if !defined( __FSTREAM_H )
  56. #include <fstream.h>
  57. #endif  // __FSTREAM_H
  58.  
  59. #if !defined( __IO_H )
  60. #include <io.h>
  61. #endif  // __IO_H
  62.  
  63. #if !defined( __STAT_H )
  64. #include <sys\Stat.h>
  65. #endif  // __STAT_H
  66.  
  67. #if !defined( __FCNTL_H )
  68. #include <fcntl.h>
  69. #endif  // __FCNTL_H
  70.  
  71. #if !defined( __STDLIB_H )
  72. #include <stdlib.h>
  73. #endif  // __STDLIB_H
  74.  
  75. #if !defined( __ASSERT_H )
  76. #include <Assert.h>
  77. #endif  // __ASSERT_H
  78.  
  79. const uchar nullStringLen = UCHAR_MAX;
  80.  
  81. TStreamableClass::TStreamableClass( const char *n, BUILDER b, int d ) :
  82.     name( n ),
  83.     build( b ),
  84.     delta( d )
  85. {
  86.     pstream::initTypes();
  87.     pstream::registerType( this );
  88. }
  89.  
  90. TStreamableTypes::TStreamableTypes() : TNSSortedCollection( 5, 5 )
  91. {
  92. }
  93.  
  94. void *TStreamableTypes::operator new( size_t, void * arena )
  95. {
  96.     return arena;
  97. }
  98.  
  99. TStreamableTypes::~TStreamableTypes()
  100. {
  101. }
  102.  
  103. void TStreamableTypes::registerType( const TStreamableClass *d )
  104. {
  105.     insert( (void *)d );
  106. }
  107.  
  108. const TStreamableClass *TStreamableTypes::lookup( const char *name )
  109. {
  110.     ccIndex loc;
  111.     if( search( (void *)name, loc ) )
  112.         return (TStreamableClass *)at( loc );
  113.     else
  114.         return 0;
  115. }
  116.  
  117. void *TStreamableTypes::keyOf( void *d )
  118. {
  119.     return (void *)((TStreamableClass *)d)->name;
  120. }
  121.  
  122. int TStreamableTypes::compare( void *d1, void *d2 )
  123. {
  124.     return strcmp( (char *)d1, (char *)d2 );
  125. }
  126.  
  127. TPWrittenObjects::TPWrittenObjects() : TNSSortedCollection( 5, 5 ), curId( 0 )
  128. {
  129. }
  130.  
  131. TPWrittenObjects::~TPWrittenObjects()
  132. {
  133. }
  134.  
  135. void TPWrittenObjects::registerObject( const void *adr )
  136. {
  137.     TPWObj *o = new TPWObj( adr, curId++ );
  138.     insert( o );
  139. }
  140.  
  141. P_id_type TPWrittenObjects::find( const void *d )
  142. {
  143.     ccIndex loc;
  144.     if( search( (void *)d, loc ) )
  145.         return ((TPWObj *)at( loc ))->ident;
  146.     else
  147.         return P_id_notFound;
  148. }
  149.  
  150. void *TPWrittenObjects::keyOf( void *d )
  151. {
  152.     return (void *)((TPWObj *)d)->address;
  153. }
  154.  
  155. int TPWrittenObjects::compare( void *o1, void *o2 )
  156. {
  157.     if( o1 == o2 )
  158.         return 0;
  159.     else if( ((char huge *)o1)+1 < ((char huge *)o2)+1 ) // force normalization
  160.         return -1;
  161.     else
  162.         return 1;
  163. }
  164.  
  165. TPWObj::TPWObj( const void *adr, P_id_type id ) : address( adr ), ident( id )
  166. {
  167. }
  168.  
  169. TPReadObjects::TPReadObjects() : TNSCollection( 5, 5 ), curId( 0 )
  170. {
  171. }
  172.  
  173. TPReadObjects::~TPReadObjects()
  174. {
  175. }
  176.  
  177. #pragma warn -aus
  178.  
  179. void TPReadObjects::registerObject( const void *adr )
  180. {
  181.     ccIndex loc = insert( (void *)adr );
  182.     assert( loc == curId++ );   // to be sure that TNSCollection
  183.                                 // continues to work the way
  184.                                 // it does now...
  185. }
  186.  
  187. #pragma warn .aus
  188.  
  189. const void *TPReadObjects::find( P_id_type id )
  190. {
  191.     return at( id );
  192. }
  193.  
  194. pstream::pstream( streambuf _FAR *sb )
  195. {
  196.     init( sb );
  197. }
  198.  
  199. pstream::~pstream()
  200. {
  201. }
  202.  
  203. void pstream::initTypes()
  204. {
  205.     if( types == 0 )
  206.         types = new TStreamableTypes;
  207. }
  208.  
  209. int pstream::rdstate() const
  210. {
  211.     return state;
  212. }
  213.  
  214. int pstream::eof() const
  215. {
  216.     return state & ios::eofbit;
  217. }
  218.  
  219. int pstream::fail() const
  220. {
  221.     return state & (ios::failbit | ios::badbit | ios::hardfail);
  222. }
  223.  
  224. int pstream::bad() const
  225. {
  226.     return state & (ios::badbit | ios::hardfail);
  227. }
  228.  
  229. int pstream::good() const
  230. {
  231.     return state == 0;
  232. }
  233.  
  234. void pstream::clear( int i )
  235. {
  236.     state = (i & 0xFF) | (state & ios::hardfail);
  237. }
  238.  
  239. void pstream::registerType( TStreamableClass *ts )
  240.     types->registerType( ts ); 
  241. }
  242.  
  243. pstream::operator void _FAR *() const
  244. {
  245.     return fail() ? 0 : (void *)this;
  246. }
  247.  
  248. int pstream::operator! () const
  249. {
  250.     return fail();
  251. }
  252.  
  253. streambuf _FAR * pstream::rdbuf() const
  254. {
  255.     return bp;
  256. }
  257.  
  258. pstream::pstream()
  259. {
  260. }
  261.  
  262. void pstream::error( StreamableError )
  263. {
  264.     abort();
  265. }
  266.  
  267. void pstream::error( StreamableError, const TStreamable& )
  268. {
  269.     abort();
  270. }
  271.  
  272. void pstream::init( streambuf *sbp )
  273. {
  274.     state = 0;
  275.     bp = sbp;
  276. }
  277.  
  278. void pstream::setstate( int b )
  279. {
  280.     state |= (b&0xFF);
  281. }
  282.  
  283. ipstream::ipstream( streambuf _FAR *sb )
  284. {
  285.     pstream::init( sb );
  286. }
  287.  
  288. ipstream::~ipstream()
  289. {
  290.     objs.shouldDelete = False;
  291.     objs.shutDown();
  292. }
  293.  
  294. streampos ipstream::tellg()
  295. {
  296.     return bp->seekoff( 0, ios::cur, ios::in );
  297. }
  298.  
  299. ipstream& ipstream::seekg( streampos pos )
  300. {
  301.     objs.removeAll();
  302.     bp->seekoff( pos, ios::beg );
  303.     return *this;
  304. }
  305.  
  306. ipstream& ipstream::seekg( streamoff off, seek_dir dir )
  307. {
  308.     objs.removeAll();
  309.     bp->seekoff( off, dir );
  310.     return *this;
  311. }
  312.  
  313. uchar ipstream::readByte()
  314. {
  315.     return bp->sbumpc();
  316. }
  317.  
  318. ushort ipstream::readWord()
  319. {
  320.     ushort temp;
  321.     bp->sgetn( (char *)&temp, sizeof( ushort ) );
  322.     return temp;
  323. }
  324.  
  325. void ipstream::readBytes( void *data, size_t sz )
  326. {
  327.     bp->sgetn( (char *)data, sz );
  328. }
  329.  
  330. char *ipstream::readString()
  331. {
  332.     uchar len = readByte();
  333.     if( len == nullStringLen )
  334.         return 0;
  335.     char *buf = new char[len+1];
  336.     if( buf == 0 )
  337.         return 0;
  338.     readBytes( buf, len );
  339.     buf[len] = EOS;
  340.     return buf;
  341. }
  342.  
  343. char *ipstream::readString( char *buf, unsigned maxLen )
  344. {
  345.     assert( buf != 0 );
  346.  
  347.     uchar len = readByte();
  348.     if( len > maxLen-1 )
  349.         return 0;
  350.     readBytes( buf, len );
  351.     buf[len] = EOS;
  352.     return buf;
  353. }
  354.  
  355. ipstream& operator >> ( ipstream& ps, signed char &ch )
  356. {
  357.     ch = ps.readByte();
  358.     return ps;
  359. }
  360.  
  361. ipstream& operator >> ( ipstream& ps, unsigned char &ch )
  362. {
  363.     ch = ps.readByte();
  364.     return ps;
  365. }
  366.  
  367. ipstream& operator >> ( ipstream& ps, signed short &sh )
  368. {
  369.     sh = ps.readWord();
  370.     return ps;
  371. }
  372.  
  373. ipstream& operator >> ( ipstream& ps, unsigned short &sh )
  374. {
  375.     sh = ps.readWord();
  376.     return ps;
  377. }
  378.  
  379. ipstream& operator >> ( ipstream& ps, signed int &i )
  380. {
  381.     i = ps.readWord();
  382.     return ps;
  383. }
  384.  
  385. ipstream& operator >> ( ipstream& ps, unsigned int &i )
  386. {
  387.     i = ps.readWord();
  388.     return ps;
  389. }
  390.  
  391. ipstream& operator >> ( ipstream& ps, signed long &l )
  392. {
  393.     ps.readBytes( &l, sizeof(l) );
  394.     return ps;
  395. }
  396.  
  397. ipstream& operator >> ( ipstream& ps, unsigned long &l )
  398. {
  399.     ps.readBytes( &l, sizeof(l) );
  400.     return ps;
  401. }
  402.  
  403. ipstream& operator >> ( ipstream& ps, float &f )
  404. {
  405.     ps.readBytes( &f, sizeof(f) );
  406.     return ps;
  407. }
  408.  
  409. ipstream& operator >> ( ipstream& ps, double &d )
  410. {
  411.     ps.readBytes( &d, sizeof(d) );
  412.     return ps;
  413. }
  414.  
  415. ipstream& operator >> ( ipstream& ps, TStreamable& t )
  416. {
  417.     const TStreamableClass *pc = ps.readPrefix();
  418.     ps.readData( pc, &t );
  419.     ps.readSuffix();
  420.     return ps;
  421. }
  422.  
  423. ipstream& operator >> ( ipstream& ps, void *&t )
  424. {
  425.     char ch = ps.readByte();
  426.     switch( ch )
  427.         {
  428.         case pstream::ptNull:
  429.             t = 0;
  430.             break;
  431.         case pstream::ptIndexed:
  432.             {
  433.             P_id_type index = ps.readWord();
  434.             t = (void *)ps.find( index );
  435.             assert( t != 0 );
  436.             break;
  437.             }
  438.         case pstream::ptObject:
  439.             {
  440.             const TStreamableClass *pc = ps.readPrefix();
  441.             t = ps.readData( pc, 0 );
  442.             ps.readSuffix();
  443.             break;
  444.             }
  445.         default:
  446.             ps.error( pstream::peInvalidType );
  447.             break;
  448.         }
  449.     return ps;
  450. }
  451.  
  452. ipstream::ipstream()
  453. {
  454. }
  455.  
  456. #pragma warn -aus
  457.  
  458. const TStreamableClass *ipstream::readPrefix()
  459. {
  460.     char ch = readByte();
  461.     assert( ch == '[' );    // don't combine this with the previous line!
  462.                             // We must always do the read, even if we're
  463.                             // not checking assertions
  464.  
  465.     char name[128];
  466.     readString( name, sizeof name );
  467.     return types->lookup( name );
  468. }
  469.  
  470. #pragma warn .aus
  471.  
  472. void *ipstream::readData( const TStreamableClass *c, TStreamable *mem )
  473. {
  474.     if( mem == 0 )
  475.         mem = c->build();
  476.  
  477.     registerObject( (char *)mem - c->delta );   // register the actual address
  478.                                         // of the object, not the address
  479.                                         // of the TStreamable sub-object
  480.     return mem->read( *this );
  481. }
  482.  
  483. #pragma warn -aus
  484.  
  485. void ipstream::readSuffix()
  486. {
  487.     char ch = readByte();
  488.     assert( ch == ']' );    // don't combine this with the previous line!
  489.                             // We must always do the write, even if we're
  490.                             // not checking assertions
  491.  
  492. }
  493.  
  494. #pragma warn .aus
  495.  
  496. const void *ipstream::find( P_id_type id )
  497. {
  498.     return objs.find( id );
  499. }
  500.  
  501. void ipstream::registerObject( const void *adr )
  502. {
  503.     objs.registerObject( adr );
  504. }
  505.  
  506. opstream::opstream()
  507. {
  508.     objs = new TPWrittenObjects;
  509. }
  510.  
  511. opstream::opstream( streambuf * sb )
  512. {
  513.     objs = new TPWrittenObjects;
  514.     pstream::init( sb );
  515. }
  516.  
  517. opstream::~opstream()
  518. {
  519.     objs->shutDown();
  520.     delete objs;
  521. }
  522.  
  523. opstream& opstream::seekp( streampos pos )
  524. {
  525.     objs->removeAll();
  526.     bp->seekoff( pos, ios::beg );
  527.     return *this;
  528. }
  529.  
  530. opstream& opstream::seekp( streamoff pos, seek_dir dir )
  531. {
  532.     objs->removeAll();
  533.     bp->seekoff( pos, dir );
  534.     return *this;
  535. }
  536.  
  537. streampos opstream::tellp()
  538. {
  539.     return bp->seekoff( 0, ios::cur, ios::out );
  540. }
  541.  
  542. opstream& opstream::flush()
  543. {
  544.     bp->sync();
  545.     return *this;
  546. }
  547.  
  548. void opstream::writeByte( uchar ch )
  549. {
  550.     bp->sputc( ch );
  551. }
  552.  
  553. void opstream::writeBytes( const void *data, size_t sz )
  554. {
  555.     bp->sputn( (char *)data, sz );
  556. }
  557.  
  558. void opstream::writeWord( ushort sh )
  559. {
  560.     bp->sputn( (char *)&sh, sizeof( ushort ) );
  561. }
  562.  
  563. void opstream::writeString( const char *str )
  564. {
  565.     if( str == 0 )
  566.         {
  567.         writeByte( nullStringLen );
  568.         return;
  569.         }
  570.     int len = strlen( str );
  571.     writeByte( (uchar)len );
  572.     writeBytes( str, len );
  573. }
  574.  
  575. opstream& operator << ( opstream& ps, signed char ch )
  576. {
  577.     ps.writeByte( ch );
  578.     return ps;
  579. }
  580.  
  581. opstream& operator << ( opstream& ps, unsigned char ch )
  582. {
  583.     ps.writeByte( ch );
  584.     return ps;
  585. }
  586.  
  587. opstream& operator << ( opstream& ps, signed short sh )
  588. {
  589.     ps.writeWord( sh );
  590.     return ps;
  591. }
  592.  
  593. opstream& operator << ( opstream& ps, unsigned short sh )
  594. {
  595.     ps.writeWord( sh );
  596.     return ps;
  597. }
  598.  
  599. opstream& operator << ( opstream& ps, signed int i )
  600. {
  601.     ps.writeWord( i );
  602.     return ps;
  603. }
  604.  
  605. opstream& operator << ( opstream& ps, unsigned int i )
  606. {
  607.     ps.writeWord( i );
  608.     return ps;
  609. }
  610. opstream& operator << ( opstream& ps, signed long l )
  611. {
  612.     ps.writeBytes( &l, sizeof(l) );
  613.     return ps;
  614. }
  615.  
  616. opstream& operator << ( opstream& ps, unsigned long l )
  617. {
  618.     ps.writeBytes( &l, sizeof(l) );
  619.     return ps;
  620. }
  621.  
  622. opstream& operator << ( opstream& ps, float f )
  623. {
  624.     ps.writeBytes( &f, sizeof(f) );
  625.     return ps;
  626. }
  627.  
  628. opstream& operator << ( opstream& ps, double d )
  629. {
  630.     ps.writeBytes( &d, sizeof(d) );
  631.     return ps;
  632. }
  633.  
  634. opstream& operator << ( opstream& ps, TStreamable& t )
  635. {
  636.     ps.writePrefix( t );
  637.     ps.writeData( t );
  638.     ps.writeSuffix( t );
  639.     return ps;
  640. }
  641.  
  642. opstream& operator << ( opstream& ps, TStreamable *t )
  643. {
  644.     P_id_type index;
  645.     if( t == 0 )
  646.         ps.writeByte( pstream::ptNull );
  647.     else if( (index = ps.find( t )) != P_id_notFound )
  648.         {
  649.         ps.writeByte( pstream::ptIndexed );
  650.         ps.writeWord( index );
  651.         }
  652.     else
  653.         {
  654.         ps.writeByte( pstream::ptObject );
  655.         ps << *t;
  656.         }
  657.     return ps;
  658. }
  659.  
  660. void opstream::writePrefix( const TStreamable& t )
  661. {
  662.     writeByte( '[' );
  663.     writeString( t.streamableName() );
  664. }
  665.  
  666. void opstream::writeData( TStreamable& t )
  667. {
  668.     if( types->lookup( t.streamableName() ) == 0 )
  669.         error( peNotRegistered, t );
  670.     else
  671.         {
  672.         registerObject( &t );
  673.         t.write( *this );
  674.         }
  675. }
  676.  
  677. void opstream::writeSuffix( const TStreamable& )
  678. {
  679.     writeByte( ']' );
  680. }
  681.  
  682. P_id_type opstream::find( const void *adr )
  683. {
  684.     return objs->find( adr );
  685. }
  686.  
  687. void opstream::registerObject( const void *adr )
  688. {
  689.     objs->registerObject( adr );
  690. }
  691.  
  692. iopstream::iopstream( streambuf * sb )
  693. {
  694.     pstream::init( sb );
  695. }
  696.  
  697. iopstream::~iopstream()
  698. {
  699. }
  700.  
  701. iopstream::iopstream()
  702. {
  703. }
  704.  
  705. fpbase::fpbase()
  706. {
  707.     pstream::init( &buf );
  708. }
  709.  
  710. fpbase::fpbase( const char *name, int omode, int prot )
  711. {
  712.     pstream::init( &buf );
  713.     open( name, omode, prot );
  714. }
  715.  
  716. fpbase::fpbase( int f ) : buf( f )
  717. {
  718.     pstream::init( &buf );
  719. }
  720.  
  721. fpbase::fpbase( int f, char *b, int len ) : buf( f, b, len )
  722. {
  723.     pstream::init( &buf );
  724. }
  725.  
  726. fpbase::~fpbase()
  727. {
  728. }
  729.  
  730. void fpbase::open( const char *b, int m, int prot )
  731. {
  732.     if( buf.is_open() )
  733.         clear(ios::failbit);        // fail - already open
  734.     else if( buf.open(b, m, prot) )
  735.         clear(ios::goodbit);        // successful open
  736.     else
  737.         clear(ios::badbit);     // open failed
  738. }
  739.  
  740. void fpbase::attach( int f )
  741. {
  742.     if( buf.is_open() )
  743.         setstate(ios::failbit);
  744.     else if( buf.attach(f) )
  745.         clear(ios::goodbit);
  746.     else
  747.         clear(ios::badbit);
  748. }
  749.  
  750. void fpbase::close()
  751. {
  752.     if( buf.close() )
  753.         clear(ios::goodbit);
  754.     else
  755.         setstate(ios::failbit);
  756. }
  757.  
  758. void fpbase::setbuf(char* b, int len)
  759. {
  760.     if( buf.setbuf(b, len) )
  761.         clear(ios::goodbit);
  762.     else
  763.         setstate(ios::failbit);
  764. }
  765.  
  766. filebuf *fpbase::rdbuf()
  767. {
  768.     return &buf;
  769. }
  770.  
  771. ifpstream::ifpstream()
  772. {
  773. }
  774.  
  775. ifpstream::ifpstream( const char* name, int omode, int prot ) :
  776.         fpbase( name, omode | ios::in | ios::binary, prot )
  777. {
  778. }
  779.  
  780. ifpstream::ifpstream( int f ) : fpbase( f )
  781. {
  782. }
  783.  
  784. ifpstream::ifpstream(int f, char* b, int len) : fpbase(f, b, len)
  785. {
  786. }
  787.  
  788. ifpstream::~ifpstream()
  789. {
  790. }
  791.  
  792. filebuf *ifpstream::rdbuf()
  793. {
  794.     return fpbase::rdbuf();
  795. }
  796.  
  797. void ifpstream::open( const char _FAR *name, int omode, int prot )
  798. {
  799.     fpbase::open( name, omode | ios::in | ios::binary, prot );
  800. }
  801.  
  802. ofpstream::ofpstream()
  803. {
  804. }
  805.  
  806. ofpstream::ofpstream( const char* name, int omode, int prot ) :
  807.         fpbase( name, omode | ios::out | ios::binary, prot )
  808. {
  809. }
  810.  
  811. ofpstream::ofpstream( int f ) : fpbase( f )
  812. {
  813. }
  814.  
  815. ofpstream::ofpstream(int f, char* b, int len) : fpbase(f, b, len)
  816. {
  817. }
  818.  
  819. ofpstream::~ofpstream()
  820. {
  821. }
  822.  
  823. filebuf *ofpstream::rdbuf()
  824. {
  825.     return fpbase::rdbuf();
  826. }
  827.  
  828. void ofpstream::open( const char _FAR *name, int omode, int prot )
  829. {
  830.     fpbase::open( name, omode | ios::out | ios::binary, prot );
  831. }
  832.  
  833. fpstream::fpstream()
  834. {
  835. }
  836.  
  837. fpstream::fpstream( const char* name, int omode, int prot ) :
  838.         fpbase( name, omode | ios::out | ios::binary, prot )
  839. {
  840. }
  841.  
  842. fpstream::fpstream( int f ) : fpbase( f )
  843. {
  844. }
  845.  
  846. fpstream::fpstream(int f, char* b, int len) : fpbase(f, b, len)
  847. {
  848. }
  849.  
  850. fpstream::~fpstream()
  851. {
  852. }
  853.  
  854. filebuf *fpstream::rdbuf()
  855. {
  856.     return fpbase::rdbuf();
  857. }
  858.  
  859. void fpstream::open( const char _FAR *name, int omode, int prot )
  860. {
  861.     fpbase::open( name, omode | ios::in | ios::out | ios::binary, prot );
  862. }
  863.  
  864.  
  865.