1use crate::consts::{AttrType, FileType, ScopeType, VarDir, VarType, WriterPackType};
2use crate::types::Handle;
3use crate::utils::*;
4use crate::{Error, Result, capi};
5use std::os::raw;
6use std::path::Path;
7
8#[derive(Debug)]
10pub struct Writer {
11 ctx: *mut raw::c_void,
13}
14
15impl Writer {
16 pub fn create<P>(path: P, use_compressed_hier: bool) -> Result<Self>
18 where
19 P: AsRef<Path>,
20 {
21 let path = path.to_str()?.into_cstring()?;
22 let ctx = unsafe { capi::fstWriterCreate(path.as_ptr(), use_compressed_hier as raw::c_int) };
23 if ctx.is_null() {
24 Err(Error::ContextCreate)
25 } else {
26 Ok(Self { ctx })
27 }
28 }
29
30 pub fn comment(self, comment: &str) -> Result<Self> {
32 let comment = comment.into_cstring()?;
33 unsafe { capi::fstWriterSetComment(self.ctx, comment.as_ptr()) };
34 Ok(self)
35 }
36
37 pub fn date(self, date: &str) -> Result<Self> {
39 let date = date.into_cstring()?;
40 unsafe { capi::fstWriterSetDate(self.ctx, date.as_ptr()) };
41 Ok(self)
42 }
43
44 pub unsafe fn date_raw(self, date: *const raw::c_char) -> Self {
51 unsafe { capi::fstWriterSetDate(self.ctx, date) };
52 self
53 }
54
55 pub fn file_type(self, ty: FileType) -> Self {
57 unsafe { capi::fstWriterSetFileType(self.ctx, ty) };
58 self
59 }
60
61 pub fn pack_type(self, ty: WriterPackType) -> Self {
63 unsafe { capi::fstWriterSetPackType(self.ctx, ty) };
64 self
65 }
66
67 pub fn parallel_mode(self, enable: bool) -> Self {
69 unsafe { capi::fstWriterSetParallelMode(self.ctx, enable as raw::c_int) };
70 self
71 }
72
73 pub fn repack_on_close(self, enable: bool) -> Self {
75 unsafe { capi::fstWriterSetRepackOnClose(self.ctx, enable as raw::c_int) };
76 self
77 }
78
79 pub fn timescale(self, timescale: i32) -> Self {
81 unsafe { capi::fstWriterSetTimescale(self.ctx, timescale) };
82 self
83 }
84
85 pub fn timescale_from_str(self, timescale: &str) -> Result<Self> {
87 let timescale = timescale.into_cstring()?;
88 unsafe { capi::fstWriterSetTimescaleFromString(self.ctx, timescale.as_ptr()) };
89 Ok(self)
90 }
91
92 pub fn timezero(self, timezero: i64) -> Self {
94 unsafe { capi::fstWriterSetTimezero(self.ctx, timezero) };
95 self
96 }
97
98 pub fn version(self, version: &str) -> Result<Self> {
100 let version = version.into_cstring()?;
101 unsafe { capi::fstWriterSetVersion(self.ctx, version.as_ptr()) };
102 Ok(self)
103 }
104
105 pub unsafe fn version_raw(self, version: *const raw::c_char) -> Self {
112 unsafe { capi::fstWriterSetVersion(self.ctx, version) };
113 self
114 }
115
116 pub fn set_attr_begin(&mut self, ty: AttrType, sub_ty: u32, name: &str, arg: u64) -> Result<()> {
118 let name = name.into_cstring()?;
119 unsafe { capi::fstWriterSetAttrBegin(self.ctx, ty, sub_ty as _, name.as_ptr(), arg) };
120 Ok(())
121 }
122
123 pub fn set_attr_end(&mut self) {
125 unsafe { capi::fstWriterSetAttrEnd(self.ctx) }
126 }
127
128 pub fn set_scope(&mut self, ty: ScopeType, name: &str, component: &str) -> Result<()> {
130 let name = name.into_cstring()?;
131 let component = component.into_cstring()?;
132 unsafe { capi::fstWriterSetScope(self.ctx, ty, name.as_ptr(), component.as_ptr()) };
133 Ok(())
134 }
135
136 pub fn set_upscope(&mut self) {
138 unsafe { capi::fstWriterSetUpscope(self.ctx) }
139 }
140
141 pub fn create_var(
143 &mut self,
144 ty: VarType,
145 dir: VarDir,
146 len: u32,
147 name: &str,
148 alias: Option<Handle>,
149 ) -> Result<Handle> {
150 let name = name.into_cstring()?;
151 Handle::new(unsafe {
152 capi::fstWriterCreateVar(self.ctx, ty, dir, len, name.as_ptr(), alias.into_handle())
153 })
154 .ok_or(Error::InvalidOperation)
155 }
156
157 pub fn emit_value_change(&mut self, handle: Handle, value: &[u8]) -> Result<()> {
159 let ret = unsafe {
160 capi::fstWriterEmitValueChange(
161 self.ctx,
162 handle.into(),
163 value.as_ptr() as *const raw::c_void,
164 value.len() as u32,
165 )
166 };
167 match ret {
168 0 => Ok(()),
169 _ => Err(Error::InvalidOperation),
170 }
171 }
172
173 pub fn emit_var_len_value_change(&mut self, handle: Handle, value: &[u8]) -> Result<()> {
175 let ret = unsafe {
176 capi::fstWriterEmitVariableLengthValueChange(
177 self.ctx,
178 handle.into(),
179 value.as_ptr() as *const raw::c_void,
180 value.len() as u32,
181 )
182 };
183 match ret {
184 0 => Ok(()),
185 _ => Err(Error::InvalidOperation),
186 }
187 }
188
189 pub fn emit_time_change(&mut self, time: u64) -> Result<()> {
191 match unsafe { capi::fstWriterEmitTimeChange(self.ctx, time) } {
192 0 => Ok(()),
193 _ => Err(Error::InvalidOperation),
194 }
195 }
196
197 pub fn flush(&mut self) {
199 unsafe { capi::fstWriterFlushContext(self.ctx) }
200 }
201}
202
203impl Drop for Writer {
204 fn drop(&mut self) {
205 unsafe { capi::fstWriterClose(self.ctx) }
206 }
207}