diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /dom/streams/TeeState.h | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | dom/streams/TeeState.h | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/dom/streams/TeeState.h b/dom/streams/TeeState.h new file mode 100644 index 0000000000..9a688be662 --- /dev/null +++ b/dom/streams/TeeState.h @@ -0,0 +1,179 @@ +/* -*- 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_TeeState_h +#define mozilla_dom_TeeState_h + +#include "mozilla/HoldDropJSObjects.h" +#include "nsISupports.h" +#include "mozilla/dom/ReadableStream.h" +#include "mozilla/dom/ReadableStreamDefaultReader.h" +#include "mozilla/dom/Promise.h" + +namespace mozilla::dom { + +class ReadableStreamDefaultTeeSourceAlgorithms; + +enum class TeeBranch : bool { + Branch1, + Branch2, +}; + +inline TeeBranch OtherTeeBranch(TeeBranch aBranch) { + if (aBranch == TeeBranch::Branch1) { + return TeeBranch::Branch2; + } + return TeeBranch::Branch1; +} + +// A closure capturing the free variables in the ReadableStreamTee family of +// algorithms. +// https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaulttee +// https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamtee +struct TeeState : public nsISupports { + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TeeState) + + static already_AddRefed<TeeState> Create(ReadableStream* aStream, + bool aCloneForBranch2, + ErrorResult& aRv); + + ReadableStream* GetStream() const { return mStream; } + void SetStream(ReadableStream* aStream) { mStream = aStream; } + + ReadableStreamGenericReader* GetReader() const { return mReader; } + void SetReader(ReadableStreamGenericReader* aReader) { mReader = aReader; } + + ReadableStreamDefaultReader* GetDefaultReader() const { + return mReader->AsDefault(); + } + + bool ReadAgain() const { return mReadAgain; } + void SetReadAgain(bool aReadAgain) { mReadAgain = aReadAgain; } + + // ReadableByteStreamTee uses ReadAgainForBranch{1,2}; + bool ReadAgainForBranch1() const { return ReadAgain(); } + void SetReadAgainForBranch1(bool aReadAgainForBranch1) { + SetReadAgain(aReadAgainForBranch1); + } + + bool ReadAgainForBranch2() const { return mReadAgainForBranch2; } + void SetReadAgainForBranch2(bool aReadAgainForBranch2) { + mReadAgainForBranch2 = aReadAgainForBranch2; + } + + bool Reading() const { return mReading; } + void SetReading(bool aReading) { mReading = aReading; } + + bool Canceled1() const { return mCanceled1; } + void SetCanceled1(bool aCanceled1) { mCanceled1 = aCanceled1; } + + bool Canceled2() const { return mCanceled2; } + void SetCanceled2(bool aCanceled2) { mCanceled2 = aCanceled2; } + + void SetCanceled(TeeBranch aBranch, bool aCanceled) { + aBranch == TeeBranch::Branch1 ? SetCanceled1(aCanceled) + : SetCanceled2(aCanceled); + } + bool Canceled(TeeBranch aBranch) { + return aBranch == TeeBranch::Branch1 ? Canceled1() : Canceled2(); + } + + JS::Value Reason1() const { return mReason1; } + void SetReason1(JS::Handle<JS::Value> aReason1) { mReason1 = aReason1; } + + JS::Value Reason2() const { return mReason2; } + void SetReason2(JS::Handle<JS::Value> aReason2) { mReason2 = aReason2; } + + void SetReason(TeeBranch aBranch, JS::Handle<JS::Value> aReason) { + aBranch == TeeBranch::Branch1 ? SetReason1(aReason) : SetReason2(aReason); + } + + ReadableStream* Branch1() const { return mBranch1; } + void SetBranch1(already_AddRefed<ReadableStream> aBranch1) { + mBranch1 = aBranch1; + } + + ReadableStream* Branch2() const { return mBranch2; } + void SetBranch2(already_AddRefed<ReadableStream> aBranch2) { + mBranch2 = aBranch2; + } + + Promise* CancelPromise() const { return mCancelPromise; } + void SetCancelPromise(Promise* aCancelPromise) { + mCancelPromise = aCancelPromise; + } + + bool CloneForBranch2() const { return mCloneForBranch2; } + void setCloneForBranch2(bool aCloneForBranch2) { + mCloneForBranch2 = aCloneForBranch2; + } + + // Some code is better served by using an enum into various internal slots to + // avoid duplication: Here we provide alternative accessors for that case. + ReadableStream* Branch(TeeBranch aBranch) const { + return aBranch == TeeBranch::Branch1 ? Branch1() : Branch2(); + } + + void SetReadAgainForBranch(TeeBranch aBranch, bool aValue) { + if (aBranch == TeeBranch::Branch1) { + SetReadAgainForBranch1(aValue); + return; + } + SetReadAgainForBranch2(aValue); + } + + MOZ_CAN_RUN_SCRIPT void PullCallback(JSContext* aCx, nsIGlobalObject* aGlobal, + ErrorResult& aRv); + + private: + TeeState(ReadableStream* aStream, bool aCloneForBranch2); + + // Implicit: + RefPtr<ReadableStream> mStream; + + // Step 3. (Step Numbering is based on ReadableStreamDefaultTee) + RefPtr<ReadableStreamGenericReader> mReader; + + // Step 4. + bool mReading = false; + + // Step 5. + // (Aliased to readAgainForBranch1, for the purpose of ReadableByteStreamTee) + bool mReadAgain = false; + + // ReadableByteStreamTee + bool mReadAgainForBranch2 = false; + + // Step 6. + bool mCanceled1 = false; + + // Step 7. + bool mCanceled2 = false; + + // Step 8. + JS::Heap<JS::Value> mReason1; + + // Step 9. + JS::Heap<JS::Value> mReason2; + + // Step 10. + RefPtr<ReadableStream> mBranch1; + + // Step 11. + RefPtr<ReadableStream> mBranch2; + + // Step 12. + RefPtr<Promise> mCancelPromise; + + // Implicit: + bool mCloneForBranch2 = false; + + virtual ~TeeState() { mozilla::DropJSObjects(this); } +}; + +} // namespace mozilla::dom +#endif |