///|
#external
priv type Handler
///|
#borrow(path, mode)
extern "C" fn fopen_ffi(path : Bytes, mode : Bytes) -> Handler = "moonbitlang_x_fs_fopen_ffi"
///|
extern "C" fn is_null(ptr : Handler) -> Int = "moonbitlang_x_fs_is_null"
///|
#borrow(ptr)
extern "C" fn fwrite_ffi(
ptr : Bytes,
size : Int,
nitems : Int,
stream : Handler,
) -> Int = "moonbitlang_x_fs_fwrite_ffi"
///|
extern "C" fn fflush_ffi(stream : Handler) -> Int = "moonbitlang_x_fs_fflush_ffi"
///|
extern "C" fn fclose_ffi(file : Handler) -> Int = "moonbitlang_x_fs_fclose_ffi"
///|
extern "C" fn get_error_message_ffi() -> Bytes = "moonbitlang_x_fs_get_error_message"
///|
fn get_error_message() -> String {
bytes_to_string(get_error_message_ffi())
}
///|
fn string_to_null_terminated_bytes(s : String) -> Bytes {
let len = s.length()
let arr = Array::make(len + 1, (0).to_byte())
for i = 0; i < len; i = i + 1 {
arr[i] = s[i].to_int().to_byte()
}
arr[len] = (0).to_byte()
Bytes::from_array(arr)
}
///|
/// Appends a Bytes payload to the file at path for Native target.
pub fn append_bytes_to_file(
path : String,
content : Bytes,
) -> Unit raise MoonKVError {
let file = fopen_ffi(string_to_null_terminated_bytes(path), b"ab\x00")
if is_null(file) != 0 {
raise MoonKVError::IOError(
"Failed to open file \{path} in append mode: " + get_error_message(),
)
}
let bytes_written = fwrite_ffi(content, 1, content.length(), file)
if bytes_written != content.length() {
let err = get_error_message()
let _ = fclose_ffi(file)
raise MoonKVError::IOError("Failed to write to file \{path}: " + err)
}
if fflush_ffi(file) != 0 {
let err = get_error_message()
let _ = fclose_ffi(file)
raise MoonKVError::IOError("Failed to flush file \{path}: " + err)
}
if fclose_ffi(file) != 0 {
raise MoonKVError::IOError(
"Failed to close file \{path}: " + get_error_message(),
)
}
}