QueueOperations.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * Copyright (c) 2023, Matthew Olsson <mattco@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <LibJS/Runtime/Error.h>
  8. #include <LibWeb/WebIDL/ExceptionOr.h>
  9. namespace Web::Streams {
  10. // https://streams.spec.whatwg.org/#value-with-size
  11. struct ValueWithSize {
  12. JS::Value value;
  13. double size;
  14. };
  15. // https://streams.spec.whatwg.org/#dequeue-value
  16. template<typename T>
  17. JS::Value dequeue_value(T& container)
  18. {
  19. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  20. // 2. Assert: container.[[queue]] is not empty.
  21. VERIFY(!container.queue().is_empty());
  22. // 3. Let valueWithSize be container.[[queue]][0].
  23. // 4. Remove valueWithSize from container.[[queue]].
  24. auto value_with_size = container.queue().take_first();
  25. // 5. Set container.[[queueTotalSize]] to container.[[queueTotalSize]] − valueWithSize’s size.
  26. container.set_queue_total_size(container.queue_total_size() - value_with_size.size);
  27. // 6. If container.[[queueTotalSize]] < 0, set container.[[queueTotalSize]] to 0. (This can occur due to rounding errors.)
  28. if (container.queue_total_size() < 0.0)
  29. container.set_queue_total_size(0.0);
  30. // 7. Return valueWithSize’s value.
  31. return value_with_size.value;
  32. }
  33. // https://streams.spec.whatwg.org/#enqueue-value-with-size
  34. template<typename T>
  35. WebIDL::ExceptionOr<void> enqueue_value_with_size(T& container, JS::Value value, double size)
  36. {
  37. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  38. // 2. If ! IsNonNegativeNumber(size) is false, throw a RangeError exception.
  39. if (size < 0.0)
  40. return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Chunk has negative size"sv };
  41. // 3. If size is +∞, throw a RangeError exception.
  42. if (size == HUGE_VAL)
  43. return WebIDL::SimpleException { WebIDL::SimpleExceptionType::RangeError, "Chunk has infinite size"sv };
  44. // 4. Append a new value-with-size with value value and size size to container.[[queue]].
  45. container.queue().append({ value, size });
  46. // 5. Set container.[[queueTotalSize]] to container.[[queueTotalSize]] + size.
  47. container.set_queue_total_size(container.queue_total_size() + size);
  48. return {};
  49. }
  50. // https://streams.spec.whatwg.org/#peek-queue-value
  51. template<typename T>
  52. JS::Value peek_queue_value(T& container)
  53. {
  54. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  55. // 2. Assert: container.[[queue]] is not empty.
  56. VERIFY(!container.queue().is_empty());
  57. // 3. Let valueWithSize be container.[[queue]][0].
  58. auto& value_with_size = container.queue().first();
  59. // 4. Return valueWithSize’s value.
  60. return value_with_size.value;
  61. }
  62. // https://streams.spec.whatwg.org/#reset-queue
  63. template<typename T>
  64. void reset_queue(T& container)
  65. {
  66. // 1. Assert: container has [[queue]] and [[queueTotalSize]] internal slots.
  67. // 2. Set container.[[queue]] to a new empty list.
  68. container.queue().clear();
  69. // 3. Set container.[[queueTotalSize]] to 0.
  70. container.set_queue_total_size(0);
  71. }
  72. }