198 lines
4.6 KiB
C++
198 lines
4.6 KiB
C++
|
//------------------------------------------------------------------------------
|
||
|
// 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)
|