AbstractOperations.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
  3. * Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
  4. * Copyright (c) 2023, Shannon Booth <shannon.ml.booth@gmail.com>
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #pragma once
  9. #include <LibJS/Heap/GCPtr.h>
  10. #include <LibWeb/Forward.h>
  11. #include <LibWeb/Streams/ReadableStream.h>
  12. #include <LibWeb/WebIDL/CallbackType.h>
  13. #include <LibWeb/WebIDL/ExceptionOr.h>
  14. #include <LibWeb/WebIDL/Promise.h>
  15. namespace Web::Streams {
  16. using SizeAlgorithm = JS::SafeFunction<JS::Completion(JS::Value)>;
  17. using PullAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>>()>;
  18. using CancelAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>>(JS::Value)>;
  19. using StartAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::Value>()>;
  20. using AbortAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>>(JS::Value)>;
  21. using CloseAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>>()>;
  22. using WriteAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>>(JS::Value)>;
  23. using FlushAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>>()>;
  24. using TransformAlgorithm = JS::SafeFunction<WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>>(JS::Value)>;
  25. WebIDL::ExceptionOr<JS::NonnullGCPtr<ReadableStreamDefaultReader>> acquire_readable_stream_default_reader(ReadableStream&);
  26. WebIDL::ExceptionOr<JS::NonnullGCPtr<ReadableStreamBYOBReader>> acquire_readable_stream_byob_reader(ReadableStream&);
  27. bool is_readable_stream_locked(ReadableStream const&);
  28. SizeAlgorithm extract_size_algorithm(QueuingStrategy const&);
  29. WebIDL::ExceptionOr<double> extract_high_water_mark(QueuingStrategy const&, double default_hwm);
  30. void readable_stream_close(ReadableStream&);
  31. void readable_stream_error(ReadableStream&, JS::Value error);
  32. void readable_stream_add_read_request(ReadableStream&, ReadRequest const&);
  33. WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> readable_stream_cancel(ReadableStream&, JS::Value reason);
  34. void readable_stream_fulfill_read_request(ReadableStream&, JS::Value chunk, bool done);
  35. size_t readable_stream_get_num_read_into_requests(ReadableStream const&);
  36. size_t readable_stream_get_num_read_requests(ReadableStream const&);
  37. bool readable_stream_has_byob_reader(ReadableStream const&);
  38. bool readable_stream_has_default_reader(ReadableStream const&);
  39. WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> readable_stream_reader_generic_cancel(ReadableStreamGenericReaderMixin&, JS::Value reason);
  40. void readable_stream_reader_generic_initialize(ReadableStreamReader, ReadableStream&);
  41. WebIDL::ExceptionOr<void> readable_stream_reader_generic_release(ReadableStreamGenericReaderMixin&);
  42. void readable_stream_default_reader_error_read_requests(ReadableStreamDefaultReader&, JS::Value error);
  43. WebIDL::ExceptionOr<void> readable_stream_default_reader_read(ReadableStreamDefaultReader&, ReadRequest&);
  44. WebIDL::ExceptionOr<void> readable_stream_default_reader_release(ReadableStreamDefaultReader&);
  45. WebIDL::ExceptionOr<void> set_up_readable_stream_default_reader(ReadableStreamDefaultReader&, ReadableStream&);
  46. WebIDL::ExceptionOr<void> set_up_readable_stream_byob_reader(ReadableStreamBYOBReader&, ReadableStream&);
  47. void readable_stream_default_controller_close(ReadableStreamDefaultController&);
  48. WebIDL::ExceptionOr<void> readable_stream_default_controller_enqueue(ReadableStreamDefaultController&, JS::Value chunk);
  49. WebIDL::ExceptionOr<void> readable_stream_default_controller_can_pull_if_needed(ReadableStreamDefaultController&);
  50. bool readable_stream_default_controller_should_call_pull(ReadableStreamDefaultController&);
  51. void readable_stream_default_controller_clear_algorithms(ReadableStreamDefaultController&);
  52. void readable_stream_default_controller_error(ReadableStreamDefaultController&, JS::Value error);
  53. Optional<double> readable_stream_default_controller_get_desired_size(ReadableStreamDefaultController&);
  54. bool readable_stream_default_controller_can_close_or_enqueue(ReadableStreamDefaultController&);
  55. WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller(ReadableStream&, ReadableStreamDefaultController&, StartAlgorithm&&, PullAlgorithm&&, CancelAlgorithm&&, double high_water_mark, SizeAlgorithm&&);
  56. WebIDL::ExceptionOr<void> set_up_readable_stream_default_controller_from_underlying_source(ReadableStream&, JS::Value underlying_source_value, UnderlyingSource, double high_water_mark, SizeAlgorithm&&);
  57. WebIDL::ExceptionOr<void> set_up_readable_stream_controller_with_byte_reading_support(ReadableStream&, Optional<PullAlgorithm>&& = {}, Optional<CancelAlgorithm>&& = {}, double high_water_mark = 0);
  58. WebIDL::ExceptionOr<void> set_up_readable_byte_stream_controller(ReadableStream&, ReadableByteStreamController&, StartAlgorithm&&, PullAlgorithm&&, CancelAlgorithm&&, double high_water_mark, JS::Value auto_allocate_chunk_size);
  59. 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);
  60. WebIDL::ExceptionOr<void> readable_stream_enqueue(ReadableStreamController& controller, JS::Value chunk);
  61. WebIDL::ExceptionOr<void> readable_byte_stream_controller_enqueue(ReadableByteStreamController& controller, JS::Value chunk);
  62. WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::ArrayBuffer>> transfer_array_buffer(JS::Realm& realm, JS::ArrayBuffer& buffer);
  63. WebIDL::ExceptionOr<void> readable_byte_stream_controller_enqueue_detached_pull_into_queue(ReadableByteStreamController& controller, PullIntoDescriptor& pull_into_descriptor);
  64. WebIDL::ExceptionOr<void> readable_byte_stream_controller_process_read_requests_using_queue(ReadableByteStreamController& controller);
  65. void readable_byte_stream_controller_enqueue_chunk_to_queue(ReadableByteStreamController& controller, JS::NonnullGCPtr<JS::ArrayBuffer> buffer, u32 byte_offset, u32 byte_length);
  66. WebIDL::ExceptionOr<void> readable_byte_stream_controller_enqueue_cloned_chunk_to_queue(ReadableByteStreamController& controller, JS::ArrayBuffer& buffer, u64 byte_offset, u64 byte_length);
  67. PullIntoDescriptor readable_byte_stream_controller_shift_pending_pull_into(ReadableByteStreamController& controller);
  68. WebIDL::ExceptionOr<void> readable_byte_stream_controller_call_pull_if_needed(ReadableByteStreamController&);
  69. void readable_byte_stream_controller_clear_algorithms(ReadableByteStreamController&);
  70. void readable_byte_stream_controller_clear_pending_pull_intos(ReadableByteStreamController&);
  71. WebIDL::ExceptionOr<void> readable_byte_stream_controller_close(ReadableByteStreamController&);
  72. void readable_byte_stream_controller_error(ReadableByteStreamController&, JS::Value error);
  73. WebIDL::ExceptionOr<void> readable_byte_stream_controller_fill_read_request_from_queue(ReadableByteStreamController&, NonnullRefPtr<ReadRequest>);
  74. Optional<double> readable_byte_stream_controller_get_desired_size(ReadableByteStreamController const&);
  75. WebIDL::ExceptionOr<void> readable_byte_stream_controller_handle_queue_drain(ReadableByteStreamController&);
  76. void readable_byte_stream_controller_invalidate_byob_request(ReadableByteStreamController&);
  77. bool readable_byte_stream_controller_should_call_pull(ReadableByteStreamController const&);
  78. WebIDL::ExceptionOr<JS::NonnullGCPtr<WritableStreamDefaultWriter>> acquire_writable_stream_default_writer(WritableStream&);
  79. bool is_writable_stream_locked(WritableStream const&);
  80. WebIDL::ExceptionOr<void> set_up_writable_stream_default_writer(WritableStreamDefaultWriter&, WritableStream&);
  81. WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_abort(WritableStream&, JS::Value reason);
  82. WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_close(WritableStream&);
  83. WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_add_write_request(WritableStream&);
  84. bool writable_stream_close_queued_or_in_flight(WritableStream const&);
  85. WebIDL::ExceptionOr<void> writable_stream_deal_with_rejection(WritableStream&, JS::Value error);
  86. WebIDL::ExceptionOr<void> writable_stream_finish_erroring(WritableStream&);
  87. void writable_stream_finish_in_flight_close(WritableStream&);
  88. WebIDL::ExceptionOr<void> writable_stream_finish_in_flight_close_with_error(WritableStream&, JS::Value error);
  89. void writable_stream_finish_in_flight_write(WritableStream&);
  90. WebIDL::ExceptionOr<void> writable_stream_finish_in_flight_write_with_error(WritableStream&, JS::Value error);
  91. bool writable_stream_has_operation_marked_in_flight(WritableStream const&);
  92. void writable_stream_mark_close_request_in_flight(WritableStream&);
  93. void writable_stream_mark_first_write_request_in_flight(WritableStream&);
  94. void writable_stream_reject_close_and_closed_promise_if_needed(WritableStream&);
  95. WebIDL::ExceptionOr<void> writable_stream_start_erroring(WritableStream&, JS::Value reason);
  96. void writable_stream_update_backpressure(WritableStream&, bool backpressure);
  97. WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_default_writer_abort(WritableStreamDefaultWriter&, JS::Value reason);
  98. WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_default_writer_close(WritableStreamDefaultWriter&);
  99. void writable_stream_default_writer_ensure_closed_promise_rejected(WritableStreamDefaultWriter&, JS::Value error);
  100. void writable_stream_default_writer_ensure_ready_promise_rejected(WritableStreamDefaultWriter&, JS::Value error);
  101. Optional<double> writable_stream_default_writer_get_desired_size(WritableStreamDefaultWriter const&);
  102. WebIDL::ExceptionOr<void> writable_stream_default_writer_release(WritableStreamDefaultWriter&);
  103. WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> writable_stream_default_writer_write(WritableStreamDefaultWriter&, JS::Value chunk);
  104. WebIDL::ExceptionOr<void> set_up_writable_stream_default_controller(WritableStream&, WritableStreamDefaultController&, StartAlgorithm&&, WriteAlgorithm&&, CloseAlgorithm&&, AbortAlgorithm&&, double high_water_mark, SizeAlgorithm&&);
  105. WebIDL::ExceptionOr<void> set_up_writable_stream_default_controller_from_underlying_sink(WritableStream&, JS::Value underlying_sink_value, UnderlyingSink&, double high_water_mark, SizeAlgorithm&& size_algorithm);
  106. WebIDL::ExceptionOr<void> writable_stream_default_controller_advance_queue_if_needed(WritableStreamDefaultController&);
  107. void writable_stream_default_controller_clear_algorithms(WritableStreamDefaultController&);
  108. WebIDL::ExceptionOr<void> writable_stream_default_controller_close(WritableStreamDefaultController&);
  109. WebIDL::ExceptionOr<void> writable_stream_default_controller_error(WritableStreamDefaultController&, JS::Value error);
  110. WebIDL::ExceptionOr<void> writable_stream_default_controller_error_if_needed(WritableStreamDefaultController&, JS::Value error);
  111. bool writable_stream_default_controller_get_backpressure(WritableStreamDefaultController const&);
  112. WebIDL::ExceptionOr<JS::Value> writable_stream_default_controller_get_chunk_size(WritableStreamDefaultController&, JS::Value chunk);
  113. double writable_stream_default_controller_get_desired_size(WritableStreamDefaultController const&);
  114. WebIDL::ExceptionOr<void> writable_stream_default_controller_process_close(WritableStreamDefaultController&);
  115. WebIDL::ExceptionOr<void> writable_stream_default_controller_process_write(WritableStreamDefaultController&, JS::Value chunk);
  116. WebIDL::ExceptionOr<void> writable_stream_default_controller_write(WritableStreamDefaultController&, JS::Value chunk, JS::Value chunk_size);
  117. bool is_non_negative_number(JS::Value);
  118. JS::Value create_close_sentinel();
  119. bool is_close_sentinel(JS::Value);
  120. JS::ThrowCompletionOr<JS::Handle<WebIDL::CallbackType>> property_to_callback(JS::VM& vm, JS::Value value, JS::PropertyKey const& property_key, WebIDL::OperationReturnsPromise);
  121. // https://streams.spec.whatwg.org/#value-with-size
  122. struct ValueWithSize {
  123. JS::Value value;
  124. double size;
  125. };
  126. // https://streams.spec.whatwg.org/#dequeue-value
  127. template<typename T>
  128. JS::Value dequeue_value(T& container)
  129. {
  130. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  131. // 2. Assert: container.[[queue]] is not empty.
  132. VERIFY(!container.queue().is_empty());
  133. // 3. Let valueWithSize be container.[[queue]][0].
  134. // 4. Remove valueWithSize from container.[[queue]].
  135. auto value_with_size = container.queue().take_first();
  136. // 5. Set container.[[queueTotalSize]] to container.[[queueTotalSize]] − valueWithSize’s size.
  137. container.set_queue_total_size(container.queue_total_size() - value_with_size.size);
  138. // 6. If container.[[queueTotalSize]] < 0, set container.[[queueTotalSize]] to 0. (This can occur due to rounding errors.)
  139. if (container.queue_total_size() < 0.0)
  140. container.set_queue_total_size(0.0);
  141. // 7. Return valueWithSize’s value.
  142. return value_with_size.value;
  143. }
  144. // https://streams.spec.whatwg.org/#enqueue-value-with-size
  145. template<typename T>
  146. WebIDL::ExceptionOr<void> enqueue_value_with_size(T& container, JS::Value value, JS::Value size_value)
  147. {
  148. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  149. // 2. If ! IsNonNegativeNumber(size) is false, throw a RangeError exception.
  150. if (!is_non_negative_number(size_value))
  151. return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Chunk has non-positive size"sv };
  152. auto size = size_value.as_double();
  153. // 3. If size is +∞, throw a RangeError exception.
  154. if (size == HUGE_VAL)
  155. return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Chunk has infinite size"sv };
  156. // 4. Append a new value-with-size with value value and size size to container.[[queue]].
  157. container.queue().append({ value, size });
  158. // 5. Set container.[[queueTotalSize]] to container.[[queueTotalSize]] + size.
  159. container.set_queue_total_size(container.queue_total_size() + size);
  160. return {};
  161. }
  162. // https://streams.spec.whatwg.org/#peek-queue-value
  163. template<typename T>
  164. JS::Value peek_queue_value(T& container)
  165. {
  166. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  167. // 2. Assert: container.[[queue]] is not empty.
  168. VERIFY(!container.queue().is_empty());
  169. // 3. Let valueWithSize be container.[[queue]][0].
  170. auto& value_with_size = container.queue().first();
  171. // 4. Return valueWithSize’s value.
  172. return value_with_size.value;
  173. }
  174. // https://streams.spec.whatwg.org/#reset-queue
  175. template<typename T>
  176. void reset_queue(T& container)
  177. {
  178. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  179. // 2. Set container.[[queue]] to a new empty list.
  180. container.queue().clear();
  181. // 3. Set container.[[queueTotalSize]] to 0.
  182. container.set_queue_total_size(0);
  183. }
  184. }