|
|
//------------------------------------------------------------------------------
// File: PStream.cpp
//
// Desc: DirectShow base classes.
//
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#ifdef PERF
#include <measure.h>
#endif
// #include "pstream.h" in streams.h
//
// Constructor
//
CPersistStream::CPersistStream(IUnknown *punk, HRESULT *phr) : mPS_fDirty(FALSE) { mPS_dwFileVersion = GetSoftwareVersion(); }
//
// Destructor
//
CPersistStream::~CPersistStream() { // Nothing to do
}
#if 0
SAMPLE CODE TO COPY - not active at the moment
//
// NonDelegatingQueryInterface
//
// This object supports IPersist & IPersistStream
STDMETHODIMP CPersistStream::NonDelegatingQueryInterface(REFIID riid, void **ppv) { if (riid == IID_IPersist) { return GetInterface((IPersist *) this, ppv); // ???
} else if (riid == IID_IPersistStream) { return GetInterface((IPersistStream *) this, ppv); } else { return CUnknown::NonDelegatingQueryInterface(riid, ppv); } } #endif
//
// WriteToStream
//
// Writes to the stream (default action is to write nothing)
HRESULT CPersistStream::WriteToStream(IStream *pStream) { // You can override this to do things like
// hr = pStream->Write(MyStructure, sizeof(MyStructure), NULL);
return NOERROR; }
HRESULT CPersistStream::ReadFromStream(IStream * pStream) { // You can override this to do things like
// hr = pStream->Read(MyStructure, sizeof(MyStructure), NULL);
return NOERROR; }
//
// Load
//
// Load all the data from the given stream
STDMETHODIMP CPersistStream::Load(LPSTREAM pStm) { HRESULT hr; // Load the version number then the data
mPS_dwFileVersion = ReadInt(pStm, hr); if (FAILED(hr)) { return hr; }
return ReadFromStream(pStm); } // Load
//
// Save
//
// Save the contents of this Stream.
STDMETHODIMP CPersistStream::Save(LPSTREAM pStm, BOOL fClearDirty) {
HRESULT hr = WriteInt(pStm, GetSoftwareVersion()); if (FAILED(hr)) { return hr; }
hr = WriteToStream(pStm); if (FAILED(hr)) { return hr; }
mPS_fDirty = !fClearDirty;
return hr; } // Save
// WriteInt
//
// Writes an integer to an IStream as 11 UNICODE characters followed by one space.
// You could use this for shorts or unsigneds or anything (up to 32 bits)
// where the value isn't actually truncated by squeezing it into 32 bits.
// Values such as (unsigned) 0x80000000 would come out as -2147483648
// but would then load as 0x80000000 through ReadInt. Cast as you please.
STDAPI WriteInt(IStream *pIStream, int n) { WCHAR Buff[13]; // Allows for trailing null that we don't write
wsprintfW(Buff, L"%011d ",n); return pIStream->Write(&(Buff[0]), 12*sizeof(WCHAR), NULL); } // WriteInt
// ReadInt
//
// Reads an integer from an IStream.
// Read as 4 bytes. You could use this for shorts or unsigneds or anything
// where the value isn't actually truncated by squeezing it into 32 bits
// Striped down subset of what sscanf can do (without dragging in the C runtime)
STDAPI_(int) ReadInt(IStream *pIStream, HRESULT &hr) {
int Sign = 1; unsigned int n = 0; // result wil be n*Sign
WCHAR wch;
hr = pIStream->Read( &wch, sizeof(wch), NULL); if (FAILED(hr)) { return 0; }
if (wch==L'-'){ Sign = -1; hr = pIStream->Read( &wch, sizeof(wch), NULL); if (FAILED(hr)) { return 0; } }
for( ; ; ) { if (wch>=L'0' && wch<=L'9') { n = 10*n+(int)(wch-L'0'); } else if ( wch == L' ' || wch == L'\t' || wch == L'\r' || wch == L'\n' || wch == L'\0' ) { break; } else { hr = VFW_E_INVALID_FILE_FORMAT; return 0; }
hr = pIStream->Read( &wch, sizeof(wch), NULL); if (FAILED(hr)) { return 0; } }
if (n==0x80000000 && Sign==-1) { // This is the negative number that has no positive version!
return (int)n; } else return (int)n * Sign; } // ReadInt
// The microsoft C/C++ compile generates level 4 warnings to the effect that
// a particular inline function (from some base class) was not needed.
// This line gets rid of hundreds of such unwanted messages and makes
// -W4 compilation feasible:
#pragma warning(disable: 4514)
|