azure_kinect/
utility.rs

1#![allow(non_upper_case_globals)]
2
3use crate::*;
4use azure_kinect_sys::k4a::*;
5use std::ffi::CString;
6use std::ptr;
7
8pub(crate) fn get_k4a_cstring(
9    f: &dyn Fn(*mut ::std::os::raw::c_char, *mut usize) -> k4a_buffer_result_t,
10) -> Result<CString, Error> {
11    unsafe {
12        let mut buffer: usize = 0;
13        let r = (f)(ptr::null_mut(), &mut buffer);
14        match r {
15            k4a_buffer_result_t_K4A_BUFFER_RESULT_SUCCEEDED => Ok(CString::default()),
16            k4a_buffer_result_t_K4A_BUFFER_RESULT_TOO_SMALL => {
17                if buffer > 1 {
18                    let mut retbuf = Vec::<u8>::with_capacity(buffer);
19                    retbuf.set_len(buffer - 1);
20                    Error::from_k4a_buffer_result_t((f)(
21                        retbuf.as_mut_ptr() as *mut ::std::os::raw::c_char,
22                        &mut buffer,
23                    ))
24                    .to_result(CString::from_vec_unchecked(retbuf))
25                } else {
26                    Err(Error::from_k4a_buffer_result_t(r))
27                }
28            }
29            _ => Err(Error::from_k4a_buffer_result_t(r)),
30        }
31    }
32}
33
34pub(crate) fn get_k4a_string(
35    f: &dyn Fn(*mut ::std::os::raw::c_char, *mut usize) -> k4a_buffer_result_t,
36) -> Result<String, Error> {
37    unsafe {
38        let mut buffer: usize = 0;
39        let r = (f)(ptr::null_mut(), &mut buffer);
40        match r {
41            k4a_buffer_result_t_K4A_BUFFER_RESULT_SUCCEEDED => Ok(String::new()),
42            k4a_buffer_result_t_K4A_BUFFER_RESULT_TOO_SMALL => {
43                if buffer > 1 {
44                    let mut retstr = String::with_capacity(buffer);
45                    retstr.as_mut_vec().set_len(buffer - 1);
46                    Error::from_k4a_buffer_result_t((f)(
47                        retstr.as_mut_ptr() as *mut ::std::os::raw::c_char,
48                        &mut buffer,
49                    ))
50                    .to_result(retstr)
51                } else {
52                    Err(Error::from_k4a_buffer_result_t(r))
53                }
54            }
55            _ => Err(Error::from_k4a_buffer_result_t(r)),
56        }
57    }
58}
59
60pub(crate) fn get_k4a_binary_data(
61    f: &dyn Fn(*mut u8, *mut usize) -> k4a_buffer_result_t,
62) -> Result<Vec<u8>, Error> {
63    unsafe {
64        let mut buffer: usize = 0;
65        let r = (f)(ptr::null_mut(), &mut buffer);
66        match r {
67            k4a_buffer_result_t_K4A_BUFFER_RESULT_SUCCEEDED => Ok(Vec::<u8>::new()),
68            k4a_buffer_result_t_K4A_BUFFER_RESULT_TOO_SMALL => {
69                if buffer > 1 {
70                    let mut retbuf = Vec::<u8>::with_capacity(buffer);
71                    retbuf.set_len(buffer);
72                    Error::from_k4a_buffer_result_t((f)(retbuf.as_mut_ptr(), &mut buffer))
73                        .to_result(retbuf)
74                } else {
75                    Err(Error::from_k4a_buffer_result_t(r))
76                }
77            }
78            _ => Err(Error::from_k4a_buffer_result_t(r)),
79        }
80    }
81}
82#[cfg(test)]
83mod tests {
84    use crate::utility::*;
85
86    #[test]
87    fn test() {
88        let t1 = "abcdefg";
89        let ct1 = std::ffi::CString::new(t1).unwrap();
90
91        let f: &dyn Fn(*mut ::std::os::raw::c_char, *mut usize) -> k4a_buffer_result_t =
92            &|s, len| unsafe {
93                *len = t1.len() + 1;
94                if s == std::ptr::null_mut() {
95                    k4a_buffer_result_t_K4A_BUFFER_RESULT_TOO_SMALL
96                } else {
97                    std::ptr::copy_nonoverlapping(ct1.as_ptr(), s, t1.len() + 1);
98                    k4a_buffer_result_t_K4A_BUFFER_RESULT_SUCCEEDED
99                }
100            };
101
102        let rst1 = get_k4a_string(&f);
103        let rst2 = get_k4a_cstring(&f);
104        assert_eq!(rst1.unwrap(), t1);
105        assert_eq!(rst2.unwrap().to_str().unwrap(), t1);
106    }
107}