TeeState.cpp (3044B)
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 #include "TeeState.h" 8 9 #include "ReadableStreamTee.h" 10 #include "js/Value.h" 11 #include "mozilla/HoldDropJSObjects.h" 12 #include "mozilla/dom/Promise.h" 13 #include "mozilla/dom/ReadableStream.h" 14 15 namespace mozilla::dom { 16 17 using namespace streams_abstract; 18 19 NS_IMPL_CYCLE_COLLECTION_WITH_JS_MEMBERS(TeeState, 20 (mStream, mReader, mBranch1, mBranch2, 21 mCancelPromise), 22 (mReason1, mReason2)) 23 NS_IMPL_CYCLE_COLLECTING_ADDREF(TeeState) 24 NS_IMPL_CYCLE_COLLECTING_RELEASE(TeeState) 25 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TeeState) 26 NS_INTERFACE_MAP_ENTRY(nsISupports) 27 NS_INTERFACE_MAP_END 28 29 TeeState::TeeState(ReadableStream* aStream, bool aCloneForBranch2) 30 : mStream(aStream), 31 mReason1(JS::NullValue()), 32 mReason2(JS::NullValue()), 33 mCloneForBranch2(aCloneForBranch2) { 34 mozilla::HoldJSObjects(this); 35 MOZ_RELEASE_ASSERT(!aCloneForBranch2, 36 "cloneForBranch2 path is not implemented."); 37 } 38 39 already_AddRefed<TeeState> TeeState::Create(ReadableStream* aStream, 40 bool aCloneForBranch2, 41 ErrorResult& aRv) { 42 RefPtr<TeeState> teeState = new TeeState(aStream, aCloneForBranch2); 43 44 RefPtr<ReadableStreamDefaultReader> reader = 45 AcquireReadableStreamDefaultReader(teeState->GetStream(), aRv); 46 if (aRv.Failed()) { 47 return nullptr; 48 } 49 teeState->SetReader(reader); 50 51 RefPtr<Promise> promise = 52 Promise::CreateInfallible(teeState->GetStream()->GetParentObject()); 53 teeState->SetCancelPromise(promise); 54 55 return teeState.forget(); 56 } 57 58 // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaulttee 59 // Pull Algorithm Steps: 60 void TeeState::PullCallback(JSContext* aCx, nsIGlobalObject* aGlobal, 61 ErrorResult& aRv) { 62 // Step 13.1: If reading is true, 63 if (Reading()) { 64 // Step 13.1.1: Set readAgain to true. 65 SetReadAgain(true); 66 67 // Step 13.1.2: Return a promise resolved with undefined. 68 // (The caller will create it if necessary) 69 return; 70 } 71 72 // Step 13.2: Set reading to true. 73 SetReading(true); 74 75 // Step 13.3: Let readRequest be a read request with the following items: 76 RefPtr<ReadRequest> readRequest = 77 new ReadableStreamDefaultTeeReadRequest(this); 78 79 // Step 13.4: Perform ! ReadableStreamDefaultReaderRead(reader, readRequest). 80 RefPtr<ReadableStreamGenericReader> reader = GetReader(); 81 ReadableStreamDefaultReaderRead(aCx, reader, readRequest, aRv); 82 83 // Step 13.5: Return a promise resolved with undefined. 84 // (The caller will create it if necessary) 85 } 86 87 } // namespace mozilla::dom