/* -*- 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 ReadableStreamGenericReader; 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) protected: virtual ~ReadableStream(); nsCOMPtr mGlobal; public: explicit ReadableStream(const GlobalObject& aGlobal); explicit ReadableStream(nsIGlobalObject* aGlobal); enum class ReaderState { Readable, Closed, Errored }; // Slot Getter/Setters: public: 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(); ReaderState State() const { return mState; } void SetState(const ReaderState& aState) { mState = aState; } JS::Value StoredError() const { return mStoredError; } void SetStoredError(JS::Handle aStoredError) { mStoredError = aStoredError; } BodyStreamHolder* GetBodyStreamHolder() { if (UnderlyingSourceAlgorithmsBase* algorithms = Controller()->GetAlgorithms()) { return algorithms->GetBodyStreamHolder(); } return nullptr; } // [Transferable] // https://html.spec.whatwg.org/multipage/structured-data.html#transfer-steps MOZ_CAN_RUN_SCRIPT bool Transfer(JSContext* aCx, UniqueMessagePortId& aPortId); // https://html.spec.whatwg.org/multipage/structured-data.html#transfer-receiving-steps static MOZ_CAN_RUN_SCRIPT bool ReceiveTransfer( JSContext* aCx, nsIGlobalObject* aGlobal, MessagePort& aPort, JS::MutableHandle aReturnObject); // Public functions to implement other specs // https://streams.spec.whatwg.org/#other-specs-rs-create // 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): MOZ_CAN_RUN_SCRIPT void CloseNative(JSContext* aCx, ErrorResult& aRv); MOZ_CAN_RUN_SCRIPT void EnqueueNative(JSContext* aCx, JS::Handle aChunk, ErrorResult& aRv); // IDL layer functions nsIGlobalObject* GetParentObject() const { return mGlobal; } JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; MOZ_CAN_RUN_SCRIPT static already_AddRefed Create( JSContext* aCx, nsIGlobalObject* aGlobal, BodyStreamHolder* aUnderlyingSource, ErrorResult& aRv); // IDL Methods // TODO: Use MOZ_CAN_RUN_SCRIPT when IDL constructors can use it (bug 1749042) MOZ_CAN_RUN_SCRIPT_BOUNDARY static already_AddRefed Constructor(const GlobalObject& aGlobal, const Optional>& aUnderlyingSource, const QueuingStrategy& aStrategy, ErrorResult& aRv); bool Locked() const; MOZ_CAN_RUN_SCRIPT already_AddRefed Cancel( JSContext* cx, JS::Handle aReason, ErrorResult& aRv); void GetReader(const ReadableStreamGetReaderOptions& aOptions, OwningReadableStreamReader& resultReader, ErrorResult& aRv); MOZ_CAN_RUN_SCRIPT already_AddRefed PipeThrough( const ReadableWritablePair& aTransform, const StreamPipeOptions& aOptions, ErrorResult& aRv); MOZ_CAN_RUN_SCRIPT already_AddRefed PipeTo( WritableStream& aDestinaton, const StreamPipeOptions& aOptions, ErrorResult& aRv); MOZ_CAN_RUN_SCRIPT void Tee(JSContext* aCx, nsTArray>& aResult, ErrorResult& aRv); struct IteratorData { void Traverse(nsCycleCollectionTraversalCallback& cb); void Unlink(); RefPtr mReader; bool mPreventCancel; }; using Iterator = AsyncIterableIterator; void InitAsyncIteratorData(IteratorData& aData, Iterator::IteratorType aType, const ReadableStreamIteratorOptions& aOptions, ErrorResult& aRv); MOZ_CAN_RUN_SCRIPT already_AddRefed GetNextIterationResult( Iterator* aIterator, ErrorResult& aRv); MOZ_CAN_RUN_SCRIPT already_AddRefed IteratorReturn( JSContext* aCx, Iterator* aIterator, JS::Handle aValue, ErrorResult& aRv); // Internal Slots: private: RefPtr mController; bool mDisturbed = false; RefPtr mReader; ReaderState mState = ReaderState::Readable; JS::Heap mStoredError; }; bool IsReadableStreamLocked(ReadableStream* aStream); double ReadableStreamGetNumReadRequests(ReadableStream* aStream); void ReadableStreamError(JSContext* aCx, ReadableStream* aStream, JS::Handle 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 aChunk, bool done, ErrorResult& aRv); void ReadableStreamAddReadRequest(ReadableStream* aStream, ReadRequest* aReadRequest); void ReadableStreamAddReadIntoRequest(ReadableStream* aStream, ReadIntoRequest* aReadIntoRequest); MOZ_CAN_RUN_SCRIPT already_AddRefed ReadableStreamCancel( JSContext* aCx, ReadableStream* aStream, JS::Handle aError, ErrorResult& aRv); already_AddRefed AcquireReadableStreamDefaultReader(ReadableStream* aStream, ErrorResult& aRv); MOZ_CAN_RUN_SCRIPT already_AddRefed CreateReadableStream( JSContext* aCx, nsIGlobalObject* aGlobal, UnderlyingSourceAlgorithmsBase* aAlgorithms, mozilla::Maybe aHighWaterMark, QueuingStrategySize* aSizeAlgorithm, ErrorResult& aRv); bool ReadableStreamHasBYOBReader(ReadableStream* aStream); bool ReadableStreamHasDefaultReader(ReadableStream* aStream); MOZ_CAN_RUN_SCRIPT already_AddRefed CreateReadableByteStream( JSContext* aCx, nsIGlobalObject* aGlobal, UnderlyingSourceAlgorithmsBase* aAlgorithms, ErrorResult& aRv); } // namespace mozilla::dom #endif // mozilla_dom_ReadableStream_h