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"
16 namespace mozilla::dom
{
18 class ReadableStreamDefaultTeeSourceAlgorithms
;
20 enum class TeeBranch
: bool {
25 inline TeeBranch
OtherTeeBranch(TeeBranch aBranch
) {
26 if (aBranch
== TeeBranch::Branch1
) {
27 return TeeBranch::Branch2
;
29 return TeeBranch::Branch1
;
32 // A closure capturing the free variables in the ReadableStreamTee family of
34 // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaulttee
35 // https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamtee
36 struct TeeState
: public nsISupports
{
37 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
38 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TeeState
)
40 static already_AddRefed
<TeeState
> Create(ReadableStream
* aStream
,
41 bool aCloneForBranch2
,
44 ReadableStream
* GetStream() const { return mStream
; }
45 void SetStream(ReadableStream
* aStream
) { mStream
= aStream
; }
47 ReadableStreamGenericReader
* GetReader() const { return mReader
; }
48 void SetReader(ReadableStreamGenericReader
* aReader
) { mReader
= aReader
; }
50 ReadableStreamDefaultReader
* GetDefaultReader() const {
51 return mReader
->AsDefault();
54 bool ReadAgain() const { return mReadAgain
; }
55 void SetReadAgain(bool aReadAgain
) { mReadAgain
= aReadAgain
; }
57 // ReadableByteStreamTee uses ReadAgainForBranch{1,2};
58 bool ReadAgainForBranch1() const { return ReadAgain(); }
59 void SetReadAgainForBranch1(bool aReadAgainForBranch1
) {
60 SetReadAgain(aReadAgainForBranch1
);
63 bool ReadAgainForBranch2() const { return mReadAgainForBranch2
; }
64 void SetReadAgainForBranch2(bool aReadAgainForBranch2
) {
65 mReadAgainForBranch2
= aReadAgainForBranch2
;
68 bool Reading() const { return mReading
; }
69 void SetReading(bool aReading
) { mReading
= aReading
; }
71 bool Canceled1() const { return mCanceled1
; }
72 void SetCanceled1(bool aCanceled1
) { mCanceled1
= aCanceled1
; }
74 bool Canceled2() const { return mCanceled2
; }
75 void SetCanceled2(bool aCanceled2
) { mCanceled2
= aCanceled2
; }
77 void SetCanceled(TeeBranch aBranch
, bool aCanceled
) {
78 aBranch
== TeeBranch::Branch1
? SetCanceled1(aCanceled
)
79 : SetCanceled2(aCanceled
);
81 bool Canceled(TeeBranch aBranch
) {
82 return aBranch
== TeeBranch::Branch1
? Canceled1() : Canceled2();
85 JS::Value
Reason1() const { return mReason1
; }
86 void SetReason1(JS::Handle
<JS::Value
> aReason1
) { mReason1
= aReason1
; }
88 JS::Value
Reason2() const { return mReason2
; }
89 void SetReason2(JS::Handle
<JS::Value
> aReason2
) { mReason2
= aReason2
; }
91 void SetReason(TeeBranch aBranch
, JS::Handle
<JS::Value
> aReason
) {
92 aBranch
== TeeBranch::Branch1
? SetReason1(aReason
) : SetReason2(aReason
);
95 ReadableStream
* Branch1() const { return mBranch1
; }
96 void SetBranch1(already_AddRefed
<ReadableStream
> aBranch1
) {
100 ReadableStream
* Branch2() const { return mBranch2
; }
101 void SetBranch2(already_AddRefed
<ReadableStream
> aBranch2
) {
105 Promise
* CancelPromise() const { return mCancelPromise
; }
106 void SetCancelPromise(Promise
* aCancelPromise
) {
107 mCancelPromise
= aCancelPromise
;
110 bool CloneForBranch2() const { return mCloneForBranch2
; }
111 void setCloneForBranch2(bool aCloneForBranch2
) {
112 mCloneForBranch2
= aCloneForBranch2
;
115 // Some code is better served by using an enum into various internal slots to
116 // avoid duplication: Here we provide alternative accessors for that case.
117 ReadableStream
* Branch(TeeBranch aBranch
) const {
118 return aBranch
== TeeBranch::Branch1
? Branch1() : Branch2();
121 void SetReadAgainForBranch(TeeBranch aBranch
, bool aValue
) {
122 if (aBranch
== TeeBranch::Branch1
) {
123 SetReadAgainForBranch1(aValue
);
126 SetReadAgainForBranch2(aValue
);
129 MOZ_CAN_RUN_SCRIPT
void PullCallback(JSContext
* aCx
, nsIGlobalObject
* aGlobal
,
133 TeeState(ReadableStream
* aStream
, bool aCloneForBranch2
);
136 RefPtr
<ReadableStream
> mStream
;
138 // Step 3. (Step Numbering is based on ReadableStreamDefaultTee)
139 RefPtr
<ReadableStreamGenericReader
> mReader
;
142 bool mReading
= false;
145 // (Aliased to readAgainForBranch1, for the purpose of ReadableByteStreamTee)
146 bool mReadAgain
= false;
148 // ReadableByteStreamTee
149 bool mReadAgainForBranch2
= false;
152 bool mCanceled1
= false;
155 bool mCanceled2
= false;
158 JS::Heap
<JS::Value
> mReason1
;
161 JS::Heap
<JS::Value
> mReason2
;
164 RefPtr
<ReadableStream
> mBranch1
;
167 RefPtr
<ReadableStream
> mBranch2
;
170 RefPtr
<Promise
> mCancelPromise
;
173 bool mCloneForBranch2
= false;
175 virtual ~TeeState() { mozilla::DropJSObjects(this); }
178 } // namespace mozilla::dom