use ll;
use std::io;
struct EncoderContext {
c: ll::ZSTDCompressionContext,
}
impl Default for EncoderContext {
fn default() -> Self {
EncoderContext { c: unsafe { ll::ZSTD_createCCtx() } }
}
}
impl Drop for EncoderContext {
fn drop(&mut self) {
let code = unsafe { ll::ZSTD_freeCCtx(self.c) };
ll::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, destination: &mut [u8],
source: &[u8], level: i32)
-> io::Result<usize> {
let code = unsafe {
ll::ZSTD_compress_usingDict(self.context.c,
destination.as_mut_ptr(),
destination.len(),
source.as_ptr(),
source.len(),
self.dict.as_ptr(),
self.dict.len(),
level)
};
ll::parse_code(code)
}
pub fn compress(&mut self, data: &[u8], level: i32) -> io::Result<Vec<u8>> {
let buffer_len = unsafe { ll::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(&mut buffer[..],
data,
level));
buffer.set_len(len);
}
Ok(buffer)
}
}