this is probably not an exhaustive set of potential errors, but it accounts for all the possible ones i've seen as i've been working on this, that are basically always a result of "bad data". still a bit worried about potential panics also resulting from bad data related to overflows and such things ...but have not seen any so far
723 lines
33 KiB
Rust
723 lines
33 KiB
Rust
use std::ffi::c_void;
|
|
|
|
use thiserror::Error;
|
|
|
|
#[derive(Error, Debug)]
|
|
pub enum PrsCompressionError {
|
|
#[error("Error due to bad input data: {0}")]
|
|
BadData(String),
|
|
}
|
|
|
|
struct Context {
|
|
bitpos: u8,
|
|
forward_log: Vec<u8>,
|
|
output: Vec<u8>,
|
|
}
|
|
|
|
impl Context {
|
|
pub fn new() -> Context {
|
|
// tiny bug from the fuzziqer implementation? it never really initializes the forward log
|
|
// anywhere (except, in newserv, as a zero-length std::string) and will ALWAYS start doing
|
|
// some bit twiddling on the first byte before it ever actually explicitly adds the first
|
|
// byte to the forward log ...
|
|
let mut forward_log = Vec::new();
|
|
forward_log.push(0);
|
|
|
|
Context {
|
|
bitpos: 0,
|
|
forward_log,
|
|
output: Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub fn put_control_bit_nosave(&mut self, bit: bool) {
|
|
self.forward_log[0] >>= 1;
|
|
self.forward_log[0] |= (bit as u8) << 7;
|
|
self.bitpos += 1;
|
|
}
|
|
|
|
pub fn put_control_save(&mut self) {
|
|
if self.bitpos >= 8 {
|
|
self.bitpos = 0;
|
|
self.output.append(&mut self.forward_log);
|
|
self.forward_log.resize(1, 0);
|
|
self.forward_log[0] = 0;
|
|
}
|
|
}
|
|
|
|
pub fn put_static_data(&mut self, data: u8) {
|
|
self.forward_log.push(data);
|
|
}
|
|
|
|
pub fn put_control_bit(&mut self, bit: bool) {
|
|
self.put_control_bit_nosave(bit);
|
|
self.put_control_save();
|
|
}
|
|
|
|
pub fn raw_byte(&mut self, value: u8) {
|
|
self.put_control_bit_nosave(true);
|
|
self.put_static_data(value);
|
|
self.put_control_save();
|
|
}
|
|
|
|
pub fn short_copy(&mut self, offset: isize, size: u8) {
|
|
let size = size - 2;
|
|
self.put_control_bit(false);
|
|
self.put_control_bit(false);
|
|
self.put_control_bit((size >> 1) & 1 == 1);
|
|
self.put_control_bit_nosave(size & 1 == 1);
|
|
self.put_static_data(offset as u8);
|
|
self.put_control_save();
|
|
}
|
|
|
|
pub fn long_copy(&mut self, offset: isize, size: u8) {
|
|
if size <= 9 {
|
|
self.put_control_bit(false);
|
|
self.put_control_bit_nosave(true);
|
|
self.put_static_data((((offset << 3) & 0xf8) as u8) | ((size - 2) & 0x07));
|
|
self.put_static_data((offset >> 5) as u8);
|
|
self.put_control_save();
|
|
} else {
|
|
self.put_control_bit(false);
|
|
self.put_control_bit_nosave(true);
|
|
self.put_static_data(((offset << 3) & 0xf8) as u8);
|
|
self.put_static_data((offset >> 5) as u8);
|
|
self.put_static_data(size - 1);
|
|
self.put_control_save();
|
|
}
|
|
}
|
|
|
|
pub fn copy(&mut self, offset: isize, size: u8) {
|
|
if (offset > -0x100) && (size <= 5) {
|
|
self.short_copy(offset, size);
|
|
} else {
|
|
self.long_copy(offset, size);
|
|
}
|
|
}
|
|
|
|
pub fn finish(mut self) -> Box<[u8]> {
|
|
self.put_control_bit(false);
|
|
self.put_control_bit(true);
|
|
if self.bitpos != 0 {
|
|
self.forward_log[0] =
|
|
(((self.forward_log[0] as u32) << (self.bitpos as u32)) >> 8) as u8;
|
|
};
|
|
self.put_static_data(0);
|
|
self.put_static_data(0);
|
|
self.output.append(&mut self.forward_log);
|
|
self.output.into_boxed_slice()
|
|
}
|
|
}
|
|
|
|
fn is_mem_equal(base: &[u8], offset1: isize, offset2: isize, length: usize) -> bool {
|
|
// the fuzziqer prs compression implementation performs memcmp's that check memory slightly
|
|
// outside of the buffers it is working with fairly often actually, despite the checks it
|
|
// does in the main prs_compress loops ... ugh
|
|
if offset1 < 0 || offset2 < 0 {
|
|
false
|
|
} else {
|
|
let offset1 = offset1 as usize;
|
|
let offset2 = offset2 as usize;
|
|
if ((offset1 + length) > base.len()) || ((offset2 + length) > base.len()) {
|
|
false
|
|
} else {
|
|
// calling memcmp directly here instead of doing slice comparisons is at least twice as
|
|
// fast in non-release builds right now. since we're doing a bunch of pre-checks anyway
|
|
// here (else, even the original slice comparisons would occasionally panic), just
|
|
// calling memcmp in all cases doesn't seem to be too bad an idea?
|
|
// NOTE: i actually wanted to use the memcmp from compiler_builtins but that seems to
|
|
// be nightly-only at the moment??
|
|
|
|
//base[offset1..(offset1 + length)] == base[offset2..(offset2 + length)]
|
|
let a = (&base[offset1] as *const u8) as *const c_void;
|
|
let b = (&base[offset2] as *const u8) as *const c_void;
|
|
unsafe { libc::memcmp(a, b, length) == 0 }
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn prs_compress(source: &[u8]) -> Result<Box<[u8]>, PrsCompressionError> {
|
|
let mut pc = Context::new();
|
|
|
|
let mut x: isize = 0;
|
|
while x < source.len() as isize {
|
|
let mut lsoffset: isize = 0;
|
|
let mut lssize: isize = 0;
|
|
let mut xsize: usize = 0;
|
|
|
|
let mut y: isize = x - 3;
|
|
while (y > 0) && (y > (x - 0x1ff0)) && (xsize < 255) {
|
|
xsize = 3;
|
|
if is_mem_equal(source, y, x, xsize) {
|
|
xsize += 1;
|
|
while (xsize < 256)
|
|
&& ((y + xsize as isize) < x)
|
|
&& ((x + xsize as isize) <= source.len() as isize)
|
|
&& is_mem_equal(source, y, x, xsize)
|
|
{
|
|
xsize += 1;
|
|
}
|
|
xsize -= 1;
|
|
|
|
if (xsize as isize) > lssize {
|
|
lsoffset = -(x - y);
|
|
lssize = xsize as isize;
|
|
}
|
|
}
|
|
y -= 1;
|
|
}
|
|
|
|
if lssize == 0 {
|
|
pc.raw_byte(match source.get(x as usize) {
|
|
Some(value) => *value,
|
|
None => {
|
|
return Err(PrsCompressionError::BadData(format!(
|
|
"tried to add raw byte from source at out-of-bounds index {}",
|
|
x
|
|
)))
|
|
}
|
|
});
|
|
} else {
|
|
pc.copy(lsoffset, lssize as u8);
|
|
x += lssize - 1;
|
|
}
|
|
|
|
x += 1;
|
|
}
|
|
|
|
Ok(pc.finish())
|
|
}
|
|
|
|
enum Next {
|
|
Byte(u8),
|
|
Eof(),
|
|
}
|
|
|
|
struct ByteReader<'a> {
|
|
source: &'a [u8],
|
|
offset: usize,
|
|
}
|
|
|
|
impl<'a> ByteReader<'a> {
|
|
pub fn new(source: &[u8]) -> ByteReader {
|
|
ByteReader { source, offset: 0 }
|
|
}
|
|
|
|
pub fn next(&mut self) -> Next {
|
|
if self.offset < self.source.len() {
|
|
let result = Next::Byte(self.source[self.offset]);
|
|
self.offset += 1;
|
|
result
|
|
} else {
|
|
Next::Eof()
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn prs_decompress(source: &[u8]) -> Result<Box<[u8]>, PrsCompressionError> {
|
|
let mut output = Vec::new();
|
|
let mut reader = ByteReader::new(source);
|
|
let mut r3: i32;
|
|
let mut r5: i32;
|
|
let mut bitpos = 9;
|
|
let mut current_byte: u8;
|
|
let mut flag: bool;
|
|
let mut offset: i32;
|
|
|
|
// if you prs_compress a zero-length buffer, you get a 3-byte "compressed" result.
|
|
// therefore, 3 byte minimum input buffer is required to get any kind of "meaningful"
|
|
// decompression result back out
|
|
if source.len() < 3 {
|
|
return Err(PrsCompressionError::BadData(format!(
|
|
"Input data is too short: {} bytes",
|
|
source.len()
|
|
)));
|
|
}
|
|
|
|
current_byte = match reader.next() {
|
|
Next::Byte(byte) => byte,
|
|
Next::Eof() => return Ok(output.into_boxed_slice()),
|
|
};
|
|
|
|
loop {
|
|
bitpos -= 1;
|
|
if bitpos == 0 {
|
|
current_byte = match reader.next() {
|
|
Next::Byte(byte) => byte,
|
|
Next::Eof() => return Ok(output.into_boxed_slice()),
|
|
};
|
|
bitpos = 8;
|
|
}
|
|
|
|
flag = (current_byte & 1) == 1;
|
|
current_byte >>= 1;
|
|
if flag {
|
|
output.push(match reader.next() {
|
|
Next::Byte(byte) => byte,
|
|
Next::Eof() => return Ok(output.into_boxed_slice()),
|
|
});
|
|
continue;
|
|
}
|
|
|
|
bitpos -= 1;
|
|
if bitpos == 0 {
|
|
current_byte = match reader.next() {
|
|
Next::Byte(byte) => byte,
|
|
Next::Eof() => return Ok(output.into_boxed_slice()),
|
|
};
|
|
bitpos = 8;
|
|
}
|
|
|
|
flag = (current_byte & 1) == 1;
|
|
current_byte >>= 1;
|
|
if flag {
|
|
r3 = match reader.next() {
|
|
Next::Byte(byte) => byte as i32,
|
|
Next::Eof() => return Ok(output.into_boxed_slice()),
|
|
};
|
|
let high_byte = match reader.next() {
|
|
Next::Byte(byte) => byte as i32,
|
|
Next::Eof() => return Ok(output.into_boxed_slice()),
|
|
};
|
|
offset = ((high_byte & 0xff) << 8) | (r3 & 0xff);
|
|
if offset == 0 {
|
|
return Ok(output.into_boxed_slice());
|
|
}
|
|
r3 &= 0x00000007;
|
|
r5 = (offset >> 3) | -8192i32; // 0xffffe000
|
|
if r3 == 0 {
|
|
r3 = match reader.next() {
|
|
Next::Byte(byte) => byte as i32,
|
|
Next::Eof() => return Ok(output.into_boxed_slice()),
|
|
};
|
|
r3 = (r3 & 0xff) + 1;
|
|
} else {
|
|
r3 += 2;
|
|
}
|
|
} else {
|
|
r3 = 0;
|
|
for _ in 0..2 {
|
|
bitpos -= 1;
|
|
if bitpos == 0 {
|
|
current_byte = match reader.next() {
|
|
Next::Byte(byte) => byte,
|
|
Next::Eof() => return Ok(output.into_boxed_slice()),
|
|
};
|
|
bitpos = 8;
|
|
}
|
|
flag = (current_byte & 1) == 1;
|
|
current_byte >>= 1;
|
|
offset = r3 << 1;
|
|
r3 = offset | (flag as i32);
|
|
}
|
|
offset = match reader.next() {
|
|
Next::Byte(byte) => byte as i32,
|
|
Next::Eof() => return Ok(output.into_boxed_slice()),
|
|
};
|
|
r3 += 2;
|
|
r5 = offset | -256i32; // 0xffffff00
|
|
}
|
|
if r3 == 0 {
|
|
continue;
|
|
}
|
|
for _ in 0..r3 {
|
|
let index = output.len() as i32 + r5;
|
|
output.push(match output.get(index as usize) {
|
|
Some(value) => *value,
|
|
None => {
|
|
return Err(PrsCompressionError::BadData(format!(
|
|
"tried to push copy of byte at out-of-bounds index {}",
|
|
index
|
|
)))
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use claim::*;
|
|
use rand::rngs::StdRng;
|
|
use rand::{Fill, SeedableRng};
|
|
|
|
use super::*;
|
|
|
|
struct TestData<'a> {
|
|
uncompressed: &'a [u8],
|
|
compressed: &'a [u8],
|
|
}
|
|
|
|
static TEST_DATA: &[TestData] = &[
|
|
TestData {
|
|
uncompressed: "Hello, world!\0".as_bytes(),
|
|
compressed: &[
|
|
0xff, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0xbf, 0x6f, 0x72, 0x6c, 0x64,
|
|
0x21, 0x00, 0x00, 0x00, 0x00,
|
|
],
|
|
},
|
|
TestData {
|
|
uncompressed: "I am Sam
|
|
|
|
Sam I am
|
|
|
|
That Sam-I-am!
|
|
That Sam-I-am!
|
|
I do not like
|
|
that Sam-I-am!
|
|
|
|
Do you like green eggs and ham?
|
|
|
|
I do not like them, Sam-I-am.
|
|
I do not like green eggs and ham."
|
|
.as_bytes(),
|
|
compressed: &[
|
|
0xff, 0x49, 0x20, 0x61, 0x6d, 0x20, 0x53, 0x61, 0x6d, 0xe3, 0x0a, 0x0a, 0xfb, 0x20,
|
|
0x49, 0xf8, 0xf2, 0x0a, 0x0a, 0x54, 0x68, 0xd3, 0x61, 0x74, 0xec, 0x2d, 0x49, 0xef,
|
|
0x2d, 0x61, 0x6d, 0x21, 0x88, 0xff, 0x0d, 0x21, 0x0a, 0xff, 0x49, 0x20, 0x64, 0x6f,
|
|
0x20, 0x6e, 0x6f, 0x74, 0x7f, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x0a, 0x74, 0xff, 0x18,
|
|
0xff, 0x0d, 0x0a, 0x44, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0xfc, 0xe4, 0x20, 0x67, 0x72,
|
|
0x65, 0xff, 0x65, 0x6e, 0x20, 0x65, 0x67, 0x67, 0x73, 0x20, 0xff, 0x61, 0x6e, 0x64,
|
|
0x20, 0x68, 0x61, 0x6d, 0x3f, 0xfd, 0x0a, 0x08, 0xfe, 0x0d, 0x20, 0x74, 0x68, 0x65,
|
|
0x6d, 0xad, 0x2c, 0x07, 0xfe, 0x2e, 0x10, 0xff, 0x0e, 0xf8, 0xfd, 0x11, 0x05, 0x2e,
|
|
0x00, 0x00,
|
|
],
|
|
},
|
|
TestData {
|
|
uncompressed: &[],
|
|
compressed: &[0x02, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"a",
|
|
compressed: &[0x05, 0x61, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aa",
|
|
compressed: &[0x0b, 0x61, 0x61, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaa",
|
|
compressed: &[0x17, 0x61, 0x61, 0x61, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaa",
|
|
compressed: &[0x2f, 0x61, 0x61, 0x61, 0x61, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaa",
|
|
compressed: &[0x5f, 0x61, 0x61, 0x61, 0x61, 0x61, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaa",
|
|
compressed: &[0xbf, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x00, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaa",
|
|
compressed: &[0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0x02, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaaa",
|
|
compressed: &[0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0x05, 0x61, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaaaa",
|
|
compressed: &[
|
|
0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0x0b, 0x61, 0x61, 0x00, 0x00,
|
|
],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaaaaa",
|
|
compressed: &[0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0x28, 0xfd, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaaaaaa",
|
|
compressed: &[0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0x24, 0xfb, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaaaaaaa",
|
|
compressed: &[0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0x2c, 0xfa, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaaaaaaaa",
|
|
compressed: &[
|
|
0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0x5c, 0xfa, 0x61, 0x00, 0x00,
|
|
],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaaaaaaaaa",
|
|
compressed: &[
|
|
0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0xbc, 0xfa, 0x61, 0x61, 0x00, 0x00, 0x00,
|
|
],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaaaaaaaaaa",
|
|
compressed: &[
|
|
0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0x8c, 0xfa, 0xfd, 0x02, 0x00, 0x00,
|
|
],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaaaaaaaaaaa",
|
|
compressed: &[
|
|
0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0x4c, 0xfa, 0xfb, 0x02, 0x00, 0x00,
|
|
],
|
|
},
|
|
TestData {
|
|
uncompressed: b"aaaaaaaaaaaaaaaaa",
|
|
compressed: &[
|
|
0x8f, 0x61, 0x61, 0x61, 0x61, 0xfd, 0xcc, 0xfa, 0xfa, 0x02, 0x00, 0x00,
|
|
],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0xff],
|
|
compressed: &[0x05, 0xff, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0xff, 0xff],
|
|
compressed: &[0x0b, 0xff, 0xff, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0xff, 0xff, 0xff],
|
|
compressed: &[0x17, 0xff, 0xff, 0xff, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0xff, 0xff, 0xff, 0xff],
|
|
compressed: &[0x2f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0xff, 0xff, 0xff, 0xff, 0xff],
|
|
compressed: &[0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
|
|
compressed: &[0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
|
|
compressed: &[0x8f, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x02, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
|
|
compressed: &[0x8f, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x05, 0xff, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0x00],
|
|
compressed: &[0x05, 0x00, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0x00, 0x00],
|
|
compressed: &[0x0b, 0x00, 0x00, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0x00, 0x00, 0x00],
|
|
compressed: &[0x17, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0x00, 0x00, 0x00, 0x00],
|
|
compressed: &[0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0x00, 0x00, 0x00, 0x00, 0x00],
|
|
compressed: &[0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
},
|
|
// when comparing these results to the fuzziqer implementation, these zero-byte run tests
|
|
// start to get a little interesting from this point onward. at this point, the fuzziqer
|
|
// implementation will sometimes start to perform memcmp() calls that check memory slightly
|
|
// out of the bounds of its buffers, and when that memory also happens to contain zeros (as
|
|
// seems to always be the case for me right now), you get things like the 6 and 7 length
|
|
// zero-byte runs compressing identically (which is obviously a bug). this buggy behaviour
|
|
// carries on for some larger run sizes too, probably indefinitely.
|
|
TestData {
|
|
uncompressed: &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
compressed: &[0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
compressed: &[0x8f, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x02, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
compressed: &[0x8f, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x05, 0x00, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
compressed: &[
|
|
0x8f, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x0b, 0x00, 0x00, 0x00, 0x00,
|
|
],
|
|
},
|
|
TestData {
|
|
uncompressed: &[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
|
compressed: &[0x8f, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x28, 0xfd, 0x00, 0x00],
|
|
},
|
|
TestData {
|
|
uncompressed: &[
|
|
0x04, 0x00, 0x02, 0x01, 0x05, 0x04, 0x08, 0x00, 0x04, 0x02, 0x07, 0x0d, 0x0c, 0x11,
|
|
0x02, 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x02, 0x09, 0x02, 0x03, 0x01, 0x0b, 0x0a,
|
|
0x0d, 0x0e, 0x04, 0x03, 0x03, 0x04, 0x02, 0x00, 0x07, 0x00, 0x08, 0x00, 0x03, 0x03,
|
|
0x0b, 0x0a, 0x0b, 0x10, 0x03, 0x03, 0x04, 0x02, 0x06, 0x04, 0x07, 0x03, 0x07, 0x04,
|
|
0x01, 0x03, 0x0a, 0x0c, 0x0c, 0x0f, 0x02, 0x04, 0x01, 0x04, 0x04, 0x02, 0x07, 0x02,
|
|
0x09, 0x04, 0x02, 0x03, 0x09, 0x0b, 0x0f, 0x0d, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03,
|
|
0x04, 0x02, 0x05, 0x02, 0x00, 0x00, 0x0a, 0x0b, 0x0d, 0x0f, 0x03, 0x00, 0x01, 0x02,
|
|
0x02, 0x02, 0x07, 0x04, 0x09, 0x02, 0x00, 0x03, 0x08, 0x0a, 0x0c, 0x11, 0x04, 0x00,
|
|
0x00, 0x04, 0x03, 0x04, 0x06, 0x01, 0x06, 0x01, 0x03, 0x01, 0x07, 0x09, 0x0e, 0x10,
|
|
0x02, 0x01, 0x03, 0x04, 0x03, 0x02, 0x04, 0x00, 0x06, 0x01, 0x00, 0x03, 0x09, 0x0a,
|
|
0x0d, 0x10, 0x02, 0x04, 0x03, 0x03, 0x05, 0x03, 0x04, 0x02, 0x09, 0x04, 0x03, 0x04,
|
|
0x08, 0x0b, 0x0b, 0x0d, 0x00, 0x03, 0x00, 0x01, 0x04, 0x01, 0x06, 0x04, 0x09, 0x04,
|
|
0x04, 0x03, 0x07, 0x0a, 0x0c, 0x0f, 0x02, 0x01, 0x02, 0x03, 0x02, 0x03, 0x05, 0x01,
|
|
0x09, 0x00, 0x01, 0x02, 0x0b, 0x0c, 0x0e, 0x0d, 0x03, 0x00, 0x03, 0x00, 0x03, 0x02,
|
|
0x04, 0x02, 0x06, 0x00, 0x00, 0x01, 0x0a, 0x0c, 0x0c, 0x0e, 0x02, 0x03, 0x01, 0x02,
|
|
0x06, 0x03, 0x03, 0x00, 0x05, 0x03, 0x03, 0x02, 0x08, 0x0c, 0x0f, 0x0e, 0x03, 0x02,
|
|
0x02, 0x01, 0x06, 0x03, 0x03, 0x02, 0x06, 0x02, 0x04, 0x04, 0x07, 0x0b, 0x0b, 0x0f,
|
|
0x00, 0x01, 0x01, 0x01, 0x06, 0x04, 0x05, 0x02, 0x07, 0x02, 0x04, 0x04, 0x09, 0x0c,
|
|
0x0d, 0x0d, 0x00, 0x04, 0x03, 0x02, 0x02, 0x00, 0x07, 0x01, 0x07, 0x00, 0x00, 0x04,
|
|
0x09, 0x0c, 0x0f, 0x10, 0x04, 0x00, 0x01, 0x01, 0x06, 0x03, 0x03, 0x04, 0x07, 0x04,
|
|
0x03, 0x04, 0x09, 0x09, 0x0c, 0x11, 0x02, 0x01, 0x03, 0x04, 0x03, 0x03, 0x03, 0x03,
|
|
0x08, 0x02, 0x03, 0x01, 0x07, 0x0b, 0x0c, 0x0f, 0x04, 0x04, 0x00, 0x01, 0x02, 0x00,
|
|
0x03, 0x02, 0x09, 0x00, 0x04, 0x03, 0x09, 0x09, 0x0f, 0x0e, 0x02, 0x03, 0x00, 0x00,
|
|
0x03, 0x02, 0x04, 0x01, 0x05, 0x01, 0x04, 0x02, 0x07, 0x0b, 0x0f, 0x11, 0x02, 0x04,
|
|
0x02, 0x02, 0x03, 0x04, 0x07, 0x00, 0x09, 0x03, 0x00, 0x04, 0x08, 0x09, 0x0b, 0x0d,
|
|
0x03, 0x01, 0x00, 0x01, 0x02, 0x01, 0x05, 0x00, 0x07, 0x04, 0x03, 0x02, 0x08, 0x0d,
|
|
0x0f, 0x10, 0x01, 0x03, 0x00, 0x02, 0x05, 0x02, 0x03, 0x02, 0x07, 0x00, 0x03, 0x03,
|
|
0x09, 0x0d, 0x0b, 0x0f, 0x02, 0x01, 0x03, 0x02, 0x06, 0x03, 0x03, 0x04, 0x07, 0x00,
|
|
0x03, 0x03, 0x0b, 0x0b, 0x0f, 0x0f, 0x03, 0x01, 0x00, 0x01, 0x05, 0x02, 0x03, 0x03,
|
|
0x07, 0x04, 0x03, 0x02, 0x0a, 0x0d, 0x0f, 0x0d, 0x02, 0x00, 0x04, 0x01, 0x05, 0x04,
|
|
0x05, 0x02, 0x06, 0x01, 0x00, 0x03, 0x07, 0x0a, 0x0b, 0x10, 0x03, 0x02, 0x04, 0x03,
|
|
0x06, 0x00, 0x04, 0x04, 0x06, 0x00, 0x01, 0x04, 0x08, 0x09, 0x0c, 0x10, 0x00, 0x02,
|
|
0x01, 0x00, 0x04, 0x04, 0x05, 0x00, 0x07, 0x00, 0x03, 0x02, 0x08, 0x0d, 0x0e, 0x0e,
|
|
0x01, 0x04, 0x00, 0x01, 0x03, 0x01, 0x05, 0x02, 0x08, 0x03, 0x01, 0x04, 0x07, 0x0d,
|
|
0x0f, 0x10, 0x02, 0x01, 0x00, 0x01, 0x04, 0x03, 0x04, 0x04, 0x05, 0x00, 0x03, 0x01,
|
|
0x0b, 0x0c, 0x0b, 0x0f, 0x03, 0x00, 0x00, 0x04, 0x05, 0x02, 0x05, 0x02, 0x05, 0x00,
|
|
0x03, 0x03, 0x09, 0x09, 0x0e, 0x11, 0x03, 0x03, 0x00, 0x00, 0x03, 0x01, 0x04, 0x01,
|
|
0x08, 0x01, 0x00, 0x02, 0x07, 0x09, 0x0d, 0x10, 0x00, 0x02, 0x04, 0x00, 0x02, 0x01,
|
|
0x05, 0x02, 0x09, 0x03, 0x00, 0x01, 0x0a, 0x0c, 0x0d, 0x0e, 0x02, 0x02, 0x03, 0x00,
|
|
0x02, 0x04, 0x05, 0x01, 0x07, 0x04, 0x03, 0x02, 0x08, 0x09, 0x0b, 0x10, 0x03, 0x00,
|
|
0x03, 0x00, 0x05, 0x03, 0x05, 0x04, 0x06, 0x03, 0x02, 0x01, 0x0a, 0x0d, 0x0f, 0x0d,
|
|
0x01, 0x02, 0x03, 0x04, 0x05, 0x02, 0x03, 0x02, 0x06, 0x00, 0x00, 0x02, 0x0a, 0x0b,
|
|
0x0b, 0x10, 0x04, 0x00, 0x03, 0x03, 0x05, 0x02, 0x07, 0x01, 0x05, 0x02, 0x04, 0x01,
|
|
0x08, 0x0c, 0x0e, 0x0d, 0x02, 0x01, 0x01, 0x02, 0x05, 0x01, 0x03, 0x01, 0x08, 0x00,
|
|
0x00, 0x03, 0x0b, 0x0b, 0x0c, 0x11, 0x03, 0x01, 0x02, 0x01, 0x06, 0x01, 0x03, 0x01,
|
|
0x05, 0x04, 0x02, 0x02, 0x0a, 0x0c, 0x0d, 0x0f, 0x04, 0x03, 0x02, 0x00, 0x03, 0x02,
|
|
0x04, 0x01, 0x09, 0x02, 0x00, 0x03, 0x0b, 0x0c, 0x0d, 0x0f, 0x02, 0x01, 0x01, 0x03,
|
|
0x02, 0x01, 0x07, 0x00, 0x07, 0x04, 0x02, 0x02, 0x09, 0x0a, 0x0b, 0x10, 0x01, 0x02,
|
|
0x03, 0x02, 0x03, 0x00, 0x07, 0x02, 0x09, 0x01, 0x00, 0x00, 0x0b, 0x09, 0x0e, 0x0e,
|
|
0x01, 0x01, 0x04, 0x03, 0x06, 0x01, 0x07, 0x01, 0x07, 0x03, 0x04, 0x01, 0x09, 0x0a,
|
|
0x0f, 0x10, 0x03, 0x03, 0x01, 0x01, 0x02, 0x02, 0x06, 0x01, 0x08, 0x00, 0x01, 0x04,
|
|
0x07, 0x0a, 0x0e, 0x11, 0x02, 0x04, 0x02, 0x01, 0x02, 0x03, 0x03, 0x02, 0x07, 0x04,
|
|
0x03, 0x01, 0x07, 0x09, 0x0f, 0x0d, 0x03, 0x02, 0x01, 0x00, 0x06, 0x01, 0x04, 0x04,
|
|
0x06, 0x02, 0x01, 0x04, 0x08, 0x0d, 0x0e, 0x10, 0x03, 0x00, 0x02, 0x01, 0x03, 0x02,
|
|
0x03, 0x00, 0x08, 0x04, 0x01, 0x03, 0x08, 0x09, 0x0b, 0x11, 0x03, 0x03, 0x01, 0x04,
|
|
0x06, 0x04, 0x04, 0x02, 0x08, 0x04, 0x01, 0x04, 0x0a, 0x0d, 0x0e, 0x10, 0x02, 0x02,
|
|
0x01, 0x03, 0x06, 0x02, 0x03, 0x04, 0x08, 0x01, 0x02, 0x04, 0x08, 0x0b, 0x0e, 0x0e,
|
|
0x00, 0x01, 0x03, 0x01, 0x02, 0x04, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x09,
|
|
0x0e, 0x10, 0x02, 0x00, 0x03, 0x03, 0x06, 0x03, 0x07, 0x02, 0x09, 0x01, 0x01, 0x03,
|
|
0x07, 0x0a, 0x0f, 0x0f, 0x02, 0x04, 0x03, 0x04, 0x05, 0x03, 0x07, 0x00, 0x08, 0x01,
|
|
0x00, 0x00, 0x0a, 0x0d, 0x0b, 0x0f, 0x01, 0x04, 0x00, 0x00, 0x06, 0x04, 0x07, 0x01,
|
|
0x07, 0x00, 0x04, 0x04, 0x08, 0x09, 0x0c, 0x0d, 0x00, 0x01, 0x04, 0x00, 0x02, 0x00,
|
|
0x04, 0x00, 0x09, 0x01, 0x02, 0x02, 0x09, 0x0c, 0x0b, 0x0d, 0x04, 0x02, 0x02, 0x03,
|
|
0x06, 0x01, 0x07, 0x01, 0x06, 0x00, 0x01, 0x04, 0x08, 0x0d, 0x0f, 0x10, 0x03, 0x00,
|
|
0x03, 0x03, 0x03, 0x01, 0x03, 0x00, 0x05, 0x03, 0x02, 0x02, 0x0a, 0x0b, 0x0b, 0x0f,
|
|
0x00, 0x02, 0x02, 0x04, 0x03, 0x04, 0x05, 0x02, 0x09, 0x00, 0x04, 0x02, 0x09, 0x0c,
|
|
0x0b, 0x0d, 0x04, 0x01, 0x00, 0x02, 0x04, 0x00, 0x05, 0x02, 0x05, 0x01, 0x02, 0x03,
|
|
0x08, 0x0b, 0x0d, 0x10, 0x01, 0x00, 0x04, 0x02, 0x03, 0x01, 0x05, 0x02, 0x09, 0x01,
|
|
0x00, 0x01, 0x08, 0x0b, 0x0c, 0x0d, 0x03, 0x03, 0x02, 0x03, 0x05, 0x01, 0x05, 0x04,
|
|
0x05, 0x04, 0x04, 0x01, 0x0a, 0x0b, 0x0f, 0x0d, 0x04, 0x03, 0x02, 0x00, 0x03, 0x01,
|
|
0x05, 0x02, 0x07, 0x04, 0x03, 0x04, 0x09, 0x0a, 0x0c, 0x0f, 0x04, 0x01, 0x00, 0x00,
|
|
0x04, 0x03, 0x04, 0x04, 0x09, 0x00, 0x00, 0x03, 0x0b, 0x0a, 0x0b, 0x10, 0x01, 0x04,
|
|
0x00, 0x00, 0x03, 0x03, 0x05, 0x00, 0x09, 0x01, 0x01, 0x01, 0x0b, 0x0c, 0x0f, 0x11,
|
|
0x01, 0x04,
|
|
],
|
|
compressed: &[
|
|
0xff, 0x04, 0x00, 0x02, 0x01, 0x05, 0x04, 0x08, 0x00, 0xff, 0x04, 0x02, 0x07, 0x0d,
|
|
0x0c, 0x11, 0x02, 0x00, 0xff, 0x03, 0x04, 0x04, 0x04, 0x03, 0x02, 0x09, 0x02, 0xff,
|
|
0x03, 0x01, 0x0b, 0x0a, 0x0d, 0x0e, 0x04, 0x03, 0xff, 0x03, 0x04, 0x02, 0x00, 0x07,
|
|
0x00, 0x08, 0x00, 0x3f, 0x03, 0x03, 0x0b, 0x0a, 0x0b, 0x10, 0xfd, 0xf1, 0x06, 0x04,
|
|
0x07, 0x03, 0x07, 0x04, 0xff, 0x01, 0x03, 0x0a, 0x0c, 0x0c, 0x0f, 0x02, 0x04, 0xe3,
|
|
0x01, 0x04, 0xc6, 0x02, 0x09, 0xff, 0x04, 0x02, 0x03, 0x09, 0x0b, 0x0f, 0x0d, 0x02,
|
|
0xc7, 0x03, 0x04, 0x01, 0xfc, 0x02, 0xff, 0x05, 0x02, 0x00, 0x00, 0x0a, 0x0b, 0x0d,
|
|
0x0f, 0xff, 0x03, 0x00, 0x01, 0x02, 0x02, 0x02, 0x07, 0x04, 0xf1, 0x09, 0xa7, 0x08,
|
|
0x0a, 0x0c, 0xff, 0x11, 0x04, 0x00, 0x00, 0x04, 0x03, 0x04, 0x06, 0xff, 0x01, 0x06,
|
|
0x01, 0x03, 0x01, 0x07, 0x09, 0x0e, 0x8f, 0x10, 0x02, 0x01, 0x03, 0x92, 0xff, 0x04,
|
|
0x00, 0x06, 0x01, 0x00, 0x03, 0x09, 0x0a, 0xc7, 0x0d, 0x10, 0x02, 0x8f, 0x05, 0x18,
|
|
0xc0, 0x09, 0x3f, 0xda, 0x08, 0x0b, 0x0b, 0x0d, 0x00, 0x7e, 0xbf, 0x04, 0x01, 0x06,
|
|
0x04, 0x09, 0x1c, 0x6b, 0x07, 0x0a, 0xf1, 0x90, 0xa2, 0x02, 0x03, 0x05, 0xe3, 0x01,
|
|
0x09, 0xa8, 0x0b, 0x0c, 0x47, 0x0e, 0x0d, 0x03, 0xdf, 0xfc, 0xc0, 0x02, 0x06, 0x00,
|
|
0x00, 0x01, 0x18, 0x70, 0x0e, 0xff, 0x49, 0x02, 0x06, 0x03, 0x03, 0x00, 0x05, 0x03,
|
|
0xff, 0x03, 0x02, 0x08, 0x0c, 0x0f, 0x0e, 0x03, 0x02, 0xe3, 0x02, 0x01, 0xf0, 0x02,
|
|
0x06, 0xff, 0x02, 0x04, 0x04, 0x07, 0x0b, 0x0b, 0x0f, 0x00, 0x63, 0x01, 0x01, 0xb2,
|
|
0x05, 0xfc, 0x4e, 0x04, 0x04, 0x09, 0x0c, 0x0d, 0x31, 0x0d, 0x72, 0x02, 0x8e, 0x20,
|
|
0x01, 0x07, 0x68, 0x1f, 0x09, 0x0c, 0x0f, 0x10, 0x04, 0x71, 0xdf, 0xd0, 0x04, 0x07,
|
|
0x5c, 0x80, 0x09, 0x09, 0x81, 0xf7, 0x7a, 0x60, 0x03, 0x03, 0x03, 0x08, 0xfc, 0xa7,
|
|
0x07, 0x0b, 0x0c, 0x0f, 0x04, 0x88, 0xdf, 0x35, 0xe3, 0x02, 0x09, 0xc7, 0x09, 0x09,
|
|
0x31, 0x0f, 0x90, 0x00, 0xdd, 0x80, 0x01, 0x05, 0x01, 0xd1, 0xf7, 0x0b, 0x23, 0x0f,
|
|
0x11, 0x75, 0xfe, 0x01, 0x07, 0x00, 0x09, 0x03, 0x00, 0x04, 0x3f, 0x08, 0x09, 0x0b,
|
|
0x0d, 0x03, 0x01, 0x1e, 0xd0, 0x01, 0x05, 0x00, 0xff, 0xb0, 0x02, 0x08, 0x0d, 0x0f,
|
|
0x10, 0x01, 0x03, 0xbd, 0x00, 0x21, 0xf7, 0x03, 0x02, 0x07, 0x81, 0xf5, 0x47, 0x09,
|
|
0x0d, 0x0b, 0x30, 0x24, 0x64, 0x90, 0x4f, 0x02, 0xf5, 0x0b, 0x0f, 0x0f, 0xd0, 0xe8,
|
|
0xe0, 0x01, 0xf5, 0x03, 0x02, 0x1b, 0x0a, 0x0d, 0x81, 0xf5, 0x00, 0xd1, 0xa4, 0x50,
|
|
0x02, 0xf7, 0x07, 0xfa, 0x02, 0xf4, 0xf9, 0xf6, 0x06, 0x00, 0x04, 0x04, 0x7d, 0x06,
|
|
0x49, 0xf7, 0x08, 0x09, 0x0c, 0x10, 0x11, 0x19, 0xf2, 0xf2, 0xf1, 0xa0, 0x7a, 0x08,
|
|
0x0d, 0x0e, 0x63, 0x0e, 0x01, 0x60, 0x03, 0xfc, 0xbe, 0x08, 0x03, 0x01, 0x04, 0x07,
|
|
0x88, 0x90, 0xe1, 0x11, 0x01, 0x35, 0xdd, 0xde, 0x81, 0xf1, 0x0c, 0x0b, 0x81, 0xf3,
|
|
0x00, 0x38, 0xb2, 0x05, 0x02, 0xe2, 0xf0, 0x40, 0x0e, 0x11, 0xe2, 0xa9, 0xf6, 0xe6,
|
|
0x04, 0x01, 0x7f, 0x08, 0x01, 0x00, 0x02, 0x07, 0x09, 0x0d, 0x6c, 0xb0, 0x04, 0x82,
|
|
0xef, 0x02, 0x74, 0x40, 0x81, 0xf5, 0x0d, 0x0e, 0xc4, 0x32, 0xed, 0x05, 0x39, 0x01,
|
|
0x40, 0x09, 0xfa, 0x80, 0x81, 0xf4, 0x05, 0x03, 0x05, 0x04, 0x4f, 0x06, 0x03, 0x02,
|
|
0x01, 0x60, 0x92, 0x9a, 0xf0, 0x30, 0x01, 0xf4, 0xaf, 0x02, 0x0a, 0x0b, 0x0b, 0x01,
|
|
0xf6, 0x01, 0xf2, 0x23, 0x02, 0x07, 0xbe, 0xfa, 0xac, 0x01, 0xf3, 0x02, 0x01, 0x01,
|
|
0x02, 0x31, 0x05, 0x6e, 0x08, 0xbe, 0x99, 0x0b, 0x0b, 0x0c, 0x11, 0x09, 0xf3, 0x16,
|
|
0x23, 0xf0, 0x05, 0xc1, 0xf6, 0xa3, 0xa0, 0x0f, 0xa9, 0x03, 0xf6, 0x46, 0x02, 0xef,
|
|
0x0b, 0xf0, 0xc4, 0xd0, 0xa6, 0x07, 0x1e, 0x81, 0xf6, 0x02, 0x02, 0x09, 0xed, 0x10,
|
|
0x8b, 0xf0, 0x00, 0x01, 0xed, 0x01, 0x00, 0x47, 0x00, 0x0b, 0x09, 0x20, 0x5c, 0x32,
|
|
0x06, 0x01, 0x81, 0xf2, 0x2f, 0xc1, 0xec, 0x09, 0x0a, 0x0f, 0x81, 0xeb, 0x1a, 0x9f,
|
|
0x11, 0xf7, 0x08, 0x2f, 0x19, 0x07, 0x0a, 0x0e, 0x02, 0xf4, 0xda, 0xcd, 0x01, 0xf5,
|
|
0x04, 0x02, 0xed, 0x0f, 0x51, 0x0d, 0xb3, 0x21, 0xed, 0x3b, 0x81, 0xf6, 0x02, 0x81,
|
|
0xf6, 0x0d, 0x0e, 0x7a, 0x40, 0x72, 0xf4, 0x03, 0x00, 0x08, 0xd1, 0x01, 0xea, 0x30,
|
|
0x01, 0xf8, 0x01, 0x8b, 0x04, 0x06, 0xf1, 0xe9, 0xf0, 0xed, 0x04, 0x89, 0xe8, 0x10,
|
|
0x89, 0xee, 0x03, 0x06, 0x78, 0x2c, 0x08, 0x01, 0x02, 0xb7, 0x01, 0xec, 0x0e, 0x0e,
|
|
0x92, 0xf5, 0x02, 0x91, 0xf4, 0x5f, 0x05, 0x00, 0x00, 0x00, 0x08, 0x82, 0xea, 0x9c,
|
|
0x20, 0x06, 0x03, 0x5a, 0x70, 0x01, 0x81, 0xf3, 0x0f, 0x01, 0xe8, 0x8b, 0x01, 0xf8,
|
|
0x03, 0x01, 0xe7, 0x60, 0xb5, 0x0a, 0x81, 0xf1, 0x01, 0xf4, 0x00, 0x01, 0xe7, 0xd8,
|
|
0x3e, 0x04, 0x02, 0xf3, 0x0d, 0xd8, 0x69, 0x00, 0xe1, 0xf1, 0x00, 0xf1, 0x09, 0x5a,
|
|
0x09, 0x0c, 0x0b, 0x25, 0x0d, 0x0a, 0xef, 0x40, 0x15, 0x03, 0xf2, 0x01, 0xf3, 0x81,
|
|
0xf5, 0xd5, 0x7d, 0x62, 0xf5, 0x81, 0xf7, 0x02, 0xeb, 0x02, 0xac, 0xae, 0x02, 0xed,
|
|
0x84, 0xfe, 0x2e, 0x41, 0xf3, 0x04, 0x00, 0x81, 0xf2, 0xbe, 0x2a, 0x08, 0x0b, 0x0d,
|
|
0x10, 0x91, 0xf0, 0xa2, 0xb1, 0xeb, 0xe0, 0x41, 0xf1, 0x45, 0x08, 0x79, 0xf6, 0x15,
|
|
0x7d, 0x91, 0xe7, 0xf1, 0xee, 0x04, 0x04, 0x01, 0x0a, 0x45, 0x01, 0xe4, 0x83, 0xf5,
|
|
0xe0, 0x45, 0x03, 0xea, 0x81, 0xe6, 0xc0, 0x57, 0x7a, 0xe4, 0x04, 0x09, 0x02, 0xf4,
|
|
0x82, 0xf5, 0x14, 0x60, 0xf1, 0xf2, 0xfb, 0x70, 0x01, 0x81, 0xef, 0x0f, 0x11, 0x01,
|
|
0x04, 0x02, 0x00, 0x00,
|
|
],
|
|
},
|
|
];
|
|
|
|
#[test]
|
|
pub fn compresses_things() -> Result<(), PrsCompressionError> {
|
|
for (index, test) in TEST_DATA.iter().enumerate() {
|
|
println!("\ntest #{}", index);
|
|
println!(" prs_compress({:02x?})", test.uncompressed);
|
|
assert_eq!(*test.compressed, *prs_compress(&test.uncompressed)?);
|
|
println!(" prs_decompress({:02x?})", test.compressed);
|
|
assert_eq!(*test.uncompressed, *prs_decompress(&test.compressed)?);
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
pub fn decompress_bad_data_error_result() -> Result<(), PrsCompressionError> {
|
|
let data: &[u8] = &[];
|
|
assert_matches!(prs_decompress(data), Err(PrsCompressionError::BadData(..)));
|
|
|
|
let data: &[u8] = &[1, 2];
|
|
assert_matches!(prs_decompress(data), Err(PrsCompressionError::BadData(..)));
|
|
|
|
let data: &[u8] = &[1, 2, 3];
|
|
assert_matches!(prs_decompress(data), Err(PrsCompressionError::BadData(..)));
|
|
|
|
let mut data = [0u8; 1024];
|
|
let mut rng = StdRng::seed_from_u64(42);
|
|
data.try_fill(&mut rng).unwrap();
|
|
assert_matches!(prs_decompress(&data), Err(PrsCompressionError::BadData(..)));
|
|
|
|
Ok(())
|
|
}
|
|
}
|