1use crate::ArrayBuffer;
2use crate::ArrayBufferView;
3use crate::BackingStore;
4use crate::Local;
5use crate::SharedRef;
6use crate::binding::memory_span_t;
7use crate::scope::PinScope;
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  #[inline(always)]
36  pub fn buffer<'s>(
37    &self,
38    scope: &PinScope<'s, '_, ()>,
39  ) -> Option<Local<'s, ArrayBuffer>> {
40    unsafe { scope.cast_local(|_| v8__ArrayBufferView__Buffer(self)) }
41  }
42
43  pub fn has_buffer(&self) -> bool {
45    unsafe { v8__ArrayBufferView__HasBuffer(self) }
46  }
47
48  #[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  #[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  #[inline(always)]
71  pub fn byte_length(&self) -> usize {
72    unsafe { v8__ArrayBufferView__ByteLength(self) }
73  }
74
75  #[inline(always)]
77  pub fn byte_offset(&self) -> usize {
78    unsafe { v8__ArrayBufferView__ByteOffset(self) }
79  }
80
81  #[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  #[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  #[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}