28#if defined(CHECK_REFCOUNT)
30 uint32 count = si->AddRef();
31 count = si->Release();
34# define RefCountCheck(si)
43class TStorageBuf :
public streambuf {
50 TStorageBuf * open(
IStorage& stg, LPCTSTR name,
int omode);
52 virtual ~TStorageBuf();
54 int is_open() {
return opened; }
57 TStorageBuf * close();
61 return traits_type::eof();
64 virtual int_type overflow(int_type c = traits_type::eof());
65 virtual int_type underflow();
67 virtual streambuf * setbuf(char_type *, streamsize);
69 virtual pos_type seekoff(off_type off, ios_base::seekdir way,
70 ios_base::openmode which = ios_base::in |
72 virtual pos_type seekpos(pos_type sp,
73 ios_base::openmode which =
74 ios_base::in | ios_base::out);
76 return pptr() ? (int)(pptr() - pbase()) : 0;
79 void setb(
char *beg,
char *end,
int = 0){
80 streamsize size_buf = end - beg;
81 buffered_ = beg && size_buf;
82 setbuf(beg, size_buf);
94 return (
int) (ebuf_ - base_);
109class TStorageStreamBase :
virtual public ios {
111 TStorageStreamBase(
IStorage& stg, LPCTSTR name,
int mode);
112 ~TStorageStreamBase() {}
113 void setbuf(
char *,
int);
122class TStorageInStream :
public TStorageStreamBase,
125 TStorageInStream(TStorageDocument& doc, LPCTSTR name,
int mode)
127 TStorageStreamBase(*doc.StorageI,name, mode) {}
128 ~TStorageInStream() {}
134class TStorageOutStream :
public TStorageStreamBase,
137 TStorageOutStream(TStorageDocument& doc, LPCTSTR name,
int mode)
139 TStorageStreamBase(*doc.StorageI,name, mode) {}
140 ~TStorageOutStream() {}
155 return (omode &
ofTemporary) ? STGM_DELETEONRELEASE : 0;
165const int stgRdWrMask = (int)(STGM_READWRITE | STGM_READ | STGM_WRITE);
166const int stgShareMask = (int)(STGM_SHARE_DENY_NONE | STGM_SHARE_DENY_READ |
167 STGM_SHARE_DENY_WRITE| STGM_SHARE_EXCLUSIVE);
168const long stgModeMask = (STGM_TRANSACTED | STGM_PRIORITY | STGM_CONVERT);
182 return (grfMode & STGM_DELETEONRELEASE) ?
ofTemporary : 0;
268 long childMode = (grfMode &
~stgShareMask) | STGM_SHARE_EXCLUSIVE;
271 bool stgcreate =
false;
282 grfMode |= STGM_CREATE;
283 childMode |= STGM_CREATE;
292 hr = parentStg->OpenStorage(
OleStr(name), 0, childMode, 0, 0, &StorageI);
297 hr = parentStg->CreateStorage(
OleStr(name), childMode, 0, 0, &StorageI);
302 hr = ::StgOpenStorage(
OleStr(name), 0, grfMode, 0, 0, &StorageI);
307 hr = ::StgCreateDocfile(
OleStr(name), grfMode, 0, &StorageI);
343 OrgStorageI = StorageI;
354 if (!SUCCEEDED(stg->Stat(&stgInfo, 0)))
362 if (stgInfo.pwcsName)
368 if (stgInfo.pwcsName) {
370 if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &memmgr))) {
371 memmgr->Free(stgInfo.pwcsName);
390 StorageI = OrgStorageI;
407 if (!SUCCEEDED(StorageI->Stat(&stgInfo, STATFLAG_NONAME)))
416 hr = ::StgOpenStorage(
OleStr(
GetDocPath()), 0, stgInfo.grfMode, 0, 0, &newStorage);
418 hr = ::StgCreateDocfile(
OleStr(
GetDocPath()), stgInfo.grfMode, 0, &newStorage);
422 StorageI = newStorage;
449 if (!SUCCEEDED(CreateILockBytesOnHGlobal(hGlobal, (omode &
ofTemporary)!=0, &LockBytes)))
451 if (!SUCCEEDED(StgCreateDocfileOnILockBytes(LockBytes, grfMode, 0, &StorageI))) {
452 LockBytes->Release();
482 if (!SUCCEEDED(CreateILockBytesOnHGlobal(hGlobal, (omode &
ofTemporary)!=0, &LockBytes)))
486 if (!SUCCEEDED(StgOpenStorageOnILockBytes(LockBytes, 0, grfMode, 0, 0, &storageI))) {
487 if (create && !SUCCEEDED(StgCreateDocfileOnILockBytes(LockBytes,
488 grfMode |STGM_CREATE, 0, &storageI))) {
489 LockBytes->Release();
518 GetHGlobalFromILockBytes(LockBytes, handle);
528 if (!StorageI || !CanRelease)
545TStorageDocument::DetachStream(
TStream& strm)
566 if (inStream && !inStream->good()) {
589 if (outStream && !outStream->good()) {
630 HRESULT hr = StorageI->Commit(0);
632 hr = StorageI->Commit(STGC_OVERWRITE);
656static LPCTSTR PropNames[] = {
661 _T(
"IStorage Instance"),
667static int PropFlags[] = {
710 if (
_tcscmp(PropNames[i], name) == 0)
723 const auto formatFileTime = [](
const FILETIME& pft,
void* dest,
int textlen) ->
int
730 *(FILETIME*) dest = pft;
731 return sizeof(FILETIME);
734 FileTimeToSystemTime(&pft, &dt);
735 len = _sntprintf(buf,
COUNTOF(buf),
_T(
"%d/%d/%d %02d:%02d:%02d.%02d"),
736 dt.wMonth, dt.wDay, dt.wYear,
737 dt.wHour, dt.wMinute, dt.wSecond, dt.wMilliseconds / 10);
740 memcpy(dest, buf, textlen *
sizeof(
tchar));
741 *((LPTSTR) dest + textlen) =
_T(
'\0');
756 StorageI->Stat(&stgInfo, STATFLAG_NONAME);
761 return sizeof(
ulong);
768 memcpy(dest, buf, textlen *
sizeof(
tchar));
769 *((LPTSTR)dest + textlen) = 0;
773 return formatFileTime(stgInfo.atime, dest, textlen);
775 return formatFileTime(stgInfo.ctime, dest, textlen);
777 return formatFileTime(stgInfo.mtime, dest, textlen);
797#if OWL_PERSISTENT_STREAMS
813TStorageDocument::Streamer::Write(
opstream& os)
const
827TStorageStreamBase::TStorageStreamBase(
IStorage& stg, LPCTSTR name,
int mode)
835 else if (buf.open(stg, name, mode))
841void TStorageStreamBase::setbuf(
char* newbuf,
int len)
843 if (buf.setbuf(newbuf, len))
846#if defined(BI_COMP_BORLANDC)
847 setstate(ios::failbit);
853void TStorageStreamBase::close()
858#if defined(BI_COMP_BORLANDC)
859 setstate(ios::failbit);
872TStorageBuf::TStorageBuf()
880 char* p =
new char[
B_size];
892TStorageBuf::~TStorageBuf()
904TStorageBuf* TStorageBuf::open(
IStorage& stg, LPCTSTR name,
int omode)
911 if (opened || !omode)
918 bool stgcreate =
false;
919 uint32 how = STGM_SHARE_EXCLUSIVE;
925 how |= STGM_READWRITE;
951 HRESULT hr = stg.OpenStream(
OleStr(name), 0, how, 0, &strm);
958 HRESULT hr = stg.CreateStream(
OleStr(name), how, 0, 0, &strm);
967 LARGE_INTEGER uli = {0,0};
969 && !SUCCEEDED(strm->Seek(uli, STREAM_SEEK_END, (ULARGE_INTEGER*)&last_seek))) {
975 int pb = b ? ((blen() > 8) ? 4 : 1) : 0;
986TStorageBuf* TStorageBuf::attach(
IStream* f)
992 if (f->Stat(&stat, STATFLAG_NONAME) != 0)
995 if (f->CreateStream(STREAMNAME,stat.grfMode & ~STGM_TRANSACTED,0,0,&strm)!)
1000 int rwmode = stat.grfMode & (STGM_READ | STGM_WRITE | STGM_READWRITE);
1001 mode = rwmode != STGM_WRITE ?
ofRead : 0;
1002 if (rwmode != STGM_READ)
1011 int pb = b ? ((blen() > 8) ? 4 : 1) : 0;
1013 setg(b, b+pb, b+pb);
1023TStorageBuf::setbuf(char_type* b, streamsize len)
1025 if (opened && base())
1030 pb = (len > 8) ? 4 : 1;
1039 setg(b, b+pb, b+pb);
1048TStorageBuf::pos_type TStorageBuf::seekoff(off_type off,
1049 ios_base::seekdir dir, ios_base::openmode )
1052 int count = out_waiting();
1056 HRESULT hr = strm->Write(pbase(), (
ulong)count, &actual);
1057 if (!SUCCEEDED(hr) || (
int)actual != count)
1060 else if (dir == ios::cur) {
1061 count =
static_cast<int>(in_avail());
1068 char *tptr = gptr();
1069 while (tptr != egptr())
1070 if (*tptr++ ==
_T(
'\n'))
1076 uint32 w = (dir == ios::beg) ? STREAM_SEEK_SET
1077 : ((dir == ios::cur) ? STREAM_SEEK_CUR
1079 int64 i64pos = loff;
1080 if (!SUCCEEDED(strm->Seek(*(LARGE_INTEGER*)&i64pos, w, (ULARGE_INTEGER*)&last_seek)))
1082 if (!unbuffered() && base()) {
1083 int pb = (blen() > 8) ? 4 : 1;
1086 setg(b, b+pb, b+pb);
1088 return (
uint32)last_seek;
1091TStorageBuf::pos_type TStorageBuf::seekpos(pos_type sp,
1092 ios_base::openmode which){
1093 return seekoff(streamoff(sp), ios::beg, which);
1099int TStorageBuf::sync()
1105 int count = out_waiting();
1108 char* srcp = pbase();
1109 char* endp = srcp + count;
1114 for (curp = srcp; curp < endp; curp++) {
1115 if (*curp ==
_T(
'\n')) {
1117 count = (int)(curp - srcp + 1);
1118 HRESULT hr = strm->Write(srcp, (
unsigned long)count, &actual);
1119 if (!SUCCEEDED(hr) || (
int)actual != count)
1121 *(srcp = curp) =
_T(
'\n');
1124 count = (int)(curp - srcp);
1126 HRESULT hr = strm->Write(srcp, (
ulong)count, &actual);
1127 if (!SUCCEEDED(hr) || (
int)actual != count)
1132 int pb = (blen() > 8) ? 4 : 1;
1134 setp(b+pb, b+blen());
1135 setg(b, b+pb, b+pb);
1138 else if (in_avail()) {
1140 if (!SUCCEEDED(strm->Seek(*(LARGE_INTEGER*)&i64, STREAM_SEEK_CUR, (ULARGE_INTEGER*)&last_seek)))
1142 setg(eback(), gptr(), gptr());
1143 setp(gptr(), gptr());
1151TStorageBuf::int_type TStorageBuf::underflow()
1163 if (!unbuffered() && base()) {
1169 int pb = (blen() > 8) ? 4 : 1;
1170 char* begp = base() + pb;
1174 HRESULT hr = strm->Read(begp, blen()-pb, &actual);
1177 count = (unsigned)actual;
1182 char* endp = begp + count;
1187 for (curp = begp; curp < endp; curp++) {
1188 if (*curp ==
_T(
'\r')) {
1190 memcpy(dstp, srcp, (
int)(curp - srcp));
1191 dstp += (int)(curp - srcp);
1199 endp = dstp + (int)(curp - srcp);
1201 memcpy(dstp, srcp, (
int)(curp - srcp));
1203 count = (int)(endp - begp);
1208 setg(base(), begp, begp + count);
1217 HRESULT hr = strm->Read(lahead, 1, &actual);
1218 if (!SUCCEEDED(hr) || actual == 0) {
1226 setg(lahead, lahead, lahead+1);
1239TStorageBuf::int_type TStorageBuf::overflow(int_type c)
1244 if (unbuffered() || !base()) {
1248 if (c ==
_T(
'\n') && (mode &
ofBinary) == 0) {
1258 strm->Write(&c, (
ulong)count, &actual);
1259 if ((
int)actual != count)
1272 int pb = (blen() > 8) ? 4 : 1;
1274 setp(b+pb, b+blen());
1275 setg(b, b+pb, b+pb);
1288TStorageBuf* TStorageBuf::close()
1294 if (out_waiting() && overflow(eof()) == eof())
1302 return ores ? 0 :
this;
#define PRECONDITION(condition)
LPCTSTR PropertyName(int index)
int FindProperty(LPCTSTR name)
int GetProperty(int index, void *dest, int textlen=0)
friend class TStorageInStream
bool Commit(bool force=false)
virtual bool OpenHandle(int omode, HANDLE hGlobal)
Create an IStorage based on a memory handle.
virtual bool SetStorage(IStorage *stg, bool remember=true)
Give an IStorage to document. This typically happens for OLE servers.
bool Open(int omode, LPCTSTR stgId)
Open the compound file with a given path.
virtual bool ReleaseDoc()
Release the IStorage and close the document.
friend class TStorageOutStream
bool IsOpen()
Return 'true' if the storage document object has opened an OLE storage.
bool Revert(bool clear=false)
owl::TInStream * InStream(int omode, LPCTSTR strmId=0)
owl::TOutStream * OutStream(int omode, LPCTSTR strmId=0)
virtual bool GetHandle(HGLOBAL *handle)
Get the global handle from ILockBytes.
virtual bool SetHandle(int omode, HANDLE hGlobal, bool create=false, bool remember=false)
Replace the IStorage with an istorage based on a memory handle.
bool SetProperty(int index, const void *src)
virtual IStorage * GetNewStorage()
Get a new IStorage, typically in a SaveAs situation.
int PropertyFlags(int index)
virtual bool RestoreStorage()
Restore the original root IStorage before the save operation.
bool SetDocPath(LPCTSTR path)
bool CommitTransactedStorage()
An abstract base class, TDocument is the base class for all document objects and serves as an interfa...
virtual int GetProperty(int index, void *dest, int textlen=0)
Retrieves the property identified by the given index.
virtual void DetachStream(TStream &strm)
called from TStream destructor
bool NotifyViews(int eventId, TParam2=0, TView *exclude=nullptr)
Notifies the views of this document, and the views of any child documents, of a change.
virtual bool SetProperty(int index, const void *src)
native type
LPCTSTR GetDocPath() const
Returns the directory path for the document.
virtual LPCTSTR PropertyName(int index)
locale invariant name
virtual bool Close()
close document, does not delete or detach
virtual int PropertyFlags(int index)
pfXxxxx bit array
virtual bool SetDocPath(LPCTSTR path)
Sets the document path for Open and Save operations.
void SetOpenMode(int mode)
Sets the mode and protection flag values for the current document.
void SetDirty(bool dirty=true)
Updates the document's dirty flag using the specified parameter.
bool IsEmbedded() const
Returns true if the document is embedded in an OLE 2 container.
virtual bool Commit(bool force=false)
save current data, force write
int GetOpenMode() const
Gets the mode and protection flag values for the current document.
void SetEmbedded(bool embed)
Marks the document as being embedded in an OLE 2 container.
TDocument * GetParentDoc()
Returns either the parent document of the current document or 0 if there is no parent document.
virtual bool Revert(bool clear=false)
abort changes, no reload if true
Derived from TStream and istream, TInStream is a base class used to define input streams for document...
TInStream(TDocument &doc, LPCTSTR name, int mode)
Constructs a TInStream object.
Derived from TStream and ostream, TOutStream is a base class used to create output storage streams fo...
TOutStream(TDocument &doc, LPCTSTR name, int mode)
Constructs a TOutStream object.
An abstract base class, TStream provides links between streams and documents, views,...
ipstream, a specialized input stream derivative of pstream, is the base class for reading (extracting...
Base class for writing streamable objects.
Definition of classes TDocument, TView, TWindowView, TStream, TInStream, TOutStream.
void ReadBaseObject(Base *base, ipstream &in)
void WriteBaseObject(Base *base, opstream &out)
const uint pfGetText
property accessible as text format
const uint vnDocClosed
document has just been closed
const uint vnDocOpened
document has just been opened
const uint pfGetBinary
property accessible as native non-text format
@ ofRead
ios::in, open for reading
@ ofTruncate
ios::trunc, truncate file if already exists
@ shRead
DENY_WRITE functionality.
@ ofParent
use open mode of parent storage
@ ofNoReplace
ios::noreplace, open fails if file already exists
@ ofPriority
STGM_PRIORITY, temporary efficient peeking.
@ ofPreserve
STGM_CONVERT, backup old data of same name.
@ ofAppend
ios::app, append mode: all additions at eof
@ ofWrite
ios::out, open for writing
@ ofAtEnd
ios::ate, seek to eof upon original open
@ ofTransacted
STGM_TRANSACTED, supports commit and revert.
@ shReadWrite
DENY_NONE functionality.
@ shNone
EXCLUSIVE functionality.
@ ofNoCreate
ios::nocreate, open fails if file doesn't exist
@ shCompat
for non-compliant applications, avoid if possible
@ ofTemporary
STGM_DELETEONRELEASE, delete when destructed.
Include for OC, gets common headers when precompiled headers are enabled.
Object Component Framework (COM encapsulation).
long IosToStgMode(int omode)
int StgToIosShareMode(long grfMode)
int StgToIosMode(long grfMode)
int StgToIosTempMode(long grfMode)
int StgToIosOpenMode(long grfMode)
long IosToStgTempMode(int omode)
const TCHAR DefaultStreamName[]
long IosToStgShareMode(int omode)
long IosToStgOpenMode(int omode)
IMPLEMENT_STREAMABLE1(TApplication, TModule)
interface _ICLASS IStorage
#define RefCountCheck(si)
interface _ICLASS IStream
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
Definition of class TString, a flexible universal string envelope class.