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/. */
7 #ifndef mozilla_dom_TeeState_h
8 #define mozilla_dom_TeeState_h
10 #include "mozilla/HoldDropJSObjects.h"
11 #include "nsISupports.h"
12 #include "mozilla/dom/ReadableStream.h"
13 #include "mozilla/dom/ReadableStreamDefaultReader.h"
14 #include "mozilla/dom/Promise.h"
15 #include "nsISupportsBase.h"
17 namespace mozilla::dom
{
19 class ReadableStreamDefaultTeeSourceAlgorithms
;
21 enum class TeeBranch
: bool {
26 inline TeeBranch
OtherTeeBranch(TeeBranch aBranch
) {
27 if (aBranch
== TeeBranch::Branch1
) {
28 return TeeBranch::Branch2
;
30 return TeeBranch::Branch1
;
33 // A closure capturing the free variables in the ReadableStreamTee family of
35 // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaulttee
36 // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamtee
37 struct TeeState
: public nsISupports
{
38 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
39 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TeeState
)
41 static already_AddRefed
<TeeState
> Create(ReadableStream
* aStream
,
42 bool aCloneForBranch2
,
45 ReadableStream
* GetStream() const { return mStream
; }
46 void SetStream(ReadableStream
* aStream
) { mStream
= aStream
; }
48 ReadableStreamGenericReader
* GetReader() const { return mReader
; }
49 void SetReader(ReadableStreamGenericReader
* aReader
) { mReader
= aReader
; }
51 ReadableStreamDefaultReader
* GetDefaultReader() const {
52 return mReader
->AsDefault();
55 bool ReadAgain() const { return mReadAgain
; }
56 void SetReadAgain(bool aReadAgain
) { mReadAgain
= aReadAgain
; }
58 // ReadableByteStreamTee uses ReadAgainForBranch{1,2};
59 bool ReadAgainForBranch1() const { return ReadAgain(); }
60 void SetReadAgainForBranch1(bool aReadAgainForBranch1
) {
61 SetReadAgain(aReadAgainForBranch1
);
64 bool ReadAgainForBranch2() const { return mReadAgainForBranch2
; }
65 void SetReadAgainForBranch2(bool aReadAgainForBranch2
) {
66 mReadAgainForBranch2
= aReadAgainForBranch2
;
69 bool Reading() const { return mReading
; }
70 void SetReading(bool aReading
) { mReading
= aReading
; }
72 bool Canceled1() const { return mCanceled1
; }
73 void SetCanceled1(bool aCanceled1
) { mCanceled1
= aCanceled1
; }
75 bool Canceled2() const { return mCanceled2
; }
76 void SetCanceled2(bool aCanceled2
) { mCanceled2
= aCanceled2
; }
78 void SetCanceled(TeeBranch aBranch
, bool aCanceled
) {
79 aBranch
== TeeBranch::Branch1
? SetCanceled1(aCanceled
)
80 : SetCanceled2(aCanceled
);
82 bool Canceled(TeeBranch aBranch
) {
83 return aBranch
== TeeBranch::Branch1
? Canceled1() : Canceled2();
86 JS::Value
Reason1() const { return mReason1
; }
87 void SetReason1(JS::Handle
<JS::Value
> aReason1
) { mReason1
= aReason1
; }
89 JS::Value
Reason2() const { return mReason2
; }
90 void SetReason2(JS::Handle
<JS::Value
> aReason2
) { mReason2
= aReason2
; }
92 void SetReason(TeeBranch aBranch
, JS::Handle
<JS::Value
> aReason
) {
93 aBranch
== TeeBranch::Branch1
? SetReason1(aReason
) : SetReason2(aReason
);
96 ReadableStream
* Branch1() const { return mBranch1
; }
97 void SetBranch1(already_AddRefed
<ReadableStream
> aBranch1
) {
101 ReadableStream
* Branch2() const { return mBranch2
; }
102 void SetBranch2(already_AddRefed
<ReadableStream
> aBranch2
) {
106 Promise
* CancelPromise() const { return mCancelPromise
; }
107 void SetCancelPromise(Promise
* aCancelPromise
) {
108 mCancelPromise
= aCancelPromise
;
111 bool CloneForBranch2() const { return mCloneForBranch2
; }
112 void setCloneForBranch2(bool aCloneForBranch2
) {
113 mCloneForBranch2
= aCloneForBranch2
;
116 // Some code is better served by using an enum into various internal slots to
117 // avoid duplication: Here we provide alternative accessors for that case.
118 ReadableStream
* Branch(TeeBranch aBranch
) const {
119 return aBranch
== TeeBranch::Branch1
? Branch1() : Branch2();
122 void SetReadAgainForBranch(TeeBranch aBranch
, bool aValue
) {
123 if (aBranch
== TeeBranch::Branch1
) {
124 SetReadAgainForBranch1(aValue
);
127 SetReadAgainForBranch2(aValue
);
130 MOZ_CAN_RUN_SCRIPT
void PullCallback(JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
134 TeeState(ReadableStream
* aStream
, bool aCloneForBranch2
);
137 RefPtr
<ReadableStream
> mStream
;
139 // Step 3. (Step Numbering is based on ReadableStreamDefaultTee)
140 RefPtr
<ReadableStreamGenericReader
> mReader
;
143 bool mReading
= false;
146 // (Aliased to readAgainForBranch1, for the purpose of ReadableByteStreamTee)
147 bool mReadAgain
= false;
149 // ReadableByteStreamTee
150 bool mReadAgainForBranch2
= false;
153 bool mCanceled1
= false;
156 bool mCanceled2
= false;
159 JS::Heap
<JS::Value
> mReason1
;
162 JS::Heap
<JS::Value
> mReason2
;
165 RefPtr
<ReadableStream
> mBranch1
;
168 RefPtr
<ReadableStream
> mBranch2
;
171 RefPtr
<Promise
> mCancelPromise
;
174 bool mCloneForBranch2
= false;
176 virtual ~TeeState() { mozilla::DropJSObjects(this); }
179 } // namespace mozilla::dom