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 #ifndef mozilla_dom_ReadableByteStreamController_h
8 #define mozilla_dom_ReadableByteStreamController_h
11 #include "UnderlyingSourceCallbackHelpers.h"
12 #include "js/RootingAPI.h"
13 #include "js/TypeDecls.h"
14 #include "mozilla/Attributes.h"
15 #include "mozilla/ErrorResult.h"
16 #include "mozilla/dom/BindingDeclarations.h"
17 #include "mozilla/dom/QueuingStrategyBinding.h"
18 #include "mozilla/dom/QueueWithSizes.h"
19 #include "mozilla/dom/ReadableStream.h"
20 #include "mozilla/dom/ReadRequest.h"
21 #include "mozilla/dom/ReadableStreamBYOBRequest.h"
22 #include "mozilla/dom/ReadableStreamController.h"
23 #include "mozilla/dom/TypedArray.h"
24 #include "nsCycleCollectionParticipant.h"
25 #include "nsWrapperCache.h"
26 #include "mozilla/dom/Nullable.h"
28 #include "nsISupportsImpl.h"
30 namespace mozilla::dom
{
32 // https://streams.spec.whatwg.org/#pull-into-descriptor-reader-type
33 // Indicates what type of readable stream reader initiated this request,
34 // or None if the initiating reader was released.
35 enum ReaderType
{ Default
, BYOB
, None
};
37 struct PullIntoDescriptor
;
38 struct ReadableByteStreamQueueEntry
;
39 struct ReadIntoRequest
;
41 class ReadableByteStreamController final
: public ReadableStreamController
,
42 public nsWrapperCache
{
44 NS_DECL_ISUPPORTS_INHERITED
45 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
46 ReadableByteStreamController
, ReadableStreamController
)
49 explicit ReadableByteStreamController(nsIGlobalObject
* aGlobal
);
52 ~ReadableByteStreamController() override
;
55 bool IsDefault() override
{ return false; }
56 bool IsByte() override
{ return true; }
57 ReadableStreamDefaultController
* AsDefault() override
{ return nullptr; }
58 ReadableByteStreamController
* AsByte() override
{ return this; }
60 JSObject
* WrapObject(JSContext
* aCx
,
61 JS::Handle
<JSObject
*> aGivenProto
) override
;
63 already_AddRefed
<ReadableStreamBYOBRequest
> GetByobRequest(JSContext
* aCx
,
66 Nullable
<double> GetDesiredSize() const;
68 MOZ_CAN_RUN_SCRIPT
void Close(JSContext
* aCx
, ErrorResult
& aRv
);
70 MOZ_CAN_RUN_SCRIPT
void Enqueue(JSContext
* aCx
, const ArrayBufferView
& aChunk
,
73 void Error(JSContext
* aCx
, JS::Handle
<JS::Value
> aErrorValue
,
76 MOZ_CAN_RUN_SCRIPT already_AddRefed
<Promise
> CancelSteps(
77 JSContext
* aCx
, JS::Handle
<JS::Value
> aReason
, ErrorResult
& aRv
) override
;
78 MOZ_CAN_RUN_SCRIPT
void PullSteps(JSContext
* aCx
, ReadRequest
* aReadRequest
,
79 ErrorResult
& aRv
) override
;
80 void ReleaseSteps() override
;
82 // Internal Slot Accessors
83 Maybe
<uint64_t> AutoAllocateChunkSize() { return mAutoAllocateChunkSize
; }
84 void SetAutoAllocateChunkSize(Maybe
<uint64_t>& aSize
) {
85 mAutoAllocateChunkSize
= aSize
;
88 ReadableStreamBYOBRequest
* GetByobRequest() const { return mByobRequest
; }
89 void SetByobRequest(ReadableStreamBYOBRequest
* aByobRequest
) {
90 mByobRequest
= aByobRequest
;
93 LinkedList
<RefPtr
<PullIntoDescriptor
>>& PendingPullIntos() {
94 return mPendingPullIntos
;
96 void ClearPendingPullIntos();
98 double QueueTotalSize() const { return mQueueTotalSize
; }
99 void SetQueueTotalSize(double aQueueTotalSize
) {
100 mQueueTotalSize
= aQueueTotalSize
;
102 void AddToQueueTotalSize(double aLength
) { mQueueTotalSize
+= aLength
; }
104 double StrategyHWM() const { return mStrategyHWM
; }
105 void SetStrategyHWM(double aStrategyHWM
) { mStrategyHWM
= aStrategyHWM
; }
107 bool CloseRequested() const { return mCloseRequested
; }
108 void SetCloseRequested(bool aCloseRequested
) {
109 mCloseRequested
= aCloseRequested
;
112 LinkedList
<RefPtr
<ReadableByteStreamQueueEntry
>>& Queue() { return mQueue
; }
115 bool Started() const { return mStarted
; }
116 void SetStarted(bool aStarted
) { mStarted
= aStarted
; }
118 bool Pulling() const { return mPulling
; }
119 void SetPulling(bool aPulling
) { mPulling
= aPulling
; }
121 bool PullAgain() const { return mPullAgain
; }
122 void SetPullAgain(bool aPullAgain
) { mPullAgain
= aPullAgain
; }
125 // A boolean flag indicating whether the stream has been closed by its
126 // underlying byte source, but still has chunks in its internal queue that
127 // have not yet been read
128 bool mCloseRequested
= false;
130 // A boolean flag set to true if the stream’s mechanisms requested a call
131 // to the underlying byte source's pull algorithm to pull more data, but the
132 // pull could not yet be done since a previous call is still executing
133 bool mPullAgain
= false;
135 // A boolean flag indicating whether the underlying byte source has finished
137 bool mStarted
= false;
139 // A boolean flag set to true while the underlying byte source's pull
140 // algorithm is executing and the returned promise has not yet fulfilled,
141 // used to prevent reentrant calls
142 bool mPulling
= false;
144 // A positive integer, when the automatic buffer allocation feature is
145 // enabled. In that case, this value specifies the size of buffer to allocate.
146 // It is undefined otherwise.
147 Maybe
<uint64_t> mAutoAllocateChunkSize
;
149 // A ReadableStreamBYOBRequest instance representing the current BYOB pull
150 // request, or null if there are no pending requests
151 RefPtr
<ReadableStreamBYOBRequest
> mByobRequest
;
153 // A list of pull-into descriptors
154 LinkedList
<RefPtr
<PullIntoDescriptor
>> mPendingPullIntos
;
156 // A list of readable byte stream queue entries representing the stream’s
157 // internal queue of chunks
159 // This is theoretically supposed to be a QueueWithSizes, but it is
160 // mostly not actually manipulated or used like QueueWithSizes, so instead we
162 LinkedList
<RefPtr
<ReadableByteStreamQueueEntry
>> mQueue
;
164 // The total size, in bytes, of all the chunks stored in [[queue]] (see § 8.1
166 double mQueueTotalSize
= 0.0;
168 // A number supplied to the constructor as part of the stream’s queuing
169 // strategy, indicating the point at which the stream will apply backpressure
170 // to its underlying byte source
171 double mStrategyHWM
= 0.0;
174 namespace streams_abstract
{
176 MOZ_CAN_RUN_SCRIPT
void ReadableByteStreamControllerRespond(
177 JSContext
* aCx
, ReadableByteStreamController
* aController
,
178 uint64_t aBytesWritten
, ErrorResult
& aRv
);
180 MOZ_CAN_RUN_SCRIPT
void ReadableByteStreamControllerRespondInternal(
181 JSContext
* aCx
, ReadableByteStreamController
* aController
,
182 uint64_t aBytesWritten
, ErrorResult
& aRv
);
184 MOZ_CAN_RUN_SCRIPT
void ReadableByteStreamControllerRespondWithNewView(
185 JSContext
* aCx
, ReadableByteStreamController
* aController
,
186 JS::Handle
<JSObject
*> aView
, ErrorResult
& aRv
);
188 MOZ_CAN_RUN_SCRIPT
void ReadableByteStreamControllerPullInto(
189 JSContext
* aCx
, ReadableByteStreamController
* aController
,
190 JS::Handle
<JSObject
*> aView
, ReadIntoRequest
* aReadIntoRequest
,
193 void ReadableByteStreamControllerError(
194 ReadableByteStreamController
* aController
, JS::Handle
<JS::Value
> aValue
,
197 MOZ_CAN_RUN_SCRIPT
void ReadableByteStreamControllerEnqueue(
198 JSContext
* aCx
, ReadableByteStreamController
* aController
,
199 JS::Handle
<JSObject
*> aChunk
, ErrorResult
& aRv
);
201 already_AddRefed
<ReadableStreamBYOBRequest
>
202 ReadableByteStreamControllerGetBYOBRequest(
203 JSContext
* aCx
, ReadableByteStreamController
* aController
,
206 MOZ_CAN_RUN_SCRIPT
void ReadableByteStreamControllerClose(
207 JSContext
* aCx
, ReadableByteStreamController
* aController
,
210 MOZ_CAN_RUN_SCRIPT
void SetUpReadableByteStreamController(
211 JSContext
* aCx
, ReadableStream
* aStream
,
212 ReadableByteStreamController
* aController
,
213 UnderlyingSourceAlgorithmsBase
* aAlgorithms
, double aHighWaterMark
,
214 Maybe
<uint64_t> aAutoAllocateChunkSize
, ErrorResult
& aRv
);
216 MOZ_CAN_RUN_SCRIPT
void ReadableByteStreamControllerCallPullIfNeeded(
217 JSContext
* aCx
, ReadableByteStreamController
* aController
,
220 MOZ_CAN_RUN_SCRIPT
void SetUpReadableByteStreamControllerFromUnderlyingSource(
221 JSContext
* aCx
, ReadableStream
* aStream
,
222 JS::Handle
<JSObject
*> aUnderlyingSource
,
223 UnderlyingSource
& aUnderlyingSourceDict
, double aHighWaterMark
,
226 } // namespace streams_abstract
228 } // namespace mozilla::dom