///|
let active_buffer_views : Ref[Int32] = Ref(0)
///|
pub struct NapiBufferView {
env : NapiEnv
value : NapiValue
mut is_alive : Bool
}
///|
fn NapiBufferView::validate(
self : NapiBufferView,
) -> (UnmanagedBuffer, Int32) raise NapiError {
if !self.is_alive {
raise napi_failure(
1,
Error,
"ERR_NAPI_BUFFER_EXPIRED",
"Buffer view is no longer valid",
)
}
let data = Ref(moonbit_dummy_unmanaged_buffer())
let len = Ref(0)
let status = napi_get_buffer_info(self.env, self.value, data, len)
result_from_status(
self.env,
status,
b"Buffer backing store is detached or invalid",
)
(data.val, len.val)
}
///|
pub fn NapiBufferView::length(self : NapiBufferView) -> Int32 raise NapiError {
self.validate().1
}
///|
pub fn NapiBufferView::load8(
self : NapiBufferView,
offset : Int32,
) -> Int32 raise NapiError {
let (buf, len) = self.validate()
if offset < 0 || offset >= len {
raise napi_failure(
1,
RangeError,
"ERR_NAPI_BUFFER_BOUNDS",
"Buffer view out of bounds",
)
}
buf.load8(offset)
}
///|
pub fn NapiBufferView::store8(
self : NapiBufferView,
offset : Int32,
val : Int32,
) -> Unit raise NapiError {
let (buf, len) = self.validate()
if offset < 0 || offset >= len {
raise napi_failure(
1,
RangeError,
"ERR_NAPI_BUFFER_BOUNDS",
"Buffer view out of bounds",
)
}
buf.store8(offset, val)
}
///|
/// Invalidates a borrowed Buffer view after the callback returns.
pub fn NapiBufferView::invalidate(self : NapiBufferView) -> Unit {
if self.is_alive {
self.is_alive = false
active_buffer_views.val -= 1
}
}
///|
pub fn get_Int(env : NapiEnv, val : NapiValue) -> Int32 raise NapiError {
let res = Ref(0.0)
let status = napi_get_value_double(env, val, res)
result_from_status(env, status, b"Invalid argument, expected Int")
let value = res.val
if !(value >= -2147483648.0 && value <= 2147483647.0) ||
value != value.to_int().to_double() {
raise napi_failure(
1,
RangeError,
"ERR_NAPI_INT_RANGE",
"Int requires a finite integral number in [-2147483648, 2147483647]",
)
}
value.to_int()
}
///|
pub fn set_Int(env : NapiEnv, val : Int32) -> NapiValue raise NapiError {
let res = Ref(moonbit_dummy_napi_value())
let status = napi_create_int32(env, val, res)
result_from_status(env, status, b"Failed to create Int")
res.val
}
///|
pub fn get_UInt(env : NapiEnv, value : NapiValue) -> UInt32 raise NapiError {
let number = get_Double(env, value)
if !(number >= 0.0 && number <= 4294967295.0) ||
UInt32::trunc_double(number).to_double() != number {
raise napi_failure(
1,
RangeError,
"ERR_NAPI_UINT_RANGE",
"UInt requires a finite integer in [0, 4294967295]",
)
}
UInt32::trunc_double(number)
}
///|
pub fn set_UInt(env : NapiEnv, value : UInt32) -> NapiValue raise NapiError {
set_Double(env, value.to_double())
}
///|
pub fn get_Float(env : NapiEnv, value : NapiValue) -> Float raise NapiError {
Float::from_double(get_Double(env, value))
}
///|
pub fn set_Float(env : NapiEnv, value : Float) -> NapiValue raise NapiError {
set_Double(env, value.to_double())
}
///|
pub fn get_Double(env : NapiEnv, val : NapiValue) -> Double raise NapiError {
let res = Ref(0.0)
let status = napi_get_value_double(env, val, res)
result_from_status(env, status, b"Invalid argument, expected Double")
res.val
}
///|
pub fn set_Double(env : NapiEnv, val : Double) -> NapiValue raise NapiError {
let res = Ref(moonbit_dummy_napi_value())
let status = napi_create_double(env, val, res)
result_from_status(env, status, b"Failed to create Double")
res.val
}
///|
pub fn get_Bool(env : NapiEnv, val : NapiValue) -> Bool raise NapiError {
let res = Ref(false)
let status = napi_get_value_bool(env, val, res)
result_from_status(env, status, b"Invalid argument, expected Bool")
res.val
}
///|
pub fn set_Bool(env : NapiEnv, val : Bool) -> NapiValue raise NapiError {
let res = Ref(moonbit_dummy_napi_value())
let status = napi_get_boolean(env, val, res)
result_from_status(env, status, b"Failed to create Bool")
res.val
}
///|
pub fn get_String(env : NapiEnv, val : NapiValue) -> String raise NapiError {
let status = Ref(0)
let result = napi_read_string(env, val, status)
result_from_status(env, status.val, b"Reading UTF-16 String")
result
}
///|
pub fn set_String(env : NapiEnv, val : String) -> NapiValue raise NapiError {
let res = Ref(moonbit_dummy_napi_value())
let status = napi_write_string(env, val, res)
result_from_status(env, status, b"Failed to create String")
res.val
}
///|
pub fn get_Bytes(env : NapiEnv, val : NapiValue) -> Bytes raise NapiError {
let len = Ref(0)
let unmanaged = Ref(moonbit_dummy_unmanaged_buffer())
let status = napi_get_buffer_info(env, val, unmanaged, len)
result_from_status(env, status, b"Invalid argument, expected Buffer")
napi_copy_bytes(unmanaged.val, len.val)
}
///|
pub fn set_Bytes(env : NapiEnv, val : Bytes) -> NapiValue raise NapiError {
let res = Ref(moonbit_dummy_napi_value())
let data = Ref(moonbit_dummy_unmanaged_buffer())
let status = napi_create_buffer_copy(env, val.length(), val, data, res)
result_from_status(env, status, b"Failed to create buffer")
res.val
}
///|
pub fn get_NapiBufferView(
env : NapiEnv,
val : NapiValue,
) -> NapiBufferView raise NapiError {
let len = Ref(0)
let unmanaged = Ref(moonbit_dummy_unmanaged_buffer())
let status = napi_get_buffer_info(env, val, unmanaged, len)
result_from_status(env, status, b"Invalid argument, expected Buffer")
active_buffer_views.val += 1
{ env, value: val, is_alive: true, }
}
///|
pub fn set_Unit(env : NapiEnv, _val : Unit) -> NapiValue raise NapiError {
let res = Ref(moonbit_dummy_napi_value())
let status = napi_get_undefined(env, res)
result_from_status(env, status, b"Failed to create undefined")
res.val
}