use crate::SBError;
use libc::FILE;
use std::ffi::CString;
pub struct SBFile {
pub raw: sys::SBFileRef,
}
impl SBFile {
pub(crate) fn wrap(raw: sys::SBFileRef) -> SBFile {
SBFile { raw }
}
#[allow(dead_code)]
pub(crate) fn maybe_wrap(raw: sys::SBFileRef) -> Option<SBFile> {
if unsafe { sys::SBFileIsValid(raw) } {
Some(SBFile { raw })
} else {
None
}
}
pub unsafe fn from_file(&self, file: *mut FILE, transfer_ownership: bool) -> SBFile {
SBFile::wrap(sys::CreateSBFile2(file, transfer_ownership))
}
pub fn from_fd(&self, fd: i32, mode: &str, transfer_ownership: bool) -> SBFile {
let cmode = CString::new(mode).unwrap();
SBFile::wrap(unsafe { sys::CreateSBFile3(fd, cmode.as_ptr(), transfer_ownership) })
}
pub fn is_valid(&self) -> bool {
unsafe { sys::SBFileIsValid(self.raw) }
}
pub fn read(&self, buf: &mut [u8]) -> Result<usize, SBError> {
let mut bytes_read: usize = 0;
let e = SBError::wrap(unsafe {
sys::SBFileRead(self.raw, buf.as_mut_ptr(), buf.len(), &mut bytes_read)
});
if e.is_success() {
Ok(bytes_read)
} else {
Err(e)
}
}
pub fn write(&self, buf: &[u8]) -> Result<usize, SBError> {
let mut bytes_written: usize = 0;
let e = SBError::wrap(unsafe {
sys::SBFileWrite(self.raw, buf.as_ptr(), buf.len(), &mut bytes_written)
});
if e.is_success() {
Ok(bytes_written)
} else {
Err(e)
}
}
pub fn flush(&self) -> Result<(), SBError> {
SBError::wrap(unsafe { sys::SBFileFlush(self.raw) }).into_result()
}
pub fn close(&self) -> Result<(), SBError> {
SBError::wrap(unsafe { sys::SBFileClose(self.raw) }).into_result()
}
}