diff options
author | Matthew Olsson <matthewcolsson@gmail.com> | 2023-04-09 10:40:15 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-04-27 07:57:53 +0200 |
commit | c9be75536733f66dfa0a8fc9a6251f2bb5031881 (patch) | |
tree | 32d66a816b44be34701047803a29c036b1360463 | |
parent | ef3810d03d57091ff82b8beea8212becab60e5ed (diff) | |
download | serenity-c9be75536733f66dfa0a8fc9a6251f2bb5031881.zip |
LibWeb: Implement ReadableByteStreamController.close()
5 files changed, 71 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp index 7114a0de6e..982019e4a0 100644 --- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp +++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.cpp @@ -864,6 +864,54 @@ void readable_byte_stream_controller_clear_pending_pull_intos(ReadableByteStream controller.pending_pull_intos().clear(); } +// https://streams.spec.whatwg.org/#readable-byte-stream-controller-close +WebIDL::ExceptionOr<void> readable_byte_stream_controller_close(ReadableByteStreamController& controller) +{ + auto& realm = controller.realm(); + + // 1. Let stream be controller.[[stream]]. + auto stream = controller.stream(); + + // 2. If controller.[[closeRequested]] is true or stream.[[state]] is not "readable", return. + if (controller.close_requested() || stream->state() != ReadableStream::State::Readable) + return {}; + + // 3. If controller.[[queueTotalSize]] > 0, + if (controller.queue_total_size() > 0.0) { + // 1. Set controller.[[closeRequested]] to true. + controller.set_close_requested(true); + + // 2. Return. + return {}; + } + + // 4. If controller.[[pendingPullIntos]] is not empty, + if (!controller.pending_pull_intos().is_empty()) { + // 1. Let firstPendingPullInto be controller.[[pendingPullIntos]][0]. + auto& first_pending_pull_into = controller.pending_pull_intos().first(); + + // 2. If firstPendingPullInto’s bytes filled > 0, + if (first_pending_pull_into.bytes_filled > 0) { + // 1. Let e be a new TypeError exception. + auto error = MUST_OR_THROW_OOM(JS::TypeError::create(realm, "Cannot close controller in the middle of processing a write request"sv)); + + // 2. Perform ! ReadableByteStreamControllerError(controller, e). + readable_byte_stream_controller_error(controller, error); + + // 3. Throw e. + return JS::throw_completion(error); + } + } + + // 5. Perform ! ReadableByteStreamControllerClearAlgorithms(controller). + readable_byte_stream_controller_clear_algorithms(controller); + + // 6. Perform ! ReadableStreamClose(stream). + readable_stream_close(*stream); + + return {}; +} + // https://streams.spec.whatwg.org/#readable-byte-stream-controller-error void readable_byte_stream_controller_error(ReadableByteStreamController& controller, JS::Value error) { diff --git a/Userland/Libraries/LibWeb/Streams/AbstractOperations.h b/Userland/Libraries/LibWeb/Streams/AbstractOperations.h index d77b500742..fce18bffc1 100644 --- a/Userland/Libraries/LibWeb/Streams/AbstractOperations.h +++ b/Userland/Libraries/LibWeb/Streams/AbstractOperations.h @@ -60,6 +60,7 @@ WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller_from_underly WebIDL::ExceptionOr<void> readable_byte_stream_controller_call_pull_if_needed(ReadableByteStreamController&); void readable_byte_stream_controller_clear_algorithms(ReadableByteStreamController&); void readable_byte_stream_controller_clear_pending_pull_intos(ReadableByteStreamController&); +WebIDL::ExceptionOr<void> readable_byte_stream_controller_close(ReadableByteStreamController&); void readable_byte_stream_controller_error(ReadableByteStreamController&, JS::Value error); WebIDL::ExceptionOr<void> readable_byte_stream_controller_fill_read_request_from_queue(ReadableByteStreamController&, NonnullRefPtr<ReadRequest>); Optional<double> readable_byte_stream_controller_get_desired_size(ReadableByteStreamController const&); diff --git a/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.cpp b/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.cpp index a7ff1c37ca..11f54242e8 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.cpp +++ b/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.cpp @@ -18,6 +18,25 @@ Optional<double> ReadableByteStreamController::desired_size() const return readable_byte_stream_controller_get_desired_size(*this); } +// https://streams.spec.whatwg.org/#rbs-controller-close +WebIDL::ExceptionOr<void> ReadableByteStreamController::close() +{ + // 1. If this.[[closeRequested]] is true, throw a TypeError exception. + if (m_close_requested) + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Controller is already closed"sv }; + + // 2. If this.[[stream]].[[state]] is not "readable", throw a TypeError exception. + if (m_stream->state() != ReadableStream::State::Readable) { + auto message = m_stream->state() == ReadableStream::State::Closed ? "Cannot close a closed stream"sv : "Cannot close an errored stream"sv; + return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, message }; + } + + // 3. Perform ? ReadableByteStreamControllerClose(this). + TRY(readable_byte_stream_controller_close(*this)); + + return {}; +} + ReadableByteStreamController::ReadableByteStreamController(JS::Realm& realm) : Bindings::PlatformObject(realm) { diff --git a/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.h b/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.h index 2afbfdc3d7..520f554953 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.h +++ b/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.h @@ -80,6 +80,7 @@ public: void set_byob_request(JS::GCPtr<ReadableStreamBYOBRequest> request) { m_byob_request = request; } Optional<double> desired_size() const; + WebIDL::ExceptionOr<void> close(); 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; } diff --git a/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.idl b/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.idl index 27c4f4bb72..923a2238d3 100644 --- a/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.idl +++ b/Userland/Libraries/LibWeb/Streams/ReadableByteStreamController.idl @@ -5,8 +5,9 @@ interface ReadableByteStreamController { readonly attribute ReadableStreamBYOBRequest? byobRequest; readonly attribute unrestricted double? desiredSize; + undefined close(); + // FIXME: Implement - // undefined close(); // undefined enqueue(ArrayBufferView chunk); // undefined error(optional any e); }; |