v8/
array_buffer_view.rs

1use crate::ArrayBuffer;
2use crate::ArrayBufferView;
3use crate::BackingStore;
4use crate::HandleScope;
5use crate::Local;
6use crate::SharedRef;
7use crate::binding::memory_span_t;
8use crate::support::int;
9use std::convert::TryInto;
10use std::ffi::c_void;
11
12unsafe extern "C" {
13  fn v8__ArrayBufferView__Buffer(
14    this: *const ArrayBufferView,
15  ) -> *const ArrayBuffer;
16  fn v8__ArrayBufferView__Buffer__Data(
17    this: *const ArrayBufferView,
18  ) -> *mut c_void;
19  fn v8__ArrayBufferView__ByteLength(this: *const ArrayBufferView) -> usize;
20  fn v8__ArrayBufferView__ByteOffset(this: *const ArrayBufferView) -> usize;
21  fn v8__ArrayBufferView__CopyContents(
22    this: *const ArrayBufferView,
23    dest: *mut c_void,
24    byte_length: int,
25  ) -> usize;
26  fn v8__ArrayBufferView__GetContents(
27    this: *const ArrayBufferView,
28    storage: memory_span_t,
29  ) -> memory_span_t;
30}
31
32impl ArrayBufferView {
33  /// Returns underlying ArrayBuffer.
34  #[inline(always)]
35  pub fn buffer<'s>(
36    &self,
37    scope: &mut HandleScope<'s>,
38  ) -> Option<Local<'s, ArrayBuffer>> {
39    unsafe { scope.cast_local(|_| v8__ArrayBufferView__Buffer(self)) }
40  }
41
42  /// Get a shared pointer to the backing store of this array buffer. This
43  /// pointer coordinates the lifetime management of the internal storage
44  /// with any live ArrayBuffers on the heap, even across isolates. The embedder
45  /// should not attempt to manage lifetime of the storage through other means.
46  #[inline(always)]
47  pub fn get_backing_store(&self) -> Option<SharedRef<BackingStore>> {
48    let buffer = unsafe { v8__ArrayBufferView__Buffer(self) };
49    unsafe { buffer.as_ref().map(|buffer| buffer.get_backing_store()) }
50  }
51
52  /// Returns the underlying storage for this `ArrayBufferView`, including the built-in `byte_offset`.
53  /// This is a more efficient way of calling `buffer(scope)->data()`, and may be called without a
54  /// scope.
55  #[inline(always)]
56  pub fn data(&self) -> *mut c_void {
57    unsafe {
58      v8__ArrayBufferView__Buffer__Data(self)
59        .add(v8__ArrayBufferView__ByteOffset(self))
60    }
61  }
62
63  /// Size of a view in bytes.
64  #[inline(always)]
65  pub fn byte_length(&self) -> usize {
66    unsafe { v8__ArrayBufferView__ByteLength(self) }
67  }
68
69  /// Byte offset in |Buffer|.
70  #[inline(always)]
71  pub fn byte_offset(&self) -> usize {
72    unsafe { v8__ArrayBufferView__ByteOffset(self) }
73  }
74
75  /// Copy the contents of the ArrayBufferView's buffer to an embedder defined
76  /// memory without additional overhead that calling ArrayBufferView::Buffer
77  /// might incur.
78  /// Returns the number of bytes actually written.
79  #[inline(always)]
80  pub fn copy_contents(&self, dest: &mut [u8]) -> usize {
81    unsafe {
82      v8__ArrayBufferView__CopyContents(
83        self,
84        dest.as_mut_ptr() as *mut c_void,
85        dest.len().try_into().unwrap(),
86      )
87    }
88  }
89
90  /// Returns the contents of the ArrayBufferView's buffer as a MemorySpan. If
91  /// the contents are on the V8 heap, they get copied into `storage`. Otherwise
92  /// a view into the off-heap backing store is returned. The provided storage
93  /// should be at least as large as the maximum on-heap size of a TypedArray,
94  /// which is available as `v8::TYPED_ARRAY_MAX_SIZE_IN_HEAP`.
95  #[inline(always)]
96  pub unsafe fn get_contents_raw_parts(
97    &self,
98    storage: &mut [u8],
99  ) -> (*mut u8, usize) {
100    unsafe {
101      let span = v8__ArrayBufferView__GetContents(
102        self,
103        memory_span_t {
104          data: storage.as_mut_ptr(),
105          size: storage.len(),
106        },
107      );
108      (span.data, span.size)
109    }
110  }
111
112  /// Returns the contents of the ArrayBufferView's buffer as a MemorySpan. If
113  /// the contents are on the V8 heap, they get copied into `storage`. Otherwise
114  /// a view into the off-heap backing store is returned. The provided storage
115  /// should be at least as large as the maximum on-heap size of a TypedArray,
116  /// which is available as `v8::TYPED_ARRAY_MAX_SIZE_IN_HEAP`.
117  #[inline(always)]
118  pub fn get_contents<'s, 'a>(&'s self, storage: &'a mut [u8]) -> &'a [u8]
119  where
120    's: 'a,
121  {
122    unsafe {
123      let (data, size) = self.get_contents_raw_parts(storage);
124      if data.is_null() {
125        debug_assert_eq!(size, 0);
126        std::slice::from_raw_parts(std::ptr::dangling(), size)
127      } else {
128        std::slice::from_raw_parts(data, size)
129      }
130    }
131  }
132}