use crate::consts::{AttrType, FileType, ScopeType, VarDir, VarType, WriterPackType};
use crate::types::Handle;
use crate::utils::*;
use crate::{Error, Result, capi};
use std::os::raw;
use std::path::Path;
#[derive(Debug)]
pub struct Writer {
ctx: *mut raw::c_void,
}
impl Writer {
pub fn create<P>(path: P, use_compressed_hier: bool) -> Result<Self>
where
P: AsRef<Path>,
{
let path = path.to_str()?.into_cstring()?;
let ctx = unsafe { capi::fstWriterCreate(path.as_ptr(), use_compressed_hier as raw::c_int) };
if ctx.is_null() {
Err(Error::ContextCreate)
} else {
Ok(Self { ctx })
}
}
pub fn comment(self, comment: &str) -> Result<Self> {
let comment = comment.into_cstring()?;
unsafe { capi::fstWriterSetComment(self.ctx, comment.as_ptr()) };
Ok(self)
}
pub fn date(self, date: &str) -> Result<Self> {
let date = date.into_cstring()?;
unsafe { capi::fstWriterSetDate(self.ctx, date.as_ptr()) };
Ok(self)
}
pub unsafe fn date_raw(self, date: *const raw::c_char) -> Self {
unsafe { capi::fstWriterSetDate(self.ctx, date) };
self
}
pub fn file_type(self, ty: FileType) -> Self {
unsafe { capi::fstWriterSetFileType(self.ctx, ty) };
self
}
pub fn pack_type(self, ty: WriterPackType) -> Self {
unsafe { capi::fstWriterSetPackType(self.ctx, ty) };
self
}
pub fn parallel_mode(self, enable: bool) -> Self {
unsafe { capi::fstWriterSetParallelMode(self.ctx, enable as raw::c_int) };
self
}
pub fn repack_on_close(self, enable: bool) -> Self {
unsafe { capi::fstWriterSetRepackOnClose(self.ctx, enable as raw::c_int) };
self
}
pub fn timescale(self, timescale: i32) -> Self {
unsafe { capi::fstWriterSetTimescale(self.ctx, timescale) };
self
}
pub fn timescale_from_str(self, timescale: &str) -> Result<Self> {
let timescale = timescale.into_cstring()?;
unsafe { capi::fstWriterSetTimescaleFromString(self.ctx, timescale.as_ptr()) };
Ok(self)
}
pub fn timezero(self, timezero: i64) -> Self {
unsafe { capi::fstWriterSetTimezero(self.ctx, timezero) };
self
}
pub fn version(self, version: &str) -> Result<Self> {
let version = version.into_cstring()?;
unsafe { capi::fstWriterSetVersion(self.ctx, version.as_ptr()) };
Ok(self)
}
pub unsafe fn version_raw(self, version: *const raw::c_char) -> Self {
unsafe { capi::fstWriterSetVersion(self.ctx, version) };
self
}
pub fn set_attr_begin(&mut self, ty: AttrType, sub_ty: u32, name: &str, arg: u64) -> Result<()> {
let name = name.into_cstring()?;
unsafe { capi::fstWriterSetAttrBegin(self.ctx, ty, sub_ty as _, name.as_ptr(), arg) };
Ok(())
}
pub fn set_attr_end(&mut self) {
unsafe { capi::fstWriterSetAttrEnd(self.ctx) }
}
pub fn set_scope(&mut self, ty: ScopeType, name: &str, component: &str) -> Result<()> {
let name = name.into_cstring()?;
let component = component.into_cstring()?;
unsafe { capi::fstWriterSetScope(self.ctx, ty, name.as_ptr(), component.as_ptr()) };
Ok(())
}
pub fn set_upscope(&mut self) {
unsafe { capi::fstWriterSetUpscope(self.ctx) }
}
pub fn create_var(
&mut self,
ty: VarType,
dir: VarDir,
len: u32,
name: &str,
alias: Option<Handle>,
) -> Result<Handle> {
let name = name.into_cstring()?;
Handle::new(unsafe {
capi::fstWriterCreateVar(self.ctx, ty, dir, len, name.as_ptr(), alias.into_handle())
})
.ok_or(Error::InvalidOperation)
}
pub fn emit_value_change(&mut self, handle: Handle, value: &[u8]) -> Result<()> {
let ret = unsafe {
capi::fstWriterEmitValueChange(
self.ctx,
handle.into(),
value.as_ptr() as *const raw::c_void,
value.len() as u32,
)
};
match ret {
0 => Ok(()),
_ => Err(Error::InvalidOperation),
}
}
pub fn emit_var_len_value_change(&mut self, handle: Handle, value: &[u8]) -> Result<()> {
let ret = unsafe {
capi::fstWriterEmitVariableLengthValueChange(
self.ctx,
handle.into(),
value.as_ptr() as *const raw::c_void,
value.len() as u32,
)
};
match ret {
0 => Ok(()),
_ => Err(Error::InvalidOperation),
}
}
pub fn emit_time_change(&mut self, time: u64) -> Result<()> {
match unsafe { capi::fstWriterEmitTimeChange(self.ctx, time) } {
0 => Ok(()),
_ => Err(Error::InvalidOperation),
}
}
pub fn flush(&mut self) {
unsafe { capi::fstWriterFlushContext(self.ctx) }
}
}
impl Drop for Writer {
fn drop(&mut self) {
unsafe { capi::fstWriterClose(self.ctx) }
}
}