1use crate::cerror::ErrorList;
2use crate::map_cerr;
3
4use super::Matrix;
5use super::{cast_const, cast_mut, cstr};
6use graphannis::{
7 corpusstorage::{FrequencyTable, QueryAttributeDescription},
8 errors::Result,
9 graph::{Annotation, Edge, NodeID},
10 model::AnnotationComponent,
11};
12use libc::{c_char, c_void, size_t};
13use std::ffi::CString;
14
15#[unsafe(no_mangle)]
21#[allow(clippy::from_raw_with_void_ptr)]
22pub unsafe extern "C" fn annis_free(ptr: *mut c_void) {
23 if ptr.is_null() {
24 return;
25 }
26 let ptr = unsafe { Box::from_raw(ptr) };
29 std::mem::drop(ptr);
30}
31
32#[unsafe(no_mangle)]
38pub unsafe extern "C" fn annis_str_free(s: *mut c_char) {
39 if s.is_null() {
40 return;
41 }
42 let s = unsafe { CString::from_raw(s) };
44 drop(s);
45}
46
47pub type IterPtr<T> = Box<dyn Iterator<Item = Result<T>>>;
48
49fn iter_next<T>(ptr: *mut Box<dyn Iterator<Item = Result<T>>>, err: *mut *mut ErrorList) -> *mut T {
50 let it: &mut Box<dyn Iterator<Item = Result<T>>> = cast_mut(ptr);
51 if let Some(v) = it.next()
52 && let Some(v) = map_cerr(v, err)
53 {
54 return Box::into_raw(Box::new(v));
55 }
56 std::ptr::null_mut()
57}
58
59#[unsafe(no_mangle)]
64pub extern "C" fn annis_iter_nodeid_next(
65 ptr: *mut IterPtr<NodeID>,
66 err: *mut *mut ErrorList,
67) -> *mut NodeID {
68 iter_next(ptr, err)
69}
70
71pub fn vec_size<T>(ptr: *const Vec<T>) -> size_t {
72 let v: &Vec<T> = cast_const(ptr);
73 v.len()
74}
75
76pub fn vec_get<T>(ptr: *const Vec<T>, i: size_t) -> *const T {
77 let v: &Vec<T> = cast_const(ptr);
78 if i < v.len() {
79 return &v[i] as *const T;
80 }
81 std::ptr::null()
82}
83
84#[unsafe(no_mangle)]
86pub extern "C" fn annis_vec_str_size(ptr: *const Vec<CString>) -> size_t {
87 vec_size(ptr)
88}
89
90#[unsafe(no_mangle)]
92pub extern "C" fn annis_vec_str_get(ptr: *const Vec<CString>, i: size_t) -> *const c_char {
93 let strvec: &Vec<CString> = cast_const(ptr);
95 if i < strvec.len() {
96 strvec[i].as_ptr()
97 } else {
98 std::ptr::null()
99 }
100}
101
102#[unsafe(no_mangle)]
104pub extern "C" fn annis_vec_str_new() -> *mut Vec<CString> {
105 let result: Vec<CString> = Vec::new();
106 Box::into_raw(Box::new(result))
107}
108
109#[unsafe(no_mangle)]
111pub extern "C" fn annis_vec_str_push(ptr: *mut Vec<CString>, v: *const c_char) {
112 let strvec: &mut Vec<CString> = cast_mut(ptr);
113 let v: &str = &cstr(v);
114 if let Ok(cval) = CString::new(v) {
115 strvec.push(cval);
116 }
117}
118
119#[unsafe(no_mangle)]
121pub extern "C" fn annis_annotation_ns(ptr: *const Annotation) -> *mut c_char {
122 let anno: &Annotation = cast_const(ptr);
123 CString::new(anno.key.ns.as_str())
124 .unwrap_or_default()
125 .into_raw()
126}
127
128#[unsafe(no_mangle)]
130pub extern "C" fn annis_annotation_name(ptr: *const Annotation) -> *mut c_char {
131 let anno: &Annotation = cast_const(ptr);
132 CString::new(anno.key.name.as_str())
133 .unwrap_or_default()
134 .into_raw()
135}
136
137#[unsafe(no_mangle)]
139pub extern "C" fn annis_annotation_val(ptr: *const Annotation) -> *mut c_char {
140 let anno: &Annotation = cast_const(ptr);
141 CString::new(anno.val.as_str())
142 .unwrap_or_default()
143 .into_raw()
144}
145
146#[unsafe(no_mangle)]
148pub extern "C" fn annis_vec_annotation_size(ptr: *const Vec<Annotation>) -> size_t {
149 vec_size(ptr)
150}
151
152#[unsafe(no_mangle)]
154pub extern "C" fn annis_vec_annotation_get(
155 ptr: *const Vec<Annotation>,
156 i: size_t,
157) -> *const Annotation {
158 vec_get(ptr, i)
159}
160
161#[unsafe(no_mangle)]
163pub extern "C" fn annis_vec_edge_size(ptr: *const Vec<Edge>) -> size_t {
164 vec_size(ptr)
165}
166
167#[unsafe(no_mangle)]
169pub extern "C" fn annis_vec_edge_get(ptr: *const Vec<Edge>, i: size_t) -> *const Edge {
170 vec_get(ptr, i)
171}
172
173#[unsafe(no_mangle)]
175pub extern "C" fn annis_vec_component_size(ptr: *const Vec<AnnotationComponent>) -> size_t {
176 vec_size(ptr)
177}
178
179#[unsafe(no_mangle)]
181pub extern "C" fn annis_vec_component_get(
182 ptr: *const Vec<AnnotationComponent>,
183 i: size_t,
184) -> *const AnnotationComponent {
185 vec_get(ptr, i)
186}
187
188#[unsafe(no_mangle)]
190pub extern "C" fn annis_vec_qattdesc_size(ptr: *const Vec<QueryAttributeDescription>) -> size_t {
191 vec_size(ptr)
192}
193
194#[unsafe(no_mangle)]
196pub extern "C" fn annis_vec_qattdesc_get_component_nr(
197 ptr: *const Vec<QueryAttributeDescription>,
198 i: size_t,
199) -> usize {
200 let desc_ptr: *const QueryAttributeDescription = vec_get(ptr, i);
201 let desc: &QueryAttributeDescription = cast_const(desc_ptr);
202 desc.alternative
203}
204
205#[unsafe(no_mangle)]
209pub extern "C" fn annis_vec_qattdesc_get_aql_fragment(
210 ptr: *const Vec<QueryAttributeDescription>,
211 i: size_t,
212) -> *mut c_char {
213 let desc_ptr: *const QueryAttributeDescription = vec_get(ptr, i);
214 let desc: &QueryAttributeDescription = cast_const(desc_ptr);
215 let cstr: CString = CString::new(desc.query_fragment.as_str()).unwrap_or_default();
216 cstr.into_raw()
217}
218
219#[unsafe(no_mangle)]
223pub extern "C" fn annis_vec_qattdesc_get_variable(
224 ptr: *const Vec<QueryAttributeDescription>,
225 i: size_t,
226) -> *mut c_char {
227 let desc_ptr: *const QueryAttributeDescription = vec_get(ptr, i);
228 let desc: &QueryAttributeDescription = cast_const(desc_ptr);
229 let cstr: CString = CString::new(desc.variable.as_str()).unwrap_or_default();
230 cstr.into_raw()
231}
232
233#[unsafe(no_mangle)]
237pub extern "C" fn annis_vec_qattdesc_get_anno_name(
238 ptr: *const Vec<QueryAttributeDescription>,
239 i: size_t,
240) -> *mut c_char {
241 let desc_ptr: *const QueryAttributeDescription = vec_get(ptr, i);
242 let desc: &QueryAttributeDescription = cast_const(desc_ptr);
243 if let Some(anno_name) = &desc.anno_name {
244 let cstr: CString = CString::new(anno_name.as_str()).unwrap_or_default();
245 cstr.into_raw()
246 } else {
247 std::ptr::null_mut()
248 }
249}
250
251#[unsafe(no_mangle)]
253pub extern "C" fn annis_matrix_str_nrows(ptr: *const Matrix<CString>) -> size_t {
254 vec_size(ptr)
255}
256
257#[unsafe(no_mangle)]
259pub extern "C" fn annis_matrix_str_ncols(ptr: *const Matrix<CString>) -> size_t {
260 let v: &Vec<Vec<CString>> = cast_const(ptr);
261 if !v.is_empty() {
262 return v[0].len();
263 }
264 0
265}
266
267#[unsafe(no_mangle)]
269pub extern "C" fn annis_matrix_str_get(
270 ptr: *const Matrix<CString>,
271 row: size_t,
272 col: size_t,
273) -> *const c_char {
274 let strmatrix: &Vec<Vec<CString>> = cast_const(ptr);
276 if row < strmatrix.len() && col < strmatrix[row].len() {
277 return strmatrix[row][col].as_ptr();
278 }
279 std::ptr::null()
280}
281
282#[unsafe(no_mangle)]
284pub extern "C" fn annis_freqtable_str_nrows(ptr: *const FrequencyTable<CString>) -> size_t {
285 vec_size(ptr)
286}
287
288#[unsafe(no_mangle)]
290pub extern "C" fn annis_freqtable_str_ncols(ptr: *const FrequencyTable<CString>) -> size_t {
291 let v: &FrequencyTable<CString> = cast_const(ptr);
292 if !v.is_empty() {
293 return v[0].values.len();
294 }
295 0
296}
297
298#[unsafe(no_mangle)]
300pub extern "C" fn annis_freqtable_str_get(
301 ptr: *const FrequencyTable<CString>,
302 row: size_t,
303 col: size_t,
304) -> *const c_char {
305 let ft: &FrequencyTable<CString> = cast_const(ptr);
307 if row < ft.len() && col < ft[row].values.len() {
308 return ft[row].values[col].as_ptr();
309 }
310 std::ptr::null()
311}
312
313#[unsafe(no_mangle)]
315pub extern "C" fn annis_freqtable_str_count(
316 ptr: *const FrequencyTable<CString>,
317 row: size_t,
318) -> size_t {
319 let ft: &FrequencyTable<CString> = cast_const(ptr);
320 if row < ft.len() {
321 return ft[row].count;
322 }
323 0
324}