From 08be5deb3f6e8ac16d55d27946f42ecfa7a23196 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sat, 2 Dec 2023 21:26:38 +1300 Subject: [PATCH] LibWeb: Implement AO ReadableByteStreamControllerRespond --- .../LibWeb/Streams/AbstractOperations.cpp | 41 +++++++++++++++++++ .../LibWeb/Streams/AbstractOperations.h | 1 + 2 files changed, 42 insertions(+) diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp index 4d325e8448..8ba23d02d5 100644 --- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -1226,6 +1226,47 @@ WebIDL::ExceptionOr readable_byte_stream_controller_respond_internal(Reada return {}; } +// https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond +WebIDL::ExceptionOr readable_byte_stream_controller_respond(ReadableByteStreamController& controller, u64 bytes_written) +{ + auto& realm = controller.realm(); + + // 1. Assert: controller.[[pendingPullIntos]] is not empty. + VERIFY(!controller.pending_pull_intos().is_empty()); + + // 2. Let firstDescriptor be controller.[[pendingPullIntos]][0]. + auto& first_descriptor = controller.pending_pull_intos().first(); + + // 3. Let state be controller.[[stream]].[[state]]. + auto state = controller.stream()->state(); + + // 4. If state is "closed", + if (state == ReadableStream::State::Closed) { + // 1. If bytesWritten is not 0, throw a TypeError exception. + if (bytes_written != 0) + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Bytes written is not zero for closed stream"sv }; + } + // 5. Otherwise, + else { + // 1. Assert: state is "readable". + VERIFY(state == ReadableStream::State::Readable); + + // 2. If bytesWritten is 0, throw a TypeError exception. + if (bytes_written == 0) + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Bytes written is zero for stream which is not closed"sv }; + + // 3. If firstDescriptor’s bytes filled + bytesWritten > firstDescriptor’s byte length, throw a RangeError exception. + if (first_descriptor.bytes_filled + bytes_written > first_descriptor.byte_length) + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Bytes written is greater than the pull requests byte length"sv }; + } + + // 6. Set firstDescriptor’s buffer to ! TransferArrayBuffer(firstDescriptor’s buffer). + first_descriptor.buffer = MUST(transfer_array_buffer(realm, *first_descriptor.buffer)); + + // 7. Perform ? ReadableByteStreamControllerRespondInternal(controller, bytesWritten). + return readable_byte_stream_controller_respond_internal(controller, bytes_written); +} + // https://streams.spec.whatwg.org/#readable-stream-default-controller-error void readable_stream_default_controller_error(ReadableStreamDefaultController& controller, JS::Value error) { diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.h b/Userland/Libraries/LibWeb/Streams/AbstractOperations.h index c03069bcc8..d7d2be43eb 100644 --- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.h +++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.h @@ -83,6 +83,7 @@ JS::GCPtr readable_byte_stream_controller_get_byob_re WebIDL::ExceptionOr readable_byte_stream_controller_respond_in_readable_state(ReadableByteStreamController&, u64 bytes_written, PullIntoDescriptor&); void readable_byte_stream_controller_respond_in_closed_state(ReadableByteStreamController&, PullIntoDescriptor&); WebIDL::ExceptionOr readable_byte_stream_controller_respond_internal(ReadableByteStreamController&, u64 bytes_written); +WebIDL::ExceptionOr readable_byte_stream_controller_respond(ReadableByteStreamController&, u64 bytes_written); WebIDL::ExceptionOr readable_stream_enqueue(ReadableStreamController& controller, JS::Value chunk); WebIDL::ExceptionOr readable_byte_stream_controller_enqueue(ReadableByteStreamController& controller, JS::Value chunk);