Skip to content

Commit

Permalink
Merge pull request #37 from KillingSpark/skipable_frames
Browse files Browse the repository at this point in the history
add basic support for skippable frames
  • Loading branch information
KillingSpark committed Mar 15, 2023
2 parents 6174749 + 4aef98d commit 6b5e4e8
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/bin/zstd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ extern crate ruzstd;
use std::fs::File;
use std::io::Read;
use std::io::Seek;
use std::io::SeekFrom;
use std::io::Write;

use ruzstd::frame::ReadFrameHeaderError;
use ruzstd::frame_decoder::FrameDecoderError;

struct StateTracker {
bytes_used: u64,
frames_used: usize,
Expand Down Expand Up @@ -57,7 +61,18 @@ fn main() {
let mut result = vec![0; batch_size];

while tracker.file_pos < tracker.file_size {
frame_dec.reset(&mut f).unwrap();
match frame_dec.reset(&mut f) {
Err(FrameDecoderError::ReadFrameHeaderError(ReadFrameHeaderError::SkipFrame(
magic_num,
skip_size,
))) => {
eprintln!("Found a skippable frame with magic number: {magic_num} and size: {skip_size}");
tracker.file_pos += skip_size as u64;
f.seek(SeekFrom::Current(skip_size as i64)).unwrap();
continue;
}
other => other.unwrap(),
}

tracker.frames_used += 1;

Expand Down
10 changes: 10 additions & 0 deletions src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ pub enum ReadFrameHeaderError {
DictionaryIdReadError(#[source] io::Error),
#[error("Error while reading frame content size: {0}")]
FrameContentSizeReadError(#[source] io::Error),
#[error("SkippableFrame encountered with MagicNumber {0} and length {1} bytes")]
SkipFrame(u32, u32),
}

use std::io::Read;
Expand All @@ -235,6 +237,14 @@ pub fn read_frame_header(mut r: impl Read) -> Result<(Frame, u8), ReadFrameHeade
r.read_exact(&mut buf).map_err(err::MagicNumberReadError)?;
let magic_num = u32::from_le_bytes(buf);

// Skippable frames have a magic number in this interval
if (0x184D2A50..=0x184D2A5F).contains(&magic_num) {
r.read_exact(&mut buf)
.map_err(err::FrameDescriptorReadError)?;
let skip_size = u32::from_le_bytes(buf);
return Err(ReadFrameHeaderError::SkipFrame(magic_num, skip_size));
}

let mut bytes_read = 4;

r.read_exact(&mut buf[0..1])
Expand Down
29 changes: 29 additions & 0 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
#[cfg(test)]
#[test]
fn skippable_frame() {
use crate::frame;

let mut content = vec![];
content.extend_from_slice(&0x184D2A50u32.to_le_bytes());
content.extend_from_slice(&300u32.to_le_bytes());
assert_eq!(8, content.len());
let err = frame::read_frame_header(content.as_slice());
assert!(matches!(
err,
Err(frame::ReadFrameHeaderError::SkipFrame(0x184D2A50u32, 300))
));

content.clear();
content.extend_from_slice(&0x184D2A5Fu32.to_le_bytes());
content.extend_from_slice(&0xFFFFFFFFu32.to_le_bytes());
assert_eq!(8, content.len());
let err = frame::read_frame_header(content.as_slice());
assert!(matches!(
err,
Err(frame::ReadFrameHeaderError::SkipFrame(
0x184D2A5Fu32,
0xFFFFFFFF
))
));
}

#[cfg(test)]
#[test]
fn test_frame_header_reading() {
Expand Down

0 comments on commit 6b5e4e8

Please sign in to comment.