use std::ffi::c_void;
use std::ops::Deref;
use std::ops::DerefMut;
use std::ptr::null_mut;
use std::slice;
use crate::support::long;
use crate::support::Delete;
use crate::support::Opaque;
use crate::support::Shared;
use crate::support::SharedRef;
use crate::support::UniqueRef;
use crate::ArrayBuffer;
use crate::InIsolate;
use crate::Isolate;
use crate::Local;
use crate::ToLocal;
extern "C" {
fn v8__ArrayBuffer__Allocator__NewDefaultAllocator() -> *mut Allocator;
fn v8__ArrayBuffer__Allocator__DELETE(this: &'static mut Allocator);
fn v8__ArrayBuffer__New__with_byte_length(
isolate: *mut Isolate,
byte_length: usize,
) -> *mut ArrayBuffer;
fn v8__ArrayBuffer__New__with_backing_store(
isolate: *mut Isolate,
backing_store: *mut SharedRef<BackingStore>,
) -> *mut ArrayBuffer;
fn v8__ArrayBuffer__ByteLength(self_: *const ArrayBuffer) -> usize;
fn v8__ArrayBuffer__GetBackingStore(
self_: *const ArrayBuffer,
) -> SharedRef<BackingStore>;
fn v8__ArrayBuffer__NewBackingStore__with_byte_length(
isolate: *mut Isolate,
byte_length: usize,
) -> *mut BackingStore;
fn v8__ArrayBuffer__NewBackingStore__with_data(
data: *mut c_void,
byte_length: usize,
deleter: BackingStoreDeleterCallback,
deleter_data: *mut c_void,
) -> *mut BackingStore;
fn v8__BackingStore__Data(this: *mut BackingStore) -> *mut c_void;
fn v8__BackingStore__ByteLength(this: *const BackingStore) -> usize;
fn v8__BackingStore__IsShared(this: *const BackingStore) -> bool;
fn v8__BackingStore__DELETE(this: &mut BackingStore);
fn std__shared_ptr__v8__BackingStore__COPY(
ptr: *const SharedRef<BackingStore>,
) -> SharedRef<BackingStore>;
fn std__shared_ptr__v8__BackingStore__CONVERT__std__unique_ptr(
unique: UniqueRef<BackingStore>,
) -> SharedRef<BackingStore>;
fn std__shared_ptr__v8__BackingStore__get(
ptr: *const SharedRef<BackingStore>,
) -> *mut BackingStore;
fn std__shared_ptr__v8__BackingStore__reset(
ptr: *mut SharedRef<BackingStore>,
);
fn std__shared_ptr__v8__BackingStore__use_count(
ptr: *const SharedRef<BackingStore>,
) -> long;
fn std__shared_ptr__v8__ArrayBuffer__Allocator__COPY(
ptr: *const SharedRef<Allocator>,
) -> SharedRef<Allocator>;
fn std__shared_ptr__v8__ArrayBuffer__Allocator__CONVERT__std__unique_ptr(
unique: UniqueRef<Allocator>,
) -> SharedRef<Allocator>;
fn std__shared_ptr__v8__ArrayBuffer__Allocator__get(
ptr: *const SharedRef<Allocator>,
) -> *mut Allocator;
fn std__shared_ptr__v8__ArrayBuffer__Allocator__reset(
ptr: *mut SharedRef<Allocator>,
);
fn std__shared_ptr__v8__ArrayBuffer__Allocator__use_count(
ptr: *const SharedRef<Allocator>,
) -> long;
}
#[repr(C)]
pub struct Allocator(Opaque);
impl Shared for Allocator {
fn clone(ptr: *const SharedRef<Self>) -> SharedRef<Self> {
unsafe { std__shared_ptr__v8__ArrayBuffer__Allocator__COPY(ptr) }
}
fn from_unique(unique: UniqueRef<Self>) -> SharedRef<Self> {
unsafe {
std__shared_ptr__v8__ArrayBuffer__Allocator__CONVERT__std__unique_ptr(
unique,
)
}
}
fn deref(ptr: *const SharedRef<Self>) -> *mut Self {
unsafe { std__shared_ptr__v8__ArrayBuffer__Allocator__get(ptr) }
}
fn reset(ptr: *mut SharedRef<Self>) {
unsafe { std__shared_ptr__v8__ArrayBuffer__Allocator__reset(ptr) }
}
fn use_count(ptr: *const SharedRef<Self>) -> long {
unsafe { std__shared_ptr__v8__ArrayBuffer__Allocator__use_count(ptr) }
}
}
pub fn new_default_allocator() -> SharedRef<Allocator> {
unsafe {
UniqueRef::from_raw(v8__ArrayBuffer__Allocator__NewDefaultAllocator())
}
.make_shared()
}
#[test]
fn test_default_allocator() {
new_default_allocator();
}
impl Delete for Allocator {
fn delete(&'static mut self) {
unsafe { v8__ArrayBuffer__Allocator__DELETE(self) };
}
}
pub type BackingStoreDeleterCallback = unsafe extern "C" fn(
data: *mut c_void,
byte_length: usize,
deleter_data: *mut c_void,
);
pub unsafe extern "C" fn backing_store_deleter_callback(
data: *mut c_void,
_byte_length: usize,
_deleter_data: *mut c_void,
) {
let b = Box::from_raw(data);
drop(b)
}
#[repr(C)]
pub struct BackingStore([usize; 6]);
unsafe impl Send for BackingStore {}
impl BackingStore {
pub fn data(&self) -> *mut c_void {
unsafe { v8__BackingStore__Data(self as *const _ as *mut Self) }
}
pub fn byte_length(&self) -> usize {
unsafe { v8__BackingStore__ByteLength(self) }
}
pub fn is_shared(&self) -> bool {
unsafe { v8__BackingStore__IsShared(self) }
}
}
impl Deref for BackingStore {
type Target = [u8];
fn deref(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.data() as *mut u8, self.byte_length()) }
}
}
impl DerefMut for BackingStore {
fn deref_mut(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(self.data() as *mut u8, self.byte_length())
}
}
}
impl Delete for BackingStore {
fn delete(&mut self) {
unsafe { v8__BackingStore__DELETE(self) };
}
}
impl Shared for BackingStore {
fn clone(ptr: *const SharedRef<Self>) -> SharedRef<Self> {
unsafe { std__shared_ptr__v8__BackingStore__COPY(ptr) }
}
fn from_unique(unique: UniqueRef<Self>) -> SharedRef<Self> {
unsafe {
std__shared_ptr__v8__BackingStore__CONVERT__std__unique_ptr(unique)
}
}
fn deref(ptr: *const SharedRef<Self>) -> *mut Self {
unsafe { std__shared_ptr__v8__BackingStore__get(ptr) }
}
fn reset(ptr: *mut SharedRef<Self>) {
unsafe { std__shared_ptr__v8__BackingStore__reset(ptr) }
}
fn use_count(ptr: *const SharedRef<Self>) -> long {
unsafe { std__shared_ptr__v8__BackingStore__use_count(ptr) }
}
}
impl ArrayBuffer {
pub fn new<'sc>(
scope: &mut impl ToLocal<'sc>,
byte_length: usize,
) -> Local<'sc, ArrayBuffer> {
let isolate = scope.isolate();
let ptr =
unsafe { v8__ArrayBuffer__New__with_byte_length(isolate, byte_length) };
unsafe { scope.to_local(ptr) }.unwrap()
}
pub fn with_backing_store<'sc>(
scope: &mut impl ToLocal<'sc>,
backing_store: &mut SharedRef<BackingStore>,
) -> Local<'sc, ArrayBuffer> {
let isolate = scope.isolate();
let ptr = unsafe {
v8__ArrayBuffer__New__with_backing_store(isolate, &mut *backing_store)
};
unsafe { scope.to_local(ptr) }.unwrap()
}
pub fn byte_length(&self) -> usize {
unsafe { v8__ArrayBuffer__ByteLength(self) }
}
pub fn get_backing_store(&self) -> SharedRef<BackingStore> {
unsafe { v8__ArrayBuffer__GetBackingStore(self) }
}
pub fn new_backing_store(
scope: &mut impl InIsolate,
byte_length: usize,
) -> UniqueRef<BackingStore> {
unsafe {
UniqueRef::from_raw(v8__ArrayBuffer__NewBackingStore__with_byte_length(
scope.isolate(),
byte_length,
))
}
}
pub fn new_backing_store_from_boxed_slice(
data: Box<[u8]>,
) -> UniqueRef<BackingStore> {
let byte_length = data.len();
let data_ptr = Box::into_raw(data) as *mut c_void;
unsafe {
UniqueRef::from_raw(v8__ArrayBuffer__NewBackingStore__with_data(
data_ptr,
byte_length,
backing_store_deleter_callback,
null_mut(),
))
}
}
}