use std::{
ffi::{c_char, CString},
path::Path,
};
use crate::{
error::{error, Error},
ffi,
};
pub fn compress_data(data: &[u8]) -> Result<&'static [u8], Error> {
let mut out_length: i32 = 0;
let buffer = {
unsafe { ffi::CompressData(data.as_ptr() as *mut _, data.len() as i32, &mut out_length) }
};
if buffer.is_null() {
return Err(error!("could not compress data"));
}
let buffer = unsafe { std::slice::from_raw_parts(buffer, out_length as usize) };
Ok(buffer)
}
pub fn decompress_data(data: &[u8]) -> Result<&'static [u8], Error> {
println!("{:?}", data.len());
let mut out_length: i32 = 0;
let buffer = {
unsafe { ffi::DecompressData(data.as_ptr() as *mut _, data.len() as i32, &mut out_length) }
};
if buffer.is_null() {
return Err(error!("could not compress data"));
}
let buffer = unsafe { std::slice::from_raw_parts(buffer, out_length as usize) };
Ok(buffer)
}
#[cfg(unix)]
fn path_to_bytes<P: AsRef<Path>>(path: P) -> Vec<u8> {
use std::os::unix::ffi::OsStrExt;
path.as_ref().as_os_str().as_bytes().to_vec()
}
#[cfg(not(unix))]
fn path_to_bytes<P: AsRef<Path>>(path: P) -> Vec<u8> {
path.as_ref().to_string_lossy().to_string().into_bytes()
}
pub fn export_data_as_code(data: &[u8], file_name: impl AsRef<Path>) -> bool {
let c_str = CString::new(path_to_bytes(file_name)).unwrap();
unsafe { ffi::ExportDataAsCode(data.as_ptr(), data.len() as i32, c_str.as_ptr()) }
}
pub fn encode_data_base64(data: &[u8]) -> Vec<c_char> {
let mut output_size = 0;
let bytes =
unsafe { ffi::EncodeDataBase64(data.as_ptr(), data.len() as i32, &mut output_size) };
let s = unsafe { std::slice::from_raw_parts(bytes, output_size as usize) };
if s.contains(&0) {
let mut keep = true;
let b: Vec<c_char> = s
.iter()
.filter(|f| {
if **f == 0 {
keep = false;
}
keep
})
.copied()
.collect();
b
} else {
s.to_vec()
}
}
pub fn compute_crc32(data: &[u8]) -> u32 {
unsafe { ffi::ComputeCRC32(data.as_ptr() as *mut u8, data.len() as i32) }
}
pub fn compute_md5(data: &[u8]) -> [u32; 4] {
unsafe {
let ptr = ffi::ComputeMD5(data.as_ptr() as *mut u8, data.len() as i32);
let mut out = [0u32; 4];
std::ptr::copy_nonoverlapping(ptr, out.as_mut_ptr(), 4);
out
}
}
pub fn compute_sha1(data: &[u8]) -> [u32; 5] {
unsafe {
let ptr = ffi::ComputeSHA1(data.as_ptr() as *mut u8, data.len() as i32);
let mut out = [0u32; 5];
std::ptr::copy_nonoverlapping(ptr, out.as_mut_ptr(), 5);
out
}
}
pub fn compute_sha256(data: &[u8]) -> [u32; 8] {
unsafe {
let ptr = ffi::ComputeSHA256(data.as_ptr() as *mut u8, data.len() as i32);
let mut out = [0u32; 8];
std::ptr::copy_nonoverlapping(ptr, out.as_mut_ptr(), 8);
out
}
}
pub fn decode_data_base64(data: &[u8]) -> Vec<u8> {
let mut output_size = 0;
let bytes = unsafe {
ffi::DecodeDataBase64(
data.as_ptr() as *const std::os::raw::c_char,
&mut output_size,
)
};
let s = unsafe { std::slice::from_raw_parts(bytes, output_size as usize) };
if s.contains(&0) {
let mut keep = true;
let b: Vec<u8> = s
.iter()
.filter(|f| {
if **f == 0 {
keep = false;
}
keep
})
.copied()
.collect();
b
} else {
s.to_vec()
}
}