use std::ffi::c_void;
use crate::{_yrx_set_last_error, YRX_MATCH, YRX_RESULT};
pub struct YRX_PATTERN<'a, 'r>(yara_x::Pattern<'a, 'r>);
impl<'a, 'r> YRX_PATTERN<'a, 'r> {
pub fn new(pattern: yara_x::Pattern<'a, 'r>) -> Self {
Self(pattern)
}
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn yrx_pattern_identifier(
pattern: *const YRX_PATTERN,
ident: &mut *const u8,
len: &mut usize,
) -> YRX_RESULT {
if let Some(pattern) = pattern.as_ref() {
*ident = pattern.0.identifier().as_ptr();
*len = pattern.0.identifier().len();
_yrx_set_last_error::<String>(None);
YRX_RESULT::YRX_SUCCESS
} else {
YRX_RESULT::YRX_INVALID_ARGUMENT
}
}
pub type YRX_MATCH_CALLBACK =
extern "C" fn(match_: *const YRX_MATCH, user_data: *mut c_void) -> ();
#[unsafe(no_mangle)]
pub unsafe extern "C" fn yrx_pattern_iter_matches(
pattern: *const YRX_PATTERN,
callback: YRX_MATCH_CALLBACK,
user_data: *mut c_void,
) -> YRX_RESULT {
let matches_iter = if let Some(pattern) = pattern.as_ref() {
pattern.0.matches()
} else {
return YRX_RESULT::YRX_INVALID_ARGUMENT;
};
for m in matches_iter {
callback(
&YRX_MATCH { offset: m.range().start, length: m.range().len() },
user_data,
)
}
YRX_RESULT::YRX_SUCCESS
}