AbstractOperations.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
  3. * Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
  4. * Copyright (c) 2023-2024, Shannon Booth <shannon@serenityos.org>
  5. * Copyright (c) 2023-2024, Kenneth Myhra <kennethmyhra@serenityos.org>
  6. *
  7. * SPDX-License-Identifier: BSD-2-Clause
  8. */
  9. #pragma once
  10. #include <LibGC/Ptr.h>
  11. #include <LibWeb/Forward.h>
  12. #include <LibWeb/Streams/Algorithms.h>
  13. #include <LibWeb/Streams/ReadableStream.h>
  14. #include <LibWeb/WebIDL/CallbackType.h>
  15. #include <LibWeb/WebIDL/ExceptionOr.h>
  16. #include <LibWeb/WebIDL/Promise.h>
  17. #include <LibWeb/WebIDL/Types.h>
  18. namespace Web::Streams {
  19. WebIDL::ExceptionOr<GC::Ref<ReadableStreamDefaultReader>> acquire_readable_stream_default_reader(ReadableStream&);
  20. WebIDL::ExceptionOr<GC::Ref<ReadableStreamBYOBReader>> acquire_readable_stream_byob_reader(ReadableStream&);
  21. bool is_readable_stream_locked(ReadableStream const&);
  22. GC::Ref<SizeAlgorithm> extract_size_algorithm(JS::VM&, QueuingStrategy const&);
  23. WebIDL::ExceptionOr<double> extract_high_water_mark(QueuingStrategy const&, double default_hwm);
  24. void readable_stream_close(ReadableStream&);
  25. void readable_stream_error(ReadableStream&, JS::Value error);
  26. WebIDL::ExceptionOr<GC::Ref<ReadableStream>> readable_stream_from_iterable(JS::VM& vm, JS::Value async_iterable);
  27. void readable_stream_add_read_request(ReadableStream&, GC::Ref<ReadRequest>);
  28. void readable_stream_add_read_into_request(ReadableStream&, GC::Ref<ReadIntoRequest>);
  29. GC::Ref<WebIDL::Promise> readable_stream_cancel(ReadableStream&, JS::Value reason);
  30. void readable_stream_fulfill_read_into_request(ReadableStream&, JS::Value chunk, bool done);
  31. void readable_stream_fulfill_read_request(ReadableStream&, JS::Value chunk, bool done);
  32. size_t readable_stream_get_num_read_into_requests(ReadableStream const&);
  33. size_t readable_stream_get_num_read_requests(ReadableStream const&);
  34. bool readable_stream_has_byob_reader(ReadableStream const&);
  35. bool readable_stream_has_default_reader(ReadableStream const&);
  36. GC::Ref<WebIDL::Promise> readable_stream_pipe_to(ReadableStream& source, WritableStream& dest, bool prevent_close, bool prevent_abort, bool prevent_cancel, JS::Value signal = JS::js_undefined());
  37. WebIDL::ExceptionOr<ReadableStreamPair> readable_stream_tee(JS::Realm&, ReadableStream&, bool clone_for_branch2);
  38. WebIDL::ExceptionOr<ReadableStreamPair> readable_stream_default_tee(JS::Realm& realm, ReadableStream& stream, bool clone_for_branch2);
  39. WebIDL::ExceptionOr<ReadableStreamPair> readable_byte_stream_tee(JS::Realm& realm, ReadableStream& stream);
  40. GC::Ref<WebIDL::Promise> readable_stream_reader_generic_cancel(ReadableStreamGenericReaderMixin&, JS::Value reason);
  41. void readable_stream_reader_generic_initialize(ReadableStreamReader, ReadableStream&);
  42. void readable_stream_reader_generic_release(ReadableStreamGenericReaderMixin&);
  43. void readable_stream_default_reader_error_read_requests(ReadableStreamDefaultReader&, JS::Value error);
  44. void readable_stream_byob_reader_error_read_into_requests(ReadableStreamBYOBReader&, JS::Value error);
  45. JS::Value readable_byte_stream_controller_convert_pull_into_descriptor(JS::Realm&, PullIntoDescriptor const&);
  46. void readable_byte_stream_controller_pull_into(ReadableByteStreamController&, WebIDL::ArrayBufferView&, u64 min, ReadIntoRequest&);
  47. void readable_stream_byob_reader_read(ReadableStreamBYOBReader&, WebIDL::ArrayBufferView&, u64 min, ReadIntoRequest&);
  48. void readable_byte_stream_controller_fill_head_pull_into_descriptor(ReadableByteStreamController const&, u64 size, PullIntoDescriptor&);
  49. void readable_stream_default_reader_read(ReadableStreamDefaultReader&, ReadRequest&);
  50. void readable_stream_default_reader_release(ReadableStreamDefaultReader&);
  51. void readable_stream_byob_reader_release(ReadableStreamBYOBReader&);
  52. WebIDL::ExceptionOr<void> set_up_readable_stream_default_reader(ReadableStreamDefaultReader&, ReadableStream&);
  53. WebIDL::ExceptionOr<void> set_up_readable_stream_byob_reader(ReadableStreamBYOBReader&, ReadableStream&);
  54. void readable_stream_default_controller_close(ReadableStreamDefaultController&);
  55. bool readable_stream_default_controller_has_backpressure(ReadableStreamDefaultController&);
  56. WebIDL::ExceptionOr<void> readable_stream_default_controller_enqueue(ReadableStreamDefaultController&, JS::Value chunk);
  57. void readable_stream_default_controller_can_pull_if_needed(ReadableStreamDefaultController&);
  58. bool readable_stream_default_controller_should_call_pull(ReadableStreamDefaultController&);
  59. void readable_stream_default_controller_clear_algorithms(ReadableStreamDefaultController&);
  60. void readable_stream_default_controller_error(ReadableStreamDefaultController&, JS::Value error);
  61. Optional<double> readable_stream_default_controller_get_desired_size(ReadableStreamDefaultController&);
  62. bool readable_stream_default_controller_can_close_or_enqueue(ReadableStreamDefaultController&);
  63. WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller(ReadableStream&, ReadableStreamDefaultController&, GC::Ref<StartAlgorithm>, GC::Ref<PullAlgorithm>, GC::Ref<CancelAlgorithm>, double high_water_mark, GC::Ref<SizeAlgorithm>);
  64. WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller_from_underlying_source(ReadableStream&, JS::Value underlying_source_value, UnderlyingSource, double high_water_mark, GC::Ref<SizeAlgorithm>);
  65. WebIDL::ExceptionOr<void> set_up_readable_byte_stream_controller(ReadableStream&, ReadableByteStreamController&, GC::Ref<StartAlgorithm>, GC::Ref<PullAlgorithm>, GC::Ref<CancelAlgorithm>, double high_water_mark, JS::Value auto_allocate_chunk_size);
  66. WebIDL::ExceptionOr<void> set_up_readable_byte_stream_controller_from_underlying_source(ReadableStream&, JS::Value underlying_source, UnderlyingSource const& underlying_source_dict, double high_water_mark);
  67. GC::Ptr<ReadableStreamBYOBRequest> readable_byte_stream_controller_get_byob_request(GC::Ref<ReadableByteStreamController>);
  68. WebIDL::ExceptionOr<void> readable_byte_stream_controller_respond_in_readable_state(ReadableByteStreamController&, u64 bytes_written, PullIntoDescriptor&);
  69. void readable_byte_stream_controller_respond_in_closed_state(ReadableByteStreamController&, PullIntoDescriptor&);
  70. WebIDL::ExceptionOr<void> readable_byte_stream_controller_respond_internal(ReadableByteStreamController&, u64 bytes_written);
  71. WebIDL::ExceptionOr<void> readable_byte_stream_controller_respond(ReadableByteStreamController&, u64 bytes_written);
  72. WebIDL::ExceptionOr<void> readable_byte_stream_controller_respond_with_new_view(JS::Realm&, ReadableByteStreamController&, WebIDL::ArrayBufferView&);
  73. WebIDL::ExceptionOr<void> readable_byte_stream_controller_enqueue(ReadableByteStreamController& controller, JS::Value chunk);
  74. WebIDL::ExceptionOr<GC::Ref<JS::ArrayBuffer>> transfer_array_buffer(JS::Realm& realm, JS::ArrayBuffer& buffer);
  75. WebIDL::ExceptionOr<void> readable_byte_stream_controller_enqueue_detached_pull_into_queue(ReadableByteStreamController& controller, PullIntoDescriptor& pull_into_descriptor);
  76. void readable_byte_stream_controller_commit_pull_into_descriptor(ReadableStream&, PullIntoDescriptor const&);
  77. void readable_byte_stream_controller_process_read_requests_using_queue(ReadableByteStreamController& controller);
  78. [[nodiscard]] SinglyLinkedList<PullIntoDescriptor> readable_byte_stream_controller_process_pull_into_descriptors_using_queue(ReadableByteStreamController&);
  79. void readable_byte_stream_controller_enqueue_chunk_to_queue(ReadableByteStreamController& controller, GC::Ref<JS::ArrayBuffer> buffer, u32 byte_offset, u32 byte_length);
  80. WebIDL::ExceptionOr<void> readable_byte_stream_controller_enqueue_cloned_chunk_to_queue(ReadableByteStreamController& controller, JS::ArrayBuffer& buffer, u64 byte_offset, u64 byte_length);
  81. PullIntoDescriptor readable_byte_stream_controller_shift_pending_pull_into(ReadableByteStreamController& controller);
  82. void readable_byte_stream_controller_call_pull_if_needed(ReadableByteStreamController&);
  83. void readable_byte_stream_controller_clear_algorithms(ReadableByteStreamController&);
  84. void readable_byte_stream_controller_clear_pending_pull_intos(ReadableByteStreamController&);
  85. WebIDL::ExceptionOr<void> readable_byte_stream_controller_close(ReadableByteStreamController&);
  86. void readable_byte_stream_controller_error(ReadableByteStreamController&, JS::Value error);
  87. void readable_byte_stream_controller_fill_read_request_from_queue(ReadableByteStreamController&, GC::Ref<ReadRequest>);
  88. bool readable_byte_stream_controller_fill_pull_into_descriptor_from_queue(ReadableByteStreamController&, PullIntoDescriptor&);
  89. Optional<double> readable_byte_stream_controller_get_desired_size(ReadableByteStreamController const&);
  90. void readable_byte_stream_controller_handle_queue_drain(ReadableByteStreamController&);
  91. void readable_byte_stream_controller_invalidate_byob_request(ReadableByteStreamController&);
  92. bool readable_byte_stream_controller_should_call_pull(ReadableByteStreamController const&);
  93. WebIDL::ExceptionOr<GC::Ref<ReadableStream>> create_readable_stream(JS::Realm& realm, GC::Ref<StartAlgorithm> start_algorithm, GC::Ref<PullAlgorithm> pull_algorithm, GC::Ref<CancelAlgorithm> cancel_algorithm, Optional<double> high_water_mark = {}, GC::Ptr<SizeAlgorithm> size_algorithm = {});
  94. WebIDL::ExceptionOr<GC::Ref<ReadableStream>> create_readable_byte_stream(JS::Realm& realm, GC::Ref<StartAlgorithm> start_algorithm, GC::Ref<PullAlgorithm> pull_algorithm, GC::Ref<CancelAlgorithm> cancel_algorithm);
  95. WebIDL::ExceptionOr<GC::Ref<WritableStream>> create_writable_stream(JS::Realm& realm, GC::Ref<StartAlgorithm> start_algorithm, GC::Ref<WriteAlgorithm> write_algorithm, GC::Ref<CloseAlgorithm> close_algorithm, GC::Ref<AbortAlgorithm> abort_algorithm, double high_water_mark, GC::Ref<SizeAlgorithm> size_algorithm);
  96. void initialize_readable_stream(ReadableStream&);
  97. void initialize_writable_stream(WritableStream&);
  98. WebIDL::ExceptionOr<GC::Ref<WritableStreamDefaultWriter>> acquire_writable_stream_default_writer(WritableStream&);
  99. bool is_writable_stream_locked(WritableStream const&);
  100. WebIDL::ExceptionOr<void> set_up_writable_stream_default_writer(WritableStreamDefaultWriter&, WritableStream&);
  101. GC::Ref<WebIDL::Promise> writable_stream_abort(WritableStream&, JS::Value reason);
  102. GC::Ref<WebIDL::Promise> writable_stream_close(WritableStream&);
  103. GC::Ref<WebIDL::Promise> writable_stream_add_write_request(WritableStream&);
  104. bool writable_stream_close_queued_or_in_flight(WritableStream const&);
  105. void writable_stream_deal_with_rejection(WritableStream&, JS::Value error);
  106. void writable_stream_finish_erroring(WritableStream&);
  107. void writable_stream_finish_in_flight_close(WritableStream&);
  108. void writable_stream_finish_in_flight_close_with_error(WritableStream&, JS::Value error);
  109. void writable_stream_finish_in_flight_write(WritableStream&);
  110. void writable_stream_finish_in_flight_write_with_error(WritableStream&, JS::Value error);
  111. bool writable_stream_has_operation_marked_in_flight(WritableStream const&);
  112. void writable_stream_mark_close_request_in_flight(WritableStream&);
  113. void writable_stream_mark_first_write_request_in_flight(WritableStream&);
  114. void writable_stream_reject_close_and_closed_promise_if_needed(WritableStream&);
  115. void writable_stream_start_erroring(WritableStream&, JS::Value reason);
  116. void writable_stream_update_backpressure(WritableStream&, bool backpressure);
  117. GC::Ref<WebIDL::Promise> writable_stream_default_writer_abort(WritableStreamDefaultWriter&, JS::Value reason);
  118. GC::Ref<WebIDL::Promise> writable_stream_default_writer_close(WritableStreamDefaultWriter&);
  119. void writable_stream_default_writer_ensure_closed_promise_rejected(WritableStreamDefaultWriter&, JS::Value error);
  120. void writable_stream_default_writer_ensure_ready_promise_rejected(WritableStreamDefaultWriter&, JS::Value error);
  121. Optional<double> writable_stream_default_writer_get_desired_size(WritableStreamDefaultWriter const&);
  122. void writable_stream_default_writer_release(WritableStreamDefaultWriter&);
  123. GC::Ref<WebIDL::Promise> writable_stream_default_writer_write(WritableStreamDefaultWriter&, JS::Value chunk);
  124. WebIDL::ExceptionOr<void> set_up_writable_stream_default_controller(WritableStream&, WritableStreamDefaultController&, GC::Ref<StartAlgorithm>, GC::Ref<WriteAlgorithm>, GC::Ref<CloseAlgorithm>, GC::Ref<AbortAlgorithm>, double high_water_mark, GC::Ref<SizeAlgorithm>);
  125. WebIDL::ExceptionOr<void> set_up_writable_stream_default_controller_from_underlying_sink(WritableStream&, JS::Value underlying_sink_value, UnderlyingSink&, double high_water_mark, GC::Ref<SizeAlgorithm> size_algorithm);
  126. void writable_stream_default_controller_advance_queue_if_needed(WritableStreamDefaultController&);
  127. void writable_stream_default_controller_clear_algorithms(WritableStreamDefaultController&);
  128. void writable_stream_default_controller_close(WritableStreamDefaultController&);
  129. void writable_stream_default_controller_error(WritableStreamDefaultController&, JS::Value error);
  130. void writable_stream_default_controller_error_if_needed(WritableStreamDefaultController&, JS::Value error);
  131. bool writable_stream_default_controller_get_backpressure(WritableStreamDefaultController const&);
  132. JS::Value writable_stream_default_controller_get_chunk_size(WritableStreamDefaultController&, JS::Value chunk);
  133. double writable_stream_default_controller_get_desired_size(WritableStreamDefaultController const&);
  134. void writable_stream_default_controller_process_close(WritableStreamDefaultController&);
  135. void writable_stream_default_controller_process_write(WritableStreamDefaultController&, JS::Value chunk);
  136. void writable_stream_default_controller_write(WritableStreamDefaultController&, JS::Value chunk, JS::Value chunk_size);
  137. void initialize_transform_stream(TransformStream&, GC::Ref<WebIDL::Promise> start_promise, double writable_high_water_mark, GC::Ref<SizeAlgorithm> writable_size_algorithm, double readable_high_water_mark, GC::Ref<SizeAlgorithm> readable_size_algorithm);
  138. void set_up_transform_stream_default_controller(TransformStream&, TransformStreamDefaultController&, GC::Ref<TransformAlgorithm>, GC::Ref<FlushAlgorithm>, GC::Ref<CancelAlgorithm>);
  139. void set_up_transform_stream_default_controller_from_transformer(TransformStream&, JS::Value transformer, Transformer&);
  140. void transform_stream_default_controller_clear_algorithms(TransformStreamDefaultController&);
  141. WebIDL::ExceptionOr<void> transform_stream_default_controller_enqueue(TransformStreamDefaultController&, JS::Value chunk);
  142. void transform_stream_default_controller_error(TransformStreamDefaultController&, JS::Value error);
  143. void transform_stream_default_controller_terminate(TransformStreamDefaultController&);
  144. GC::Ref<WebIDL::Promise> transform_stream_default_controller_perform_transform(TransformStreamDefaultController&, JS::Value chunk);
  145. GC::Ref<WebIDL::Promise> transform_stream_default_sink_abort_algorithm(TransformStream&, JS::Value reason);
  146. GC::Ref<WebIDL::Promise> transform_stream_default_sink_close_algorithm(TransformStream&);
  147. GC::Ref<WebIDL::Promise> transform_stream_default_sink_write_algorithm(TransformStream&, JS::Value chunk);
  148. GC::Ref<WebIDL::Promise> transform_stream_default_source_pull_algorithm(TransformStream&);
  149. GC::Ref<WebIDL::Promise> transform_stream_default_source_cancel_algorithm(TransformStream&, JS::Value reason);
  150. void transform_stream_error(TransformStream&, JS::Value error);
  151. void transform_stream_error_writable_and_unblock_write(TransformStream&, JS::Value error);
  152. void transform_stream_set_backpressure(TransformStream&, bool backpressure);
  153. void transform_stream_unblock_write(TransformStream&);
  154. bool is_non_negative_number(JS::Value);
  155. 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);
  156. bool can_transfer_array_buffer(JS::ArrayBuffer const& array_buffer);
  157. WebIDL::ExceptionOr<JS::Value> clone_as_uint8_array(JS::Realm&, WebIDL::ArrayBufferView&);
  158. WebIDL::ExceptionOr<JS::Value> structured_clone(JS::Realm&, JS::Value value);
  159. // https://streams.spec.whatwg.org/#value-with-size
  160. struct ValueWithSize {
  161. JS::Value value;
  162. double size;
  163. };
  164. // https://streams.spec.whatwg.org/#dequeue-value
  165. template<typename T>
  166. JS::Value dequeue_value(T& container)
  167. {
  168. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  169. // 2. Assert: container.[[queue]] is not empty.
  170. VERIFY(!container.queue().is_empty());
  171. // 3. Let valueWithSize be container.[[queue]][0].
  172. // 4. Remove valueWithSize from container.[[queue]].
  173. auto value_with_size = container.queue().take_first();
  174. // 5. Set container.[[queueTotalSize]] to container.[[queueTotalSize]] − valueWithSize’s size.
  175. container.set_queue_total_size(container.queue_total_size() - value_with_size.size);
  176. // 6. If container.[[queueTotalSize]] < 0, set container.[[queueTotalSize]] to 0. (This can occur due to rounding errors.)
  177. if (container.queue_total_size() < 0.0)
  178. container.set_queue_total_size(0.0);
  179. // 7. Return valueWithSize’s value.
  180. return value_with_size.value;
  181. }
  182. // https://streams.spec.whatwg.org/#enqueue-value-with-size
  183. template<typename T>
  184. WebIDL::ExceptionOr<void> enqueue_value_with_size(T& container, JS::Value value, JS::Value size)
  185. {
  186. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  187. // 2. If ! IsNonNegativeNumber(size) is false, throw a RangeError exception.
  188. if (!is_non_negative_number(size))
  189. return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Chunk has non-positive size"sv };
  190. // 3. If size is +∞, throw a RangeError exception.
  191. if (size.is_positive_infinity())
  192. return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Chunk has infinite size"sv };
  193. // 4. Append a new value-with-size with value value and size size to container.[[queue]].
  194. container.queue().append({ value, size.as_double() });
  195. // 5. Set container.[[queueTotalSize]] to container.[[queueTotalSize]] + size.
  196. container.set_queue_total_size(container.queue_total_size() + size.as_double());
  197. return {};
  198. }
  199. // https://streams.spec.whatwg.org/#peek-queue-value
  200. template<typename T>
  201. JS::Value peek_queue_value(T& container)
  202. {
  203. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  204. // 2. Assert: container.[[queue]] is not empty.
  205. VERIFY(!container.queue().is_empty());
  206. // 3. Let valueWithSize be container.[[queue]][0].
  207. auto& value_with_size = container.queue().first();
  208. // 4. Return valueWithSize’s value.
  209. return value_with_size.value;
  210. }
  211. // https://streams.spec.whatwg.org/#reset-queue
  212. template<typename T>
  213. void reset_queue(T& container)
  214. {
  215. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  216. // 2. Set container.[[queue]] to a new empty list.
  217. container.queue().clear();
  218. // 3. Set container.[[queueTotalSize]] to 0.
  219. container.set_queue_total_size(0);
  220. }
  221. }