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_ReadableStream_h
8 #define mozilla_dom_ReadableStream_h
10 #include "js/TypeDecls.h"
12 #include "mozilla/Attributes.h"
13 #include "mozilla/ErrorResult.h"
14 #include "mozilla/dom/BindingDeclarations.h"
15 #include "mozilla/dom/IterableIterator.h"
16 #include "mozilla/dom/QueuingStrategyBinding.h"
17 #include "mozilla/dom/ReadableStreamController.h"
18 #include "mozilla/dom/ReadableStreamDefaultController.h"
19 #include "mozilla/dom/UnderlyingSourceCallbackHelpers.h"
20 #include "nsCycleCollectionParticipant.h"
21 #include "nsWrapperCache.h"
23 namespace mozilla::dom
{
26 class ReadableStreamBYOBRequest
;
27 class ReadableStreamDefaultReader
;
28 class ReadableStreamGenericReader
;
29 struct ReadableStreamGetReaderOptions
;
30 struct ReadableStreamIteratorOptions
;
31 struct ReadIntoRequest
;
33 struct ReadableWritablePair
;
34 struct StreamPipeOptions
;
36 using ReadableStreamReader
=
37 ReadableStreamDefaultReaderOrReadableStreamBYOBReader
;
38 using OwningReadableStreamReader
=
39 OwningReadableStreamDefaultReaderOrReadableStreamBYOBReader
;
40 class NativeUnderlyingSource
;
41 class BodyStreamHolder
;
42 class UniqueMessagePortId
;
45 class ReadableStream
: public nsISupports
, public nsWrapperCache
{
47 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
48 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ReadableStream
)
50 friend class WritableStream
;
53 virtual ~ReadableStream();
55 nsCOMPtr
<nsIGlobalObject
> mGlobal
;
57 // If one extends ReadableStream with another cycle collectable class,
58 // calling HoldJSObjects and DropJSObjects should happen using 'this' of
59 // that extending class. And in that case Explicit should be passed to the
60 // constructor of ReadableStream so that it doesn't make those calls.
61 // See also https://bugzilla.mozilla.org/show_bug.cgi?id=1801214.
62 enum class HoldDropJSObjectsCaller
{ Implicit
, Explicit
};
64 explicit ReadableStream(const GlobalObject
& aGlobal
,
65 HoldDropJSObjectsCaller aHoldDropCaller
);
66 explicit ReadableStream(nsIGlobalObject
* aGlobal
,
67 HoldDropJSObjectsCaller aHoldDropCaller
);
70 // Abstract algorithms
71 MOZ_CAN_RUN_SCRIPT
static already_AddRefed
<ReadableStream
> CreateAbstract(
72 JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
73 UnderlyingSourceAlgorithmsBase
* aAlgorithms
,
74 mozilla::Maybe
<double> aHighWaterMark
,
75 QueuingStrategySize
* aSizeAlgorithm
, ErrorResult
& aRv
);
76 MOZ_CAN_RUN_SCRIPT
static already_AddRefed
<ReadableStream
> CreateByteAbstract(
77 JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
78 UnderlyingSourceAlgorithmsBase
* aAlgorithms
, ErrorResult
& aRv
);
80 // Slot Getter/Setters:
81 MOZ_KNOWN_LIVE ReadableStreamController
* Controller() { return mController
; }
82 ReadableStreamDefaultController
* DefaultController() {
83 MOZ_ASSERT(mController
&& mController
->IsDefault());
84 return mController
->AsDefault();
86 void SetController(ReadableStreamController
& aController
) {
87 MOZ_ASSERT(!mController
);
88 mController
= &aController
;
91 bool Disturbed() const { return mDisturbed
; }
92 void SetDisturbed(bool aDisturbed
) { mDisturbed
= aDisturbed
; }
94 ReadableStreamGenericReader
* GetReader() { return mReader
; }
95 void SetReader(ReadableStreamGenericReader
* aReader
);
97 ReadableStreamDefaultReader
* GetDefaultReader();
99 enum class ReaderState
{ Readable
, Closed
, Errored
};
101 ReaderState
State() const { return mState
; }
102 void SetState(const ReaderState
& aState
) { mState
= aState
; }
104 JS::Value
StoredError() const { return mStoredError
; }
105 void SetStoredError(JS::Handle
<JS::Value
> aStoredError
) {
106 mStoredError
= aStoredError
;
109 nsIInputStream
* MaybeGetInputStreamIfUnread() {
110 MOZ_ASSERT(!Disturbed());
111 if (UnderlyingSourceAlgorithmsBase
* algorithms
=
112 Controller()->GetAlgorithms()) {
113 return algorithms
->MaybeGetInputStreamIfUnread();
119 // https://html.spec.whatwg.org/multipage/structured-data.html#transfer-steps
120 MOZ_CAN_RUN_SCRIPT
bool Transfer(JSContext
* aCx
,
121 UniqueMessagePortId
& aPortId
);
122 MOZ_CAN_RUN_SCRIPT
static already_AddRefed
<ReadableStream
>
123 ReceiveTransferImpl(JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
125 // https://html.spec.whatwg.org/multipage/structured-data.html#transfer-receiving-steps
126 MOZ_CAN_RUN_SCRIPT
static bool ReceiveTransfer(
127 JSContext
* aCx
, nsIGlobalObject
* aGlobal
, MessagePort
& aPort
,
128 JS::MutableHandle
<JSObject
*> aReturnObject
);
130 // Public functions to implement other specs
131 // https://streams.spec.whatwg.org/#other-specs-rs
133 // https://streams.spec.whatwg.org/#readablestream-set-up
134 static already_AddRefed
<ReadableStream
> CreateNative(
135 JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
136 UnderlyingSourceAlgorithmsWrapper
& aAlgorithms
,
137 mozilla::Maybe
<double> aHighWaterMark
,
138 QueuingStrategySize
* aSizeAlgorithm
, ErrorResult
& aRv
);
140 // https://streams.spec.whatwg.org/#readablestream-set-up-with-byte-reading-support
143 // Sets up the ReadableStream with byte reading support. Intended for
145 void SetUpByteNative(JSContext
* aCx
,
146 UnderlyingSourceAlgorithmsWrapper
& aAlgorithms
,
147 mozilla::Maybe
<double> aHighWaterMark
, ErrorResult
& aRv
);
150 // Creates and sets up a ReadableStream with byte reading support. Use
151 // SetUpByteNative for this purpose in subclasses.
152 static already_AddRefed
<ReadableStream
> CreateByteNative(
153 JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
154 UnderlyingSourceAlgorithmsWrapper
& aAlgorithms
,
155 mozilla::Maybe
<double> aHighWaterMark
, ErrorResult
& aRv
);
157 // The following algorithms must only be used on ReadableStream instances
158 // initialized via the above set up or set up with byte reading support
159 // algorithms (not, e.g., on web-developer-created instances):
161 // https://streams.spec.whatwg.org/#readablestream-close
162 MOZ_CAN_RUN_SCRIPT
void CloseNative(JSContext
* aCx
, ErrorResult
& aRv
);
164 // https://streams.spec.whatwg.org/#readablestream-error
165 void ErrorNative(JSContext
* aCx
, JS::Handle
<JS::Value
> aError
,
168 // https://streams.spec.whatwg.org/#readablestream-enqueue
169 MOZ_CAN_RUN_SCRIPT
void EnqueueNative(JSContext
* aCx
,
170 JS::Handle
<JS::Value
> aChunk
,
173 // https://streams.spec.whatwg.org/#readablestream-current-byob-request-view
174 void GetCurrentBYOBRequestView(JSContext
* aCx
,
175 JS::MutableHandle
<JSObject
*> aView
,
178 // The following algorithms can be used on arbitrary ReadableStream instances,
179 // including ones that are created by web developers. They can all fail in
180 // various operation-specific ways, and these failures should be handled by
181 // the calling specification.
183 // https://streams.spec.whatwg.org/#readablestream-get-a-reader
184 already_AddRefed
<mozilla::dom::ReadableStreamDefaultReader
> GetReader(
187 // IDL layer functions
189 nsIGlobalObject
* GetParentObject() const { return mGlobal
; }
191 JSObject
* WrapObject(JSContext
* aCx
,
192 JS::Handle
<JSObject
*> aGivenProto
) override
;
196 // TODO: Use MOZ_CAN_RUN_SCRIPT when IDL constructors can use it (bug 1749042)
197 MOZ_CAN_RUN_SCRIPT_BOUNDARY
static already_AddRefed
<ReadableStream
>
198 Constructor(const GlobalObject
& aGlobal
,
199 const Optional
<JS::Handle
<JSObject
*>>& aUnderlyingSource
,
200 const QueuingStrategy
& aStrategy
, ErrorResult
& aRv
);
202 MOZ_CAN_RUN_SCRIPT
static already_AddRefed
<ReadableStream
> From(
203 const GlobalObject
& aGlobal
, JS::Handle
<JS::Value
> asyncIterable
,
208 MOZ_CAN_RUN_SCRIPT already_AddRefed
<Promise
> Cancel(
209 JSContext
* cx
, JS::Handle
<JS::Value
> aReason
, ErrorResult
& aRv
);
211 void GetReader(const ReadableStreamGetReaderOptions
& aOptions
,
212 OwningReadableStreamReader
& resultReader
, ErrorResult
& aRv
);
214 MOZ_CAN_RUN_SCRIPT already_AddRefed
<ReadableStream
> PipeThrough(
215 const ReadableWritablePair
& aTransform
, const StreamPipeOptions
& aOptions
,
218 MOZ_CAN_RUN_SCRIPT already_AddRefed
<Promise
> PipeTo(
219 WritableStream
& aDestination
, const StreamPipeOptions
& aOptions
,
222 MOZ_CAN_RUN_SCRIPT
void Tee(JSContext
* aCx
,
223 nsTArray
<RefPtr
<ReadableStream
>>& aResult
,
226 struct IteratorData
{
227 void Traverse(nsCycleCollectionTraversalCallback
& cb
);
230 RefPtr
<ReadableStreamDefaultReader
> mReader
;
234 using Iterator
= AsyncIterableIterator
<ReadableStream
>;
236 void InitAsyncIteratorData(IteratorData
& aData
, Iterator::IteratorType aType
,
237 const ReadableStreamIteratorOptions
& aOptions
,
239 MOZ_CAN_RUN_SCRIPT already_AddRefed
<Promise
> GetNextIterationResult(
240 Iterator
* aIterator
, ErrorResult
& aRv
);
241 MOZ_CAN_RUN_SCRIPT already_AddRefed
<Promise
> IteratorReturn(
242 JSContext
* aCx
, Iterator
* aIterator
, JS::Handle
<JS::Value
> aValue
,
247 RefPtr
<ReadableStreamController
> mController
;
248 bool mDisturbed
= false;
249 RefPtr
<ReadableStreamGenericReader
> mReader
;
250 ReaderState mState
= ReaderState::Readable
;
251 JS::Heap
<JS::Value
> mStoredError
;
253 HoldDropJSObjectsCaller mHoldDropCaller
;
256 namespace streams_abstract
{
258 bool IsReadableStreamLocked(ReadableStream
* aStream
);
260 double ReadableStreamGetNumReadRequests(ReadableStream
* aStream
);
262 void ReadableStreamError(JSContext
* aCx
, ReadableStream
* aStream
,
263 JS::Handle
<JS::Value
> aValue
, ErrorResult
& aRv
);
265 MOZ_CAN_RUN_SCRIPT
void ReadableStreamClose(JSContext
* aCx
,
266 ReadableStream
* aStream
,
269 MOZ_CAN_RUN_SCRIPT
void ReadableStreamFulfillReadRequest(
270 JSContext
* aCx
, ReadableStream
* aStream
, JS::Handle
<JS::Value
> aChunk
,
271 bool done
, ErrorResult
& aRv
);
273 void ReadableStreamAddReadRequest(ReadableStream
* aStream
,
274 ReadRequest
* aReadRequest
);
275 void ReadableStreamAddReadIntoRequest(ReadableStream
* aStream
,
276 ReadIntoRequest
* aReadIntoRequest
);
278 MOZ_CAN_RUN_SCRIPT already_AddRefed
<Promise
> ReadableStreamCancel(
279 JSContext
* aCx
, ReadableStream
* aStream
, JS::Handle
<JS::Value
> aError
,
282 already_AddRefed
<ReadableStreamDefaultReader
>
283 AcquireReadableStreamDefaultReader(ReadableStream
* aStream
, ErrorResult
& aRv
);
285 bool ReadableStreamHasBYOBReader(ReadableStream
* aStream
);
286 bool ReadableStreamHasDefaultReader(ReadableStream
* aStream
);
288 } // namespace streams_abstract
290 } // namespace mozilla::dom
292 #endif // mozilla_dom_ReadableStream_h