1use std::ffi::c_void;
8
9use crate::scan_block::*;
10use crate::scores::*;
11use crate::cigar::*;
12
13pub type BlockHandle = *mut c_void;
16
17#[derive(Copy, Clone, PartialEq)]
19#[repr(C)]
20pub struct SizeRange {
21 pub min: usize,
22 pub max: usize
23}
24
25
26#[no_mangle]
32pub unsafe extern fn block_new_simple_aamatrix(match_score: i8, mismatch_score: i8) -> *mut AAMatrix {
33 let matrix = Box::new(AAMatrix::new_simple(match_score, mismatch_score));
34 Box::into_raw(matrix)
35}
36
37#[no_mangle]
39pub unsafe extern fn block_set_aamatrix(matrix: *mut AAMatrix, a: u8, b: u8, score: i8) {
40 let matrix = &mut *matrix;
41 matrix.set(a, b, score);
42}
43
44#[no_mangle]
46pub unsafe extern fn block_free_aamatrix(matrix: *mut AAMatrix) {
47 drop(Box::from_raw(matrix));
48}
49
50
51#[no_mangle]
61pub unsafe extern fn block_new_aaprofile(str_len: usize, block_size: usize, gap_extend: i8) -> *mut AAProfile {
62 let profile = Box::new(AAProfile::new(str_len, block_size, gap_extend));
63 Box::into_raw(profile)
64}
65
66#[no_mangle]
68pub unsafe extern fn block_len_aaprofile(profile: *const AAProfile) -> usize {
69 let profile = &*profile;
70 profile.len()
71}
72
73#[no_mangle]
76pub unsafe extern fn block_clear_aaprofile(profile: *mut AAProfile, str_len: usize, block_size: usize) {
77 let profile = &mut *profile;
78 profile.clear(str_len, block_size);
79}
80
81#[no_mangle]
88pub unsafe extern fn block_set_aaprofile(profile: *mut AAProfile, i: usize, b: u8, score: i8) {
89 let profile = &mut *profile;
90 profile.set(i, b, score);
91}
92
93#[no_mangle]
101pub unsafe extern fn block_set_all_aaprofile(profile: *mut AAProfile, order: *const u8, order_len: usize, scores: *const i8, scores_len: usize, left_shift: usize, right_shift: usize) {
102 let profile = &mut *profile;
103 let order = std::slice::from_raw_parts(order, order_len);
104 let scores = std::slice::from_raw_parts(scores, scores_len);
105 profile.set_all(order, scores, left_shift, right_shift);
106}
107
108#[no_mangle]
116pub unsafe extern fn block_set_all_rev_aaprofile(profile: *mut AAProfile, order: *const u8, order_len: usize, scores: *const i8, scores_len: usize, left_shift: usize, right_shift: usize) {
117 let profile = &mut *profile;
118 let order = std::slice::from_raw_parts(order, order_len);
119 let scores = std::slice::from_raw_parts(scores, scores_len);
120 profile.set_all_rev(order, scores, left_shift, right_shift);
121}
122
123#[no_mangle]
129pub unsafe extern fn block_set_gap_open_C_aaprofile(profile: *mut AAProfile, i: usize, gap: i8) {
130 let profile = &mut *profile;
131 profile.set_gap_open_C(i, gap);
132}
133
134#[no_mangle]
140pub unsafe extern fn block_set_gap_close_C_aaprofile(profile: *mut AAProfile, i: usize, gap: i8) {
141 let profile = &mut *profile;
142 profile.set_gap_close_C(i, gap);
143}
144
145#[no_mangle]
151pub unsafe extern fn block_set_gap_open_R_aaprofile(profile: *mut AAProfile, i: usize, gap: i8) {
152 let profile = &mut *profile;
153 profile.set_gap_open_R(i, gap);
154}
155
156#[no_mangle]
158pub unsafe extern fn block_set_all_gap_open_C_aaprofile(profile: *mut AAProfile, gap: i8) {
159 let profile = &mut *profile;
160 profile.set_all_gap_open_C(gap);
161}
162
163#[no_mangle]
165pub unsafe extern fn block_set_all_gap_close_C_aaprofile(profile: *mut AAProfile, gap: i8) {
166 let profile = &mut *profile;
167 profile.set_all_gap_close_C(gap);
168}
169
170#[no_mangle]
172pub unsafe extern fn block_set_all_gap_open_R_aaprofile(profile: *mut AAProfile, gap: i8) {
173 let profile = &mut *profile;
174 profile.set_all_gap_open_R(gap);
175}
176
177#[no_mangle]
179pub unsafe extern fn block_get_aaprofile(profile: *const AAProfile, i: usize, b: u8) -> i8 {
180 let profile = &*profile;
181 profile.get(i, b)
182}
183
184#[no_mangle]
186pub unsafe extern fn block_get_gap_extend_aaprofile(profile: *const AAProfile) -> i8 {
187 let profile = &*profile;
188 profile.get_gap_extend()
189}
190
191#[no_mangle]
193pub unsafe extern fn block_free_aaprofile(profile: *mut AAProfile) {
194 drop(Box::from_raw(profile));
195}
196
197
198#[no_mangle]
202pub unsafe extern fn block_new_cigar(query_len: usize, reference_len: usize) -> *mut Cigar {
203 let cigar = Box::new(Cigar::new(query_len, reference_len));
204 Box::into_raw(cigar)
205}
206
207#[no_mangle]
209pub unsafe extern fn block_get_cigar(cigar: *const Cigar, i: usize) -> OpLen {
210 let cigar_str = &*cigar;
211 cigar_str.get(i)
212}
213
214#[no_mangle]
216pub unsafe extern fn block_len_cigar(cigar: *const Cigar) -> usize {
217 let cigar_str = &*cigar;
218 cigar_str.len()
219}
220
221#[no_mangle]
223pub unsafe extern fn block_free_cigar(cigar: *mut Cigar) {
224 drop(Box::from_raw(cigar));
225}
226
227
228#[no_mangle]
232pub unsafe extern fn block_new_padded_aa(len: usize, max_size: usize) -> *mut PaddedBytes {
233 let padded_bytes = Box::new(PaddedBytes::new::<AAMatrix>(len, max_size));
234 Box::into_raw(padded_bytes)
235}
236
237#[no_mangle]
239pub unsafe extern fn block_set_bytes_padded_aa(padded: *mut PaddedBytes, s: *const u8, len: usize, max_size: usize) {
240 let bytes = std::slice::from_raw_parts(s, len);
241 let padded_bytes = &mut *padded;
242 padded_bytes.set_bytes::<AAMatrix>(bytes, max_size);
243}
244
245#[no_mangle]
247pub unsafe extern fn block_set_bytes_rev_padded_aa(padded: *mut PaddedBytes, s: *const u8, len: usize, max_size: usize) {
248 let bytes = std::slice::from_raw_parts(s, len);
249 let padded_bytes = &mut *padded;
250 padded_bytes.set_bytes_rev::<AAMatrix>(bytes, max_size);
251}
252
253#[no_mangle]
255pub unsafe extern fn block_free_padded_aa(padded: *mut PaddedBytes) {
256 drop(Box::from_raw(padded));
257}
258
259
260macro_rules! gen_functions {
263 ($new_name:ident, $new_doc:expr,
264 $align_name:ident, $align_doc:expr,
265 $align_profile_name:ident, $align_profile_doc:expr,
266 $res_name:ident, $res_doc:expr,
267 $trace_name:ident, $trace_doc:expr,
268 $trace_eq_name:ident, $trace_eq_doc:expr,
269 $free_name:ident, $free_doc:expr,
270 $matrix:ty, $profile:ty, $trace:literal, $x_drop:literal) => {
271 #[doc = $new_doc]
272 #[no_mangle]
273 pub unsafe extern fn $new_name(query_len: usize,
274 reference_len: usize,
275 max_size: usize) -> BlockHandle {
276 let aligner = Box::new(Block::<$trace, $x_drop>::new(query_len, reference_len, max_size));
277 Box::into_raw(aligner) as BlockHandle
278 }
279
280 #[doc = $align_doc]
281 #[no_mangle]
282 pub unsafe extern fn $align_name(b: BlockHandle,
283 q: *const PaddedBytes,
284 r: *const PaddedBytes,
285 m: *const $matrix,
286 g: Gaps,
287 s: SizeRange,
288 x: i32) {
289 let aligner = &mut *(b as *mut Block<$trace, $x_drop>);
290 aligner.align(&*q, &*r, &*m, g, s.min..=s.max, x);
291 }
292
293 #[doc = $align_profile_doc]
294 #[no_mangle]
295 pub unsafe extern fn $align_profile_name(b: BlockHandle,
296 q: *const PaddedBytes,
297 r: *const $profile,
298 s: SizeRange,
299 x: i32) {
300 let aligner = &mut *(b as *mut Block<$trace, $x_drop>);
301 aligner.align_profile(&*q, &*r, s.min..=s.max, x);
302 }
303
304 #[doc = $res_doc]
305 #[no_mangle]
306 pub unsafe extern fn $res_name(b: BlockHandle) -> AlignResult {
307 let aligner = &*(b as *const Block<$trace, $x_drop>);
308 aligner.res()
309 }
310
311 #[doc = $trace_doc]
312 #[no_mangle]
313 pub unsafe extern fn $trace_name(b: BlockHandle, query_idx: usize, reference_idx: usize, cigar: *mut Cigar) {
314 let aligner = &*(b as *const Block<$trace, $x_drop>);
315 aligner.trace().cigar(query_idx, reference_idx, &mut *cigar);
316 }
317
318 #[doc = $trace_eq_doc]
319 #[no_mangle]
320 pub unsafe extern fn $trace_eq_name(b: BlockHandle, q: *const PaddedBytes, r: *const PaddedBytes, query_idx: usize, reference_idx: usize, cigar: *mut Cigar) {
321 let aligner = &*(b as *const Block<$trace, $x_drop>);
322 aligner.trace().cigar_eq(&*q, &*r, query_idx, reference_idx, &mut *cigar);
323 }
324
325 #[doc = $free_doc]
326 #[no_mangle]
327 pub unsafe extern fn $free_name(b: BlockHandle) {
328 drop(Box::from_raw(b as *mut Block<$trace, $x_drop>));
329 }
330 };
331}
332
333gen_functions!(
334 block_new_aa,
335 "Create a new block aligner instance for global alignment of amino acid strings (no traceback).",
336 block_align_aa,
337 "Global alignment of two amino acid strings (no traceback).",
338 block_align_profile_aa,
339 "Global alignment of an amino acid sequence to a profile (no traceback).",
340 block_res_aa,
341 "Retrieves the result of global alignment of two amino acid strings (no traceback).",
342 _block_cigar_aa,
343 "Don't use.",
344 _block_cigar_eq_aa,
345 "Don't use.",
346 block_free_aa,
347 "Frees the block used for global alignment of two amino acid strings (no traceback).",
348 AAMatrix, AAProfile, false, false
349);
350
351gen_functions!(
352 block_new_aa_xdrop,
353 "Create a new block aligner instance for X-drop alignment of amino acid strings (no traceback).",
354 block_align_aa_xdrop,
355 "X-drop alignment of two amino acid strings (no traceback).",
356 block_align_profile_aa_xdrop,
357 "X-drop alignment of an amino acid sequence to a profile (no traceback).",
358 block_res_aa_xdrop,
359 "Retrieves the result of X-drop alignment of two amino acid strings (no traceback).",
360 _block_cigar_aa_xdrop,
361 "Don't use.",
362 _block_cigar_eq_aa_xdrop,
363 "Don't use.",
364 block_free_aa_xdrop,
365 "Frees the block used for X-drop alignment of two amino acid strings (no traceback).",
366 AAMatrix, AAProfile, false, true
367);
368
369gen_functions!(
370 block_new_aa_trace,
371 "Create a new block aligner instance for global alignment of amino acid strings, with traceback.",
372 block_align_aa_trace,
373 "Global alignment of two amino acid strings, with traceback.",
374 block_align_profile_aa_trace,
375 "Global alignment of an amino acid sequence to a profile, with traceback.",
376 block_res_aa_trace,
377 "Retrieves the result of global alignment of two amino acid strings, with traceback.",
378 block_cigar_aa_trace,
379 "Retrieves the resulting CIGAR string from global alignment of two amino acid strings, with traceback.",
380 block_cigar_eq_aa_trace,
381 "Retrieves the resulting CIGAR string from global alignment of two amino acid strings, with traceback containing =/X.",
382 block_free_aa_trace,
383 "Frees the block used for global alignment of two amino acid strings, with traceback.",
384 AAMatrix, AAProfile, true, false
385);
386
387gen_functions!(
388 block_new_aa_trace_xdrop,
389 "Create a new block aligner instance for X-drop alignment of amino acid strings, with traceback.",
390 block_align_aa_trace_xdrop,
391 "X-drop alignment of two amino acid strings, with traceback.",
392 block_align_profile_aa_trace_xdrop,
393 "X-drop alignment of an amino acid sequence to a profile, with traceback.",
394 block_res_aa_trace_xdrop,
395 "Retrieves the result of X-drop alignment of two amino acid strings, with traceback.",
396 block_cigar_aa_trace_xdrop,
397 "Retrieves the resulting CIGAR string from X-drop alignment of two amino acid strings, with traceback.",
398 block_cigar_eq_aa_trace_xdrop,
399 "Retrieves the resulting CIGAR string from X-drop alignment of two amino acid strings, with traceback containing =/X.",
400 block_free_aa_trace_xdrop,
401 "Frees the block used for X-drop alignment of two amino acid strings, with traceback.",
402 AAMatrix, AAProfile, true, true
403);