/* * Copyright (c) 2023, Matthew Olsson * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace Web::Streams { struct ReadableStreamReadResult { JS::Value value; bool done; }; class ReadRequest : public JS::Cell { JS_CELL(ReadRequest, JS::Cell); public: virtual ~ReadRequest() = default; virtual void on_chunk(JS::Value chunk) = 0; virtual void on_close() = 0; virtual void on_error(JS::Value error) = 0; }; class ReadLoopReadRequest final : public ReadRequest { JS_CELL(ReadLoopReadRequest, ReadRequest); JS_DECLARE_ALLOCATOR(ReadLoopReadRequest); public: // successSteps, which is an algorithm accepting a byte sequence using SuccessSteps = JS::HeapFunction; // failureSteps, which is an algorithm accepting a JavaScript value using FailureSteps = JS::HeapFunction; // AD-HOC: callback triggered on every chunk received from the stream. using ChunkSteps = JS::HeapFunction; ReadLoopReadRequest(JS::VM& vm, JS::Realm& realm, ReadableStreamDefaultReader& reader, JS::NonnullGCPtr success_steps, JS::NonnullGCPtr failure_steps, JS::GCPtr chunk_steps = {}); virtual void on_chunk(JS::Value chunk) override; virtual void on_close() override; virtual void on_error(JS::Value error) override; private: virtual void visit_edges(Visitor&) override; JS::VM& m_vm; JS::NonnullGCPtr m_realm; JS::NonnullGCPtr m_reader; ByteBuffer m_bytes; JS::NonnullGCPtr m_success_steps; JS::NonnullGCPtr m_failure_steps; JS::GCPtr m_chunk_steps; }; // https://streams.spec.whatwg.org/#readablestreamdefaultreader class ReadableStreamDefaultReader final : public Bindings::PlatformObject , public ReadableStreamGenericReaderMixin { WEB_PLATFORM_OBJECT(ReadableStreamDefaultReader, Bindings::PlatformObject); JS_DECLARE_ALLOCATOR(ReadableStreamDefaultReader); public: static WebIDL::ExceptionOr> construct_impl(JS::Realm&, JS::NonnullGCPtr); virtual ~ReadableStreamDefaultReader() override = default; JS::NonnullGCPtr read(); void read_a_chunk(Fetch::Infrastructure::IncrementalReadLoopReadRequest& read_request); void read_all_bytes(JS::NonnullGCPtr, JS::NonnullGCPtr); void read_all_chunks(JS::NonnullGCPtr, JS::NonnullGCPtr, JS::NonnullGCPtr); JS::NonnullGCPtr read_all_bytes_deprecated(); void release_lock(); SinglyLinkedList>& read_requests() { return m_read_requests; } private: explicit ReadableStreamDefaultReader(JS::Realm&); virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; SinglyLinkedList> m_read_requests; }; }