tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ReadableStream.h (11464B)


      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/. */
      6 
      7 #ifndef mozilla_dom_ReadableStream_h
      8 #define mozilla_dom_ReadableStream_h
      9 
     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/ReadableStreamControllerBase.h"
     18 #include "mozilla/dom/ReadableStreamDefaultController.h"
     19 #include "mozilla/dom/UnderlyingSourceCallbackHelpers.h"
     20 #include "nsCycleCollectionParticipant.h"
     21 #include "nsWrapperCache.h"
     22 
     23 namespace mozilla::dom {
     24 
     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;
     35 
     36 using ReadableStreamReader =
     37    ReadableStreamDefaultReaderOrReadableStreamBYOBReader;
     38 using OwningReadableStreamReader =
     39    OwningReadableStreamDefaultReaderOrReadableStreamBYOBReader;
     40 class NativeUnderlyingSource;
     41 class BodyStreamHolder;
     42 class UniqueMessagePortId;
     43 class MessagePort;
     44 
     45 class ReadableStream : public nsISupports, public nsWrapperCache {
     46 public:
     47  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     48  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ReadableStream)
     49 
     50  friend class WritableStream;
     51 
     52 protected:
     53  virtual ~ReadableStream();
     54 
     55  nsCOMPtr<nsIGlobalObject> mGlobal;
     56 
     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 };
     63 
     64  explicit ReadableStream(const GlobalObject& aGlobal,
     65                          HoldDropJSObjectsCaller aHoldDropCaller);
     66  explicit ReadableStream(nsIGlobalObject* aGlobal,
     67                          HoldDropJSObjectsCaller aHoldDropCaller);
     68 
     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);
     79 
     80  // Slot Getter/Setters:
     81  MOZ_KNOWN_LIVE ReadableStreamControllerBase* Controller() {
     82    return mController;
     83  }
     84  ReadableStreamDefaultController* DefaultController() {
     85    MOZ_ASSERT(mController && mController->IsDefault());
     86    return mController->AsDefault();
     87  }
     88  void SetController(ReadableStreamControllerBase& aController) {
     89    MOZ_ASSERT(!mController);
     90    mController = &aController;
     91  }
     92 
     93  bool Disturbed() const { return mDisturbed; }
     94  void SetDisturbed(bool aDisturbed) { mDisturbed = aDisturbed; }
     95 
     96  ReadableStreamGenericReader* GetReader() { return mReader; }
     97  void SetReader(ReadableStreamGenericReader* aReader);
     98 
     99  ReadableStreamDefaultReader* GetDefaultReader();
    100 
    101  enum class ReaderState { Readable, Closed, Errored };
    102 
    103  ReaderState State() const { return mState; }
    104  void SetState(const ReaderState& aState) { mState = aState; }
    105 
    106  JS::Value StoredError() const { return mStoredError; }
    107  void SetStoredError(JS::Handle<JS::Value> aStoredError) {
    108    mStoredError = aStoredError;
    109  }
    110 
    111  nsIInputStream* MaybeGetInputStreamIfUnread() {
    112    MOZ_ASSERT(!Disturbed());
    113    if (UnderlyingSourceAlgorithmsBase* algorithms =
    114            Controller()->GetAlgorithms()) {
    115      return algorithms->MaybeGetInputStreamIfUnread();
    116    }
    117    return nullptr;
    118  }
    119 
    120  // [Transferable]
    121  // https://html.spec.whatwg.org/multipage/structured-data.html#transfer-steps
    122  MOZ_CAN_RUN_SCRIPT bool Transfer(JSContext* aCx,
    123                                   UniqueMessagePortId& aPortId);
    124  MOZ_CAN_RUN_SCRIPT static already_AddRefed<ReadableStream>
    125  ReceiveTransferImpl(JSContext* aCx, nsIGlobalObject* aGlobal,
    126                      MessagePort& aPort);
    127  // https://html.spec.whatwg.org/multipage/structured-data.html#transfer-receiving-steps
    128  MOZ_CAN_RUN_SCRIPT static bool ReceiveTransfer(
    129      JSContext* aCx, nsIGlobalObject* aGlobal, MessagePort& aPort,
    130      JS::MutableHandle<JSObject*> aReturnObject);
    131 
    132  // Public functions to implement other specs
    133  // https://streams.spec.whatwg.org/#other-specs-rs
    134 
    135  // https://streams.spec.whatwg.org/#readablestream-set-up
    136  static already_AddRefed<ReadableStream> CreateNative(
    137      JSContext* aCx, nsIGlobalObject* aGlobal,
    138      UnderlyingSourceAlgorithmsWrapper& aAlgorithms,
    139      mozilla::Maybe<double> aHighWaterMark,
    140      QueuingStrategySize* aSizeAlgorithm, ErrorResult& aRv);
    141 
    142  // https://streams.spec.whatwg.org/#readablestream-set-up-with-byte-reading-support
    143 
    144 protected:
    145  // Sets up the ReadableStream with byte reading support. Intended for
    146  // subclasses.
    147  void SetUpByteNative(JSContext* aCx,
    148                       UnderlyingSourceAlgorithmsWrapper& aAlgorithms,
    149                       mozilla::Maybe<double> aHighWaterMark, ErrorResult& aRv);
    150 
    151 public:
    152  // Creates and sets up a ReadableStream with byte reading support. Use
    153  // SetUpByteNative for this purpose in subclasses.
    154  static already_AddRefed<ReadableStream> CreateByteNative(
    155      JSContext* aCx, nsIGlobalObject* aGlobal,
    156      UnderlyingSourceAlgorithmsWrapper& aAlgorithms,
    157      mozilla::Maybe<double> aHighWaterMark, ErrorResult& aRv);
    158 
    159  // The following algorithms must only be used on ReadableStream instances
    160  // initialized via the above set up or set up with byte reading support
    161  // algorithms (not, e.g., on web-developer-created instances):
    162 
    163  // https://streams.spec.whatwg.org/#readablestream-close
    164  MOZ_CAN_RUN_SCRIPT void CloseNative(JSContext* aCx, ErrorResult& aRv);
    165 
    166  // https://streams.spec.whatwg.org/#readablestream-error
    167  void ErrorNative(JSContext* aCx, JS::Handle<JS::Value> aError,
    168                   ErrorResult& aRv);
    169 
    170  // https://streams.spec.whatwg.org/#readablestream-enqueue
    171  MOZ_CAN_RUN_SCRIPT void EnqueueNative(JSContext* aCx,
    172                                        JS::Handle<JS::Value> aChunk,
    173                                        ErrorResult& aRv);
    174 
    175  // https://streams.spec.whatwg.org/#readablestream-current-byob-request-view
    176  void GetCurrentBYOBRequestView(JSContext* aCx,
    177                                 JS::MutableHandle<JSObject*> aView,
    178                                 ErrorResult& aRv);
    179 
    180  // The following algorithms can be used on arbitrary ReadableStream instances,
    181  // including ones that are created by web developers. They can all fail in
    182  // various operation-specific ways, and these failures should be handled by
    183  // the calling specification.
    184 
    185  // https://streams.spec.whatwg.org/#readablestream-get-a-reader
    186  already_AddRefed<mozilla::dom::ReadableStreamDefaultReader> GetReader(
    187      ErrorResult& aRv);
    188 
    189  // IDL layer functions
    190 
    191  nsIGlobalObject* GetParentObject() const { return mGlobal; }
    192 
    193  JSObject* WrapObject(JSContext* aCx,
    194                       JS::Handle<JSObject*> aGivenProto) override;
    195 
    196  // IDL methods
    197 
    198  // TODO: Use MOZ_CAN_RUN_SCRIPT when IDL constructors can use it (bug 1749042)
    199  MOZ_CAN_RUN_SCRIPT_BOUNDARY static already_AddRefed<ReadableStream>
    200  Constructor(const GlobalObject& aGlobal,
    201              const Optional<JS::Handle<JSObject*>>& aUnderlyingSource,
    202              const QueuingStrategy& aStrategy, ErrorResult& aRv);
    203 
    204  MOZ_CAN_RUN_SCRIPT static already_AddRefed<ReadableStream> From(
    205      const GlobalObject& aGlobal, JS::Handle<JS::Value> asyncIterable,
    206      ErrorResult& aRv);
    207 
    208  bool Locked() const;
    209 
    210  MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> Cancel(
    211      JSContext* cx, JS::Handle<JS::Value> aReason, ErrorResult& aRv);
    212 
    213  void GetReader(const ReadableStreamGetReaderOptions& aOptions,
    214                 OwningReadableStreamReader& resultReader, ErrorResult& aRv);
    215 
    216  MOZ_CAN_RUN_SCRIPT already_AddRefed<ReadableStream> PipeThrough(
    217      const ReadableWritablePair& aTransform, const StreamPipeOptions& aOptions,
    218      ErrorResult& aRv);
    219 
    220  MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> PipeTo(
    221      WritableStream& aDestination, const StreamPipeOptions& aOptions,
    222      ErrorResult& aRv);
    223 
    224  MOZ_CAN_RUN_SCRIPT void Tee(JSContext* aCx,
    225                              nsTArray<RefPtr<ReadableStream>>& aResult,
    226                              ErrorResult& aRv);
    227 
    228  struct IteratorData {
    229    void Traverse(nsCycleCollectionTraversalCallback& cb);
    230    void Unlink();
    231 
    232    RefPtr<ReadableStreamDefaultReader> mReader;
    233    bool mPreventCancel;
    234  };
    235 
    236  using Iterator = AsyncIterableIterator<ReadableStream>;
    237 
    238  void InitAsyncIteratorData(IteratorData& aData, Iterator::IteratorType aType,
    239                             const ReadableStreamIteratorOptions& aOptions,
    240                             ErrorResult& aRv);
    241  MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> GetNextIterationResult(
    242      Iterator* aIterator, ErrorResult& aRv);
    243  MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> IteratorReturn(
    244      JSContext* aCx, Iterator* aIterator, JS::Handle<JS::Value> aValue,
    245      ErrorResult& aRv);
    246 
    247  // Internal Slots:
    248 private:
    249  RefPtr<ReadableStreamControllerBase> mController;
    250  bool mDisturbed = false;
    251  RefPtr<ReadableStreamGenericReader> mReader;
    252  ReaderState mState = ReaderState::Readable;
    253  JS::Heap<JS::Value> mStoredError;
    254 
    255  HoldDropJSObjectsCaller mHoldDropCaller;
    256 };
    257 
    258 namespace streams_abstract {
    259 
    260 bool IsReadableStreamLocked(ReadableStream* aStream);
    261 
    262 double ReadableStreamGetNumReadRequests(ReadableStream* aStream);
    263 
    264 void ReadableStreamError(JSContext* aCx, ReadableStream* aStream,
    265                         JS::Handle<JS::Value> aValue, ErrorResult& aRv);
    266 
    267 MOZ_CAN_RUN_SCRIPT void ReadableStreamClose(JSContext* aCx,
    268                                            ReadableStream* aStream,
    269                                            ErrorResult& aRv);
    270 
    271 MOZ_CAN_RUN_SCRIPT void ReadableStreamFulfillReadRequest(
    272    JSContext* aCx, ReadableStream* aStream, JS::Handle<JS::Value> aChunk,
    273    bool done, ErrorResult& aRv);
    274 
    275 void ReadableStreamAddReadRequest(ReadableStream* aStream,
    276                                  ReadRequest* aReadRequest);
    277 void ReadableStreamAddReadIntoRequest(ReadableStream* aStream,
    278                                      ReadIntoRequest* aReadIntoRequest);
    279 
    280 MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> ReadableStreamCancel(
    281    JSContext* aCx, ReadableStream* aStream, JS::Handle<JS::Value> aError,
    282    ErrorResult& aRv);
    283 
    284 already_AddRefed<ReadableStreamDefaultReader>
    285 AcquireReadableStreamDefaultReader(ReadableStream* aStream, ErrorResult& aRv);
    286 
    287 bool ReadableStreamHasBYOBReader(ReadableStream* aStream);
    288 bool ReadableStreamHasDefaultReader(ReadableStream* aStream);
    289 
    290 }  // namespace streams_abstract
    291 
    292 }  // namespace mozilla::dom
    293 
    294 #endif  // mozilla_dom_ReadableStream_h