OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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:672
static const int NPOS
Definition template.h:682
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:1664
void Remove(int index)
Definition template.h:1692
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.