ReadableStreamDefaultController.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/SafeFunction.h>
  7. #include <LibWeb/Bindings/Intrinsics.h>
  8. #include <LibWeb/Bindings/ReadableStreamDefaultControllerPrototype.h>
  9. #include <LibWeb/Streams/AbstractOperations.h>
  10. #include <LibWeb/Streams/ReadableStream.h>
  11. #include <LibWeb/Streams/ReadableStreamDefaultController.h>
  12. #include <LibWeb/Streams/ReadableStreamDefaultReader.h>
  13. #include <LibWeb/WebIDL/ExceptionOr.h>
  14. #include <LibWeb/WebIDL/Promise.h>
  15. namespace Web::Streams {
  16. ReadableStreamDefaultController::ReadableStreamDefaultController(JS::Realm& realm)
  17. : Bindings::PlatformObject(realm)
  18. {
  19. }
  20. // https://streams.spec.whatwg.org/#rs-default-controller-desired-size
  21. Optional<float> ReadableStreamDefaultController::desired_size()
  22. {
  23. // 1. Return ! ReadableStreamDefaultControllerGetDesiredSize(this).
  24. return readable_stream_default_controller_get_desired_size(*this);
  25. }
  26. // https://streams.spec.whatwg.org/#rs-default-controller-close
  27. WebIDL::ExceptionOr<void> ReadableStreamDefaultController::close()
  28. {
  29. // 1. If ! ReadableStreamDefaultControllerCanCloseOrEnqueue(this) is false, throw a TypeError exception.
  30. if (!readable_stream_default_controller_can_close_or_enqueue(*this)) {
  31. return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Stream is not closable"sv };
  32. }
  33. // 2. Perform ! ReadableStreamDefaultControllerClose(this).
  34. readable_stream_default_controller_close(*this);
  35. return {};
  36. }
  37. // https://streams.spec.whatwg.org/#rs-default-controller-enqueue
  38. WebIDL::ExceptionOr<void> ReadableStreamDefaultController::enqueue(JS::Value chunk)
  39. {
  40. // 1. If ! ReadableStreamDefaultControllerCanCloseOrEnqueue(this) is false, throw a TypeError exception.
  41. if (!readable_stream_default_controller_can_close_or_enqueue(*this))
  42. return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Cannot enqueue chunk to stream"sv };
  43. // 2. Perform ? ReadableStreamDefaultControllerEnqueue(this, chunk).
  44. TRY(readable_stream_default_controller_enqueue(*this, chunk));
  45. return {};
  46. }
  47. // https://streams.spec.whatwg.org/#rs-default-controller-error
  48. void ReadableStreamDefaultController::error(JS::Value error)
  49. {
  50. // 1. Perform ! ReadableStreamDefaultControllerError(this, e).
  51. readable_stream_default_controller_error(*this, error);
  52. }
  53. // https://streams.spec.whatwg.org/#rs-default-controller-private-cancel
  54. WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::Promise>> ReadableStreamDefaultController::cancel_steps(JS::Value reason)
  55. {
  56. // 1. Perform ! ResetQueue(this).
  57. reset_queue(*this);
  58. // 2. Let result be the result of performing this.[[cancelAlgorithm]], passing reason.
  59. auto result = (*cancel_algorithm())(reason);
  60. // 3. Perform ! ReadableStreamDefaultControllerClearAlgorithms(this).
  61. readable_stream_default_controller_clear_algorithms(*this);
  62. // 4. Return result.
  63. return result;
  64. }
  65. // https://streams.spec.whatwg.org/#rs-default-controller-private-pull
  66. WebIDL::ExceptionOr<void> ReadableStreamDefaultController::pull_steps(Web::Streams::ReadRequest& read_request)
  67. {
  68. // 1. Let stream be this.[[stream]].
  69. auto& stream = *m_stream;
  70. // 2. If this.[[queue]] is not empty,
  71. if (!m_queue.is_empty()) {
  72. // 1. Let chunk be ! DequeueValue(this).
  73. auto chunk = dequeue_value(*this);
  74. // 2. If this.[[closeRequested]] is true and this.[[queue]] is empty,
  75. if (m_close_requested && m_queue.is_empty()) {
  76. // 1. Perform ! ReadableStreamDefaultControllerClearAlgorithms(this).
  77. readable_stream_default_controller_clear_algorithms(*this);
  78. // 2. Perform ! ReadableStreamClose(stream).
  79. readable_stream_close(stream);
  80. }
  81. // 3. Otherwise, perform ! ReadableStreamDefaultControllerCallPullIfNeeded(this).
  82. else {
  83. TRY(readable_stream_default_controller_can_pull_if_needed(*this));
  84. }
  85. // 4. Perform readRequest’s chunk steps, given chunk.
  86. read_request.on_chunk(chunk);
  87. }
  88. // 3. Otherwise,
  89. else {
  90. // 1. Perform ! ReadableStreamAddReadRequest(stream, readRequest).
  91. readable_stream_add_read_request(stream, read_request);
  92. // 2. Perform ! ReadableStreamDefaultControllerCallPullIfNeeded(this).
  93. TRY(readable_stream_default_controller_can_pull_if_needed(*this));
  94. }
  95. return {};
  96. }
  97. // https://streams.spec.whatwg.org/#abstract-opdef-readablestreamdefaultcontroller-releasesteps
  98. WebIDL::ExceptionOr<void> ReadableStreamDefaultController::release_steps()
  99. {
  100. // 1. Return.
  101. return {};
  102. }
  103. JS::ThrowCompletionOr<void> ReadableStreamDefaultController::initialize(JS::Realm& realm)
  104. {
  105. MUST_OR_THROW_OOM(Base::initialize(realm));
  106. set_prototype(&Bindings::ensure_web_prototype<Bindings::ReadableStreamDefaultControllerPrototype>(realm, "ReadableStreamDefaultController"));
  107. return {};
  108. }
  109. void ReadableStreamDefaultController::visit_edges(Cell::Visitor& visitor)
  110. {
  111. Base::visit_edges(visitor);
  112. for (auto const& item : m_queue)
  113. visitor.visit(item.value);
  114. visitor.visit(m_stream);
  115. }
  116. }