Bug 1852740: add tests for the `fetchpriority` attribute in Link headers. r=necko...
[gecko.git] / dom / streams / ReadableStream.h
blobac2d06caf1b2ee52364efa4cd08ef82942acf1fa
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"
11 #include "js/Value.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 {
25 class Promise;
26 class ReadableStreamBYOBRequest;
27 class ReadableStreamDefaultReader;
28 class ReadableStreamGenericReader;
29 struct ReadableStreamGetReaderOptions;
30 struct ReadableStreamIteratorOptions;
31 struct ReadIntoRequest;
32 class WritableStream;
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;
43 class MessagePort;
45 class ReadableStream : public nsISupports, public nsWrapperCache {
46 public:
47 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
48 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ReadableStream)
50 friend class WritableStream;
52 protected:
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);
69 public:
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();
115 return nullptr;
118 // [Transferable]
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,
124 MessagePort& aPort);
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
142 protected:
143 // Sets up the ReadableStream with byte reading support. Intended for
144 // subclasses.
145 void SetUpByteNative(JSContext* aCx,
146 UnderlyingSourceAlgorithmsWrapper& aAlgorithms,
147 mozilla::Maybe<double> aHighWaterMark, ErrorResult& aRv);
149 public:
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,
166 ErrorResult& aRv);
168 // https://streams.spec.whatwg.org/#readablestream-enqueue
169 MOZ_CAN_RUN_SCRIPT void EnqueueNative(JSContext* aCx,
170 JS::Handle<JS::Value> aChunk,
171 ErrorResult& aRv);
173 // https://streams.spec.whatwg.org/#readablestream-current-byob-request-view
174 void GetCurrentBYOBRequestView(JSContext* aCx,
175 JS::MutableHandle<JSObject*> aView,
176 ErrorResult& aRv);
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(
185 ErrorResult& aRv);
187 // IDL layer functions
189 nsIGlobalObject* GetParentObject() const { return mGlobal; }
191 JSObject* WrapObject(JSContext* aCx,
192 JS::Handle<JSObject*> aGivenProto) override;
194 // IDL methods
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,
204 ErrorResult& aRv);
206 bool Locked() const;
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,
216 ErrorResult& aRv);
218 MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> PipeTo(
219 WritableStream& aDestination, const StreamPipeOptions& aOptions,
220 ErrorResult& aRv);
222 MOZ_CAN_RUN_SCRIPT void Tee(JSContext* aCx,
223 nsTArray<RefPtr<ReadableStream>>& aResult,
224 ErrorResult& aRv);
226 struct IteratorData {
227 void Traverse(nsCycleCollectionTraversalCallback& cb);
228 void Unlink();
230 RefPtr<ReadableStreamDefaultReader> mReader;
231 bool mPreventCancel;
234 using Iterator = AsyncIterableIterator<ReadableStream>;
236 void InitAsyncIteratorData(IteratorData& aData, Iterator::IteratorType aType,
237 const ReadableStreamIteratorOptions& aOptions,
238 ErrorResult& aRv);
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,
243 ErrorResult& aRv);
245 // Internal Slots:
246 private:
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,
267 ErrorResult& aRv);
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,
280 ErrorResult& aRv);
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