azure-kinect 0.2.0

Rust Bindings for Azure Kinect Sensor SDK
Documentation
#![allow(non_upper_case_globals)]

use crate::*;
use azure_kinect_sys::k4a::*;
use std::ffi::CString;
use std::ptr;

pub(crate) fn get_k4a_cstring(
    f: &dyn Fn(*mut ::std::os::raw::c_char, *mut usize) -> k4a_buffer_result_t,
) -> Result<CString, Error> {
    unsafe {
        let mut buffer: usize = 0;
        let r = (f)(ptr::null_mut(), &mut buffer);
        match r {
            k4a_buffer_result_t_K4A_BUFFER_RESULT_SUCCEEDED => Ok(CString::default()),
            k4a_buffer_result_t_K4A_BUFFER_RESULT_TOO_SMALL => {
                if buffer > 1 {
                    let mut retbuf = Vec::<u8>::with_capacity(buffer);
                    retbuf.set_len(buffer - 1);
                    Error::from_k4a_buffer_result_t((f)(
                        retbuf.as_mut_ptr() as *mut ::std::os::raw::c_char,
                        &mut buffer,
                    ))
                    .to_result(CString::from_vec_unchecked(retbuf))
                } else {
                    Err(Error::from_k4a_buffer_result_t(r))
                }
            }
            _ => Err(Error::from_k4a_buffer_result_t(r)),
        }
    }
}

pub(crate) fn get_k4a_string(
    f: &dyn Fn(*mut ::std::os::raw::c_char, *mut usize) -> k4a_buffer_result_t,
) -> Result<String, Error> {
    unsafe {
        let mut buffer: usize = 0;
        let r = (f)(ptr::null_mut(), &mut buffer);
        match r {
            k4a_buffer_result_t_K4A_BUFFER_RESULT_SUCCEEDED => Ok(String::new()),
            k4a_buffer_result_t_K4A_BUFFER_RESULT_TOO_SMALL => {
                if buffer > 1 {
                    let mut retstr = String::with_capacity(buffer);
                    retstr.as_mut_vec().set_len(buffer - 1);
                    Error::from_k4a_buffer_result_t((f)(
                        retstr.as_mut_ptr() as *mut ::std::os::raw::c_char,
                        &mut buffer,
                    ))
                    .to_result(retstr)
                } else {
                    Err(Error::from_k4a_buffer_result_t(r))
                }
            }
            _ => Err(Error::from_k4a_buffer_result_t(r)),
        }
    }
}

pub(crate) fn get_k4a_binary_data(
    f: &dyn Fn(*mut u8, *mut usize) -> k4a_buffer_result_t,
) -> Result<Vec<u8>, Error> {
    unsafe {
        let mut buffer: usize = 0;
        let r = (f)(ptr::null_mut(), &mut buffer);
        match r {
            k4a_buffer_result_t_K4A_BUFFER_RESULT_SUCCEEDED => Ok(Vec::<u8>::new()),
            k4a_buffer_result_t_K4A_BUFFER_RESULT_TOO_SMALL => {
                if buffer > 1 {
                    let mut retbuf = Vec::<u8>::with_capacity(buffer);
                    retbuf.set_len(buffer);
                    Error::from_k4a_buffer_result_t((f)(retbuf.as_mut_ptr(), &mut buffer))
                        .to_result(retbuf)
                } else {
                    Err(Error::from_k4a_buffer_result_t(r))
                }
            }
            _ => Err(Error::from_k4a_buffer_result_t(r)),
        }
    }
}
#[cfg(test)]
mod tests {
    use crate::utility::*;

    #[test]
    fn test() {
        let t1 = "abcdefg";
        let ct1 = std::ffi::CString::new(t1).unwrap();

        let f: &dyn Fn(*mut ::std::os::raw::c_char, *mut usize) -> k4a_buffer_result_t =
            &|s, len| unsafe {
                *len = t1.len() + 1;
                if s == std::ptr::null_mut() {
                    k4a_buffer_result_t_K4A_BUFFER_RESULT_TOO_SMALL
                } else {
                    std::ptr::copy_nonoverlapping(ct1.as_ptr(), s, t1.len() + 1);
                    k4a_buffer_result_t_K4A_BUFFER_RESULT_SUCCEEDED
                }
            };

        let rst1 = get_k4a_string(&f);
        let rst2 = get_k4a_cstring(&f);
        assert_eq!(rst1.unwrap(), t1);
        assert_eq!(rst2.unwrap().to_str().unwrap(), t1);
    }
}