content/media/wmf/WMFByteStream.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial