reth_nippy_jar/compression/lz4.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
use crate::{compression::Compression, NippyJarError};
use serde::{Deserialize, Serialize};
/// Wrapper type for `lz4_flex` that implements [`Compression`].
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
#[non_exhaustive]
pub struct Lz4;
impl Compression for Lz4 {
fn decompress_to(&self, value: &[u8], dest: &mut Vec<u8>) -> Result<(), NippyJarError> {
let previous_length = dest.len();
// SAFETY: We're setting len to the existing capacity.
unsafe {
dest.set_len(dest.capacity());
}
match lz4_flex::decompress_into(value, &mut dest[previous_length..]) {
Ok(written) => {
// SAFETY: `compress_into` can only write if there's enough capacity. Therefore, it
// shouldn't write more than our capacity.
unsafe {
dest.set_len(previous_length + written);
}
Ok(())
}
Err(_) => {
// SAFETY: we are resetting it to the previous value.
unsafe {
dest.set_len(previous_length);
}
Err(NippyJarError::OutputTooSmall)
}
}
}
fn decompress(&self, value: &[u8]) -> Result<Vec<u8>, NippyJarError> {
let mut multiplier = 1;
loop {
match lz4_flex::decompress(value, multiplier * value.len()) {
Ok(v) => return Ok(v),
Err(err) => {
multiplier *= 2;
if multiplier == 16 {
return Err(NippyJarError::Custom(err.to_string()))
}
}
}
}
}
fn compress_to(&self, src: &[u8], dest: &mut Vec<u8>) -> Result<usize, NippyJarError> {
let previous_length = dest.len();
// SAFETY: We're setting len to the existing capacity.
unsafe {
dest.set_len(dest.capacity());
}
match lz4_flex::compress_into(src, &mut dest[previous_length..]) {
Ok(written) => {
// SAFETY: `compress_into` can only write if there's enough capacity. Therefore, it
// shouldn't write more than our capacity.
unsafe {
dest.set_len(previous_length + written);
}
Ok(written)
}
Err(_) => {
// SAFETY: we are resetting it to the previous value.
unsafe {
dest.set_len(previous_length);
}
Err(NippyJarError::OutputTooSmall)
}
}
}
fn compress(&self, src: &[u8]) -> Result<Vec<u8>, NippyJarError> {
Ok(lz4_flex::compress(src))
}
}