Skip to content

Commit

Permalink
Add content_size (#44)
Browse files Browse the repository at this point in the history
* Attempt to add content_size.

* update Lz4FrameInfo to match lz4, and test setting content_size

* fmt

---------

Co-authored-by: opq <achriste@hawaii.edu>
  • Loading branch information
pmarks and anthonyjchriste authored Jun 11, 2024
1 parent 1248105 commit edd20f4
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 7 deletions.
27 changes: 25 additions & 2 deletions lz4-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ extern crate libc;
target_arch = "wasm32",
not(any(target_env = "wasi", target_os = "wasi"))
)))]
use libc::{c_void, c_char, c_uint, size_t, c_int};
use libc::{c_void, c_char, c_uint, size_t, c_int, c_ulonglong};

#[cfg(all(
target_arch = "wasm32",
Expand Down Expand Up @@ -74,13 +74,31 @@ pub enum ContentChecksum {
ChecksumEnabled,
}

#[derive(Clone, Debug)]
#[repr(u32)]
pub enum FrameType {
Frame = 0,
SkippableFrame,
}


#[derive(Clone, Debug)]
#[repr(u32)]
pub enum BlockChecksum {
NoBlockChecksum = 0,
BlockChecksumEnabled,
}

#[derive(Debug)]
#[repr(C)]
pub struct LZ4FFrameInfo {
pub block_size_id: BlockSize,
pub block_mode: BlockMode,
pub content_checksum_flag: ContentChecksum,
pub reserved: [c_uint; 5],
pub frame_type: FrameType,
pub content_size: c_ulonglong,
pub dict_id: c_uint,
pub block_checksum_flag: BlockChecksum,
}

#[derive(Debug)]
Expand Down Expand Up @@ -408,3 +426,8 @@ extern "C" {
fn test_version_number() {
unsafe { LZ4_versionNumber(); }
}

#[test]
fn test_frame_info_size() {
assert_eq!(core::mem::size_of::<LZ4FFrameInfo>(), 32);
}
56 changes: 51 additions & 5 deletions src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ struct EncoderContext {
pub struct EncoderBuilder {
block_size: BlockSize,
block_mode: BlockMode,
// 1: each block followed by a checksum of block's compressed data; 0: disabled (default)
block_checksum: BlockChecksum,
checksum: ContentChecksum,
// 0 == default (fast mode); values above 16 count as 16; values below 0 count as 0
level: u32,
// 1 == always flush (reduce need for tmp buffer)
auto_flush: bool,
favor_dec_speed: bool,
content_size: u64,
}

#[derive(Debug)]
Expand All @@ -36,9 +39,11 @@ impl EncoderBuilder {
block_size: BlockSize::Default,
block_mode: BlockMode::Linked,
checksum: ContentChecksum::ChecksumEnabled,
block_checksum: BlockChecksum::NoBlockChecksum,
level: 0,
auto_flush: false,
favor_dec_speed: false,
content_size: 0,
}
}

Expand All @@ -52,6 +57,11 @@ impl EncoderBuilder {
self
}

pub fn block_checksum(&mut self, block_checksum: BlockChecksum) -> &mut Self {
self.block_checksum = block_checksum;
self
}

pub fn checksum(&mut self, checksum: ContentChecksum) -> &mut Self {
self.checksum = checksum;
self
Expand All @@ -74,14 +84,22 @@ impl EncoderBuilder {
self
}

pub fn content_size(&mut self, content_size: u64) -> &mut Self {
self.content_size = content_size;
self
}

pub fn build<W: Write>(&self, w: W) -> Result<Encoder<W>> {
let block_size = self.block_size.get_size();
let preferences = LZ4FPreferences {
frame_info: LZ4FFrameInfo {
block_size_id: self.block_size.clone(),
block_mode: self.block_mode.clone(),
content_checksum_flag: self.checksum.clone(),
reserved: [0; 5],
content_size: self.content_size.clone(),
frame_type: FrameType::Frame,
dict_id: 0,
block_checksum_flag: BlockChecksum::BlockChecksumEnabled,
},
compression_level: self.level,
auto_flush: if self.auto_flush { 1 } else { 0 },
Expand Down Expand Up @@ -215,15 +233,43 @@ mod test {
#[test]
fn test_encoder_random() {
let mut encoder = EncoderBuilder::new().level(1).build(Vec::new()).unwrap();
let mut buffer = Vec::new();
let mut input = Vec::new();
let mut rnd: u32 = 42;
for _ in 0..1024 * 1024 {
buffer.push((rnd & 0xFF) as u8);
input.push((rnd & 0xFF) as u8);
rnd = ((1664525 as u64) * (rnd as u64) + (1013904223 as u64)) as u32;
}
encoder.write(&buffer).unwrap();
let (_, result) = encoder.finish();
encoder.write(&input).unwrap();
let (compressed, result) = encoder.finish();
result.unwrap();

let mut dec = crate::decoder::Decoder::new(&compressed[..]).unwrap();
let mut output = Vec::new();
dec.read_to_end(&mut output).unwrap();
assert_eq!(input, output);
}

#[test]
fn test_encoder_content_size() {
let mut encoder = EncoderBuilder::new()
.level(1)
.content_size(1024 * 1024)
.build(Vec::new())
.unwrap();
let mut input = Vec::new();
let mut rnd: u32 = 42;
for _ in 0..1024 * 1024 {
input.push((rnd & 0xFF) as u8);
rnd = ((1664525 as u64) * (rnd as u64) + (1013904223 as u64)) as u32;
}
encoder.write(&input).unwrap();
let (compressed, result) = encoder.finish();
result.unwrap();

let mut dec = crate::decoder::Decoder::new(&compressed[..]).unwrap();
let mut output = Vec::new();
dec.read_to_end(&mut output).unwrap();
assert_eq!(input, output);
}

#[test]
Expand Down

0 comments on commit edd20f4

Please sign in to comment.