pstream.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //------------------------------------------------------------------------------
  2. // File: PStream.cpp
  3. //
  4. // Desc: DirectShow base classes.
  5. //
  6. // Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
  7. //------------------------------------------------------------------------------
  8. #include <streams.h>
  9. #include <strsafe.h>
  10. #ifdef PERF
  11. #include <measure.h>
  12. #endif
  13. // #include "pstream.h" in streams.h
  14. //
  15. // Constructor
  16. //
  17. CPersistStream::CPersistStream(IUnknown *punk, __inout HRESULT *phr)
  18. : mPS_fDirty(FALSE)
  19. {
  20. mPS_dwFileVersion = GetSoftwareVersion();
  21. }
  22. //
  23. // Destructor
  24. //
  25. CPersistStream::~CPersistStream() {
  26. // Nothing to do
  27. }
  28. #if 0
  29. SAMPLE CODE TO COPY - not active at the moment
  30. //
  31. // NonDelegatingQueryInterface
  32. //
  33. // This object supports IPersist & IPersistStream
  34. STDMETHODIMP CPersistStream::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
  35. {
  36. if (riid == IID_IPersist) {
  37. return GetInterface((IPersist *) this, ppv); // ???
  38. }
  39. else if (riid == IID_IPersistStream) {
  40. return GetInterface((IPersistStream *) this, ppv);
  41. }
  42. else {
  43. return CUnknown::NonDelegatingQueryInterface(riid, ppv);
  44. }
  45. }
  46. #endif
  47. //
  48. // WriteToStream
  49. //
  50. // Writes to the stream (default action is to write nothing)
  51. HRESULT CPersistStream::WriteToStream(IStream *pStream)
  52. {
  53. // You can override this to do things like
  54. // hr = pStream->Write(MyStructure, sizeof(MyStructure), NULL);
  55. return NOERROR;
  56. }
  57. HRESULT CPersistStream::ReadFromStream(IStream * pStream)
  58. {
  59. // You can override this to do things like
  60. // hr = pStream->Read(MyStructure, sizeof(MyStructure), NULL);
  61. return NOERROR;
  62. }
  63. //
  64. // Load
  65. //
  66. // Load all the data from the given stream
  67. STDMETHODIMP CPersistStream::Load(LPSTREAM pStm)
  68. {
  69. HRESULT hr;
  70. // Load the version number then the data
  71. mPS_dwFileVersion = ReadInt(pStm, hr);
  72. if (FAILED(hr)) {
  73. return hr;
  74. }
  75. return ReadFromStream(pStm);
  76. } // Load
  77. //
  78. // Save
  79. //
  80. // Save the contents of this Stream.
  81. STDMETHODIMP CPersistStream::Save(LPSTREAM pStm, BOOL fClearDirty)
  82. {
  83. HRESULT hr = WriteInt(pStm, GetSoftwareVersion());
  84. if (FAILED(hr)) {
  85. return hr;
  86. }
  87. hr = WriteToStream(pStm);
  88. if (FAILED(hr)) {
  89. return hr;
  90. }
  91. mPS_fDirty = !fClearDirty;
  92. return hr;
  93. } // Save
  94. // WriteInt
  95. //
  96. // Writes an integer to an IStream as 11 UNICODE characters followed by one space.
  97. // You could use this for shorts or unsigneds or anything (up to 32 bits)
  98. // where the value isn't actually truncated by squeezing it into 32 bits.
  99. // Values such as (unsigned) 0x80000000 would come out as -2147483648
  100. // but would then load as 0x80000000 through ReadInt. Cast as you please.
  101. STDAPI WriteInt(IStream *pIStream, int n)
  102. {
  103. WCHAR Buff[13]; // Allows for trailing null that we don't write
  104. (void)StringCchPrintfW(Buff, NUMELMS(Buff),L"%011d ",n);
  105. return pIStream->Write(&(Buff[0]), 12*sizeof(WCHAR), NULL);
  106. } // WriteInt
  107. // ReadInt
  108. //
  109. // Reads an integer from an IStream.
  110. // Read as 4 bytes. You could use this for shorts or unsigneds or anything
  111. // where the value isn't actually truncated by squeezing it into 32 bits
  112. // Striped down subset of what sscanf can do (without dragging in the C runtime)
  113. STDAPI_(int) ReadInt(IStream *pIStream, __out HRESULT &hr)
  114. {
  115. int Sign = 1;
  116. unsigned int n = 0; // result wil be n*Sign
  117. WCHAR wch;
  118. hr = pIStream->Read( &wch, sizeof(wch), NULL);
  119. if (FAILED(hr)) {
  120. return 0;
  121. }
  122. if (wch==L'-'){
  123. Sign = -1;
  124. hr = pIStream->Read( &wch, sizeof(wch), NULL);
  125. if (FAILED(hr)) {
  126. return 0;
  127. }
  128. }
  129. for( ; ; ) {
  130. if (wch>=L'0' && wch<=L'9') {
  131. n = 10*n+(int)(wch-L'0');
  132. } else if ( wch == L' '
  133. || wch == L'\t'
  134. || wch == L'\r'
  135. || wch == L'\n'
  136. || wch == L'\0'
  137. ) {
  138. break;
  139. } else {
  140. hr = VFW_E_INVALID_FILE_FORMAT;
  141. return 0;
  142. }
  143. hr = pIStream->Read( &wch, sizeof(wch), NULL);
  144. if (FAILED(hr)) {
  145. return 0;
  146. }
  147. }
  148. if (n==0x80000000 && Sign==-1) {
  149. // This is the negative number that has no positive version!
  150. return (int)n;
  151. }
  152. else return (int)n * Sign;
  153. } // ReadInt
  154. // The microsoft C/C++ compile generates level 4 warnings to the effect that
  155. // a particular inline function (from some base class) was not needed.
  156. // This line gets rid of hundreds of such unwanted messages and makes
  157. // -W4 compilation feasible:
  158. #pragma warning(disable: 4514)