Skip to content

Commit

Permalink
Allow Gnarle to decompress chunked input data (oxidecomputer#502)
Browse files Browse the repository at this point in the history
  • Loading branch information
arjenroodselaar authored Apr 15, 2022
1 parent 1685af6 commit 2e74907
Showing 1 changed file with 20 additions and 7 deletions.
27 changes: 20 additions & 7 deletions lib/gnarle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ enum DState {
/// We're in a run, we are going to produce the given byte N times, where
/// the count on the right is `N-1`.
Repeating(u8, RunType),
/// We encountered an escape byte, keep track of this fact in the event that
/// the input is exhausted before the full run sequence was read.
AwaitingByte,
/// An escape byte and the byte to be produced was read, keep track of this
/// fact in the event that the input is exhausted before the full run
/// sequence was read.
AwaitingCount(u8),
}

/// Decompresses a chunk of data `input`, writing results to the start of
Expand Down Expand Up @@ -140,20 +147,26 @@ pub fn decompress<'a>(
}
DState::Copying => match take_byte(input) {
Some(ESC) => {
let actual_byte = take_byte(input);
let count = take_byte(input);
if let (Some(ab), Some(c)) = (actual_byte, count) {
state.0 = DState::Repeating(ab, c);
} else {
break;
}
state.0 = DState::AwaitingByte;
}
Some(byte) => {
output[n] = byte;
n += 1;
}
None => break,
},
DState::AwaitingByte => match take_byte(input) {
Some(byte) => {
state.0 = DState::AwaitingCount(byte);
}
None => break,
},
DState::AwaitingCount(byte) => match take_byte(input) {
Some(count) => {
state.0 = DState::Repeating(*byte, count);
}
None => break,
},
}
}

Expand Down

0 comments on commit 2e74907

Please sign in to comment.