2022-09-21 23:27:13 +01:00
|
|
|
|
/*
|
|
|
|
|
|
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
2023-03-28 17:43:34 -07:00
|
|
|
|
* Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
|
2025-01-18 00:43:11 +13:00
|
|
|
|
* Copyright (c) 2023-2025, Shannon Booth <shannon@serenityos.org>
|
2024-04-06 18:56:42 +02:00
|
|
|
|
* Copyright (c) 2023-2024, Kenneth Myhra <kennethmyhra@serenityos.org>
|
2025-04-17 15:47:53 -04:00
|
|
|
|
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
2022-09-21 23:27:13 +01:00
|
|
|
|
*
|
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
2024-11-15 04:01:23 +13:00
|
|
|
|
#include <LibGC/Ptr.h>
|
2022-09-21 23:27:13 +01:00
|
|
|
|
#include <LibWeb/Forward.h>
|
2024-12-08 17:12:11 +13:00
|
|
|
|
#include <LibWeb/Streams/Algorithms.h>
|
2023-04-09 15:21:50 -07:00
|
|
|
|
#include <LibWeb/WebIDL/ExceptionOr.h>
|
2022-09-21 23:27:13 +01:00
|
|
|
|
|
|
|
|
|
|
namespace Web::Streams {
|
|
|
|
|
|
|
2025-04-17 20:09:43 -04:00
|
|
|
|
// 7.4. Abstract operations, https://streams.spec.whatwg.org/#qs-abstract-ops
|
2023-06-18 21:45:39 +12:00
|
|
|
|
WebIDL::ExceptionOr<double> extract_high_water_mark(QueuingStrategy const&, double default_hwm);
|
2025-04-17 20:09:43 -04:00
|
|
|
|
GC::Ref<SizeAlgorithm> extract_size_algorithm(JS::VM&, QueuingStrategy const&);
|
2023-06-18 21:45:39 +12:00
|
|
|
|
|
2025-05-20 17:18:20 -04:00
|
|
|
|
// 8.2. Transferable streams, https://streams.spec.whatwg.org/#transferrable-streams
|
|
|
|
|
|
void cross_realm_transform_send_error(JS::Realm&, HTML::MessagePort&, JS::Value error);
|
|
|
|
|
|
WebIDL::ExceptionOr<void> pack_and_post_message(JS::Realm&, HTML::MessagePort&, StringView type, JS::Value value);
|
|
|
|
|
|
WebIDL::ExceptionOr<void> pack_and_post_message_handling_error(JS::Realm&, HTML::MessagePort&, StringView type, JS::Value value);
|
|
|
|
|
|
void set_up_cross_realm_transform_readable(JS::Realm&, ReadableStream&, HTML::MessagePort&);
|
|
|
|
|
|
void set_up_cross_realm_transform_writable(JS::Realm&, WritableStream&, HTML::MessagePort&);
|
|
|
|
|
|
|
2025-04-17 20:09:43 -04:00
|
|
|
|
// 8.3. Miscellaneous, https://streams.spec.whatwg.org/#misc-abstract-ops
|
2023-12-02 20:28:17 +13:00
|
|
|
|
bool can_transfer_array_buffer(JS::ArrayBuffer const& array_buffer);
|
2025-04-17 20:09:43 -04:00
|
|
|
|
bool is_non_negative_number(JS::Value);
|
|
|
|
|
|
WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> transfer_array_buffer(JS::Realm& realm, JS::ArrayBuffer& buffer);
|
2024-01-28 12:20:55 -05:00
|
|
|
|
WebIDL::ExceptionOr<JS::Value> clone_as_uint8_array(JS::Realm&, WebIDL::ArrayBufferView&);
|
2024-01-28 10:22:52 -05:00
|
|
|
|
WebIDL::ExceptionOr<JS::Value> structured_clone(JS::Realm&, JS::Value value);
|
2025-04-17 20:09:43 -04:00
|
|
|
|
bool can_copy_data_block_bytes_buffer(JS::ArrayBuffer const& to_buffer, u64 to_index, JS::ArrayBuffer const& from_buffer, u64 from_index, u64 count);
|
|
|
|
|
|
|
|
|
|
|
|
// 8.1. Queue-with-sizes, https://streams.spec.whatwg.org/#queue-with-sizes
|
2023-04-09 15:21:54 -07:00
|
|
|
|
|
2023-04-09 15:21:50 -07:00
|
|
|
|
// https://streams.spec.whatwg.org/#value-with-size
|
|
|
|
|
|
struct ValueWithSize {
|
|
|
|
|
|
JS::Value value;
|
2025-04-17 20:09:43 -04:00
|
|
|
|
double size { 0 };
|
2023-04-09 15:21:50 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// https://streams.spec.whatwg.org/#dequeue-value
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
|
JS::Value dequeue_value(T& container)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
|
|
|
|
|
|
|
|
|
|
|
|
// 2. Assert: container.[[queue]] is not empty.
|
|
|
|
|
|
VERIFY(!container.queue().is_empty());
|
|
|
|
|
|
|
|
|
|
|
|
// 3. Let valueWithSize be container.[[queue]][0].
|
|
|
|
|
|
// 4. Remove valueWithSize from container.[[queue]].
|
|
|
|
|
|
auto value_with_size = container.queue().take_first();
|
|
|
|
|
|
|
|
|
|
|
|
// 5. Set container.[[queueTotalSize]] to container.[[queueTotalSize]] − valueWithSize’s size.
|
|
|
|
|
|
container.set_queue_total_size(container.queue_total_size() - value_with_size.size);
|
|
|
|
|
|
|
|
|
|
|
|
// 6. If container.[[queueTotalSize]] < 0, set container.[[queueTotalSize]] to 0. (This can occur due to rounding errors.)
|
|
|
|
|
|
if (container.queue_total_size() < 0.0)
|
|
|
|
|
|
container.set_queue_total_size(0.0);
|
|
|
|
|
|
|
|
|
|
|
|
// 7. Return valueWithSize’s value.
|
|
|
|
|
|
return value_with_size.value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// https://streams.spec.whatwg.org/#enqueue-value-with-size
|
|
|
|
|
|
template<typename T>
|
2024-04-29 17:20:55 -04:00
|
|
|
|
WebIDL::ExceptionOr<void> enqueue_value_with_size(T& container, JS::Value value, JS::Value size)
|
2023-04-09 15:21:50 -07:00
|
|
|
|
{
|
|
|
|
|
|
// 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
|
|
|
|
|
|
|
|
|
|
|
|
// 2. If ! IsNonNegativeNumber(size) is false, throw a RangeError exception.
|
2024-04-29 17:20:55 -04:00
|
|
|
|
if (!is_non_negative_number(size))
|
2023-04-09 15:21:54 -07:00
|
|
|
|
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Chunk has non-positive size"sv };
|
|
|
|
|
|
|
2023-04-09 15:21:50 -07:00
|
|
|
|
// 3. If size is +∞, throw a RangeError exception.
|
2024-04-29 17:20:55 -04:00
|
|
|
|
if (size.is_positive_infinity())
|
2023-04-09 15:21:50 -07:00
|
|
|
|
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Chunk has infinite size"sv };
|
|
|
|
|
|
|
|
|
|
|
|
// 4. Append a new value-with-size with value value and size size to container.[[queue]].
|
2024-04-29 17:20:55 -04:00
|
|
|
|
container.queue().append({ value, size.as_double() });
|
2023-04-09 15:21:50 -07:00
|
|
|
|
|
|
|
|
|
|
// 5. Set container.[[queueTotalSize]] to container.[[queueTotalSize]] + size.
|
2024-04-29 17:20:55 -04:00
|
|
|
|
container.set_queue_total_size(container.queue_total_size() + size.as_double());
|
2023-04-09 15:21:50 -07:00
|
|
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// https://streams.spec.whatwg.org/#peek-queue-value
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
|
JS::Value peek_queue_value(T& container)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
|
|
|
|
|
|
|
|
|
|
|
|
// 2. Assert: container.[[queue]] is not empty.
|
|
|
|
|
|
VERIFY(!container.queue().is_empty());
|
|
|
|
|
|
|
|
|
|
|
|
// 3. Let valueWithSize be container.[[queue]][0].
|
|
|
|
|
|
auto& value_with_size = container.queue().first();
|
|
|
|
|
|
|
|
|
|
|
|
// 4. Return valueWithSize’s value.
|
|
|
|
|
|
return value_with_size.value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// https://streams.spec.whatwg.org/#reset-queue
|
|
|
|
|
|
template<typename T>
|
|
|
|
|
|
void reset_queue(T& container)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
|
|
|
|
|
|
|
|
|
|
|
|
// 2. Set container.[[queue]] to a new empty list.
|
|
|
|
|
|
container.queue().clear();
|
|
|
|
|
|
|
|
|
|
|
|
// 3. Set container.[[queueTotalSize]] to 0.
|
|
|
|
|
|
container.set_queue_total_size(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-21 23:27:13 +01:00
|
|
|
|
}
|