1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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/. */
6 
7 #include "MutableBlobStreamListener.h"
8 #include "MutableBlobStorage.h"
9 #include "nsIInputStream.h"
10 #include "nsThreadUtils.h"
11 
12 namespace mozilla {
13 namespace dom {
14 
MutableBlobStreamListener(MutableBlobStorage::MutableBlobStorageType aStorageType,const nsACString & aContentType,MutableBlobStorageCallback * aCallback,nsIEventTarget * aEventTarget)15 MutableBlobStreamListener::MutableBlobStreamListener(
16     MutableBlobStorage::MutableBlobStorageType aStorageType,
17     const nsACString& aContentType, MutableBlobStorageCallback* aCallback,
18     nsIEventTarget* aEventTarget)
19     : mCallback(aCallback),
20       mStorageType(aStorageType),
21       mContentType(aContentType),
22       mEventTarget(aEventTarget) {
23   MOZ_ASSERT(NS_IsMainThread());
24   MOZ_ASSERT(aCallback);
25 
26   if (!mEventTarget) {
27     mEventTarget = GetMainThreadEventTarget();
28   }
29 
30   MOZ_ASSERT(mEventTarget);
31 }
32 
~MutableBlobStreamListener()33 MutableBlobStreamListener::~MutableBlobStreamListener() {
34   MOZ_ASSERT(NS_IsMainThread());
35 }
36 
NS_IMPL_ISUPPORTS(MutableBlobStreamListener,nsIStreamListener,nsIThreadRetargetableStreamListener,nsIRequestObserver)37 NS_IMPL_ISUPPORTS(MutableBlobStreamListener, nsIStreamListener,
38                   nsIThreadRetargetableStreamListener, nsIRequestObserver)
39 
40 NS_IMETHODIMP
41 MutableBlobStreamListener::OnStartRequest(nsIRequest* aRequest) {
42   MOZ_ASSERT(NS_IsMainThread());
43   MOZ_ASSERT(!mStorage);
44   MOZ_ASSERT(mEventTarget);
45 
46   mStorage = new MutableBlobStorage(mStorageType, mEventTarget);
47   return NS_OK;
48 }
49 
50 NS_IMETHODIMP
OnStopRequest(nsIRequest * aRequest,nsresult aStatus)51 MutableBlobStreamListener::OnStopRequest(nsIRequest* aRequest,
52                                          nsresult aStatus) {
53   MOZ_ASSERT(NS_IsMainThread());
54   MOZ_ASSERT(mStorage);
55 
56   // Resetting mStorage to nullptr.
57   RefPtr<MutableBlobStorage> storage;
58   storage.swap(mStorage);
59 
60   // Let's propagate the error simulating a failure of the storage.
61   if (NS_FAILED(aStatus)) {
62     mCallback->BlobStoreCompleted(storage, nullptr, aStatus);
63     return NS_OK;
64   }
65 
66   storage->GetBlobImplWhenReady(mContentType, mCallback);
67   return NS_OK;
68 }
69 
70 NS_IMETHODIMP
OnDataAvailable(nsIRequest * aRequest,nsIInputStream * aStream,uint64_t aSourceOffset,uint32_t aCount)71 MutableBlobStreamListener::OnDataAvailable(nsIRequest* aRequest,
72                                            nsIInputStream* aStream,
73                                            uint64_t aSourceOffset,
74                                            uint32_t aCount) {
75   // This method could be called on any thread.
76   MOZ_ASSERT(mStorage);
77 
78   uint32_t countRead;
79   return aStream->ReadSegments(WriteSegmentFun, this, aCount, &countRead);
80 }
81 
WriteSegmentFun(nsIInputStream * aWriterStream,void * aClosure,const char * aFromSegment,uint32_t aToOffset,uint32_t aCount,uint32_t * aWriteCount)82 nsresult MutableBlobStreamListener::WriteSegmentFun(
83     nsIInputStream* aWriterStream, void* aClosure, const char* aFromSegment,
84     uint32_t aToOffset, uint32_t aCount, uint32_t* aWriteCount) {
85   // This method could be called on any thread.
86 
87   MutableBlobStreamListener* self =
88       static_cast<MutableBlobStreamListener*>(aClosure);
89   MOZ_ASSERT(self->mStorage);
90 
91   nsresult rv = self->mStorage->Append(aFromSegment, aCount);
92   if (NS_WARN_IF(NS_FAILED(rv))) {
93     return rv;
94   }
95 
96   *aWriteCount = aCount;
97   return NS_OK;
98 }
99 
100 NS_IMETHODIMP
CheckListenerChain()101 MutableBlobStreamListener::CheckListenerChain() { return NS_OK; }
102 
103 }  // namespace dom
104 }  // namespace mozilla
105