1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsStreamLoader.h"
7 #include "nsIInputStream.h"
8 #include "nsIChannel.h"
10 #include "mozilla/ProfilerLabels.h"
17 nsStreamLoader::nsStreamLoader() : mData() {}
20 nsStreamLoader::Init(nsIStreamLoaderObserver
* aStreamObserver
,
21 nsIRequestObserver
* aRequestObserver
) {
22 NS_ENSURE_ARG_POINTER(aStreamObserver
);
23 mObserver
= aStreamObserver
;
24 mRequestObserver
= aRequestObserver
;
28 nsresult
nsStreamLoader::Create(REFNSIID aIID
, void** aResult
) {
29 RefPtr
<nsStreamLoader
> it
= new nsStreamLoader();
30 return it
->QueryInterface(aIID
, aResult
);
33 NS_IMPL_ISUPPORTS(nsStreamLoader
, nsIStreamLoader
, nsIRequestObserver
,
34 nsIStreamListener
, nsIThreadRetargetableStreamListener
)
37 nsStreamLoader::GetNumBytesRead(uint32_t* aNumBytes
) {
38 *aNumBytes
= mBytesRead
;
43 nsStreamLoader::GetRequest(nsIRequest
** aRequest
) {
44 nsCOMPtr
<nsIRequest
> req
= mRequest
;
50 nsStreamLoader::OnStartRequest(nsIRequest
* request
) {
51 nsCOMPtr
<nsIChannel
> chan(do_QueryInterface(request
));
53 int64_t contentLength
= -1;
54 chan
->GetContentLength(&contentLength
);
55 if (contentLength
>= 0) {
56 // On 64bit platforms size of uint64_t coincides with the size of size_t,
57 // so we want to compare with the minimum from size_t and int64_t.
58 if (static_cast<uint64_t>(contentLength
) >
59 std::min(std::numeric_limits
<size_t>::max(),
60 static_cast<size_t>(std::numeric_limits
<int64_t>::max()))) {
61 // Too big to fit into size_t, so let's bail.
62 return NS_ERROR_OUT_OF_MEMORY
;
65 if (!mData
.initCapacity(contentLength
)) {
66 return NS_ERROR_OUT_OF_MEMORY
;
70 if (mRequestObserver
) {
71 mRequestObserver
->OnStartRequest(request
);
77 nsStreamLoader::OnStopRequest(nsIRequest
* request
, nsresult aStatus
) {
78 AUTO_PROFILER_LABEL("nsStreamLoader::OnStopRequest", NETWORK
);
81 // provide nsIStreamLoader::request during call to OnStreamComplete
83 size_t length
= mData
.length();
84 uint8_t* elems
= mData
.extractOrCopyRawBuffer();
86 mObserver
->OnStreamComplete(this, mContext
, aStatus
, length
, elems
);
87 if (rv
!= NS_SUCCESS_ADOPTED_DATA
) {
88 // The observer didn't take ownership of the extracted data buffer, so
89 // put it back into mData.
90 mData
.replaceRawBuffer(elems
, length
);
98 if (mRequestObserver
) {
99 mRequestObserver
->OnStopRequest(request
, aStatus
);
100 mRequestObserver
= nullptr;
106 nsresult
nsStreamLoader::WriteSegmentFun(nsIInputStream
* inStr
, void* closure
,
107 const char* fromSegment
,
108 uint32_t toOffset
, uint32_t count
,
109 uint32_t* writeCount
) {
110 nsStreamLoader
* self
= (nsStreamLoader
*)closure
;
112 if (!self
->mData
.append(fromSegment
, count
)) {
113 self
->mData
.clearAndFree();
114 return NS_ERROR_OUT_OF_MEMORY
;
122 nsStreamLoader::OnDataAvailable(nsIRequest
* request
, nsIInputStream
* inStr
,
123 uint64_t sourceOffset
, uint32_t count
) {
125 nsresult rv
= inStr
->ReadSegments(WriteSegmentFun
, this, count
, &countRead
);
126 NS_ENSURE_SUCCESS(rv
, rv
);
127 mBytesRead
+= countRead
;
131 void nsStreamLoader::ReleaseData() { mData
.clearAndFree(); }
134 nsStreamLoader::CheckListenerChain() { return NS_OK
; }
137 } // namespace mozilla