OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
objstrm.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1992, 1996 by Borland International, All Rights Reserved
4//
5//----------------------------------------------------------------------------
6#include <owl/pch.h>
7#include <owl/defs.h>
8#include <owl/streambl.h>
9#include <owl/objstrm.h>
10#include <owl/private/memory.h>
11#include <owl/template.h>
12#include <owl/pointer.h>
13
14#include <streambuf>
15#if defined(BI_MULTI_THREAD_RTL)
16#include <owl/thread.h>
17#endif
18
19#include <owl/except.h>
20#include <set>
21
22#if defined(__BORLANDC__)
23# pragma option -w-ccc // Disable "Condition is always true/false"
24#endif
25
26using namespace std;
27
28namespace owl {
29
31
32namespace
33{
34 const uint32 streamVersion = 0x0101;
35 const tchar versionIndicator = _T(':');
36 const tchar EOS = _T('\0');
37
40
42 {
43 static TStreamableTypes types; // Synchronised in C++11.
44 return types;
45 }
46
47 //
48 // Support for multi-threading
49 // NOTE: This support is incomplete, untested and probably unreliable.
50 //
51
52#if defined(BI_MULTI_THREAD_RTL)
53
54 TMRSWSection& GetLock_()
55 {
56 static TMRSWSection lock; // Synchronised in C++11.
57 return lock;
58 }
59
60#define LOCK_TYPES_(s) TMRSWSection::TLock lock__(GetLock_(), s, false)
61
62#else
63
64#define LOCK_TYPES_(s)
65
66#endif
67
68} // namespace
69
70class TStreamableBaseArray: public TPtrArray<TStreamableBase*>{
71 public:
72 TStreamableBaseArray(int a, int b=0, int c=0): TPtrArray<TStreamableBase*>(a,b,c){}
73 TStreamableBaseArray(){}
74};
75//
76class TStreamableClassArray: public TISortedPtrArray<TStreamableClass*>{
77 public:
78 TStreamableClassArray(int a, int b=0, int c=0): TISortedPtrArray<TStreamableClass*>(a,b,c){}
79 TStreamableClassArray(){}
80
81 int Add(TStreamableClass* t);
82 bool DetachItem(TStreamableClass* t)
83 {
84 const auto index = Find(t);
85 if (index != NPOS)
86 {
87 Remove(index);
88 return true;
89 }
90 return false;
91 }
92 int Find(TStreamableClass* t) const;
93 private:
94 int Add(const TStreamableClass* t);
95 bool DetachItem(const TStreamableClass* t);
96 int Find(const TStreamableClass* t) const;
97};
98int TStreamableClassArray::Add(TStreamableClass* t)
99{
100 if(ItemCnt>=Reserved)
101 Resize(ItemCnt+1); // on error -> throw xalloc
102 unsigned loc = ItemCnt++;
103 while( loc > 0 && *t < *(Data[loc-1])) {
104 Data[loc] = Data[loc-1];
105 loc--;
106 }
107 Data[loc] = (TStreamableClass*)t;
108 return loc;
109}
110int TStreamableClassArray::Find(TStreamableClass* t) const
111{
112 auto lower = 0;
113 auto upper = static_cast<int>(Size()) - 1;
114 while (lower <= upper)
115 {
116 const auto middle = (lower + upper) / 2;
117 if (*(Data[middle]) == *t)
118 return middle;
119 if (*(Data[middle]) < *t)
120 lower = middle + 1;
121 else
122 upper = middle - 1;
123 }
124 return NPOS;
125}
126
127//
128// Uses a std::set for faster insertion and lookup. The Borland sorted arrays
129// have very poor performance for large numbers of items (O(n^2)).
130//
131class TSortedTPWObjObjectArray
132{
133public:
134
135 TSortedTPWObjObjectArray(int = 0) {}
136
137 void Flush() { m_Items.clear(); }
138 void Add(TPWrittenObjects::TPWObj obj) { m_Items.insert(obj); }
139 P_id_type Find(TPWrittenObjects::TPWObj obj) const
140 {
141 std::set<TPWrittenObjects::TPWObj>::const_iterator i = m_Items.find(obj);
142 return (i != m_Items.end()) ? i->Ident : 0;
143 }
144
145private:
146
147 std::set<TPWrittenObjects::TPWObj> m_Items;
148
149};
150
151// -----------------------------------------------------------------------------
152const char* TStreamer::StreamableName() const
153{
154 return 0;
155}
156//----------------------------------------------------------------------------------------------
157/// Creates a TStreamableClass object with the given name (n) and the given builder
158/// function (b), then registers the type.
159/// For example, each streamable has a Build member function of type BUILDER. For
160/// type-safe object-stream I/O, the stream manager needs to access the names and
161/// the type information for each class. To ensure that the appropriate functions
162/// are linked into any application using the stream manager, you must provide a
163/// reference such as:
164/// \code
165/// TStreamableClass RegClassName;
166/// \endcode
167/// where TClassName is the name of the class for which objects need to be streamed.
168/// (Note that RegClassName is a single identifier.) This not only registers
169/// TClassName (telling the stream manager which Build function to use), it also
170/// automatically registers any dependent classes. You can register a class more
171/// than once without any harm or overhead.
172/// Invoke this function to provide raw memory of the correct size into which an
173/// object of the specified class can be read. Because the Build procedure invokes a
174/// special constructor for the class, all virtual table pointers are initialized
175/// correctly.
176/// The distance, in bytes, between the base of the streamable object and the
177/// beginning of the TStreamableBase component of the object is d. Calculate d by
178/// using the _ _DELTA macro.
179/// Example
180/// \code
181/// TStreamableClass RegTClassName = TStreamableClass("TClassName",
182/// TClassName::build, _ _DELTA(TClassName));
183/// \endcode
185 BUILDER b,
186 int d,
187 ModuleId id )
188:
189 ObjectBuilder( b, d ),
190 ModId(id)
191{
192 ObjectId = strnewdup(n);
193 if (id != 0) // id == 0 is used only during lookup. It flags an instance that shouldn't be registered.
194 GetTypes_().RegisterType(id, *this);
195}
196
198{
199 if (ModId != 0)
200 GetTypes_().UnRegisterType(ModId, *this);
201 delete [] CONST_CAST(char*, ObjectId);
202}
203
204
206{
207 Types = new TStreamableClassArray(30);
208}
209
210
212{
213 delete Types;
214}
215
216void
218{
219 PRECONDITION(Types);
220 LOCK_TYPES_(false);
221 Types->Add(&ts);
222}
223
225{
226 PRECONDITION(Types);
227 LOCK_TYPES_(false);
228 Types->DetachItem(&ts);
229}
230
232{
233 PRECONDITION(Types);
234 LOCK_TYPES_(true);
235 TStreamableClass sc(name, 0, 0, 0);
236 const auto loc = Types->Find(&sc);
237 if (loc == Types->NPOS)
238 {
240 tstring msg;
241 msg.reserve(128);
242 msg = _T("Attempt to stream unregistered type '");
243 msg += _A2W(name);
244 msg += _T("'");
245 TXBase(msg).Throw();
246 }
247 return (*Types)[loc];
248}
249
251{
252 // delete all objects and flush container
253 Data->Flush();
254}
255
256void TPReadObjects::RegisterObject( TStreamableBase *adr )
257{
258 Data->Add( adr );
259}
260
261TStreamableBase* TPReadObjects::Find( P_id_type id )
262{
263 if(id < Data->Size())
264 return (*Data)[id];
265 return 0;
266}
267
268TPReadObjects::TPReadObjects()
269{
270 Data = new TStreamableBaseArray;
271 Data->Add(0); // prime it: 0 is not a legal index.
272}
273TPReadObjects::~TPReadObjects()
274{
275 RemoveAll();
276 delete Data;
277}
278
279TPWrittenObjects::TPWrittenObjects()
280:
281 CurId(0)
282{
283 Data = new TSortedTPWObjObjectArray(10);
284}
285TPWrittenObjects::~TPWrittenObjects()
286{
287 delete Data;
288}
289
291{
292 CurId = 0;
293 Data->Flush();
294}
295
296void TPWrittenObjects::RegisterObject( TStreamableBase *adr )
297{
298 Data->Add(TPWObj(((tchar*)(void*)adr)+1, ++CurId));
299}
300
301void TPWrittenObjects::RegisterVB( const TStreamableBase *adr )
302{
303 Data->Add(TPWObj(adr,++CurId));
304}
305
306P_id_type TPWrittenObjects::FindObject( TStreamableBase *d )
307{
308 return Data->Find(TPWObj(((tchar*)(void*)d)+1,0));
309}
310
311P_id_type TPWrittenObjects::FindVB( TStreamableBase *d )
312{
313 return Data->Find(TPWObj(d,0));
314}
315
319
320/// Returns the (absolute) current stream position.
322{
324 if( !good() )
325 res = streampos(EOF);
326 else{
327 res = bp->pubseekoff(0, ios::cur, ios::in );
328 if( res == streampos(EOF) )
329 clear( ios::failbit );
330 }
331 return res;
332}
333
334/// Moves the stream position to the absolute position given by pos.
336{
337 if( good() ){
338 objs.RemoveAll();
339 streampos p = bp->pubseekoff(pos, ios::beg, ios::in );
340 if( p == streampos(EOF) )
341 clear( ios::failbit );
342 }
343 return *this;
344}
345
346/// Moves to a position relative to the current position by an offset off (+
347/// or -) starting at ios::seekdir. You can set ios::seekdir to one of the
348/// following:
349/// - \c \b beg (start of stream)
350/// - \c \b cur (current stream position)
351/// - \c \b end (end of stream).
352ipstream& ipstream::seekg( streamoff off, ios::seekdir dir )
353{
354 if( good() ){
355 objs.RemoveAll();
356#if __GNUC__ >=3
357 streampos p = bp->pubseekoff(off, dir, ios::in );
358#else
359 streampos p = bp->pubseekoff((ios::off_type)off, dir, (ios::openmode)ios::in );
360#endif
361 if( p == streampos(EOF) )
362 clear( ios::failbit );
363 }
364 return *this;
365}
366
367/// Returns the byte at the current stream position.
369{
370 int res;
371 if( !good() )
372 res = uint8(0);
373 else{
374 res = bp->sbumpc();
375 if( res == EOF )
376 clear( ios::failbit );
377 }
378 return uint8(res);
379}
380
381/// Reads sz bytes from current stream position, and writes them to data.
382void ipstream::readBytes( void *data, size_t sz )
383{
384 PRECONDITION( data != 0 );
385 if( good() && sz > 0 )
386 {
387 if( bp->sgetn( (char*)data, sz ) != static_cast<int>(sz) )
388 clear( ios::failbit );
389 }
390}
391
392/// Reads the number of bytes specified by sz into the supplied buffer (data).
393void ipstream::freadBytes( void *data, size_t sz )
394{
395 PRECONDITION( data != 0 );
396
397 if( good() && sz > 0){
398 TTmpBuffer<char> buf(static_cast<int>(sz));
399
400 if( bp->sgetn( (char*)buf, sz ) != static_cast<int>(sz))
401 clear( ios::failbit );
402 else
403 memcpy( data, (char*)buf, sz);
404 }
405}
406
407/// Returns the word at the current stream position.
409{
410 if( getVersion() > 0 )
411 return readWord32();
412 else
413 return readWord16();
414}
415
416/// Returns the 16-bit word at the current stream position.
418{
419 if( !good() )
420 return 0;
421 else{
422 uint16 temp;
423 if( bp->sgetn( (char*)&temp, sizeof( temp ) ) !=
424 static_cast<int>(sizeof( temp )) )
425 clear( ios::failbit );
426 return temp;
427 }
428}
429
430/// Returns the 32-bit word at the current stream position.
432{
433 if( !good() )
434 return 0;
435 else{
436 uint32 temp;
437 if( bp->sgetn( (char*)&temp, sizeof( temp ) ) !=
438 static_cast<int>(sizeof( temp )) )
439 clear( ios::failbit );
440 return temp;
441 }
442}
443
444uint32 ipstream::readStringLength()
445{
446 uint32 len;
447 if( getVersion() > 0x0100 ){
448 len = readWord32();
449 }
450 else{
451 len = readByte();
452 if( len == oldNullStringLen )
454 }
455 return len;
456}
457
458/// Allocates a buffer large enough to contain the string at the current
459/// stream position and reads the string into the buffer. The caller must free the
460/// buffer.
462{
463 if( !good() )
464 return 0;
465 else{
466 uint32 len = readStringLength();
467 if( len == nullStringLen )
468 return 0;
469
470 char* buf = new char[size_t(len+1)];
471 if( buf == 0 )
472 return 0;
473 readBytes( buf, size_t(len) );
474 buf[size_t(len)] = EOS;
475 return buf;
476 }
477}
478
479/// Reads the string at the current stream position into the buffer
480/// specified by buf. If the length of the string is greater than maxLen - 1, it
481/// reads nothing. Otherwise, it reads the string into the buffer and appends a
482/// null-terminating byte.
484{
485 PRECONDITION( buf != 0 );
486
487 if( !good() )
488 return 0;
489 else{
490 uint32 len = readStringLength();
491 if( len == nullStringLen || len > maxLen-1 )
492 return 0;
493 readBytes( buf, size_t(len) );
494 buf[size_t(len)] = EOS;
495 return buf;
496 }
497}
498
499/// Reads a string from the stream. It determines the length of the string
500/// and allocates a character array of the appropriate length. It reads the
501/// string into this array and returns a pointer to the string. The caller is
502/// expected to free the allocated memory block.
504{
505 if( !good() )
506 return 0;
507 else{
508 uint32 len = readStringLength();
509 if( len == nullStringLen )
510 return 0;
511
512 char* buf = new char[size_t(len)+1];
513 freadBytes(buf, size_t(len));
514 buf[size_t(len)] = EOS;
515 return buf;
516 }
517}
518
519/// Reads a string from the stream into the supplied far buffer (buf). If
520/// the length of the string is greater than maxLen-1, it reads nothing. Otherwise,
521/// it reads the string into the buffer and appends a null-terminating byte.
522char* ipstream::freadString( char *buf, unsigned maxLen )
523{
524 PRECONDITION(buf != 0 );
525
526 if( !good() )
527 return 0;
528 else{
529 uint32 len = readStringLength();
530 if( len == nullStringLen || len > maxLen-1 )
531 return 0;
532
533 freadBytes( buf, size_t(len));
534 buf[size_t(len)] = EOS;
535 return buf;
536 }
537}
538
539/// Reads the version number of the input stream.
541{
542 if( !good() )
543 version = 0;
544 else{
545 int res = bp->sgetc();
546 if( res == EOF ){
547 clear( ios::eofbit );
548 version = 0;
549 return;
550 }
551 if( res != versionIndicator )
552 version = 0;
553 else{
554 bp->sbumpc();
555 version = readWord32();
556 }
557 }
558}
559
561 ModuleId mid )
562{
563 if( good() ){
564 const ObjectBuilder *pc = readPrefix( mid );
565 if( pc == 0 )
566 mem = 0;
567 else{
568 readData( pc, mem );
569 readSuffix();
570 }
571 }
572 return mem;
573}
574
575/// Returns the TStreamableClass object corresponding to the class name stored at
576/// the current position in the stream.
578{
579 char ch = readByte();
580 if( ch != '[' ){
581 clear( ios::failbit );
582 return 0;
583 }
584
585 char name[128];
586 name[0] = EOS;
587 readString( name, sizeof name );
588 if( name[0] == EOS ){
589 clear( ios::failbit );
590 return 0;
591 }
592
594
595 TRACEX(Objstrm,0,_T("Reading ") << _A2W(name));
596 const ObjectBuilder *res = GetTypes_().Lookup(mid, name);
597
598 WARNX(Objstrm,res==0,0,_T("Unrecognized class identifier: ") << _A2W(name));
599 if( res == 0 ){
600 clear( ios::failbit );
601 return 0;
602 }
603
604 return res;
605}
606
607/// If mem is 0, it calls the appropriate build function to allocate memory and
608/// initialize the virtual table pointer for the object.
609/// Finally, it invokes the appropriate read function to read the object from the
610/// stream into the memory pointed to by mem.
612{
613 TPointer<TStreamer> strmr(c->Builder(mem));
614 mem = strmr->GetObject();
615
616 // register the address
618
619 uint32 classVer = 0;
620 if( getVersion() > 0 )
622
623 strmr->Read( *this, classVer );
624}
625
626/// Reads and checks the suffix of the object.
628{
629 if( !good() )
630 return;
631 char ch = readByte();
632 if( ch != ']' )
633 clear( ios::failbit );
634}
635
637 ModuleId mid )
638{
639 if( !good() )
640 return 0;
641
642 char ch = readByte();
643 switch( ch ){
644 case pstream::ptNull:
645 mem = 0;
646 break;
647 case pstream::ptIndexed:{
648 P_id_type index = P_id_type(readWord());
649 mem = find( index );
650 CHECK( mem != 0 );
651 break;
652 }
653 case pstream::ptObject: {
654 const ObjectBuilder *pc = readPrefix( mid );
655 readData( pc, mem );
656 readSuffix();
657 break;
658 }
659 default:
660 clear( ios::failbit );
661 break;
662 }
663 return mem;
664}
665
666/// Creates a buffered opstream with the given buffer and sets the bp data
667/// member to buf. The state is set to 0.
669{
670 objs = new TPWrittenObjects;
671 if( bp != 0 )
672 writeVersion();
673}
674
675/// Creates an opstream object without initializing the buffer pointer, bp.
676/// Use pstream::init to set the buffer and state.
677opstream::opstream( streambuf * sb )
678{
679 objs = new TPWrittenObjects;
680 pstream::init( sb );
681 writeVersion();
682}
683
684/// Returns the (absolute) current stream position.
686{
688 if( !good() )
689 res = streampos(EOF);
690 else{
691 res = bp->pubseekoff(0, ios::cur, ios::out );
692 if( res == streampos(EOF) )
693 clear( ios::failbit );
694 }
695 return res;
696}
697
698/// Moves the current position of the stream to the absolute position given by pos.
700{
701 if( good() ){
702 objs->RemoveAll();
703#if __GNUC__ >=3
704 streampos p = bp->pubseekoff(pos, ios::beg, ios::out);
705#else
706 streampos p = bp->pubseekoff((ios::off_type)pos, (ios::seekdir)ios::beg,
707 (ios::openmode)ios::out);
708#endif
709 if( p == streampos(EOF) )
710 clear( ios::failbit );
711 }
712 return *this;
713}
714
715/// Form 2: Moves to a position relative to the current position by an offset off (+
716/// or -) starting at ios::seekdir. You can set ios::seekdir to one if the
717/// following:
718/// - \c \b beg (start of stream)
719/// - \c \b cur (current stream position)
720/// - \c \b end (end of stream).
721opstream& opstream::seekp( streamoff off, ios::seekdir dir )
722{
723 if( good() ){
724 objs->RemoveAll();
725#if __GNUC__ >=3
726 streampos p = bp->pubseekoff(off, dir, ios::out );
727#else
728 streampos p = bp->pubseekoff((ios::off_type)off, dir, (ios::openmode)ios::out );
729#endif
730 if( p == streampos(EOF) )
731 clear( ios::failbit );
732 }
733 return *this;
734}
735
737{
738 if( good() ){
741 }
742}
743
744/// Flushes the stream.
746{
747 if( bp->pubsync() == EOF )
748 clear( ios::badbit );
749 return *this;
750}
751
752/// Writes the byte ch to the stream.
754{
755 if( good() ){
756 if( bp->sputc( ch ) == EOF )
757 clear( ios::failbit );
758 }
759}
760
761/// Writes sz bytes from the data buffer to the stream.
762void opstream::writeBytes( const void *data, size_t sz )
763{
764 PRECONDITION( data != 0 );
765
766 if( good() && sz > 0 ){
767 if( bp->sputn( (char*)data, sz ) != static_cast<int>(sz) )
768 clear( ios::failbit );
769 }
770}
771
772/// Writes the 16-bit word us to the stream.
774{
775 if( good() ){
776 if( bp->sputn( (char*)&word16, sizeof(word16) ) !=
777 static_cast<int>(sizeof(word16)) )
778 clear( ios::failbit );
779 }
780}
781
782/// Writes the 32-bit word us to the stream.
784{
785 if( good() ){
786 if( bp->sputn( (char*)&word32, sizeof(word32) ) !=
787 static_cast<int>(sizeof(word32)) )
788 clear( ios::failbit );
789 }
790}
791
792/// Writes the specified number of bytes (sz) from the supplied buffer (data) to the
793/// stream.
794void opstream::fwriteBytes( const void *data, size_t sz )
795{
796 PRECONDITION( data != 0 );
797
798 if( good() && sz > 0 ){
799 char* buf = new char[sz];
800
801 memcpy( buf, data, sz );
802 if( bp->sputn( (char*)buf, sz ) != static_cast<int>(sz) )
803 clear( ios::failbit );
804
805 delete[] buf;
806 }
807}
808
809/// Writes str to the stream.
810void opstream::writeString( const char* str )
811{
812 if( !good() )
813 return;
814
815 if( str == 0 ){
817 return;
818 }
819 size_t len = strlen( str );
820 writeWord32(static_cast<uint32>(len));
821 writeBytes( str, len );
822}
823
824/// Writes the specified far character string (str) to the stream.
825void opstream::fwriteString( const char * str )
826{
827 if( !good() )
828 return;
829
830 if( str == 0 ){
832 return;
833 }
834 size_t len = strlen( str );
835 writeWord32(static_cast<uint32>(len));
836 fwriteBytes(str, len);
837}
838
839#if !defined(BI_COMP_GNUC)
840#pragma warn -par
841#endif
842/// Writes the object, pointed to by t, to the output stream. The isPtrargument
843/// indicates whether the object was allocated from the heap.
845{
849 0,
850 _T("Pointer written before object: ") \
851 << _A2W(_OBJ_FULLTYPENAME(mem)) << _T('(') << (void*)mem << _T(')') );
852 if( good() ){
853 writePrefix( mem );
854 writeData( mem, mid );
855 writeSuffix( mem );
856 }
857}
858#if !defined(BI_COMP_GNUC)
859#pragma warn .par
860#endif
861
862/// Writes the object pointer t to the output stream.
864{
865 if( good() ){
866 P_id_type index;
867 if( t == 0 )
869 else if( (index = findObject( CONST_CAST(TStreamableBase *,t) )) != 0 ){
871 writeWord( index );
872 }
873 else{
875 writeObject( t, 1, mid );
876 }
877 }
878}
879
880/// Writes the class name prefix to the stream. The << operator uses this function
881/// to write a prefix and suffix around the data written with writeData. The
882/// prefix/suffix is used to ensure type-safe stream I/O.
884{
885 if( good() ){
886 writeByte( '[' );
888 }
889}
890
891/// Writes data to the stream by calling the write member function of the
892/// appropriate class for the object being written.
894{
896 if( good() ){
898 const ObjectBuilder *res = GetTypes_().Lookup(mid, _OBJ_TYPENAME(t));
901 writeWord32( strmr->ClassVersion() );
902 strmr->Write( *this );
903 }
904}
905
906/// Opens the named file in the given mode (app, ate, in, out, binary, trunc,
907/// nocreate, or noreplace) and protection. The opened file is attached to this
908/// stream.
909void fpbase::open( LPCSTR b, int m, int)
910{
911 if (buf.is_open())
912 clear(ios::failbit);
913 else if (buf.open(b, static_cast<ios::openmode>(m)))
914 clear(ios::goodbit);
915 else
916 clear(ios::badbit);
917}
918
919/// Opens the named file in the given mode (app, ate, in, out, binary, trunc,
920/// nocreate, or noreplace) and protection. The opened file is attached to this
921/// stream.
922void fpbase::open(LPCWSTR b, int m, int)
923{
924 if (buf.is_open())
925 clear(ios::failbit);
926 else if (buf.open(b, static_cast<ios::openmode>(m)))
927 clear(ios::goodbit);
928 else
929 clear(ios::badbit);
930}
931
932/// Closes the stream and associated file.
934{
935 if( buf.close() )
936 clear(ios::goodbit);
937 else
938 clear(ios::failbit);
939}
940
941/// Sets the location of the buffer to buf and the buffer size to len.
943{
944 if( buf.pubsetbuf(b, len) )
945 clear(ios::goodbit);
946 else
947 clear(ios::failbit);
948}
949
950//
951// These operators are not friends of string, so
952// they must use only the public interface.
953//
955{
957 os.writeString( _W2A(str.c_str()) );
958 return os;
959}
960
961/// This operator of ipstream extracts (reads) from the ipstream is, to the string
962/// str. It returns a reference to the stream that lets you chain >> operations in
963/// the usual way.
965{
966 if( is.good() ){
967 uint32 len = is.readStringLength();
968 if( len == nullStringLen )
969 str = _T("");
970 else{
971 char *temp = new char[size_t(len)+1];
972 is.readBytes( temp, size_t(len) );
973 temp[size_t(len)] = EOS;
975 str = _A2W(temp);
976 delete [] temp;
977 }
978 }
979 return is;
980}
981
982} // OWL namespace
983/* ========================================================================== */
#define CHECK(condition)
Definition checks.h:239
#define WARNX(group, condition, level, message)
Definition checks.h:277
#define PRECONDITION(condition)
Definition checks.h:227
#define CHECKX(condition, message)
Definition checks.h:245
#define IFDIAG(a)
Definition checks.h:418
#define TRACEX(group, level, message)
Definition checks.h:263
#define DIAG_DEFINE_GROUP_INIT(f, g, e, l)
Definition checks.h:429
uint Size() const
Definition template.h:601
static const auto NPOS
Definition template.h:608
Classes that inherit from TStreamableBase are known as streamable classes (their objects can be writt...
Definition objstrm.h:108
TStreamableClass is used by the private database class and pstream in the registration of streamable ...
Definition streambl.h:75
TStreamableClass(LPCSTR n, BUILDER b, int d=NoDelta, ModuleId mid=GetModuleId())
Creates a TStreamableClass object with the given name (n) and the given builder function (b),...
Definition objstrm.cpp:184
const ObjectBuilder * Lookup(ModuleId id, LPCSTR name) const
Definition objstrm.cpp:231
void UnRegisterType(ModuleId id, TStreamableClass &)
Definition objstrm.cpp:224
void RegisterType(ModuleId id, TStreamableClass &)
Definition objstrm.cpp:217
virtual LPCSTR StreamableName() const =0
This pure virtual member function must be redefined for every streamable class.
Definition objstrm.cpp:152
void Resize(int delta)
Definition template.h:1538
void Remove(int index)
Definition template.h:1567
Derived from xmsg, TXBase is the base class for ObjectWindows and ObjectComponents exception-handling...
Definition exbase.h:41
virtual void Throw()
Throws the exception object.
Definition exbase.cpp:142
void open(LPCSTR, int, int=openprot)
Opens the named file in the given mode (app, ate, in, out, binary, trunc, nocreate,...
Definition objstrm.cpp:909
void close()
Closes the stream and associated file.
Definition objstrm.cpp:933
void setbuf(LPSTR, int)
Sets the location of the buffer to buf and the buffer size to len.
Definition objstrm.cpp:942
ipstream, a specialized input stream derivative of pstream, is the base class for reading (extracting...
Definition objstrm.h:391
std::streampos tellg()
Returns the (absolute) current stream position.
Definition objstrm.cpp:321
TStreamableBase * readObjectPointer(TStreamableBase *&mem, ModuleId mid=GetModuleId())
Definition objstrm.cpp:636
const ObjectBuilder * readPrefix(ModuleId mid)
Returns the TStreamableClass object corresponding to the class name stored at the current position in...
Definition objstrm.cpp:577
LPSTR readString()
Allocates a buffer large enough to contain the string at the current stream position and reads the st...
Definition objstrm.cpp:461
uint32 readWord32()
Returns the 32-bit word at the current stream position.
Definition objstrm.cpp:431
void readSuffix()
Reads and checks the suffix of the object.
Definition objstrm.cpp:627
void readVersion()
Reads the version number of the input stream.
Definition objstrm.cpp:540
void readData(const ObjectBuilder *, TStreamableBase *&)
If mem is 0, it calls the appropriate build function to allocate memory and initialize the virtual ta...
Definition objstrm.cpp:611
char * freadString()
Reads a string from the stream.
Definition objstrm.cpp:503
ipstream & seekg(std::streampos)
uint16 readWord16()
Returns the 16-bit word at the current stream position.
Definition objstrm.cpp:417
void freadBytes(void *data, size_t sz)
Reads the number of bytes specified by sz into the supplied buffer (data).
Definition objstrm.cpp:393
TStreamableBase * readObject(TStreamableBase *&mem, ModuleId mid=GetModuleId())
Definition objstrm.cpp:560
uint32 readWord()
Returns the word at the current stream position.
Definition objstrm.cpp:408
uint8 readByte()
Returns the byte at the current stream position.
Definition objstrm.cpp:368
void readBytes(void *, size_t)
Reads sz bytes from current stream position, and writes them to data.
Definition objstrm.cpp:382
Base class for writing streamable objects.
Definition objstrm.h:480
void writeWord16(uint16)
Writes the 16-bit word us to the stream.
Definition objstrm.cpp:773
opstream & flush()
Flushes the stream.
Definition objstrm.cpp:745
void writeString(const char *)
Writes str to the stream.
Definition objstrm.cpp:810
void fwriteBytes(const void *data, size_t sz)
Writes the specified number of bytes (sz) from the supplied buffer (data) to the stream.
Definition objstrm.cpp:794
void writeObject(const TStreamableBase *t, int isPtr=0, ModuleId mid=GetModuleId())
Writes the object, pointed to by t, to the output stream.
Definition objstrm.cpp:844
void writeBytes(const void *, size_t)
Writes sz bytes from the data buffer to the stream.
Definition objstrm.cpp:762
void writeByte(uint8)
Writes the byte ch to the stream.
Definition objstrm.cpp:753
opstream()
Creates a buffered opstream with the given buffer and sets the bp data member to buf.
Definition objstrm.cpp:668
void fwriteString(const char *str)
Writes the specified far character string (str) to the stream.
Definition objstrm.cpp:825
void writeData(const TStreamableBase *, ModuleId mid)
Writes data to the stream by calling the write member function of the appropriate class for the objec...
Definition objstrm.cpp:893
void writeVersion()
Definition objstrm.cpp:736
opstream & seekp(std::streampos)
void writeWord32(uint32)
Writes the 32-bit word us to the stream.
Definition objstrm.cpp:783
void writeObjectPointer(const TStreamableBase *t, ModuleId mid=GetModuleId())
Writes the object pointer t to the output stream.
Definition objstrm.cpp:863
std::streampos tellp()
Returns the (absolute) current stream position.
Definition objstrm.cpp:685
void writePrefix(const TStreamableBase *)
Writes the class name prefix to the stream.
Definition objstrm.cpp:883
virtual ~pstream()
Definition objstrm.cpp:316
std::streambuf * bp
Definition objstrm.h:356
#define _T(x)
Definition cygwin.h:51
unsigned P_id_type
Definition objstrm.h:54
int good() const
Returns nonzero if no error states have been recorded for the stream (that is, no errors have occurre...
Definition objstrm.h:666
void registerObject(TStreamableBase *adr)
Registers the class of the object pointed to by adr.
Definition objstrm.h:757
void registerObject(TStreamableBase *adr)
Registers the object pointed to by adr.
Definition objstrm.h:727
P_id_type findObject(TStreamableBase *adr)
Returns the type ID for the object pointed to by adr.
Definition objstrm.h:752
void writeSuffix(const TStreamableBase *)
Writes the class name suffix to the stream.
Definition objstrm.h:747
void clear(int=0)
Sets the stream state to the given value (defaults to 0).
Definition objstrm.h:671
#define _OBJ_TYPENAME(obj)
Definition objstrm.h:86
void writeWord(uint32)
Writes the 32-bit word us to the stream.
Definition objstrm.h:740
uint32 getVersion() const
Returns the object version number.
Definition objstrm.h:732
TStreamableBase * find(P_id_type)
Returns a pointer to the object corresponding to Id.
Definition objstrm.h:722
#define _OBJ_FULLTYPENAME(obj)
Definition objstrm.h:78
void init(std::streambuf *)
The init member function initializes the stream and sets state to 0 and bp to sbp.
Definition objstrm.h:698
Reliable platform independent header for common memory and string functions.
#define _W2A(lpw)
Definition memory.h:219
char * strnewdup(const char *s, size_t minAllocSize=0)
Definition memory.cpp:25
#define _A2W(lpw)
Definition memory.h:220
#define _USES_CONVERSION
Definition memory.h:217
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
unsigned ModuleId
Definition streambl.h:52
owl::opstream & operator<<(owl::opstream &os, const TColor &c)
Insert the color value into a persistent output stream.
Definition color.h:498
unsigned char uint8
Definition number.h:32
unsigned long uint32
Definition number.h:34
char tchar
Definition defs.h:77
class _OWLFASTTHIS _RTTI TStreamableBase
Definition streambl.h:56
unsigned short uint16
Definition number.h:33
std::string tstring
Definition defs.h:79
TStreamer *(* BUILDER)(TStreamableBase *)
Definition streambl.h:58
owl::ipstream & operator>>(owl::ipstream &is, TColor &c)
Extract the color value from a persistent input stream.
Definition color.h:489
#define LOCK_TYPES_(s)
Definition objstrm.cpp:64
General definitions used by all ObjectWindows programs.
#define OWL_INI
Definition defs.h:170
ObjectWindows exception class & function definitions.
#define CONST_CAST(targetType, object)
Definition defs.h:273
#define _OWLCFUNC(p)
Definition defs.h:342
Various types of smart pointer templatized classes.
Class definitions for object streaming.
Definition of container classes used and made available by OWL.