2021-10-06 18:43:02 +00:00
|
|
|
/* -*- 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 {
|
2021-11-15 22:01:39 +00:00
|
|
|
|
2022-03-08 19:29:14 +00:00
|
|
|
class ReadableStreamDefaultTeeSourceAlgorithms;
|
2021-11-15 22:01:39 +00:00
|
|
|
|
2022-02-08 16:37:45 +00:00
|
|
|
enum class TeeBranch : bool {
|
|
|
|
Branch1,
|
|
|
|
Branch2,
|
|
|
|
};
|
|
|
|
|
|
|
|
inline TeeBranch OtherTeeBranch(TeeBranch aBranch) {
|
|
|
|
if (aBranch == TeeBranch::Branch1) {
|
|
|
|
return TeeBranch::Branch2;
|
|
|
|
}
|
|
|
|
return TeeBranch::Branch1;
|
|
|
|
}
|
|
|
|
|
2021-10-06 18:43:02 +00:00
|
|
|
// A closure capturing the free variables in the ReadableStreamTee family of
|
|
|
|
// algorithms.
|
|
|
|
// https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaulttee
|
2022-01-04 22:33:23 +00:00
|
|
|
// https://streams.spec.whatwg.org/#abstract-opdef-readablebytestreamtee
|
2021-10-06 18:43:02 +00:00
|
|
|
struct TeeState : public nsISupports {
|
|
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
|
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TeeState)
|
|
|
|
|
2022-02-28 22:31:42 +00:00
|
|
|
static already_AddRefed<TeeState> Create(ReadableStream* aStream,
|
2021-10-06 18:43:02 +00:00
|
|
|
bool aCloneForBranch2,
|
|
|
|
ErrorResult& aRv);
|
|
|
|
|
|
|
|
ReadableStream* GetStream() const { return mStream; }
|
|
|
|
void SetStream(ReadableStream* aStream) { mStream = aStream; }
|
|
|
|
|
2022-01-04 22:33:22 +00:00
|
|
|
ReadableStreamGenericReader* GetReader() const { return mReader; }
|
|
|
|
void SetReader(ReadableStreamGenericReader* aReader) { mReader = aReader; }
|
|
|
|
|
|
|
|
ReadableStreamDefaultReader* GetDefaultReader() const {
|
|
|
|
return mReader->AsDefault();
|
|
|
|
}
|
2021-10-06 18:43:02 +00:00
|
|
|
|
2021-11-15 22:01:39 +00:00
|
|
|
bool ReadAgain() const { return mReadAgain; }
|
|
|
|
void SetReadAgain(bool aReadAgain) { mReadAgain = aReadAgain; }
|
|
|
|
|
2022-01-04 22:33:23 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2021-10-06 18:43:02 +00:00
|
|
|
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; }
|
|
|
|
|
2022-02-08 16:37:45 +00:00
|
|
|
void SetCanceled(TeeBranch aBranch, bool aCanceled) {
|
|
|
|
aBranch == TeeBranch::Branch1 ? SetCanceled1(aCanceled)
|
|
|
|
: SetCanceled2(aCanceled);
|
2022-01-04 22:33:24 +00:00
|
|
|
}
|
2022-02-08 16:37:45 +00:00
|
|
|
bool Canceled(TeeBranch aBranch) {
|
|
|
|
return aBranch == TeeBranch::Branch1 ? Canceled1() : Canceled2();
|
2022-01-04 22:33:24 +00:00
|
|
|
}
|
|
|
|
|
2021-10-06 18:43:02 +00:00
|
|
|
JS::Value Reason1() const { return mReason1; }
|
2022-05-18 08:43:08 +00:00
|
|
|
void SetReason1(JS::Handle<JS::Value> aReason1) { mReason1 = aReason1; }
|
2021-10-06 18:43:02 +00:00
|
|
|
|
|
|
|
JS::Value Reason2() const { return mReason2; }
|
2022-05-18 08:43:08 +00:00
|
|
|
void SetReason2(JS::Handle<JS::Value> aReason2) { mReason2 = aReason2; }
|
2021-10-06 18:43:02 +00:00
|
|
|
|
2022-05-18 08:43:08 +00:00
|
|
|
void SetReason(TeeBranch aBranch, JS::Handle<JS::Value> aReason) {
|
2022-02-08 16:37:45 +00:00
|
|
|
aBranch == TeeBranch::Branch1 ? SetReason1(aReason) : SetReason2(aReason);
|
2022-01-04 22:33:24 +00:00
|
|
|
}
|
|
|
|
|
2021-10-06 18:43:02 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-02-08 16:37:45 +00:00
|
|
|
// Some code is better served by using an enum into various internal slots to
|
2022-01-04 22:33:24 +00:00
|
|
|
// avoid duplication: Here we provide alternative accessors for that case.
|
2022-02-08 16:37:45 +00:00
|
|
|
ReadableStream* Branch(TeeBranch aBranch) const {
|
|
|
|
return aBranch == TeeBranch::Branch1 ? Branch1() : Branch2();
|
2022-01-04 22:33:24 +00:00
|
|
|
}
|
|
|
|
|
2022-02-08 16:37:45 +00:00
|
|
|
void SetReadAgainForBranch(TeeBranch aBranch, bool aValue) {
|
|
|
|
if (aBranch == TeeBranch::Branch1) {
|
|
|
|
SetReadAgainForBranch1(aValue);
|
2022-01-04 22:33:24 +00:00
|
|
|
return;
|
|
|
|
}
|
2022-02-08 16:37:45 +00:00
|
|
|
SetReadAgainForBranch2(aValue);
|
2022-01-04 22:33:24 +00:00
|
|
|
}
|
|
|
|
|
2022-03-08 19:29:14 +00:00
|
|
|
MOZ_CAN_RUN_SCRIPT void PullCallback(JSContext* aCx, nsIGlobalObject* aGlobal,
|
|
|
|
ErrorResult& aRv);
|
|
|
|
|
2021-10-06 18:43:02 +00:00
|
|
|
private:
|
2022-02-28 22:31:42 +00:00
|
|
|
TeeState(ReadableStream* aStream, bool aCloneForBranch2);
|
2021-10-06 18:43:02 +00:00
|
|
|
|
|
|
|
// Implicit:
|
|
|
|
RefPtr<ReadableStream> mStream;
|
|
|
|
|
2022-01-04 22:33:23 +00:00
|
|
|
// Step 3. (Step Numbering is based on ReadableStreamDefaultTee)
|
2022-01-04 22:33:22 +00:00
|
|
|
RefPtr<ReadableStreamGenericReader> mReader;
|
2021-10-06 18:43:02 +00:00
|
|
|
|
|
|
|
// Step 4.
|
|
|
|
bool mReading = false;
|
|
|
|
|
|
|
|
// Step 5.
|
2022-01-04 22:33:23 +00:00
|
|
|
// (Aliased to readAgainForBranch1, for the purpose of ReadableByteStreamTee)
|
2021-11-15 22:01:39 +00:00
|
|
|
bool mReadAgain = false;
|
2021-10-06 18:43:02 +00:00
|
|
|
|
2022-01-04 22:33:23 +00:00
|
|
|
// ReadableByteStreamTee
|
|
|
|
bool mReadAgainForBranch2 = false;
|
|
|
|
|
2021-10-06 18:43:02 +00:00
|
|
|
// Step 6.
|
2021-11-15 22:01:39 +00:00
|
|
|
bool mCanceled1 = false;
|
2021-10-06 18:43:02 +00:00
|
|
|
|
|
|
|
// Step 7.
|
2021-11-15 22:01:39 +00:00
|
|
|
bool mCanceled2 = false;
|
2021-10-06 18:43:02 +00:00
|
|
|
|
|
|
|
// Step 8.
|
2021-11-15 22:01:39 +00:00
|
|
|
JS::Heap<JS::Value> mReason1;
|
2021-10-06 18:43:02 +00:00
|
|
|
|
|
|
|
// Step 9.
|
2021-11-15 22:01:39 +00:00
|
|
|
JS::Heap<JS::Value> mReason2;
|
2021-10-06 18:43:02 +00:00
|
|
|
|
|
|
|
// Step 10.
|
2021-11-15 22:01:39 +00:00
|
|
|
RefPtr<ReadableStream> mBranch1;
|
2021-10-06 18:43:02 +00:00
|
|
|
|
|
|
|
// Step 11.
|
2021-11-15 22:01:39 +00:00
|
|
|
RefPtr<ReadableStream> mBranch2;
|
|
|
|
|
|
|
|
// Step 12.
|
2021-10-06 18:43:02 +00:00
|
|
|
RefPtr<Promise> mCancelPromise;
|
|
|
|
|
|
|
|
// Implicit:
|
|
|
|
bool mCloneForBranch2 = false;
|
|
|
|
|
|
|
|
virtual ~TeeState() { mozilla::DropJSObjects(this); }
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace mozilla::dom
|
|
|
|
#endif
|