content/media/wmf/WMFByteStream.cpp

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "WMF.h"
     9 #include <unknwn.h>
    10 #include <ole2.h>
    12 #include "WMFByteStream.h"
    13 #include "WMFSourceReaderCallback.h"
    14 #include "WMFUtils.h"
    15 #include "MediaResource.h"
    16 #include "nsISeekableStream.h"
    17 #include "mozilla/RefPtr.h"
    18 #include "nsIThreadPool.h"
    19 #include "nsXPCOMCIDInternal.h"
    20 #include "nsComponentManagerUtils.h"
    21 #include "mozilla/DebugOnly.h"
    22 #include "SharedThreadPool.h"
    23 #include <algorithm>
    24 #include <cassert>
    26 namespace mozilla {
    28 #ifdef PR_LOGGING
    29 PRLogModuleInfo* gWMFByteStreamLog = nullptr;
    30 #define WMF_BS_LOG(...) PR_LOG(gWMFByteStreamLog, PR_LOG_DEBUG, (__VA_ARGS__))
    31 #else
    32 #define WMF_BS_LOG(...)
    33 #endif
    35 WMFByteStream::WMFByteStream(MediaResource* aResource,
    36                              WMFSourceReaderCallback* aSourceReaderCallback)
    37   : mSourceReaderCallback(aSourceReaderCallback),
    38     mResource(aResource),
    39     mReentrantMonitor("WMFByteStream.Data"),
    40     mOffset(0),
    41     mIsShutdown(false)
    42 {
    43   NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
    44   NS_ASSERTION(mSourceReaderCallback, "Must have a source reader callback.");
    46 #ifdef PR_LOGGING
    47   if (!gWMFByteStreamLog) {
    48     gWMFByteStreamLog = PR_NewLogModule("WMFByteStream");
    49   }
    50 #endif
    51   WMF_BS_LOG("[%p] WMFByteStream CTOR", this);
    52   MOZ_COUNT_CTOR(WMFByteStream);
    53 }
    55 WMFByteStream::~WMFByteStream()
    56 {
    57   MOZ_COUNT_DTOR(WMFByteStream);
    58   WMF_BS_LOG("[%p] WMFByteStream DTOR", this);
    59 }
    61 nsresult
    62 WMFByteStream::Init()
    63 {
    64   NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
    66   mThreadPool = SharedThreadPool::Get(NS_LITERAL_CSTRING("WMFByteStream IO"), 4);
    67   NS_ENSURE_TRUE(mThreadPool, NS_ERROR_FAILURE);
    69   NS_ConvertUTF8toUTF16 contentTypeUTF16(mResource->GetContentType());
    70   if (!contentTypeUTF16.IsEmpty()) {
    71     HRESULT hr = wmf::MFCreateAttributes(byRef(mAttributes), 1);
    72     NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
    74     hr = mAttributes->SetString(MF_BYTESTREAM_CONTENT_TYPE,
    75                                 contentTypeUTF16.get());
    76     NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
    78     WMF_BS_LOG("[%p] WMFByteStream has Content-Type=%s", this, mResource->GetContentType().get());
    79   }
    80   return NS_OK;
    81 }
    83 nsresult
    84 WMFByteStream::Shutdown()
    85 {
    86   {
    87     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
    88     mIsShutdown = true;
    89   }
    90   mSourceReaderCallback->Cancel();
    91   return NS_OK;
    92 }
    94 // IUnknown Methods
    95 STDMETHODIMP
    96 WMFByteStream::QueryInterface(REFIID aIId, void **aInterface)
    97 {
    98   WMF_BS_LOG("[%p] WMFByteStream::QueryInterface %s", this, GetGUIDName(aIId).get());
   100   if (aIId == IID_IMFByteStream) {
   101     return DoGetInterface(static_cast<IMFByteStream*>(this), aInterface);
   102   }
   103   if (aIId == IID_IUnknown) {
   104     return DoGetInterface(static_cast<IMFByteStream*>(this), aInterface);
   105   }
   106   if (aIId == IID_IMFAttributes) {
   107     return DoGetInterface(static_cast<IMFAttributes*>(this), aInterface);
   108   }
   110   *aInterface = nullptr;
   111   return E_NOINTERFACE;
   112 }
   114 NS_IMPL_ADDREF(WMFByteStream)
   115 NS_IMPL_RELEASE(WMFByteStream)
   118 // Stores data regarding an async read opreation.
   119 class ReadRequest MOZ_FINAL : public IUnknown {
   120 public:
   121   ReadRequest(int64_t aOffset, BYTE* aBuffer, ULONG aLength)
   122     : mOffset(aOffset),
   123       mBuffer(aBuffer),
   124       mBufferLength(aLength),
   125       mBytesRead(0)
   126   {}
   128   // IUnknown Methods
   129   STDMETHODIMP QueryInterface(REFIID aRIID, LPVOID *aOutObject);
   130   STDMETHODIMP_(ULONG) AddRef();
   131   STDMETHODIMP_(ULONG) Release();
   133   int64_t mOffset;
   134   BYTE* mBuffer;
   135   ULONG mBufferLength;
   136   ULONG mBytesRead;
   138   // IUnknown ref counting.
   139   ThreadSafeAutoRefCnt mRefCnt;
   140   NS_DECL_OWNINGTHREAD
   141 };
   143 NS_IMPL_ADDREF(ReadRequest)
   144 NS_IMPL_RELEASE(ReadRequest)
   146 // IUnknown Methods
   147 STDMETHODIMP
   148 ReadRequest::QueryInterface(REFIID aIId, void **aInterface)
   149 {
   150   WMF_BS_LOG("ReadRequest::QueryInterface %s", GetGUIDName(aIId).get());
   152   if (aIId == IID_IUnknown) {
   153     return DoGetInterface(static_cast<IUnknown*>(this), aInterface);
   154   }
   156   *aInterface = nullptr;
   157   return E_NOINTERFACE;
   158 }
   160 class ProcessReadRequestEvent MOZ_FINAL : public nsRunnable {
   161 public:
   162   ProcessReadRequestEvent(WMFByteStream* aStream,
   163                           IMFAsyncResult* aResult,
   164                           ReadRequest* aRequestState)
   165     : mStream(aStream),
   166       mResult(aResult),
   167       mRequestState(aRequestState) {}
   169   NS_IMETHOD Run() {
   170     mStream->ProcessReadRequest(mResult, mRequestState);
   171     return NS_OK;
   172   }
   173 private:
   174   RefPtr<WMFByteStream> mStream;
   175   RefPtr<IMFAsyncResult> mResult;
   176   RefPtr<ReadRequest> mRequestState;
   177 };
   179 // IMFByteStream Methods
   180 STDMETHODIMP
   181 WMFByteStream::BeginRead(BYTE *aBuffer,
   182                          ULONG aLength,
   183                          IMFAsyncCallback *aCallback,
   184                          IUnknown *aCallerState)
   185 {
   186   NS_ENSURE_TRUE(aBuffer, E_POINTER);
   187   NS_ENSURE_TRUE(aCallback, E_POINTER);
   189   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   190   WMF_BS_LOG("[%p] WMFByteStream::BeginRead() mOffset=%lld tell=%lld length=%lu mIsShutdown=%d",
   191              this, mOffset, mResource->Tell(), aLength, mIsShutdown);
   193   if (mIsShutdown || mOffset < 0) {
   194     return E_INVALIDARG;
   195   }
   197   // Create an object to store our state.
   198   RefPtr<ReadRequest> requestState = new ReadRequest(mOffset, aBuffer, aLength);
   200   // Create an IMFAsyncResult, this is passed back to the caller as a token to
   201   // retrieve the number of bytes read.
   202   RefPtr<IMFAsyncResult> callersResult;
   203   HRESULT hr = wmf::MFCreateAsyncResult(requestState,
   204                                         aCallback,
   205                                         aCallerState,
   206                                         byRef(callersResult));
   207   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
   209   // Dispatch an event to perform the read in the thread pool.
   210   nsCOMPtr<nsIRunnable> r = new ProcessReadRequestEvent(this,
   211                                                         callersResult,
   212                                                         requestState);
   213   nsresult rv = mThreadPool->Dispatch(r, NS_DISPATCH_NORMAL);
   215   if (mResource->GetLength() > -1) {
   216     mOffset = std::min<int64_t>(mOffset + aLength, mResource->GetLength());
   217   } else {
   218     mOffset += aLength;
   219   }
   221   return NS_SUCCEEDED(rv) ? S_OK : E_FAIL;
   222 }
   224 nsresult
   225 WMFByteStream::Read(ReadRequest* aRequestState)
   226 {
   227   // Read in a loop to ensure we fill the buffer, when possible.
   228   ULONG totalBytesRead = 0;
   229   nsresult rv = NS_OK;
   230   while (totalBytesRead < aRequestState->mBufferLength) {
   231     BYTE* buffer = aRequestState->mBuffer + totalBytesRead;
   232     ULONG bytesRead = 0;
   233     ULONG length = aRequestState->mBufferLength - totalBytesRead;
   234     rv = mResource->ReadAt(aRequestState->mOffset + totalBytesRead,
   235                            reinterpret_cast<char*>(buffer),
   236                            length,
   237                            reinterpret_cast<uint32_t*>(&bytesRead));
   238     NS_ENSURE_SUCCESS(rv, rv);
   239     totalBytesRead += bytesRead;
   240     if (bytesRead == 0) {
   241       break;
   242     }
   243   }
   244   aRequestState->mBytesRead = totalBytesRead;
   245   return NS_OK;
   246 }
   248 // Note: This is called on one of the thread pool's threads.
   249 void
   250 WMFByteStream::ProcessReadRequest(IMFAsyncResult* aResult,
   251                                   ReadRequest* aRequestState)
   252 {
   253   if (mResource->GetLength() > -1 &&
   254       aRequestState->mOffset > mResource->GetLength()) {
   255     aResult->SetStatus(S_OK);
   256     wmf::MFInvokeCallback(aResult);
   257     WMF_BS_LOG("[%p] WMFByteStream::ProcessReadRequest() read offset greater than length, soft-failing read", this);
   258     return;
   259   }
   261   nsresult rv = Read(aRequestState);
   262   if (NS_FAILED(rv)) {
   263     Shutdown();
   264     aResult->SetStatus(E_ABORT);
   265   } else {
   266     aResult->SetStatus(S_OK);
   267   }
   269   WMF_BS_LOG("[%p] WMFByteStream::ProcessReadRequest() read %d at %lld finished rv=%x",
   270              this, aRequestState->mBytesRead, aRequestState->mOffset, rv);
   272   // Let caller know read is complete.
   273   DebugOnly<HRESULT> hr = wmf::MFInvokeCallback(aResult);
   274   NS_ASSERTION(SUCCEEDED(hr), "Failed to invoke callback!");
   275 }
   277 STDMETHODIMP
   278 WMFByteStream::BeginWrite(const BYTE *, ULONG ,
   279                           IMFAsyncCallback *,
   280                           IUnknown *)
   281 {
   282   WMF_BS_LOG("[%p] WMFByteStream::BeginWrite()", this);
   283   return E_NOTIMPL;
   284 }
   286 STDMETHODIMP
   287 WMFByteStream::Close()
   288 {
   289   WMF_BS_LOG("[%p] WMFByteStream::Close()", this);
   290   return S_OK;
   291 }
   293 STDMETHODIMP
   294 WMFByteStream::EndRead(IMFAsyncResult* aResult, ULONG *aBytesRead)
   295 {
   296   NS_ENSURE_TRUE(aResult, E_POINTER);
   297   NS_ENSURE_TRUE(aBytesRead, E_POINTER);
   299   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   301   // Extract our state object.
   302   RefPtr<IUnknown> unknown;
   303   HRESULT hr = aResult->GetObject(byRef(unknown));
   304   if (FAILED(hr) || !unknown) {
   305     return E_INVALIDARG;
   306   }
   307   ReadRequest* requestState =
   308     static_cast<ReadRequest*>(unknown.get());
   310   // Report result.
   311   *aBytesRead = requestState->mBytesRead;
   313   WMF_BS_LOG("[%p] WMFByteStream::EndRead() offset=%lld *aBytesRead=%u mOffset=%lld status=0x%x hr=0x%x eof=%d",
   314              this, requestState->mOffset, *aBytesRead, mOffset, aResult->GetStatus(), hr, IsEOS());
   316   return aResult->GetStatus();
   317 }
   319 STDMETHODIMP
   320 WMFByteStream::EndWrite(IMFAsyncResult *, ULONG *)
   321 {
   322   WMF_BS_LOG("[%p] WMFByteStream::EndWrite()", this);
   323   return E_NOTIMPL;
   324 }
   326 STDMETHODIMP
   327 WMFByteStream::Flush()
   328 {
   329   WMF_BS_LOG("[%p] WMFByteStream::Flush()", this);
   330   return S_OK;
   331 }
   333 STDMETHODIMP
   334 WMFByteStream::GetCapabilities(DWORD *aCapabilities)
   335 {
   336   WMF_BS_LOG("[%p] WMFByteStream::GetCapabilities()", this);
   337   NS_ENSURE_TRUE(aCapabilities, E_POINTER);
   338   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   339   bool seekable = mResource->IsTransportSeekable();
   340   bool cached = mResource->IsDataCachedToEndOfResource(0);
   341   *aCapabilities = MFBYTESTREAM_IS_READABLE |
   342                    MFBYTESTREAM_IS_SEEKABLE |
   343                    (!cached ? MFBYTESTREAM_IS_PARTIALLY_DOWNLOADED : 0) |
   344                    (!seekable ? MFBYTESTREAM_HAS_SLOW_SEEK : 0);
   345   return S_OK;
   346 }
   348 STDMETHODIMP
   349 WMFByteStream::GetCurrentPosition(QWORD *aPosition)
   350 {
   351   NS_ENSURE_TRUE(aPosition, E_POINTER);
   352   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   353   // Note: Returning the length of stream as position when read
   354   // cursor is < 0 seems to be the behaviour expected by WMF, but
   355   // also note it doesn't seem to expect that the position is an
   356   // unsigned value since if you seek to > length and read WMF
   357   // expects the read to succeed after reading 0 bytes, but if you
   358   // seek to < 0 and read, the read is expected to fails... So
   359   // go figure...
   360   *aPosition = mOffset < 0 ? mResource->GetLength() : mOffset;
   361   WMF_BS_LOG("[%p] WMFByteStream::GetCurrentPosition() %lld", this, mOffset);
   362   return S_OK;
   363 }
   365 STDMETHODIMP
   366 WMFByteStream::GetLength(QWORD *aLength)
   367 {
   368   NS_ENSURE_TRUE(aLength, E_POINTER);
   369   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   370   *aLength = mResource->GetLength();
   371   WMF_BS_LOG("[%p] WMFByteStream::GetLength() %lld", this, *aLength);
   372   return S_OK;
   373 }
   375 bool
   376 WMFByteStream::IsEOS()
   377 {
   378   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   379   return mResource->GetLength() > -1 &&
   380          (mOffset < 0 ||
   381           mOffset >= mResource->GetLength());
   382 }
   384 STDMETHODIMP
   385 WMFByteStream::IsEndOfStream(BOOL *aEndOfStream)
   386 {
   387   NS_ENSURE_TRUE(aEndOfStream, E_POINTER);
   388   *aEndOfStream = IsEOS();
   389   WMF_BS_LOG("[%p] WMFByteStream::IsEndOfStream() %d", this, *aEndOfStream);
   390   return S_OK;
   391 }
   393 STDMETHODIMP
   394 WMFByteStream::Read(BYTE* aBuffer, ULONG aBufferLength, ULONG* aOutBytesRead)
   395 {
   396   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   397   ReadRequest request(mOffset, aBuffer, aBufferLength);
   398   if (NS_FAILED(Read(&request))) {
   399     WMF_BS_LOG("[%p] WMFByteStream::Read() offset=%lld failed!", this, mOffset);
   400     return E_FAIL;
   401   }
   402   if (aOutBytesRead) {
   403     *aOutBytesRead = request.mBytesRead;
   404   }
   405   WMF_BS_LOG("[%p] WMFByteStream::Read() offset=%lld length=%u bytesRead=%u",
   406              this, mOffset, aBufferLength, request.mBytesRead);
   407   mOffset += request.mBytesRead;
   408   return S_OK;
   409 }
   411 STDMETHODIMP
   412 WMFByteStream::Seek(MFBYTESTREAM_SEEK_ORIGIN aSeekOrigin,
   413                     LONGLONG aSeekOffset,
   414                     DWORD aSeekFlags,
   415                     QWORD *aCurrentPosition)
   416 {
   417   WMF_BS_LOG("[%p] WMFByteStream::Seek(%d, %lld)", this, aSeekOrigin, aSeekOffset);
   419   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   421   int64_t offset = mOffset;
   422   if (aSeekOrigin == msoBegin) {
   423     offset = aSeekOffset;
   424   } else {
   425     offset += aSeekOffset;
   426   }
   427   int64_t length = mResource->GetLength();
   428   if (length > -1) {
   429     mOffset = std::min<int64_t>(offset, length);
   430   } else {
   431     mOffset = offset;
   432   }
   433   if (aCurrentPosition) {
   434     *aCurrentPosition = mOffset;
   435   }
   437   return S_OK;
   438 }
   440 STDMETHODIMP
   441 WMFByteStream::SetCurrentPosition(QWORD aPosition)
   442 {
   443   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   444   WMF_BS_LOG("[%p] WMFByteStream::SetCurrentPosition(%lld)",
   445              this, aPosition);
   447   int64_t length = mResource->GetLength();
   448   if (length > -1) {
   449     mOffset = std::min<int64_t>(aPosition, length);
   450   } else {
   451     mOffset = aPosition;
   452   }
   454   return S_OK;
   455 }
   457 STDMETHODIMP
   458 WMFByteStream::SetLength(QWORD)
   459 {
   460   WMF_BS_LOG("[%p] WMFByteStream::SetLength()", this);
   461   return E_NOTIMPL;
   462 }
   464 STDMETHODIMP
   465 WMFByteStream::Write(const BYTE *, ULONG, ULONG *)
   466 {
   467   WMF_BS_LOG("[%p] WMFByteStream::Write()", this);
   468   return E_NOTIMPL;
   469 }
   471 // IMFAttributes methods
   472 STDMETHODIMP
   473 WMFByteStream::GetItem(REFGUID guidKey, PROPVARIANT* pValue)
   474 {
   475     MOZ_ASSERT(mAttributes);
   476     return mAttributes->GetItem(guidKey, pValue);
   477 }
   479 STDMETHODIMP
   480 WMFByteStream::GetItemType(REFGUID guidKey, MF_ATTRIBUTE_TYPE* pType)
   481 {
   482     assert(mAttributes);
   483     return mAttributes->GetItemType(guidKey, pType);
   484 }
   486 STDMETHODIMP
   487 WMFByteStream::CompareItem(REFGUID guidKey, REFPROPVARIANT Value, BOOL* pbResult)
   488 {
   489     assert(mAttributes);
   490     return mAttributes->CompareItem(guidKey, Value, pbResult);
   491 }
   493 STDMETHODIMP
   494 WMFByteStream::Compare(IMFAttributes* pTheirs,
   495                        MF_ATTRIBUTES_MATCH_TYPE MatchType,
   496                        BOOL* pbResult)
   497 {
   498     assert(mAttributes);
   499     return mAttributes->Compare(pTheirs, MatchType, pbResult);
   500 }
   502 STDMETHODIMP
   503 WMFByteStream::GetUINT32(REFGUID guidKey, UINT32* punValue)
   504 {
   505     assert(mAttributes);
   506     return mAttributes->GetUINT32(guidKey, punValue);
   507 }
   509 STDMETHODIMP
   510 WMFByteStream::GetUINT64(REFGUID guidKey, UINT64* punValue)
   511 {
   512     assert(mAttributes);
   513     return mAttributes->GetUINT64(guidKey, punValue);
   514 }
   516 STDMETHODIMP
   517 WMFByteStream::GetDouble(REFGUID guidKey, double* pfValue)
   518 {
   519     assert(mAttributes);
   520     return mAttributes->GetDouble(guidKey, pfValue);
   521 }
   523 STDMETHODIMP
   524 WMFByteStream::GetGUID(REFGUID guidKey, GUID* pguidValue)
   525 {
   526     assert(mAttributes);
   527     return mAttributes->GetGUID(guidKey, pguidValue);
   528 }
   530 STDMETHODIMP
   531 WMFByteStream::GetStringLength(REFGUID guidKey, UINT32* pcchLength)
   532 {
   533     assert(mAttributes);
   534     return mAttributes->GetStringLength(guidKey, pcchLength);
   535 }
   537 STDMETHODIMP
   538 WMFByteStream::GetString(REFGUID guidKey, LPWSTR pwszValue, UINT32 cchBufSize, UINT32* pcchLength)
   539 {
   540     assert(mAttributes);
   541     return mAttributes->GetString(guidKey, pwszValue, cchBufSize, pcchLength);
   542 }
   544 STDMETHODIMP
   545 WMFByteStream::GetAllocatedString(REFGUID guidKey, LPWSTR* ppwszValue, UINT32* pcchLength)
   546 {
   547     assert(mAttributes);
   548     return mAttributes->GetAllocatedString(guidKey, ppwszValue, pcchLength);
   549 }
   551 STDMETHODIMP
   552 WMFByteStream::GetBlobSize(REFGUID guidKey, UINT32* pcbBlobSize)
   553 {
   554     assert(mAttributes);
   555     return mAttributes->GetBlobSize(guidKey, pcbBlobSize);
   556 }
   558 STDMETHODIMP
   559 WMFByteStream::GetBlob(REFGUID guidKey, UINT8* pBuf, UINT32 cbBufSize, UINT32* pcbBlobSize)
   560 {
   561     assert(mAttributes);
   562     return mAttributes->GetBlob(guidKey, pBuf, cbBufSize, pcbBlobSize);
   563 }
   565 STDMETHODIMP
   566 WMFByteStream::GetAllocatedBlob(REFGUID guidKey, UINT8** ppBuf, UINT32* pcbSize)
   567 {
   568     assert(mAttributes);
   569     return mAttributes->GetAllocatedBlob(guidKey, ppBuf, pcbSize);
   570 }
   572 STDMETHODIMP
   573 WMFByteStream::GetUnknown(REFGUID guidKey, REFIID riid, LPVOID* ppv)
   574 {
   575     assert(mAttributes);
   576     return mAttributes->GetUnknown(guidKey, riid, ppv);
   577 }
   579 STDMETHODIMP
   580 WMFByteStream::SetItem(REFGUID guidKey, REFPROPVARIANT Value)
   581 {
   582     assert(mAttributes);
   583     return mAttributes->SetItem(guidKey, Value);
   584 }
   586 STDMETHODIMP
   587 WMFByteStream::DeleteItem(REFGUID guidKey)
   588 {
   589     assert(mAttributes);
   590     return mAttributes->DeleteItem(guidKey);
   591 }
   593 STDMETHODIMP
   594 WMFByteStream::DeleteAllItems()
   595 {
   596     assert(mAttributes);
   597     return mAttributes->DeleteAllItems();
   598 }
   600 STDMETHODIMP
   601 WMFByteStream::SetUINT32(REFGUID guidKey, UINT32 unValue)
   602 {
   603     assert(mAttributes);
   604     return mAttributes->SetUINT32(guidKey, unValue);
   605 }
   607 STDMETHODIMP
   608 WMFByteStream::SetUINT64(REFGUID guidKey,UINT64 unValue)
   609 {
   610     assert(mAttributes);
   611     return mAttributes->SetUINT64(guidKey, unValue);
   612 }
   614 STDMETHODIMP
   615 WMFByteStream::SetDouble(REFGUID guidKey, double fValue)
   616 {
   617     assert(mAttributes);
   618     return mAttributes->SetDouble(guidKey, fValue);
   619 }
   621 STDMETHODIMP
   622 WMFByteStream::SetGUID(REFGUID guidKey, REFGUID guidValue)
   623 {
   624     assert(mAttributes);
   625     return mAttributes->SetGUID(guidKey, guidValue);
   626 }
   628 STDMETHODIMP
   629 WMFByteStream::SetString(REFGUID guidKey, LPCWSTR wszValue)
   630 {
   631     assert(mAttributes);
   632     return mAttributes->SetString(guidKey, wszValue);
   633 }
   635 STDMETHODIMP
   636 WMFByteStream::SetBlob(REFGUID guidKey, const UINT8* pBuf, UINT32 cbBufSize)
   637 {
   638     assert(mAttributes);
   639     return mAttributes->SetBlob(guidKey, pBuf, cbBufSize);
   640 }
   642 STDMETHODIMP
   643 WMFByteStream::SetUnknown(REFGUID guidKey, IUnknown* pUnknown)
   644 {
   645     assert(mAttributes);
   646     return mAttributes->SetUnknown(guidKey, pUnknown);
   647 }
   649 STDMETHODIMP
   650 WMFByteStream::LockStore()
   651 {
   652     assert(mAttributes);
   653     return mAttributes->LockStore();
   654 }
   656 STDMETHODIMP
   657 WMFByteStream::UnlockStore()
   658 {
   659     assert(mAttributes);
   660     return mAttributes->UnlockStore();
   661 }
   663 STDMETHODIMP
   664 WMFByteStream::GetCount(UINT32* pcItems)
   665 {
   666     assert(mAttributes);
   667     return mAttributes->GetCount(pcItems);
   668 }
   670 STDMETHODIMP
   671 WMFByteStream::GetItemByIndex(UINT32 unIndex, GUID* pguidKey, PROPVARIANT* pValue)
   672 {
   673     assert(mAttributes);
   674     return mAttributes->GetItemByIndex(unIndex, pguidKey, pValue);
   675 }
   677 STDMETHODIMP
   678 WMFByteStream::CopyAllItems(IMFAttributes* pDest)
   679 {
   680     assert(mAttributes);
   681     return mAttributes->CopyAllItems(pDest);
   682 }
   684 } // namespace mozilla

mercurial