//------------------------------------------------------------------------------ | |
// File: PStream.cpp | |
// | |
// Desc: DirectShow base classes. | |
// | |
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. | |
//------------------------------------------------------------------------------ | |
#include <streams.h> | |
#include <strsafe.h> | |
#ifdef PERF | |
#include <measure.h> | |
#endif | |
// #include "pstream.h" in streams.h | |
// | |
// Constructor | |
// | |
CPersistStream::CPersistStream(IUnknown *punk, __inout 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, __deref_out 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 | |
(void)StringCchPrintfW(Buff, NUMELMS(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, __out 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) |