//--_vsop.h--------------------------------------------------------------------
//
// CEDKVirtualStreamOnProperty class header file.
//
// Copyright Microsoft Corp., 1986-1996. All rights reserved.
//
//-----------------------------------------------------------------------------
#ifndef __VSOP_H
#define __VSOP_H
// maximum number of stream characters to buffer
const ULONGcbMaxBuffered=8192;// 8K data bytes
//--$CEDKVirtualStreamOnProperty---------------------------------------------------------
//
// Class which buffers stream access to a binary or string property.
//
//-----------------------------------------------------------------------------
class CEDKVirtualStreamOnProperty : public IUnknown
{
public:
// The HrOpenVirtualStreamOnProperty() function is CEDKVirtualStreamOnProperty
// friend.
friend HRESULT _HrOpenVirtualStreamOnProperty(
IN LPMAPIPROP pPropObject,// MAPI property object pointer
IN ULONG ulPropTag, // property tag to open virtual stream on
IN ULONG ulFlags,// MAPI property flags
OUT PVIRTUALSTREAMONPROPERTY * ppVirtualStreamOnProperty); // pointer buffered stream
// methods
// Note: Order IS important. The CEDKVirtualStreamOnProperty interface
// must have the same vtable order as the IStream interface.
// IUnknown methods
STDMETHOD(QueryInterface)(
IN REFIID riid, // interface identifier reference
OUT LPVOID * ppvObj); // pointer to object pointer
STDMETHOD_(ULONG, AddRef)();
STDMETHOD_(ULONG, Release)();
// IStream Methods.
//
// Note: Some methods are not currrently suppoerted.
// These methods all return STG_E_INVALIDFUNCTION:
// Seek, Clone, Revert, SetSize, UnlockRegion & LockRegion.
//
STDMETHOD(Read)(
IN LPVOID pv, // output buffer pointer
IN ULONG cb, // maximum # of bytes to read
OUT ULONG * pcb); // # of bytes read
STDMETHOD(Write)(
IN VOID const * pv, // data to write
IN ULONG cb, // # bytes to write
OUT ULONG *pcb); // # bytes written
STDMETHOD(Seek)(
IN LARGE_INTEGER cbOffset, // byte offset
IN DWORD dwOrigin, // origin
OUT ULARGE_INTEGER * pcbPos); // new position
STDMETHOD(SetSize)(
IN ULARGE_INTEGER nSize); // new size
STDMETHOD(CopyTo)(
IN LPSTREAM pStrm, // destination stream pointer
IN ULARGE_INTEGER cb, // # bytes to copy
OUT ULARGE_INTEGER * pcbRead, // # bytes read
OUT ULARGE_INTEGER * pcbWritten);// # bytes written
STDMETHOD(Commit)(
IN DWORD dwFlags); // flags
STDMETHOD(Revert)();
STDMETHOD(LockRegion)(
IN ULARGE_INTEGER cbOffset, // offset
IN ULARGE_INTEGER cbLength, // length
IN DWORD dwFlags); // flags
STDMETHOD(UnlockRegion)(
IN ULARGE_INTEGER cbOffset, // offset
IN ULARGE_INTEGER cbLength, // length
IN DWORD dwFlags); // flags
STDMETHOD(Stat)(
OUT STATSTG * pStatStg, // stream statistic pointer
IN DWORD dwFlags); // flags
STDMETHOD(Clone)(
OUT LPSTREAM * ppStrm); // pointer to new stream
protected:
// constructor
CEDKVirtualStreamOnProperty();
// destructor
~CEDKVirtualStreamOnProperty();
// Initialize virtual stream on property data
HRESULT HrInitialize(
IN LPMAPIPROP pPropObject,// MAPI property object pointer
IN ULONG ulPropTag, // property tag to open virtual stream on
IN ULONG ulFlags);// MAPI property flags
private:
// Utility functions
// Sets mode in the storage statistics structure
inline VOID SetMode(
IN ULONG ulMode)// stream mode
{
m_StatStg.grfMode = ulMode;
}
// returns TRUE if property opened for writing
inline BOOL fIsWriteProperty()
{
return ( ((m_ulFlags & MAPI_MODIFY) == MAPI_MODIFY) );
}
// returns TRUE if property to be created
inline BOOL fIsNewProperty()
{
return ( ((m_ulFlags & MAPI_CREATE) == MAPI_CREATE) );
}
// returns TRUE if property not opened for writing
inline BOOL fIsReadProperty()
{
return ( ((m_ulFlags & MAPI_MODIFY) == 0) &&
((m_ulFlags & MAPI_CREATE) == 0) );
}
// calculates current size of stream.
HRESULT HrComputeCurrentSize(
IN ULARGE_INTEGER * pcbSize);
// Initializes newly created data buffer to a particular size
inline VOID InitBufferSize(
IN ULONG cbSize)// new buffer size
{
ASSERT_READ_PTR(m_rgbBuffer, cbSize, "Bad m_rgbBuffer");
m_cbBuffer = cbSize;// new buffer size
m_pbBuffer = m_rgbBuffer;// current data pointer
m_fDataInitialized = TRUE;// have read data
// If buffer is a write buffer,
// then zero fill write buffer, including
// the extra space left for null-terminating
// exactly 8K long strings. (Read
// buffers will already be filled with data read.)
if ( fIsWriteProperty() == TRUE )
{
ASSERTERROR(cbSize == cbMaxBuffered, "Bad cbSize");
ZeroMemory(
m_rgbBuffer,
cbSize + sizeof(CHAR));
}
}
// Retrieves number of unread bytes in local data buffer
inline ULONG GetBytesUnread()
{
return (m_cbBuffer - (m_pbBuffer - m_rgbBuffer));
}
// Retrieves number of unwritten bytes in local data buffer
inline ULONG GetBytesUnwritten()
{
return (m_cbBuffer - (m_pbBuffer - m_rgbBuffer));
}
inline ULONG GetBytesWritten()
// Retrieves number of bytes written to local data buffer
{
return (m_pbBuffer - m_rgbBuffer);
}
// Increments number of bytes read in local data buffer
inline VOID IncrementBytesRead(
IN ULONG cbRead)// number of bytes read
{
m_pbBuffer += cbRead;
}
// Increments number of bytes written to local data buffer
inline VOID IncrementBytesWritten(
IN ULONG cbWritten)// number of bytes written
{
m_pbBuffer += cbWritten;
}
// Increments size of underlying stream
inline VOID IncrementStreamSize(
IN LARGE_INTEGER cbAdd)// number of bytes to add to stream size
{
DWORDLONGcbCurrent=0;// current size
DWORDLONGcbIncrement=0;// amount ot add
// Determine current stream size
cbCurrent = MAKEDWORDLONG(m_StatStg.cbSize.LowPart,
m_StatStg.cbSize.HighPart);
// Determine amount to increase stream size by.
cbIncrement = MAKEDWORDLONG(cbAdd.LowPart,cbAdd.HighPart);
// Increment current stream size
cbCurrent += cbIncrement;
// Set size in storage statistics structure
m_StatStg.cbSize.LowPart = LOWDWORD(cbCurrent);
m_StatStg.cbSize.HighPart = HIDWORD(cbCurrent);;
}
// Retrieves value of data initialized flag
inline BOOL fDataInitialized()
{
return m_fDataInitialized;
}
// Opens/Creates an underlying property stream for reading or writing.
HRESULT HrOpenUnderlyingStream();
// Flushes the data in the write buffer to the underlying stream.
HRESULT HrFlushWriteBuffer(
IN BOOL fCleanWriteBuffer);// TRUE if should zero out write buffer also
// data members
LPMAPIPROPm_pPropObject;// MAPI property object pointer
ULONGm_ulFlags;// MAPI property flags
ULONGm_ulPropTag;// MAPI property tag (must be string or binary)
// underlying stream structures (if there is an underlying stream)
LPSTREAMm_pStream;// unbuffered stream pointer (if any)
STATSTG m_StatStg; // stream statistics
// buffered read or write data (exclusive OR)
BYTE *m_rgbBuffer;
BYTE *m_pbBuffer;// pointer into the data buffer
ULONGm_cbBuffer;// current size of data buffer
BOOLm_fDataInitialized;// TRUE if data buffer has been initialized
ULONG m_refs; // reference count
};
#endif