|
|
//---------------------------------------------------------------------------
// Stream.cpp : Stream implementation
//
// Copyright (c) 1996 Microsoft Corporation, All Rights Reserved
// Developed by Sheridan Software Systems, Inc.
//---------------------------------------------------------------------------
#include "stdafx.h"
#ifndef VD_DONT_IMPLEMENT_ISTREAM
#include "Notifier.h"
#include "RSColumn.h"
#include "RSSource.h"
#include "CursMain.h"
#include "ColUpdat.h"
#include "CursPos.h"
#include "EntryID.h"
#include "fastguid.h"
#include "Stream.h"
#include "resource.h"
SZTHISFILE
static const GUID IID_IStreamEx = {0xf74e27fc, 0x5a3, 0x11d0, {0x91, 0x95, 0x0, 0xa0, 0x24, 0x7b, 0x73, 0x5b}};
//=--------------------------------------------------------------------------=
// CVDStream - Constructor
//
CVDStream::CVDStream() { m_dwRefCount = 1; m_pEntryIDData = NULL; m_pStream = NULL; m_pResourceDLL = NULL;
#ifdef _DEBUG
g_cVDStreamCreated++; #endif
}
//=--------------------------------------------------------------------------=
// ~CVDStream - Destructor
//
CVDStream::~CVDStream() { m_pEntryIDData->Release();
if (m_pStream) m_pStream->Release();
#ifdef _DEBUG
g_cVDStreamDestroyed++; #endif
}
//=--------------------------------------------------------------------------=
// Create - Create stream object
//=--------------------------------------------------------------------------=
// This function creates and initializes a new stream object
//
// Parameters:
// pEntryIDData - [in] backwards pointer to CVDEntryIDData object
// pStream - [in] data stream pointer
// ppVDStream - [out] a pointer in which to return pointer to
// viaduct stream object
// pResourceDLL - [in] a pointer which keeps track of resource DLL
//
// Output:
// HRESULT - S_OK if successful
// E_OUTOFMEMORY not enough memory to create object
//
// Notes:
//
HRESULT CVDStream::Create(CVDEntryIDData * pEntryIDData, IStream * pStream, CVDStream ** ppVDStream, CVDResourceDLL * pResourceDLL) { ASSERT_POINTER(pEntryIDData, CVDEntryIDData) ASSERT_POINTER(pStream, IStream*) ASSERT_POINTER(ppVDStream, CVDStream*)
if (!pStream || !ppVDStream) { VDSetErrorInfo(IDS_ERR_INVALIDARG, IID_IEntryID, pResourceDLL); return E_INVALIDARG; }
*ppVDStream = NULL;
CVDStream * pVDStream = new CVDStream();
if (!pStream) { VDSetErrorInfo(IDS_ERR_OUTOFMEMORY, IID_IEntryID, pResourceDLL); return E_OUTOFMEMORY; }
pEntryIDData->AddRef(); pStream->AddRef();
pVDStream->m_pEntryIDData = pEntryIDData; pVDStream->m_pStream = pStream; pVDStream->m_pResourceDLL = pResourceDLL;
*ppVDStream = pVDStream;
return S_OK; }
//=--------------------------------------------------------------------------=
// IUnknown Methods
//=--------------------------------------------------------------------------=
//=--------------------------------------------------------------------------=
// IUnknown QueryInterface
//
HRESULT CVDStream::QueryInterface(REFIID riid, void **ppvObjOut) { ASSERT_POINTER(ppvObjOut, IUnknown*)
if (!ppvObjOut) return E_INVALIDARG;
*ppvObjOut = NULL;
switch (riid.Data1) { QI_INTERFACE_SUPPORTED(this, IUnknown); QI_INTERFACE_SUPPORTED(this, IStream); QI_INTERFACE_SUPPORTED(this, IStreamEx); }
if (NULL == *ppvObjOut) return E_NOINTERFACE;
AddRef();
return S_OK; }
//=--------------------------------------------------------------------------=
// IUnknown AddRef
//
ULONG CVDStream::AddRef(void) { return ++m_dwRefCount; }
//=--------------------------------------------------------------------------=
// IUnknown Release
//
ULONG CVDStream::Release(void) { if (1 > --m_dwRefCount) { delete this; return 0; }
return m_dwRefCount; }
//=--------------------------------------------------------------------------=
// IStream Methods
//=--------------------------------------------------------------------------=
//=--------------------------------------------------------------------------=
// IStream Read
//
HRESULT CVDStream::Read(void *pv, ULONG cb, ULONG *pcbRead) { return m_pStream->Read(pv, cb, pcbRead); }
//=--------------------------------------------------------------------------=
// IStream Write
//
HRESULT CVDStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten) { HRESULT hr = m_pStream->Write(pv, cb, pcbWritten);
if (SUCCEEDED(hr)) m_pEntryIDData->SetDirty(TRUE);
return hr; }
//=--------------------------------------------------------------------------=
// IStream Seek
//
HRESULT CVDStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { return m_pStream->Seek(dlibMove, dwOrigin, plibNewPosition); }
//=--------------------------------------------------------------------------=
// IStream SetSize
//
HRESULT CVDStream::SetSize(ULARGE_INTEGER libNewSize) { return m_pStream->SetSize(libNewSize); }
//=--------------------------------------------------------------------------=
// IStream CopyTo
//
HRESULT CVDStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten) { IStreamEx * pStreamEx;
HRESULT hr = pstm->QueryInterface(IID_IStreamEx, (void**)&pStreamEx);
if (SUCCEEDED(hr)) { hr = pStreamEx->CopyFrom(m_pStream, cb, pcbWritten, pcbRead); pStreamEx->Release(); } else hr = m_pStream->CopyTo(pstm, cb, pcbRead, pcbWritten);
return hr; }
//=--------------------------------------------------------------------------=
// IStream Commit
//
HRESULT CVDStream::Commit(DWORD grfCommitFlags) { return m_pEntryIDData->Commit(); }
//=--------------------------------------------------------------------------=
// IStream Revert
//
HRESULT CVDStream::Revert(void) { return m_pStream->Revert(); }
//=--------------------------------------------------------------------------=
// IStream LockRegion
//
HRESULT CVDStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { return m_pStream->LockRegion(libOffset, cb, dwLockType); }
//=--------------------------------------------------------------------------=
// IStream UnlockRegion
//
HRESULT CVDStream::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { return m_pStream->UnlockRegion(libOffset, cb, dwLockType); }
//=--------------------------------------------------------------------------=
// IStream Stat
//
HRESULT CVDStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag) { return m_pStream->Stat(pstatstg, grfStatFlag); }
//=--------------------------------------------------------------------------=
// IStream Clone
//
HRESULT CVDStream::Clone(IStream **ppstm) { ASSERT_POINTER(ppstm, IStream*)
// check pointer
if (!ppstm) { VDSetErrorInfo(IDS_ERR_INVALIDARG, IID_IEntryID, m_pResourceDLL); return E_INVALIDARG; }
// init out parameter
*ppstm = NULL;
IStream * pStream;
// clone stream
HRESULT hr = m_pStream->Clone(&pStream);
if (FAILED(hr)) { VDSetErrorInfo(IDS_ERR_CLONEFAILED, IID_IEntryID, m_pResourceDLL); return hr; }
CVDStream * pVDStream;
// create viaduct stream object
hr = CVDStream::Create(m_pEntryIDData, pStream, &pVDStream, m_pResourceDLL);
// release reference on clone
pStream->Release();
if (FAILED(hr)) return hr;
*ppstm = pVDStream;
return S_OK; }
//=--------------------------------------------------------------------------=
// IStreamEx CopyFrom
//
HRESULT CVDStream::CopyFrom(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbWritten, ULARGE_INTEGER *pcbRead) { HRESULT hr = pstm->CopyTo(m_pStream, cb, pcbRead, pcbWritten);
if (SUCCEEDED(hr)) m_pEntryIDData->SetDirty(TRUE);
return hr; }
#endif //VD_DONT_IMPLEMENT_ISTREAM
|