_VSOP.H
//--_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