oc_wasm_safe/helpers.rs
1use super::error::{Error, Result};
2use core::ptr;
3
4/// Calls a function and passes an optional string.
5///
6/// `f` is the function. `s` is the string.
7///
8/// # Errors
9/// Any error returned by `f` (encoded as a negative integer) is returned by this function.
10///
11/// # Safety
12/// `f` must be safe to call with a string pointer/length pair or with a null pointer and zero
13/// length.
14pub unsafe fn call_string(
15 f: unsafe extern "C" fn(*const u8, usize) -> i32,
16 s: Option<&str>,
17) -> Result<u32> {
18 let (ptr, len) = s.map_or((ptr::null(), 0), |s| (s.as_ptr(), s.len()));
19 Error::from_i32(f(ptr, len))
20}
21
22/// Calls a function that accepts a buffer pointer/length, passes null, and returns the needed
23/// buffer length.
24///
25/// `f` is the buffer-writing function.
26///
27/// # Errors
28/// Any error returned by `f` (encoded as a negative integer) is returned by this function.
29///
30/// # Safety
31/// `f` must be safe to call with a null pointer and zero length.
32pub unsafe fn call_buffer_len(f: unsafe extern "C" fn(*mut u8, usize) -> isize) -> Result<usize> {
33 Error::from_isize(f(ptr::null_mut(), 0))
34}
35
36/// Calls a function that accepts a buffer pointer/length, passes a slice, and returns the
37/// written-to portion of the buffer.
38///
39/// `f` is the buffer-writing function. `buf` is the buffer.
40///
41/// # Errors
42/// Any error returned by `f` (encoded as a negative integer) is returned by this function.
43///
44/// # Safety
45/// `f` must be safe to call with a buffer pointer and length, and must return the number of bytes
46/// written into the buffer.
47pub unsafe fn call_buffer(
48 f: unsafe extern "C" fn(*mut u8, usize) -> isize,
49 buf: &mut [u8],
50) -> Result<&mut [u8]> {
51 let len = buf.len();
52 let ptr = buf.as_mut_ptr();
53 let bytes_written = Error::from_isize(f(ptr, len))?;
54 Ok(buf.get_unchecked_mut(0..bytes_written))
55}
56
57/// Calls a function that accepts a buffer pointer/length, passes a slice, and returns the
58/// written-to portion of that buffer as a string.
59///
60/// `f` is the buffer-writing function. `buf` is the buffer.
61///
62/// # Errors
63/// Any error returned by `f` (encoded as a negative integer) is returned by this function.
64///
65/// # Safety
66/// In addition to the requirements specified by [`call_buffer`](call_buffer), the data written
67/// into the buffer by `f` must be UTF-8.
68pub unsafe fn call_buffer_str(
69 f: unsafe extern "C" fn(*mut u8, usize) -> isize,
70 buf: &mut [u8],
71) -> Result<&mut str> {
72 Ok(core::str::from_utf8_unchecked_mut(call_buffer(f, buf)?))
73}