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