From 6547d35fa5a6ae29e25e7592c5b7a06cb8399c1e Mon Sep 17 00:00:00 2001 From: Taym Haddadi Date: Tue, 4 Feb 2025 12:58:46 +0100 Subject: [PATCH] Script: implement ReadableStreamBYOBRequest (#35074) * Script: implement ReadableStreamBYOBReader::Read Signed-off-by: Taym Haddadi * implement viewed_buffer_array_byte_length and byte_length Signed-off-by: Taym Haddadi * Correct BufferSource implemntation Signed-off-by: Taym Haddadi * Reduce BufferSource to two variants ArrayBuffer and ArrayBufferView Signed-off-by: Taym Haddadi * Scriptt: implement ReadableStreamBYOBRequest Signed-off-by: Taym Haddadi * fix is_detached_buffer and viewed_buffer_array_byte_length Signed-off-by: Taym Haddadi * Use if let Some instead of unwrap() Signed-off-by: Taym Haddadi --------- Signed-off-by: Taym Haddadi --- .../dom/readablebytestreamcontroller.rs | 13 ++++ .../script/dom/readablestreambyobrequest.rs | 66 +++++++++++++++---- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/components/script/dom/readablebytestreamcontroller.rs b/components/script/dom/readablebytestreamcontroller.rs index 8d1c1b91eed..85c2a08fe76 100644 --- a/components/script/dom/readablebytestreamcontroller.rs +++ b/components/script/dom/readablebytestreamcontroller.rs @@ -39,6 +39,19 @@ impl ReadableByteStreamController { ) { todo!() } + + /// + pub(crate) fn respond(&self, _bytes_written: u64) -> Fallible<()> { + todo!() + } + + /// + pub(crate) fn respond_with_new_view( + &self, + _view: HeapBufferSource, + ) -> Fallible<()> { + todo!() + } } impl ReadableByteStreamControllerMethods for ReadableByteStreamController { diff --git a/components/script/dom/readablestreambyobrequest.rs b/components/script/dom/readablestreambyobrequest.rs index 47df222e1d8..973dede62d9 100644 --- a/components/script/dom/readablestreambyobrequest.rs +++ b/components/script/dom/readablestreambyobrequest.rs @@ -3,37 +3,81 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom_struct::dom_struct; +use js::gc::CustomAutoRooterGuard; +use js::jsapi::Heap; +use js::typedarray::{ArrayBufferView, ArrayBufferViewU8}; +use super::bindings::buffer_source::{BufferSource, HeapBufferSource}; use crate::dom::bindings::codegen::Bindings::ReadableStreamBYOBRequestBinding::ReadableStreamBYOBRequestMethods; use crate::dom::bindings::import::module::{Error, Fallible}; use crate::dom::bindings::reflector::Reflector; +use crate::dom::bindings::root::MutNullableDom; +use crate::dom::readablebytestreamcontroller::ReadableByteStreamController; +use crate::dom::types::GlobalScope; use crate::script_runtime::JSContext as SafeJSContext; /// #[dom_struct] pub(crate) struct ReadableStreamBYOBRequest { reflector_: Reflector, + controller: MutNullableDom, + #[ignore_malloc_size_of = "mozjs"] + view: HeapBufferSource, } impl ReadableStreamBYOBRequestMethods for ReadableStreamBYOBRequest { /// fn GetView(&self, _cx: SafeJSContext) -> Option { - // TODO - None + // Return this.[[view]]. + self.view.buffer_to_option() } /// - fn Respond(&self, _bytes_written: u64) -> Fallible<()> { - // TODO - Err(Error::NotFound) + fn Respond(&self, bytes_written: u64) -> Fallible<()> { + let cx = GlobalScope::get_cx(); + + // If this.[[controller]] is undefined, throw a TypeError exception. + let controller = if let Some(controller) = self.controller.get() { + controller + } else { + return Err(Error::Type("controller is undefined".to_owned())); + }; + + // If ! IsDetachedBuffer(this.[[view]].[[ArrayBuffer]]) is true, throw a TypeError exception. + if self.view.is_detached_buffer(cx) { + return Err(Error::Type("buffer is detached".to_owned())); + } + + // Assert: this.[[view]].[[ByteLength]] > 0. + assert!(self.view.byte_length() > 0); + + // Assert: this.[[view]].[[ViewedArrayBuffer]].[[ByteLength]] > 0. + assert!(self.view.viewed_buffer_array_byte_length(cx) > 0); + + // Perform ? ReadableByteStreamControllerRespond(this.[[controller]], bytesWritten). + controller.respond(bytes_written) } /// - fn RespondWithNewView( - &self, - _view: js::gc::CustomAutoRooterGuard, - ) -> Fallible<()> { - // TODO - Err(Error::NotFound) + #[allow(unsafe_code)] + fn RespondWithNewView(&self, view: CustomAutoRooterGuard) -> Fallible<()> { + let view = HeapBufferSource::::new(BufferSource::ArrayBufferView( + Heap::boxed(unsafe { *view.underlying_object() }), + )); + + // If this.[[controller]] is undefined, throw a TypeError exception. + let controller = if let Some(controller) = self.controller.get() { + controller + } else { + return Err(Error::Type("controller is undefined".to_owned())); + }; + + // If ! IsDetachedBuffer(view.[[ViewedArrayBuffer]]) is true, throw a TypeError exception. + if self.view.is_detached_buffer(GlobalScope::get_cx()) { + return Err(Error::Type("buffer is detached".to_owned())); + } + + // Return ? ReadableByteStreamControllerRespondWithNewView(this.[[controller]], view). + controller.respond_with_new_view(view) } }