sfcgal/
utils.rs

1use std::{ffi::CStr, os::raw::c_char};
2
3use approx::AbsDiff;
4use sfcgal_sys::{sfcgal_geometry_t, sfcgal_prepared_geometry_t};
5
6use crate::errors::get_last_error;
7use crate::Result;
8
9pub(crate) fn _string(raw_ptr: *const c_char) -> String {
10    let c_str = unsafe { CStr::from_ptr(raw_ptr) };
11
12    std::str::from_utf8(c_str.to_bytes()).unwrap().to_string()
13}
14
15pub(crate) fn check_null_geom(g: *const sfcgal_geometry_t) -> Result<()> {
16    if g.is_null() {
17        return Err(format_err!(
18            "Error - Encountered a null Geometry : {}",
19            get_last_error()
20        ));
21    }
22
23    Ok(())
24}
25
26pub(crate) fn check_null_prepared_geom(g: *mut sfcgal_prepared_geometry_t) -> Result<()> {
27    if g.is_null() {
28        return Err(format_err!(
29            "Error - Encountered a null Prepared Geometry : {}",
30            get_last_error()
31        ));
32    }
33
34    Ok(())
35}
36
37pub(crate) fn check_predicate(val: i32) -> Result<bool> {
38    match val {
39        1 => Ok(true),
40        0 => Ok(false),
41        _ => Err(format_err!("SFCGAL error: {}", get_last_error())),
42    }
43}
44
45pub(crate) fn check_computed_value(val: f64) -> Result<f64> {
46    if AbsDiff::default().eq(&val, &-1.0) {
47        Err(format_err!("SFCGAL error: {}", get_last_error()))
48    } else {
49        Ok(val)
50    }
51}
52
53pub(crate) fn check_nan_value(val: f64) -> Result<f64> {
54    if val.is_nan() {
55        Err(format_err!("SFCGAL error: {}", get_last_error()))
56    } else {
57        Ok(val)
58    }
59}
60
61// Use the size returned by the C API to build the string
62// (as it seems to not always end with a null byte)
63// from the pointer to uninitialized memory with give
64// to it earlier.
65pub(crate) fn _c_string_with_size(raw_ptr: *const c_char, size: usize) -> String {
66    let slice: &[u8] = unsafe { std::slice::from_raw_parts(raw_ptr as *const u8, size) };
67
68    let res = std::str::from_utf8(slice).unwrap().to_string();
69
70    unsafe { libc::free(raw_ptr as *mut libc::c_void) };
71
72    res
73}
74
75// Get the raw u8 bytes
76// The users can proceed to use it however they want.
77pub(crate) fn get_raw_bytes(raw_ptr: *const c_char, size: usize) -> Vec<u8> {
78    let slice: &[u8] = unsafe { std::slice::from_raw_parts(raw_ptr as *const u8, size) };
79
80    slice.to_vec()
81}