use std::ptr;
use vectorscan_rs_sys as hs;
use crate::vectorscan::error::{AsResult, Error};
#[derive(Debug)]
pub struct Scratch {
scratch: *mut hs::hs_scratch_t,
last_db_ptr: *mut hs::hs_database_t,
}
unsafe impl Send for Scratch {}
unsafe impl Sync for Scratch {}
impl Scratch {
pub unsafe fn new(db: *mut hs::hs_database_t) -> Result<Self, Error> {
let mut scratch: *mut hs::hs_scratch_t = ptr::null_mut();
unsafe {
hs::hs_alloc_scratch(db, &mut scratch).ok()?;
}
Ok(Scratch {
scratch,
last_db_ptr: db,
})
}
#[inline(always)]
pub fn as_ptr(&self) -> *mut hs::hs_scratch_t {
self.scratch
}
#[inline(always)]
pub unsafe fn update(&mut self, db: *mut hs::hs_database_t) -> Result<(), Error> {
if self.last_db_ptr == db {
return Ok(());
}
unsafe {
hs::hs_alloc_scratch(db, &mut self.scratch).ok()?;
}
self.last_db_ptr = db;
Ok(())
}
pub fn try_clone(&self) -> Result<Self, Error> {
let mut scratch: *mut hs::hs_scratch_t = ptr::null_mut();
unsafe {
hs::hs_clone_scratch(self.scratch, &mut scratch).ok()?;
}
Ok(Scratch {
scratch,
last_db_ptr: self.last_db_ptr,
})
}
}
impl Clone for Scratch {
fn clone(&self) -> Self {
self.try_clone()
.expect("failed to clone vectorscan scratch")
}
}
impl Drop for Scratch {
fn drop(&mut self) {
unsafe {
hs::hs_free_scratch(self.scratch);
}
}
}