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
use std::ffi::CStr;
use std::mem::MaybeUninit;

use foreign_types::{foreign_type, ForeignTypeRef};

use crate::{
    chimera::{error::AsResult, ffi},
    Result,
};

/// Utility function for identifying this release version.
pub fn version() -> &'static CStr {
    unsafe { CStr::from_ptr(ffi::ch_version()) }
}

foreign_type! {
    /// A compiled pattern database that can then be used to scan data.
    pub unsafe type Database: Send + Sync {
        type CType = ffi::ch_database_t;

        fn drop = drop_database;
    }
}

unsafe fn drop_database(db: *mut ffi::ch_database_t) {
    ffi::ch_free_database(db).expect("drop database");
}

impl DatabaseRef {
    /// Returns the size of the given database.
    pub fn size(&self) -> Result<usize> {
        let mut size = MaybeUninit::uninit();

        unsafe { ffi::ch_database_size(self.as_ptr(), size.as_mut_ptr()).map(|_| size.assume_init()) }
    }

    /// Utility function providing information about a database.
    pub fn info(&self) -> Result<String> {
        let mut p = MaybeUninit::uninit();

        unsafe {
            ffi::ch_database_info(self.as_ptr(), p.as_mut_ptr()).and_then(|_| {
                let p = p.assume_init();
                let info = CStr::from_ptr(p).to_str()?.into();
                libc::free(p as *mut _);
                Ok(info)
            })
        }
    }
}