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