use libc::c_void;
use parse_code;
use std::io;
use zstd_sys;
struct EncoderContext {
c: *mut zstd_sys::ZSTD_CCtx,
}
impl Default for EncoderContext {
fn default() -> Self {
EncoderContext { c: unsafe { zstd_sys::ZSTD_createCCtx() } }
}
}
impl Drop for EncoderContext {
fn drop(&mut self) {
let code = unsafe { zstd_sys::ZSTD_freeCCtx(self.c) };
parse_code(code).unwrap();
}
}
#[derive(Default)]
pub struct Compressor {
context: EncoderContext,
dict: Vec<u8>,
}
impl Compressor {
pub fn new() -> Self {
Compressor::with_dict(Vec::new())
}
pub fn with_dict(dict: Vec<u8>) -> Self {
Compressor {
context: EncoderContext::default(),
dict: dict,
}
}
pub fn compress_to_buffer(&mut self, source: &[u8],
destination: &mut [u8], level: i32)
-> io::Result<usize> {
let code = unsafe {
zstd_sys::ZSTD_compress_usingDict(self.context.c,
destination.as_mut_ptr() as
*mut c_void,
destination.len(),
source.as_ptr() as *mut c_void,
source.len(),
self.dict.as_ptr() as
*mut c_void,
self.dict.len(),
level)
};
parse_code(code)
}
pub fn compress(&mut self, data: &[u8], lvl: i32) -> io::Result<Vec<u8>> {
let buffer_len = unsafe { zstd_sys::ZSTD_compressBound(data.len()) };
let mut buffer = Vec::with_capacity(buffer_len);
unsafe {
buffer.set_len(buffer_len);
let len =
try!(self.compress_to_buffer(data, &mut buffer[..], lvl));
buffer.set_len(len);
}
Ok(buffer)
}
}