summaryrefslogtreecommitdiffstats
path: root/dom/streams/ReadableStream.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/streams/ReadableStream.h282
1 files changed, 282 insertions, 0 deletions
diff --git a/dom/streams/ReadableStream.h b/dom/streams/ReadableStream.h
new file mode 100644
index 0000000000..95e29d9fc0
--- /dev/null
+++ b/dom/streams/ReadableStream.h
@@ -0,0 +1,282 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_ReadableStream_h
+#define mozilla_dom_ReadableStream_h
+
+#include "js/TypeDecls.h"
+#include "js/Value.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/IterableIterator.h"
+#include "mozilla/dom/QueuingStrategyBinding.h"
+#include "mozilla/dom/ReadableStreamController.h"
+#include "mozilla/dom/ReadableStreamDefaultController.h"
+#include "mozilla/dom/UnderlyingSourceCallbackHelpers.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
+
+namespace mozilla::dom {
+
+class Promise;
+class ReadableStreamDefaultReader;
+class ReadableStreamGenericReader;
+struct ReadableStreamGetReaderOptions;
+struct ReadableStreamIteratorOptions;
+struct ReadIntoRequest;
+class WritableStream;
+struct ReadableWritablePair;
+struct StreamPipeOptions;
+
+using ReadableStreamReader =
+ ReadableStreamDefaultReaderOrReadableStreamBYOBReader;
+using OwningReadableStreamReader =
+ OwningReadableStreamDefaultReaderOrReadableStreamBYOBReader;
+class NativeUnderlyingSource;
+class BodyStreamHolder;
+class UniqueMessagePortId;
+class MessagePort;
+
+class ReadableStream : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ReadableStream)
+
+ friend class WritableStream;
+
+ protected:
+ virtual ~ReadableStream();
+
+ nsCOMPtr<nsIGlobalObject> mGlobal;
+
+ // If one extends ReadableStream with another cycle collectable class,
+ // calling HoldJSObjects and DropJSObjects should happen using 'this' of
+ // that extending class. And in that case Explicit should be passed to the
+ // constructor of ReadableStream so that it doesn't make those calls.
+ // See also https://bugzilla.mozilla.org/show_bug.cgi?id=1801214.
+ enum class HoldDropJSObjectsCaller { Implicit, Explicit };
+
+ explicit ReadableStream(const GlobalObject& aGlobal,
+ HoldDropJSObjectsCaller aHoldDropCaller);
+ explicit ReadableStream(nsIGlobalObject* aGlobal,
+ HoldDropJSObjectsCaller aHoldDropCaller);
+
+ public:
+ // Abstract algorithms
+ MOZ_CAN_RUN_SCRIPT static already_AddRefed<ReadableStream> CreateAbstract(
+ JSContext* aCx, nsIGlobalObject* aGlobal,
+ UnderlyingSourceAlgorithmsBase* aAlgorithms,
+ mozilla::Maybe<double> aHighWaterMark,
+ QueuingStrategySize* aSizeAlgorithm, ErrorResult& aRv);
+ MOZ_CAN_RUN_SCRIPT static already_AddRefed<ReadableStream> CreateByteAbstract(
+ JSContext* aCx, nsIGlobalObject* aGlobal,
+ UnderlyingSourceAlgorithmsBase* aAlgorithms, ErrorResult& aRv);
+
+ // Slot Getter/Setters:
+ MOZ_KNOWN_LIVE ReadableStreamController* Controller() { return mController; }
+ ReadableStreamDefaultController* DefaultController() {
+ MOZ_ASSERT(mController && mController->IsDefault());
+ return mController->AsDefault();
+ }
+ void SetController(ReadableStreamController& aController) {
+ MOZ_ASSERT(!mController);
+ mController = &aController;
+ }
+
+ bool Disturbed() const { return mDisturbed; }
+ void SetDisturbed(bool aDisturbed) { mDisturbed = aDisturbed; }
+
+ ReadableStreamGenericReader* GetReader() { return mReader; }
+ void SetReader(ReadableStreamGenericReader* aReader);
+
+ ReadableStreamDefaultReader* GetDefaultReader();
+
+ enum class ReaderState { Readable, Closed, Errored };
+
+ ReaderState State() const { return mState; }
+ void SetState(const ReaderState& aState) { mState = aState; }
+
+ JS::Value StoredError() const { return mStoredError; }
+ void SetStoredError(JS::Handle<JS::Value> aStoredError) {
+ mStoredError = aStoredError;
+ }
+
+ nsIInputStream* MaybeGetInputStreamIfUnread() {
+ MOZ_ASSERT(!Disturbed());
+ if (UnderlyingSourceAlgorithmsBase* algorithms =
+ Controller()->GetAlgorithms()) {
+ return algorithms->MaybeGetInputStreamIfUnread();
+ }
+ return nullptr;
+ }
+
+ // [Transferable]
+ // https://html.spec.whatwg.org/multipage/structured-data.html#transfer-steps
+ MOZ_CAN_RUN_SCRIPT bool Transfer(JSContext* aCx,
+ UniqueMessagePortId& aPortId);
+ MOZ_CAN_RUN_SCRIPT static already_AddRefed<ReadableStream>
+ ReceiveTransferImpl(JSContext* aCx, nsIGlobalObject* aGlobal,
+ MessagePort& aPort);
+ // https://html.spec.whatwg.org/multipage/structured-data.html#transfer-receiving-steps
+ MOZ_CAN_RUN_SCRIPT static bool ReceiveTransfer(
+ JSContext* aCx, nsIGlobalObject* aGlobal, MessagePort& aPort,
+ JS::MutableHandle<JSObject*> aReturnObject);
+
+ // Public functions to implement other specs
+ // https://streams.spec.whatwg.org/#other-specs-rs
+
+ // https://streams.spec.whatwg.org/#readablestream-set-up
+ static already_AddRefed<ReadableStream> CreateNative(
+ JSContext* aCx, nsIGlobalObject* aGlobal,
+ UnderlyingSourceAlgorithmsWrapper& aAlgorithms,
+ mozilla::Maybe<double> aHighWaterMark,
+ QueuingStrategySize* aSizeAlgorithm, ErrorResult& aRv);
+
+ // https://streams.spec.whatwg.org/#readablestream-set-up-with-byte-reading-support
+
+ protected:
+ // Sets up the ReadableStream with byte reading support. Intended for
+ // subclasses.
+ void SetUpByteNative(JSContext* aCx,
+ UnderlyingSourceAlgorithmsWrapper& aAlgorithms,
+ mozilla::Maybe<double> aHighWaterMark, ErrorResult& aRv);
+
+ public:
+ // Creates and sets up a ReadableStream with byte reading support. Use
+ // SetUpByteNative for this purpose in subclasses.
+ static already_AddRefed<ReadableStream> CreateByteNative(
+ JSContext* aCx, nsIGlobalObject* aGlobal,
+ UnderlyingSourceAlgorithmsWrapper& aAlgorithms,
+ mozilla::Maybe<double> aHighWaterMark, ErrorResult& aRv);
+
+ // The following algorithms must only be used on ReadableStream instances
+ // initialized via the above set up or set up with byte reading support
+ // algorithms (not, e.g., on web-developer-created instances):
+
+ // https://streams.spec.whatwg.org/#readablestream-close
+ MOZ_CAN_RUN_SCRIPT void CloseNative(JSContext* aCx, ErrorResult& aRv);
+
+ // https://streams.spec.whatwg.org/#readablestream-error
+ void ErrorNative(JSContext* aCx, JS::Handle<JS::Value> aError,
+ ErrorResult& aRv);
+
+ // https://streams.spec.whatwg.org/#readablestream-enqueue
+ MOZ_CAN_RUN_SCRIPT void EnqueueNative(JSContext* aCx,
+ JS::Handle<JS::Value> aChunk,
+ ErrorResult& aRv);
+
+ // The following algorithms can be used on arbitrary ReadableStream instances,
+ // including ones that are created by web developers. They can all fail in
+ // various operation-specific ways, and these failures should be handled by
+ // the calling specification.
+
+ // https://streams.spec.whatwg.org/#readablestream-get-a-reader
+ already_AddRefed<mozilla::dom::ReadableStreamDefaultReader> GetReader(
+ ErrorResult& aRv);
+
+ // IDL layer functions
+
+ nsIGlobalObject* GetParentObject() const { return mGlobal; }
+
+ JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+
+ // IDL methods
+
+ // TODO: Use MOZ_CAN_RUN_SCRIPT when IDL constructors can use it (bug 1749042)
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY static already_AddRefed<ReadableStream>
+ Constructor(const GlobalObject& aGlobal,
+ const Optional<JS::Handle<JSObject*>>& aUnderlyingSource,
+ const QueuingStrategy& aStrategy, ErrorResult& aRv);
+
+ bool Locked() const;
+
+ MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> Cancel(
+ JSContext* cx, JS::Handle<JS::Value> aReason, ErrorResult& aRv);
+
+ void GetReader(const ReadableStreamGetReaderOptions& aOptions,
+ OwningReadableStreamReader& resultReader, ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT already_AddRefed<ReadableStream> PipeThrough(
+ const ReadableWritablePair& aTransform, const StreamPipeOptions& aOptions,
+ ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> PipeTo(
+ WritableStream& aDestination, const StreamPipeOptions& aOptions,
+ ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT void Tee(JSContext* aCx,
+ nsTArray<RefPtr<ReadableStream>>& aResult,
+ ErrorResult& aRv);
+
+ struct IteratorData {
+ void Traverse(nsCycleCollectionTraversalCallback& cb);
+ void Unlink();
+
+ RefPtr<ReadableStreamDefaultReader> mReader;
+ bool mPreventCancel;
+ };
+
+ using Iterator = AsyncIterableIterator<ReadableStream>;
+
+ void InitAsyncIteratorData(IteratorData& aData, Iterator::IteratorType aType,
+ const ReadableStreamIteratorOptions& aOptions,
+ ErrorResult& aRv);
+ MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> GetNextIterationResult(
+ Iterator* aIterator, ErrorResult& aRv);
+ MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> IteratorReturn(
+ JSContext* aCx, Iterator* aIterator, JS::Handle<JS::Value> aValue,
+ ErrorResult& aRv);
+
+ // Internal Slots:
+ private:
+ RefPtr<ReadableStreamController> mController;
+ bool mDisturbed = false;
+ RefPtr<ReadableStreamGenericReader> mReader;
+ ReaderState mState = ReaderState::Readable;
+ JS::Heap<JS::Value> mStoredError;
+
+ HoldDropJSObjectsCaller mHoldDropCaller;
+};
+
+namespace streams_abstract {
+
+bool IsReadableStreamLocked(ReadableStream* aStream);
+
+double ReadableStreamGetNumReadRequests(ReadableStream* aStream);
+
+void ReadableStreamError(JSContext* aCx, ReadableStream* aStream,
+ JS::Handle<JS::Value> aValue, ErrorResult& aRv);
+
+MOZ_CAN_RUN_SCRIPT void ReadableStreamClose(JSContext* aCx,
+ ReadableStream* aStream,
+ ErrorResult& aRv);
+
+MOZ_CAN_RUN_SCRIPT void ReadableStreamFulfillReadRequest(
+ JSContext* aCx, ReadableStream* aStream, JS::Handle<JS::Value> aChunk,
+ bool done, ErrorResult& aRv);
+
+void ReadableStreamAddReadRequest(ReadableStream* aStream,
+ ReadRequest* aReadRequest);
+void ReadableStreamAddReadIntoRequest(ReadableStream* aStream,
+ ReadIntoRequest* aReadIntoRequest);
+
+MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> ReadableStreamCancel(
+ JSContext* aCx, ReadableStream* aStream, JS::Handle<JS::Value> aError,
+ ErrorResult& aRv);
+
+already_AddRefed<ReadableStreamDefaultReader>
+AcquireReadableStreamDefaultReader(ReadableStream* aStream, ErrorResult& aRv);
+
+bool ReadableStreamHasBYOBReader(ReadableStream* aStream);
+bool ReadableStreamHasDefaultReader(ReadableStream* aStream);
+
+} // namespace streams_abstract
+
+} // namespace mozilla::dom
+
+#endif // mozilla_dom_ReadableStream_h