rustfst_ffi/
symbol_table.rs1use crate::{get, get_mut, wrap, CStateId, RUSTFST_FFI_RESULT};
2use ffi_convert::*;
3use std::ffi::{CStr, CString};
4use std::sync::Arc;
5
6use anyhow::{anyhow, format_err};
7use rustfst::SymbolTable;
8
9#[derive(RawPointerConverter)]
10pub struct CSymbolTable(pub(crate) Arc<SymbolTable>);
11
12#[no_mangle]
16pub unsafe extern "C" fn symt_new(new_struct: *mut *const CSymbolTable) -> RUSTFST_FFI_RESULT {
17 wrap(|| {
18 let table = Arc::new(SymbolTable::new());
19 let raw_ptr = CSymbolTable(table).into_raw_pointer();
20 unsafe { *new_struct = raw_ptr };
21 Ok(())
22 })
23}
24
25#[no_mangle]
29pub unsafe extern "C" fn symt_add_symbol(
30 symt: *mut CSymbolTable,
31 symbol: *const libc::c_char,
32 integer_key: *mut libc::size_t,
33) -> RUSTFST_FFI_RESULT {
34 wrap(|| {
35 let symt = get_mut!(CSymbolTable, symt);
36 let symbol: String = unsafe { CStr::from_ptr(symbol) }.as_rust()?;
37 let res = Arc::get_mut(symt)
38 .ok_or_else(|| anyhow!("Could not get a mutable reference to the symbol table"))?
39 .add_symbol(&symbol);
40 unsafe { *integer_key = res as libc::size_t };
41 Ok(())
42 })
43}
44
45#[no_mangle]
49pub unsafe extern "C" fn symt_add_table(
50 symt: *mut CSymbolTable,
51 other_symt: *const CSymbolTable,
52) -> RUSTFST_FFI_RESULT {
53 wrap(|| {
54 let symt = get_mut!(CSymbolTable, symt);
55 let other_symt = get!(CSymbolTable, other_symt);
56 Arc::get_mut(symt)
57 .ok_or_else(|| anyhow!("Could not get a mutable reference to the symbol table"))?
58 .add_table(other_symt);
59 Ok(())
60 })
61}
62
63#[no_mangle]
67pub unsafe extern "C" fn symt_find_index(
68 symt: *const CSymbolTable,
69 key: CStateId,
70 symbol: *mut *const libc::c_char,
71) -> RUSTFST_FFI_RESULT {
72 wrap(|| {
73 let symt = get!(CSymbolTable, symt);
74 let found_symbol = symt
75 .get_symbol(key)
76 .ok_or_else(|| format_err!("No symbol found at index:{}", key as i32))?;
77 unsafe {
78 *symbol = CString::c_repr_of(found_symbol.to_string())?.into_raw_pointer()
79 as *const libc::c_char
80 };
81 Ok(())
82 })
83}
84
85#[no_mangle]
89pub unsafe extern "C" fn symt_find_symbol(
90 symt: *const CSymbolTable,
91 symbol: *const libc::c_char,
92 key: *mut libc::size_t,
93) -> RUSTFST_FFI_RESULT {
94 wrap(|| {
95 let symt = get!(CSymbolTable, symt);
96 let symbol = unsafe { CStr::from_ptr(symbol) }.as_rust()?;
97 let res = symt
98 .get_label(&symbol)
99 .ok_or_else(|| format_err!("No symbol `{}` found", symbol))?;
100 unsafe { *key = res as libc::size_t };
101 Ok(())
102 })
103}
104
105#[no_mangle]
109pub unsafe extern "C" fn symt_from_path(
110 table_ptr: *mut *const CSymbolTable,
111 path_ptr: *const libc::c_char,
112 binary: *const libc::size_t,
113) -> RUSTFST_FFI_RESULT {
114 wrap(|| {
115 let path = unsafe { CStr::from_ptr(path_ptr) }.as_rust()?;
116 let binary = binary as i32 != 0;
117 let symb = if binary {
118 SymbolTable::read(&path)?
119 } else {
120 SymbolTable::read_text(&path)?
121 };
122 let raw_ptr = CSymbolTable(Arc::new(symb)).into_raw_pointer();
123 unsafe { *table_ptr = raw_ptr };
124 Ok(())
125 })
126}
127
128#[no_mangle]
132pub unsafe extern "C" fn symt_write_file(
133 symt: *const CSymbolTable,
134 path_ptr: *const libc::c_char,
135 binary: *const libc::size_t,
136) -> RUSTFST_FFI_RESULT {
137 wrap(|| {
138 let symt = get!(CSymbolTable, symt);
139 let path = unsafe { CStr::from_ptr(path_ptr) }.as_rust()?;
140 let binary = binary as i32 != 0;
141 if binary {
142 symt.write(&path)?
143 } else {
144 symt.write_text(&path)?
145 };
146
147 Ok(())
148 })
149}
150
151#[no_mangle]
155pub unsafe extern "C" fn symt_member_index(
156 symt: *const CSymbolTable,
157 key: CStateId,
158 is_present: *mut libc::size_t,
159) -> RUSTFST_FFI_RESULT {
160 wrap(|| {
161 let symt = get!(CSymbolTable, symt);
162 let res = symt.contains_label(key);
163 unsafe { *is_present = res as libc::size_t };
164 Ok(())
165 })
166}
167
168#[no_mangle]
172pub unsafe extern "C" fn symt_member_symbol(
173 symt: *const CSymbolTable,
174 symbol: *const libc::c_char,
175 is_present: *mut libc::size_t,
176) -> RUSTFST_FFI_RESULT {
177 wrap(|| {
178 let symt = get!(CSymbolTable, symt);
179 let symbol = unsafe { CStr::from_ptr(symbol) }.as_rust()?;
180 let res = symt.contains_symbol(symbol);
181 unsafe { *is_present = res as libc::size_t };
182 Ok(())
183 })
184}
185
186#[no_mangle]
190pub unsafe extern "C" fn symt_num_symbols(
191 symt: *const CSymbolTable,
192 num_symbols: *mut libc::size_t,
193) -> RUSTFST_FFI_RESULT {
194 wrap(|| {
195 let symt = get!(CSymbolTable, symt);
196 unsafe { *num_symbols = symt.len() as libc::size_t };
197 Ok(())
198 })
199}
200
201#[no_mangle]
205pub unsafe extern "C" fn symt_copy(
206 symt: *const CSymbolTable,
207 cloned_symt: *mut *const CSymbolTable,
208) -> RUSTFST_FFI_RESULT {
209 wrap(|| {
210 let symt = get!(CSymbolTable, symt);
211 let clone = Arc::new(SymbolTable::clone(symt));
212 let raw_ptr = CSymbolTable(clone).into_raw_pointer();
213 unsafe { *cloned_symt = raw_ptr };
214 Ok(())
215 })
216}
217
218#[no_mangle]
222pub unsafe fn symt_equals(
223 symt: *const CSymbolTable,
224 other_symt: *const CSymbolTable,
225 is_equal: *mut libc::size_t,
226) -> RUSTFST_FFI_RESULT {
227 wrap(|| {
228 let symt = get!(CSymbolTable, symt);
229 let other_symt = get!(CSymbolTable, other_symt);
230 let res = symt.eq(other_symt);
231 unsafe { *is_equal = res as usize }
232 Ok(())
233 })
234}
235
236#[no_mangle]
241pub unsafe extern "C" fn symt_destroy(symt_ptr: *mut CSymbolTable) -> RUSTFST_FFI_RESULT {
242 wrap(|| {
243 if symt_ptr.is_null() {
244 return Ok(());
245 }
246
247 drop(unsafe { Box::from_raw(symt_ptr) });
248 Ok(())
249 })
250}