Browse Source

`JsArrayBuffer` take method and docs (#2454)

<!---
Thank you for contributing to Boa! Please fill out the template below, and remove or add any
information as you feel necessary.
--->

This Pull Request is related to the #2058 and the discussion in the discord chat.

It changes the following:

- Adds a `take` method to `JsArrayBuffer`
- Builds out `JsArrayBuffer` docs
- Adds a `JsArrayBuffer::take()` example to `jsarraybuffer.rs` in `boa_examples`
pull/2462/head
Kevin 2 years ago
parent
commit
8c882817c0
  1. 97
      boa_engine/src/object/builtins/jsarraybuffer.rs
  2. 10
      boa_examples/src/bin/jsarraybuffer.rs

97
boa_engine/src/object/builtins/jsarraybuffer.rs

@ -19,6 +19,23 @@ pub struct JsArrayBuffer {
impl JsArrayBuffer {
/// Create a new array buffer with byte length.
///
/// ```
/// # use boa_engine::{
/// # object::builtins::JsArrayBuffer,
/// # Context, JsResult
/// # };
/// # fn main() -> JsResult<()> {
/// # // Initialize context
/// # let context = &mut Context::default();
/// // Creates a blank array buffer of n bytes
/// let array_buffer = JsArrayBuffer::new(4, context)?;
///
/// assert_eq!(array_buffer.take()?, vec![0_u8; 4]);
///
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn new(byte_length: usize, context: &mut Context) -> JsResult<Self> {
let inner = ArrayBuffer::allocate(
@ -40,6 +57,24 @@ impl JsArrayBuffer {
/// This uses the passed byte block as the internal storage, it does not clone it!
///
/// The `byte_length` will be set to `byte_block.len()`.
///
/// ```
/// # use boa_engine::{
/// # object::builtins::JsArrayBuffer,
/// # Context, JsResult,
/// # };
/// # fn main() -> JsResult<()> {
/// # // Initialize context
/// # let context = &mut Context::default();
///
/// // Create a buffer from a chunk of data
/// let data_block: Vec<u8> = (0..5).collect();
/// let array_buffer = JsArrayBuffer::from_byte_block(data_block, context)?;
///
/// assert_eq!(array_buffer.take()?, (0..5).collect::<Vec<u8>>());
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn from_byte_block(byte_block: Vec<u8>, context: &mut Context) -> JsResult<Self> {
let byte_length = byte_block.len();
@ -92,6 +127,26 @@ impl JsArrayBuffer {
}
/// Returns the byte length of the array buffer.
///
/// ```
/// # use boa_engine::{
/// # object::builtins::JsArrayBuffer,
/// # Context, JsResult,
/// # };
/// # fn main() -> JsResult<()> {
/// # // Initialize context
/// # let context = &mut Context::default();
/// // Create a buffer from a chunk of data
/// let data_block: Vec<u8> = (0..5).collect();
/// let array_buffer = JsArrayBuffer::from_byte_block(data_block, context)?;
///
/// // Take the inner buffer
/// let buffer_length = array_buffer.byte_length(context);
///
/// assert_eq!(buffer_length, 5);
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn byte_length(&self, context: &mut Context) -> usize {
ArrayBuffer::get_byte_length(&self.inner.clone().into(), &[], context)
@ -99,6 +154,48 @@ impl JsArrayBuffer {
.as_number()
.expect("expected a number") as usize
}
/// Take the inner `ArrayBuffer`'s `array_buffer_data` field and replace it with `None`
///
/// Note: This causes the pre-existing `JsArrayBuffer` to become detached.
///
/// ```
/// # use boa_engine::{
/// # object::builtins::JsArrayBuffer,
/// # Context, JsResult,
/// # };
/// # fn main() -> JsResult<()> {
/// # // Initialize context
/// # let context = &mut Context::default();
/// // Create a buffer from a chunk of data
/// let data_block: Vec<u8> = (0..5).collect();
/// let array_buffer = JsArrayBuffer::from_byte_block(data_block, context)?;
///
/// // Take the inner buffer
/// let internal_buffer = array_buffer.take()?;
///
/// assert_eq!(internal_buffer, (0..5).collect::<Vec<u8>>());
///
/// // Anymore interaction with the buffer will return an error
/// let detached_err = array_buffer.take();
/// assert!(detached_err.is_err());
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn take(&self) -> JsResult<Vec<u8>> {
self.inner
.borrow_mut()
.as_array_buffer_mut()
.expect("inner must be an ArrayBuffer")
.array_buffer_data
.take()
.ok_or_else(|| {
JsNativeError::typ()
.with_message("ArrayBuffer is detached")
.into()
})
}
}
impl From<JsArrayBuffer> for JsObject {

10
boa_examples/src/bin/jsarraybuffer.rs

@ -56,5 +56,15 @@ fn main() -> JsResult<()> {
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
);
// We can also take the inner data from a JsArrayBuffer
let data_block: Vec<u8> = (0..5).collect();
let array_buffer = JsArrayBuffer::from_byte_block(data_block, context)?;
let internal_buffer = array_buffer.take()?;
assert_eq!(internal_buffer, (0..5).collect::<Vec<u8>>());
let detached_err = array_buffer.take();
assert!(detached_err.is_err());
Ok(())
}

Loading…
Cancel
Save