mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:27:35 +00:00
LibWeb: Add ReadableStreamByteController interface
This commit is contained in:
parent
c7aa4fa166
commit
819b6332d1
10 changed files with 253 additions and 1 deletions
|
@ -464,6 +464,7 @@ set(SOURCES
|
||||||
ResizeObserver/ResizeObserver.cpp
|
ResizeObserver/ResizeObserver.cpp
|
||||||
SecureContexts/AbstractOperations.cpp
|
SecureContexts/AbstractOperations.cpp
|
||||||
Streams/AbstractOperations.cpp
|
Streams/AbstractOperations.cpp
|
||||||
|
Streams/ReadableByteStreamController.cpp
|
||||||
Streams/ReadableStream.cpp
|
Streams/ReadableStream.cpp
|
||||||
Streams/ReadableStreamBYOBRequest.cpp
|
Streams/ReadableStreamBYOBRequest.cpp
|
||||||
Streams/ReadableStreamDefaultController.cpp
|
Streams/ReadableStreamDefaultController.cpp
|
||||||
|
|
|
@ -426,6 +426,7 @@ class Selection;
|
||||||
|
|
||||||
namespace Web::Streams {
|
namespace Web::Streams {
|
||||||
class ReadableStream;
|
class ReadableStream;
|
||||||
|
class ReadableByteStreamController;
|
||||||
class ReadableStreamBYOBRequest;
|
class ReadableStreamBYOBRequest;
|
||||||
class ReadableStreamDefaultController;
|
class ReadableStreamDefaultController;
|
||||||
class ReadableStreamDefaultReader;
|
class ReadableStreamDefaultReader;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||||
#include <LibWeb/DOM/AbortSignal.h>
|
#include <LibWeb/DOM/AbortSignal.h>
|
||||||
#include <LibWeb/Streams/AbstractOperations.h>
|
#include <LibWeb/Streams/AbstractOperations.h>
|
||||||
|
#include <LibWeb/Streams/ReadableByteStreamController.h>
|
||||||
#include <LibWeb/Streams/ReadableStream.h>
|
#include <LibWeb/Streams/ReadableStream.h>
|
||||||
#include <LibWeb/Streams/ReadableStreamDefaultController.h>
|
#include <LibWeb/Streams/ReadableStreamDefaultController.h>
|
||||||
#include <LibWeb/Streams/ReadableStreamDefaultReader.h>
|
#include <LibWeb/Streams/ReadableStreamDefaultReader.h>
|
||||||
|
@ -739,6 +740,24 @@ WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller_from_underly
|
||||||
return set_up_readable_stream_default_controller(stream, controller, move(start_algorithm), move(pull_algorithm), move(cancel_algorithm), high_water_mark, move(size_algorithm));
|
return set_up_readable_stream_default_controller(stream, controller, move(start_algorithm), move(pull_algorithm), move(cancel_algorithm), high_water_mark, move(size_algorithm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readable-byte-stream-controller-get-desired-size
|
||||||
|
Optional<double> readable_byte_stream_controller_get_desired_size(ReadableByteStreamController const& controller)
|
||||||
|
{
|
||||||
|
auto stream = controller.stream();
|
||||||
|
|
||||||
|
// 1. Let state be controller.[[stream]].[[state]].
|
||||||
|
// 2. If state is "errored", return null.
|
||||||
|
if (stream->is_errored())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// 3. If state is "closed", return 0.
|
||||||
|
if (stream->is_closed())
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
// 4. Return controller.[[strategyHWM]] − controller.[[queueTotalSize]].
|
||||||
|
return controller.strategy_hwm() - controller.queue_total_size();
|
||||||
|
}
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#acquire-writable-stream-default-writer
|
// https://streams.spec.whatwg.org/#acquire-writable-stream-default-writer
|
||||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<WritableStreamDefaultWriter>> acquire_writable_stream_default_writer(WritableStream& stream)
|
WebIDL::ExceptionOr<JS::NonnullGCPtr<WritableStreamDefaultWriter>> acquire_writable_stream_default_writer(WritableStream& stream)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,8 @@ bool readable_stream_default_controller_can_close_or_enqueue(ReadableStreamDefau
|
||||||
WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller(ReadableStream&, ReadableStreamDefaultController&, StartAlgorithm&&, PullAlgorithm&&, CancelAlgorithm&&, double high_water_mark, SizeAlgorithm&&);
|
WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller(ReadableStream&, ReadableStreamDefaultController&, StartAlgorithm&&, PullAlgorithm&&, CancelAlgorithm&&, double high_water_mark, SizeAlgorithm&&);
|
||||||
WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller_from_underlying_source(ReadableStream&, JS::Value underlying_source_value, UnderlyingSource, double high_water_mark, SizeAlgorithm&&);
|
WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller_from_underlying_source(ReadableStream&, JS::Value underlying_source_value, UnderlyingSource, double high_water_mark, SizeAlgorithm&&);
|
||||||
|
|
||||||
|
Optional<double> readable_byte_stream_controller_get_desired_size(ReadableByteStreamController const&);
|
||||||
|
|
||||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<WritableStreamDefaultWriter>> acquire_writable_stream_default_writer(WritableStream&);
|
WebIDL::ExceptionOr<JS::NonnullGCPtr<WritableStreamDefaultWriter>> acquire_writable_stream_default_writer(WritableStream&);
|
||||||
bool is_writable_stream_locked(WritableStream const&);
|
bool is_writable_stream_locked(WritableStream const&);
|
||||||
WebIDL::ExceptionOr<void> set_up_writable_stream_default_writer(WritableStreamDefaultWriter&, WritableStream&);
|
WebIDL::ExceptionOr<void> set_up_writable_stream_default_writer(WritableStreamDefaultWriter&, WritableStream&);
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibWeb/Streams/ReadableByteStreamController.h>
|
||||||
|
#include <LibWeb/Streams/ReadableStream.h>
|
||||||
|
#include <LibWeb/Streams/ReadableStreamBYOBRequest.h>
|
||||||
|
|
||||||
|
namespace Web::Streams {
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#rbs-controller-desired-size
|
||||||
|
Optional<double> ReadableByteStreamController::desired_size() const
|
||||||
|
{
|
||||||
|
// 1. Return ! ReadableByteStreamControllerGetDesiredSize(this).
|
||||||
|
return readable_byte_stream_controller_get_desired_size(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadableByteStreamController::ReadableByteStreamController(JS::Realm& realm)
|
||||||
|
: Bindings::PlatformObject(realm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadableByteStreamController::visit_edges(Cell::Visitor& visitor)
|
||||||
|
{
|
||||||
|
Base::visit_edges(visitor);
|
||||||
|
visitor.visit(m_byob_request);
|
||||||
|
for (auto const& pending_pull_into : m_pending_pull_intos) {
|
||||||
|
visitor.visit(pending_pull_into.buffer);
|
||||||
|
visitor.visit(pending_pull_into.view_constructor);
|
||||||
|
}
|
||||||
|
for (auto const& item : m_queue)
|
||||||
|
visitor.visit(item.buffer);
|
||||||
|
visitor.visit(m_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
177
Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.h
Normal file
177
Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.h
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Optional.h>
|
||||||
|
#include <AK/SinglyLinkedList.h>
|
||||||
|
#include <LibWeb/Bindings/PlatformObject.h>
|
||||||
|
#include <LibWeb/Streams/AbstractOperations.h>
|
||||||
|
|
||||||
|
namespace Web::Streams {
|
||||||
|
|
||||||
|
enum class ReaderType {
|
||||||
|
Default,
|
||||||
|
Byob,
|
||||||
|
None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#pull-into-descriptor
|
||||||
|
struct PullIntoDescriptor {
|
||||||
|
// https://streams.spec.whatwg.org/#pull-into-descriptor-buffer
|
||||||
|
// An ArrayBuffer
|
||||||
|
JS::NonnullGCPtr<JS::ArrayBuffer> buffer;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#pull-into-descriptor-buffer-byte-length
|
||||||
|
// A positive integer representing the initial byte length of buffer
|
||||||
|
u32 buffer_byte_length;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#pull-into-descriptor-byte-offset
|
||||||
|
// A nonnegative integer byte offset into the buffer where the underlying byte source will start writing
|
||||||
|
u32 byte_offset;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#pull-into-descriptor-byte-length
|
||||||
|
// A positive integer number of bytes which can be written into the buffer
|
||||||
|
u32 byte_length;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#pull-into-descriptor-bytes-filled
|
||||||
|
// A nonnegative integer number of bytes that have been written into the buffer so far
|
||||||
|
u32 bytes_filled;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#pull-into-descriptor-element-size
|
||||||
|
// A positive integer representing the number of bytes that can be written into the buffer at a time, using views of the type described by the view constructor
|
||||||
|
u32 element_size;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#pull-into-descriptor-view-constructor
|
||||||
|
// A typed array constructor or %DataView%, which will be used for constructing a view with which to write into the buffer
|
||||||
|
JS::NonnullGCPtr<JS::NativeFunction> view_constructor;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#pull-into-descriptor-reader-type
|
||||||
|
// Either "default" or "byob", indicating what type of readable stream reader initiated this request, or "none" if the initiating reader was released
|
||||||
|
ReaderType reader_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readable-byte-stream-queue-entry
|
||||||
|
struct ReadableByteStreamQueueEntry {
|
||||||
|
// https://streams.spec.whatwg.org/#readable-byte-stream-queue-entry-buffer
|
||||||
|
// An ArrayBuffer, which will be a transferred version of the one originally supplied by the underlying byte source
|
||||||
|
JS::NonnullGCPtr<JS::ArrayBuffer> buffer;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readable-byte-stream-queue-entry-byte-offset
|
||||||
|
// A nonnegative integer number giving the byte offset derived from the view originally supplied by the underlying byte source
|
||||||
|
u32 byte_offset;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readable-byte-stream-queue-entry-byte-length
|
||||||
|
// A nonnegative integer number giving the byte length derived from the view originally supplied by the underlying byte source
|
||||||
|
u32 byte_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablebytestreamcontroller
|
||||||
|
class ReadableByteStreamController : public Bindings::PlatformObject {
|
||||||
|
WEB_PLATFORM_OBJECT(ReadableByteStreamController, Bindings::PlatformObject);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~ReadableByteStreamController() override = default;
|
||||||
|
|
||||||
|
JS::GCPtr<ReadableStreamBYOBRequest> byob_request() { return m_byob_request; }
|
||||||
|
void set_byob_request(JS::GCPtr<ReadableStreamBYOBRequest> request) { m_byob_request = request; }
|
||||||
|
|
||||||
|
Optional<double> desired_size() const;
|
||||||
|
|
||||||
|
Optional<u32> const& auto_allocate_chunk_size() { return m_auto_allocate_chunk_size; }
|
||||||
|
void set_auto_allocate_chunk_size(Optional<u32> value) { m_auto_allocate_chunk_size = value; }
|
||||||
|
|
||||||
|
auto& cancel_algorithm() { return m_cancel_algorithm; }
|
||||||
|
void set_cancel_algorithm(Optional<CancelAlgorithm> value) { m_cancel_algorithm = move(value); }
|
||||||
|
|
||||||
|
bool close_requested() const { return m_close_requested; }
|
||||||
|
void set_close_requested(bool value) { m_close_requested = value; }
|
||||||
|
|
||||||
|
bool pull_again() const { return m_pull_again; }
|
||||||
|
void set_pull_again(bool value) { m_pull_again = value; }
|
||||||
|
|
||||||
|
auto& pull_algorithm() { return m_pull_algorithm; }
|
||||||
|
void set_pull_algorithm(Optional<PullAlgorithm> value) { m_pull_algorithm = move(value); }
|
||||||
|
|
||||||
|
bool pulling() const { return m_pulling; }
|
||||||
|
void set_pulling(bool value) { m_pulling = value; }
|
||||||
|
|
||||||
|
SinglyLinkedList<PullIntoDescriptor>& pending_pull_intos() { return m_pending_pull_intos; }
|
||||||
|
|
||||||
|
SinglyLinkedList<ReadableByteStreamQueueEntry>& queue() { return m_queue; }
|
||||||
|
|
||||||
|
u32 queue_total_size() const { return m_queue_total_size; }
|
||||||
|
void set_queue_total_size(u32 size) { m_queue_total_size = size; }
|
||||||
|
|
||||||
|
bool started() const { return m_started; }
|
||||||
|
void set_started(bool value) { m_started = value; }
|
||||||
|
|
||||||
|
u32 strategy_hwm() const { return m_strategy_hwm; }
|
||||||
|
void set_strategy_hwm(u32 value) { m_strategy_hwm = value; }
|
||||||
|
|
||||||
|
JS::GCPtr<ReadableStream const> stream() const { return m_stream; }
|
||||||
|
JS::GCPtr<ReadableStream> stream() { return m_stream; }
|
||||||
|
void set_stream(JS::GCPtr<ReadableStream> stream) { m_stream = stream; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit ReadableByteStreamController(JS::Realm&);
|
||||||
|
|
||||||
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablebytestreamcontroller-autoallocatechunksize
|
||||||
|
// A positive integer, when the automatic buffer allocation feature is enabled. In that case, this value specifies the size of buffer to allocate. It is undefined otherwise.
|
||||||
|
Optional<u32> m_auto_allocate_chunk_size;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablebytestreamcontroller-byobrequest
|
||||||
|
// A ReadableStreamBYOBRequest instance representing the current BYOB pull request, or null if there are no pending requests
|
||||||
|
JS::GCPtr<ReadableStreamBYOBRequest> m_byob_request;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablestreamdefaultcontroller-cancelalgorithm
|
||||||
|
// A promise-returning algorithm, taking one argument (the cancel reason), which communicates a requested cancelation to the underlying source
|
||||||
|
Optional<CancelAlgorithm> m_cancel_algorithm;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablestreamdefaultcontroller-closerequested
|
||||||
|
// A boolean flag indicating whether the stream has been closed by its underlying source, but still has chunks in its internal queue that have not yet been read
|
||||||
|
bool m_close_requested { false };
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablestreamdefaultcontroller-pullagain
|
||||||
|
// A boolean flag set to true if the stream’s mechanisms requested a call to the underlying source's pull algorithm to pull more data, but the pull could not yet be done since a previous call is still executing
|
||||||
|
bool m_pull_again { false };
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablestreamdefaultcontroller-pullalgorithm
|
||||||
|
// A promise-returning algorithm that pulls data from the underlying source
|
||||||
|
Optional<PullAlgorithm> m_pull_algorithm;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablestreamdefaultcontroller-pulling
|
||||||
|
// A boolean flag set to true while the underlying source's pull algorithm is executing and the returned promise has not yet fulfilled, used to prevent reentrant calls
|
||||||
|
bool m_pulling { false };
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablebytestreamcontroller-pendingpullintos
|
||||||
|
// A list of pull-into descriptors
|
||||||
|
SinglyLinkedList<PullIntoDescriptor> m_pending_pull_intos;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablestreamdefaultcontroller-queue
|
||||||
|
// A list representing the stream’s internal queue of chunks
|
||||||
|
SinglyLinkedList<ReadableByteStreamQueueEntry> m_queue;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablestreamdefaultcontroller-queuetotalsize
|
||||||
|
// The total size of all the chunks stored in [[queue]]
|
||||||
|
u32 m_queue_total_size { 0 };
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablestreamdefaultcontroller-started
|
||||||
|
// A boolean flag indicating whether the underlying source has finished starting
|
||||||
|
bool m_started { false };
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablestreamdefaultcontroller-strategyhwm
|
||||||
|
// A number supplied to the constructor as part of the stream’s queuing strategy, indicating the point at which the stream will apply backpressure to its underlying source
|
||||||
|
u32 m_strategy_hwm { 0 };
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#readablestreamdefaultcontroller-stream
|
||||||
|
// The ReadableStream instance controlled
|
||||||
|
JS::GCPtr<ReadableStream> m_stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#import <Streams/ReadableStreamBYOBRequest.idl>
|
||||||
|
|
||||||
|
[Exposed=*]
|
||||||
|
interface ReadableByteStreamController {
|
||||||
|
readonly attribute ReadableStreamBYOBRequest? byobRequest;
|
||||||
|
readonly attribute unrestricted double? desiredSize;
|
||||||
|
|
||||||
|
// FIXME: Implement
|
||||||
|
// undefined close();
|
||||||
|
// undefined enqueue(ArrayBufferView chunk);
|
||||||
|
// undefined error(optional any e);
|
||||||
|
};
|
|
@ -4,6 +4,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <LibWeb/Streams/ReadableByteStreamController.h>
|
||||||
#include <LibWeb/Streams/ReadableStreamBYOBRequest.h>
|
#include <LibWeb/Streams/ReadableStreamBYOBRequest.h>
|
||||||
|
|
||||||
namespace Web::Streams {
|
namespace Web::Streams {
|
||||||
|
|
|
@ -27,7 +27,7 @@ private:
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#readablestreambyobrequest-controller
|
// https://streams.spec.whatwg.org/#readablestreambyobrequest-controller
|
||||||
// The parent ReadableByteStreamController instance
|
// The parent ReadableByteStreamController instance
|
||||||
JS::GCPtr<JS::Object> m_controller;
|
JS::GCPtr<ReadableByteStreamController> m_controller;
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#readablestreambyobrequest-view
|
// https://streams.spec.whatwg.org/#readablestreambyobrequest-view
|
||||||
// A typed array representing the destination region to which the controller can write generated data, or null after the BYOB request has been invalidated.
|
// A typed array representing the destination region to which the controller can write generated data, or null after the BYOB request has been invalidated.
|
||||||
|
|
|
@ -179,6 +179,7 @@ libweb_js_bindings(NavigationTiming/PerformanceTiming)
|
||||||
libweb_js_bindings(PerformanceTimeline/PerformanceEntry)
|
libweb_js_bindings(PerformanceTimeline/PerformanceEntry)
|
||||||
libweb_js_bindings(RequestIdleCallback/IdleDeadline)
|
libweb_js_bindings(RequestIdleCallback/IdleDeadline)
|
||||||
libweb_js_bindings(ResizeObserver/ResizeObserver)
|
libweb_js_bindings(ResizeObserver/ResizeObserver)
|
||||||
|
libweb_js_bindings(Streams/ReadableByteStreamController)
|
||||||
libweb_js_bindings(Streams/ReadableStream)
|
libweb_js_bindings(Streams/ReadableStream)
|
||||||
libweb_js_bindings(Streams/ReadableStreamBYOBRequest)
|
libweb_js_bindings(Streams/ReadableStreamBYOBRequest)
|
||||||
libweb_js_bindings(Streams/ReadableStreamDefaultController)
|
libweb_js_bindings(Streams/ReadableStreamDefaultController)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue