ReadableByteStreamController.h (8778B)
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_ReadableByteStreamController_h 8 #define mozilla_dom_ReadableByteStreamController_h 9 10 #include <cstddef> 11 12 #include "UnderlyingSourceCallbackHelpers.h" 13 #include "js/RootingAPI.h" 14 #include "js/TypeDecls.h" 15 #include "mozilla/Attributes.h" 16 #include "mozilla/ErrorResult.h" 17 #include "mozilla/dom/BindingDeclarations.h" 18 #include "mozilla/dom/Nullable.h" 19 #include "mozilla/dom/QueueWithSizes.h" 20 #include "mozilla/dom/QueuingStrategyBinding.h" 21 #include "mozilla/dom/ReadRequest.h" 22 #include "mozilla/dom/ReadableStream.h" 23 #include "mozilla/dom/ReadableStreamBYOBRequest.h" 24 #include "mozilla/dom/ReadableStreamControllerBase.h" 25 #include "mozilla/dom/TypedArray.h" 26 #include "nsCycleCollectionParticipant.h" 27 #include "nsISupportsImpl.h" 28 #include "nsTArray.h" 29 #include "nsWrapperCache.h" 30 31 namespace mozilla::dom { 32 33 // https://streams.spec.whatwg.org/#pull-into-descriptor-reader-type 34 // Indicates what type of readable stream reader initiated this request, 35 // or None if the initiating reader was released. 36 enum ReaderType { Default, BYOB, None }; 37 38 struct PullIntoDescriptor; 39 struct ReadableByteStreamQueueEntry; 40 struct ReadIntoRequest; 41 42 class ReadableByteStreamController final : public ReadableStreamControllerBase, 43 public nsWrapperCache { 44 public: 45 NS_DECL_ISUPPORTS_INHERITED 46 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED( 47 ReadableByteStreamController, ReadableStreamControllerBase) 48 49 public: 50 explicit ReadableByteStreamController(nsIGlobalObject* aGlobal); 51 52 protected: 53 ~ReadableByteStreamController() override; 54 55 public: 56 bool IsDefault() override { return false; } 57 bool IsByte() override { return true; } 58 ReadableStreamDefaultController* AsDefault() override { return nullptr; } 59 ReadableByteStreamController* AsByte() override { return this; } 60 61 JSObject* WrapObject(JSContext* aCx, 62 JS::Handle<JSObject*> aGivenProto) override; 63 64 already_AddRefed<ReadableStreamBYOBRequest> GetByobRequest(JSContext* aCx, 65 ErrorResult& aRv); 66 67 Nullable<double> GetDesiredSize() const; 68 69 MOZ_CAN_RUN_SCRIPT void Close(JSContext* aCx, ErrorResult& aRv); 70 71 MOZ_CAN_RUN_SCRIPT void Enqueue(JSContext* aCx, const ArrayBufferView& aChunk, 72 ErrorResult& aRv); 73 74 void Error(JSContext* aCx, JS::Handle<JS::Value> aErrorValue, 75 ErrorResult& aRv); 76 77 MOZ_CAN_RUN_SCRIPT already_AddRefed<Promise> CancelSteps( 78 JSContext* aCx, JS::Handle<JS::Value> aReason, ErrorResult& aRv) override; 79 MOZ_CAN_RUN_SCRIPT void PullSteps(JSContext* aCx, ReadRequest* aReadRequest, 80 ErrorResult& aRv) override; 81 void ReleaseSteps() override; 82 83 // Internal Slot Accessors 84 Maybe<uint64_t> AutoAllocateChunkSize() { return mAutoAllocateChunkSize; } 85 void SetAutoAllocateChunkSize(Maybe<uint64_t>& aSize) { 86 mAutoAllocateChunkSize = aSize; 87 } 88 89 ReadableStreamBYOBRequest* GetByobRequest() const { return mByobRequest; } 90 void SetByobRequest(ReadableStreamBYOBRequest* aByobRequest) { 91 mByobRequest = aByobRequest; 92 } 93 94 LinkedList<RefPtr<PullIntoDescriptor>>& PendingPullIntos() { 95 return mPendingPullIntos; 96 } 97 void ClearPendingPullIntos(); 98 99 double QueueTotalSize() const { return mQueueTotalSize; } 100 void SetQueueTotalSize(double aQueueTotalSize) { 101 mQueueTotalSize = aQueueTotalSize; 102 } 103 void AddToQueueTotalSize(double aLength) { mQueueTotalSize += aLength; } 104 105 double StrategyHWM() const { return mStrategyHWM; } 106 void SetStrategyHWM(double aStrategyHWM) { mStrategyHWM = aStrategyHWM; } 107 108 bool CloseRequested() const { return mCloseRequested; } 109 void SetCloseRequested(bool aCloseRequested) { 110 mCloseRequested = aCloseRequested; 111 } 112 113 LinkedList<RefPtr<ReadableByteStreamQueueEntry>>& Queue() { return mQueue; } 114 void ClearQueue(); 115 116 bool Started() const { return mStarted; } 117 void SetStarted(bool aStarted) { mStarted = aStarted; } 118 119 bool Pulling() const { return mPulling; } 120 void SetPulling(bool aPulling) { mPulling = aPulling; } 121 122 bool PullAgain() const { return mPullAgain; } 123 void SetPullAgain(bool aPullAgain) { mPullAgain = aPullAgain; } 124 125 private: 126 // A boolean flag indicating whether the stream has been closed by its 127 // underlying byte source, but still has chunks in its internal queue that 128 // have not yet been read 129 bool mCloseRequested = false; 130 131 // A boolean flag set to true if the stream’s mechanisms requested a call 132 // to the underlying byte source's pull algorithm to pull more data, but the 133 // pull could not yet be done since a previous call is still executing 134 bool mPullAgain = false; 135 136 // A boolean flag indicating whether the underlying byte source has finished 137 // starting 138 bool mStarted = false; 139 140 // A boolean flag set to true while the underlying byte source's pull 141 // algorithm is executing and the returned promise has not yet fulfilled, 142 // used to prevent reentrant calls 143 bool mPulling = false; 144 145 // A positive integer, when the automatic buffer allocation feature is 146 // enabled. In that case, this value specifies the size of buffer to allocate. 147 // It is undefined otherwise. 148 Maybe<uint64_t> mAutoAllocateChunkSize; 149 150 // A ReadableStreamBYOBRequest instance representing the current BYOB pull 151 // request, or null if there are no pending requests 152 RefPtr<ReadableStreamBYOBRequest> mByobRequest; 153 154 // A list of pull-into descriptors 155 LinkedList<RefPtr<PullIntoDescriptor>> mPendingPullIntos; 156 157 // A list of readable byte stream queue entries representing the stream’s 158 // internal queue of chunks 159 // 160 // This is theoretically supposed to be a QueueWithSizes, but it is 161 // mostly not actually manipulated or used like QueueWithSizes, so instead we 162 // use a LinkedList. 163 LinkedList<RefPtr<ReadableByteStreamQueueEntry>> mQueue; 164 165 // The total size, in bytes, of all the chunks stored in [[queue]] (see § 8.1 166 // Queue-with-sizes) 167 double mQueueTotalSize = 0.0; 168 169 // A number supplied to the constructor as part of the stream’s queuing 170 // strategy, indicating the point at which the stream will apply backpressure 171 // to its underlying byte source 172 double mStrategyHWM = 0.0; 173 }; 174 175 namespace streams_abstract { 176 177 MOZ_CAN_RUN_SCRIPT void ReadableByteStreamControllerRespond( 178 JSContext* aCx, ReadableByteStreamController* aController, 179 uint64_t aBytesWritten, ErrorResult& aRv); 180 181 MOZ_CAN_RUN_SCRIPT void ReadableByteStreamControllerRespondInternal( 182 JSContext* aCx, ReadableByteStreamController* aController, 183 uint64_t aBytesWritten, ErrorResult& aRv); 184 185 MOZ_CAN_RUN_SCRIPT void ReadableByteStreamControllerRespondWithNewView( 186 JSContext* aCx, ReadableByteStreamController* aController, 187 JS::Handle<JSObject*> aView, ErrorResult& aRv); 188 189 MOZ_CAN_RUN_SCRIPT void ReadableByteStreamControllerPullInto( 190 JSContext* aCx, ReadableByteStreamController* aController, 191 JS::Handle<JSObject*> aView, uint64_t aMin, 192 ReadIntoRequest* aReadIntoRequest, ErrorResult& aRv); 193 194 void ReadableByteStreamControllerError( 195 ReadableByteStreamController* aController, JS::Handle<JS::Value> aValue, 196 ErrorResult& aRv); 197 198 MOZ_CAN_RUN_SCRIPT void ReadableByteStreamControllerEnqueue( 199 JSContext* aCx, ReadableByteStreamController* aController, 200 JS::Handle<JSObject*> aChunk, ErrorResult& aRv); 201 202 already_AddRefed<ReadableStreamBYOBRequest> 203 ReadableByteStreamControllerGetBYOBRequest( 204 JSContext* aCx, ReadableByteStreamController* aController, 205 ErrorResult& aRv); 206 207 MOZ_CAN_RUN_SCRIPT void ReadableByteStreamControllerClose( 208 JSContext* aCx, ReadableByteStreamController* aController, 209 ErrorResult& aRv); 210 211 MOZ_CAN_RUN_SCRIPT void SetUpReadableByteStreamController( 212 JSContext* aCx, ReadableStream* aStream, 213 ReadableByteStreamController* aController, 214 UnderlyingSourceAlgorithmsBase* aAlgorithms, double aHighWaterMark, 215 Maybe<uint64_t> aAutoAllocateChunkSize, ErrorResult& aRv); 216 217 MOZ_CAN_RUN_SCRIPT void ReadableByteStreamControllerCallPullIfNeeded( 218 JSContext* aCx, ReadableByteStreamController* aController, 219 ErrorResult& aRv); 220 221 MOZ_CAN_RUN_SCRIPT void SetUpReadableByteStreamControllerFromUnderlyingSource( 222 JSContext* aCx, ReadableStream* aStream, 223 JS::Handle<JSObject*> aUnderlyingSource, 224 UnderlyingSource& aUnderlyingSourceDict, double aHighWaterMark, 225 ErrorResult& aRv); 226 227 } // namespace streams_abstract 228 229 } // namespace mozilla::dom 230 231 #endif