1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use crate::error::Error;
use libbfio_sys::FILE;
use libyal_rs_common::ffi::AsTypeRef;
use log::trace;
use std::convert::TryFrom;
use std::ffi::{CStr};



#[repr(C)]
pub struct __LibbfioError(isize);

pub type LibbfioErrorRefMut = *mut __LibbfioError;
pub type LibbfioErrorRef = *const __LibbfioError;

#[repr(C)]
pub struct LibbfioError(LibbfioErrorRefMut);

impl AsTypeRef for LibbfioError {
    type Ref = LibbfioErrorRef;
    type RefMut = LibbfioErrorRefMut;

    fn as_type_ref(&self) -> Self::Ref {
        self.0 as *const _
    }

    fn as_type_ref_mut(&mut self) -> Self::RefMut {
        self.0
    }

    fn as_raw(&mut self) -> *mut Self::RefMut {
        &mut self.0 as *mut _
    }
}

extern "C" {
    pub fn libbfio_error_free(error: *mut LibbfioErrorRefMut);

    pub fn libbfio_error_fprint(error: LibbfioErrorRef, stream: *mut FILE)
        -> ::std::os::raw::c_int;

    pub fn libbfio_error_sprint(
        error: LibbfioErrorRef,
        string: *mut ::std::os::raw::c_char,
        size: usize,
    ) -> ::std::os::raw::c_int;

    pub fn libbfio_error_backtrace_fprint(
        error: LibbfioErrorRef,
        stream: *mut FILE,
    ) -> ::std::os::raw::c_int;

    pub fn libbfio_error_backtrace_sprint(
        error: LibbfioErrorRef,
        string: *mut ::std::os::raw::c_char,
        size: usize,
    ) -> ::std::os::raw::c_int;
}

impl Drop for LibbfioError {
    fn drop(&mut self) {
        trace!("Calling `libbfio_error_free`");

        unsafe { libbfio_error_free(self.as_raw()) };
    }
}

impl TryFrom<*mut __LibbfioError> for Error {
    type Error = Error;

    fn try_from(err: *mut __LibbfioError) -> Result<Self, Self::Error> {
        if err.is_null() {
            return Err(Error::Other("Error pointer cannot be NULL".to_owned()));
        }

        let mut buffer = vec![0; 1024];

        let retcode =
            unsafe { libbfio_error_sprint(err as *const _, buffer.as_mut_ptr(), buffer.len()) };

        if retcode == -1 {
            Err(Error::FFI("Failed to print error".to_owned()))
        } else {
            let repr = unsafe { CStr::from_ptr(buffer.as_ptr()) };
            Ok(Error::FFI(repr.to_string_lossy().to_string()))
        }
    }
}