The streams which come with the OWL Document / View architecture are standard c++ iostreams. In other words, if you write a short integer of 500 to a stream obtained via
TDocument::OutStream, the characters 0x35 0x30 0x30 ('5','0','0') will be written to the stream followed by a separator, instead of just 0x01 0xf4. Often you may prefer the more efficient representation. This is an even more significant consideration when streaming floating point numbers. Borland persistent streams also allow you to stream and recreate complete objects with versioning and resolution of pointers etc. For more information on Borland persistent streams please refer to the documentation.There are two ways to use the Borland persistent streaming mechanisms with the OWL Document / View architecture.
// ----- --------- // class TInStream - base class for input streams // #if defined(USE_DOCUMENT_STREAMS) class _OWLCLASS_RTL TInStream : public TStream, public ipstream { public: TInStream(TDocument& doc, const char far* name, int mode) : TStream(doc, name, mode), ipstream() {} #else class _OWLCLASS_RTL TInStream : public TStream, public istream { public: TInStream(TDocument& doc, const char far* name, int mode) : TStream(doc, name, mode), istream() {} #endif }; // // class TOutStream - base class for output streams // ----- --------- // #if defined(USE_DOCUMENT_STREAMS) class _OWLCLASS_RTL TOutStream : public TStream, public opstream { public: TOutStream(TDocument& doc, const char far* name, int mode) : TStream(doc, name, mode), opstream() {} #else class _OWLCLASS_RTL TOutStream : public TStream, public ostream { public: TOutStream(TDocument& doc, const char far* name, int mode) : TStream(doc, name, mode), ostream() {} #endif };
Change the declaration of
TStorageStreamBase in stgdoc.cpp// // class TStorageStreamBase // ----- ------------------ // #if defined(USE_DOCUMENT_STREAMS) class _OWLCLASS_RTL TStorageStreamBase : virtual public pstream { #else class _OWLCLASS_RTL TStorageStreamBase : virtual public ios { #endif
Change the initiation in the constructor of
TstorageStreamBase in stgdoc.cppTStorageStreamBase::TStorageStreamBase(IStorage& stg, const char far* name, int mode) : buf() { #if defined(USE_DOCUMENT_STREAMS) pstream::init(&buf); #else ios::init(&buf); #endif
The following code is standard streaming code modified from the OWL tutorial.
To use persistent streams, use the following code with USE_DOCUMENT_STREAMS defined. The lines highlighted in blue add persistent streaming.
bool TYourDocument::Commit(bool force) { TOleDocument::Commit(force); // use TPointer to make sure stream is deleted on exit from this function #if defined(USE_DOCUMENT_STREAMS) TPointer<TOutStream> outstrm = OutStream(ofWrite | ofBinary); TPointer<opstream> os = new opstream(outstrm->rdbuf()); #elseif TPointer<TOutStream> os = OutStream(ofWrite); #endif if (!os) return false; // Write a test integer int Test = 500; *os << Test; #if defined(USE_DOCUMENT_STREAMS) os.flush(); #endif // // Commit the storage if it was opened in transacted mode TOleDocument::CommitTransactedStorage(); SetDirty(false); return true; } bool TYourDocument::Open(int mode, const char far* path) { TOleDocument::Open(mode, path); // normally path should be null #if defined(USE_DOCUMENT_STREAMS) TPointer<TInStream> isstrm = InStream(ofRead | ofBinary); TPointer<ipstream> is = new ipstream(isstrm->rdbuf()); #elseif TPointer<TInStream> is = InStream(ofRead); #endif if (!is) return false; // Read a test integer int Test; *is >> Test; }