use zstd::zstd_safe::WriteBuf;
use crate::rt::{BlockingResult, spawn_blocking};
use crate::util::{BufMut, BytesMut};
mod decoder;
mod encoder;
pub use self::decoder::Decoder;
pub use self::encoder::Encoder;
#[cfg(test)]
thread_local! {
static OFFLOADED: std::cell::Cell<usize> = const { std::cell::Cell::new(0) };
}
fn offload<F, R>(f: F) -> BlockingResult<R>
where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
#[cfg(test)]
OFFLOADED.with(|n| n.set(n.get() + 1));
spawn_blocking(f)
}
#[cfg(test)]
fn offloaded() -> usize {
OFFLOADED.with(std::cell::Cell::get)
}
fn zstd_error(code: usize) -> std::io::Error {
std::io::Error::other(zstd::zstd_safe::get_error_name(code))
}
struct Spare<'a> {
buf: &'a mut BytesMut,
start: usize,
ptr: *mut u8,
capacity: usize,
}
impl<'a> Spare<'a> {
fn new(buf: &'a mut BytesMut) -> Self {
let start = buf.len();
let spare = buf.chunk_mut();
let (ptr, capacity) = (spare.as_mut_ptr(), spare.len());
Spare {
buf,
start,
ptr,
capacity,
}
}
}
unsafe impl WriteBuf for Spare<'_> {
fn as_slice(&self) -> &[u8] {
&self.buf[self.start..]
}
fn capacity(&self) -> usize {
self.capacity
}
fn as_mut_ptr(&mut self) -> *mut u8 {
self.ptr
}
unsafe fn filled_until(&mut self, n: usize) {
unsafe { self.buf.set_len(self.start + n) }
}
}