use core::ffi::CStr;
use alloc::{boxed::Box, ffi::CString, string::{String, ToString}};
use byte_strings::c_str;
use crate::{bindings, error::{self, PROSErr, PROSResult}};
pub fn is_available() -> bool {
unsafe {
bindings::usd_is_installed() != 0
}
}
pub fn list_files(path: &str) -> Result<Box<[String]>, PROSErr> {
const BUFF_SIZE: i32 = 1024;
let mut buffer = [0u8; BUFF_SIZE as usize];
unsafe {
let path = CString::new(path).unwrap();
bindings::usd_list_files(
path.as_ptr() as *const u8,
(&mut buffer) as *mut u8,
BUFF_SIZE,
)
}.check()?;
let cstring = CStr::from_bytes_until_nul(&buffer).unwrap();
let split = cstring.to_str()
.unwrap()
.split("\n")
.map(|x| x.to_string())
.collect::<Box<[String]>>();
Ok(split)
}
pub struct FileWrite {
pointer: *mut bindings::FILE,
}
impl FileWrite {
pub fn create(path: &str) -> Result<FileWrite, PROSErr> {
let path = CString::new(path).unwrap();
let pointer = unsafe {
bindings::fopen(
path.as_ptr() as *const u8,
c_str!("w").as_ptr() as *const u8,
)
};
if pointer.is_null() {
return Err(error::from_errno());
}
Ok(FileWrite {
pointer
})
}
pub fn open(path: &str) -> Result<FileWrite, PROSErr> {
let path = CString::new(path).unwrap();
let pointer = unsafe {
bindings::fopen(
path.as_ptr() as *const u8,
c_str!("a").as_ptr() as *const u8,
)
};
if pointer.is_null() {
return Err(error::from_errno());
}
Ok(FileWrite {
pointer
})
}
pub fn write(&mut self, string: &str) -> Result<(), PROSErr> {
let c_string = CString::new(string).unwrap();
let error = unsafe {
bindings::fputs(c_string.as_ptr() as *const u8, self.pointer)
};
if error == -1 { return Err(error::from_errno());
}
Ok(())
}
pub fn close(self) {
unsafe {
bindings::fclose(self.pointer);
}
}
}
impl Drop for FileWrite {
fn drop(&mut self) {
unsafe {
bindings::fclose(self.pointer);
}
}
}