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)
 |