316 lines
10 KiB
Rust
316 lines
10 KiB
Rust
// Copyright 2015 Ilkka Rauta
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn read_buffer() {
|
|
let bytes = &[
|
|
0b1011_0101, 0b0110_1010, 0b1010_1100, 0b1001_1001,
|
|
0b1001_1001, 0b1001_1001, 0b1001_1001, 0b1110_0111,
|
|
];
|
|
|
|
let mut reader = BitReader::new(bytes);
|
|
|
|
assert_eq!(reader.read_u8(1).unwrap(), 0b1);
|
|
assert_eq!(reader.peek_u8(3).unwrap(), 0b011);
|
|
assert_eq!(reader.read_u8(1).unwrap(), 0b0);
|
|
assert_eq!(reader.read_u8(2).unwrap(), 0b11);
|
|
|
|
assert!(!reader.is_aligned(1));
|
|
assert!(!reader.is_aligned(2));
|
|
assert!(!reader.is_aligned(4));
|
|
|
|
assert_eq!(reader.position(), 4);
|
|
assert_eq!(reader.remaining(), 60);
|
|
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
|
|
|
|
assert!(reader.is_aligned(1));
|
|
assert!(!reader.is_aligned(2));
|
|
assert!(!reader.is_aligned(4));
|
|
|
|
assert_eq!(reader.align(1), Ok(())); // shouldn't do anything if already aligned
|
|
|
|
assert_eq!(reader.peek_u64(16).unwrap(), 0b110_1010_1010_1100);
|
|
assert_eq!(reader.read_u8(3).unwrap(), 0b11);
|
|
assert_eq!(reader.peek_u16(13).unwrap(), 0b1010_1010_1100);
|
|
assert_eq!(reader.peek_u32(13).unwrap(), 0b1010_1010_1100);
|
|
assert_eq!(reader.peek_u64(13).unwrap(), 0b1010_1010_1100);
|
|
assert_eq!(reader.peek_u16(10).unwrap(), 0b01_0101_0101);
|
|
assert_eq!(reader.peek_u8(8).unwrap(), 0b0101_0101);
|
|
assert_eq!(reader.read_u16(10).unwrap(), 0b01_0101_0101);
|
|
assert_eq!(reader.read_u8(3).unwrap(), 0b100);
|
|
|
|
assert_eq!(reader.position(), 24);
|
|
assert_eq!(reader.remaining(), 40);
|
|
|
|
assert!(reader.is_aligned(1));
|
|
|
|
assert_eq!(reader.read_u32(32).unwrap(), 0b1001_1001_1001_1001_1001_1001_1001_1001);
|
|
|
|
assert_eq!(reader.peek_bool().unwrap(), true);
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b1110);
|
|
assert_eq!(reader.peek_bool().unwrap(), false);
|
|
assert_eq!(reader.read_u8(3).unwrap(), 0b011);
|
|
assert_eq!(reader.peek_bool().unwrap(), true);
|
|
assert_eq!(reader.read_bool().unwrap(), true);
|
|
|
|
// Could also be 8 at this point!
|
|
assert!(reader.is_aligned(4));
|
|
|
|
// shouldn't do anything if already aligned
|
|
assert_eq!(reader.align(1), Ok(()));
|
|
assert_eq!(reader.align(2), Ok(()));
|
|
assert_eq!(reader.align(4), Ok(()));
|
|
assert_eq!(reader.align(8), Ok(()));
|
|
|
|
// Start over to test align()
|
|
let mut reader = BitReader::new(bytes);
|
|
|
|
// shouldn't do anything if already aligned
|
|
assert_eq!(reader.align(1), Ok(()));
|
|
assert_eq!(reader.align(2), Ok(()));
|
|
assert_eq!(reader.align(4), Ok(()));
|
|
assert_eq!(reader.align(8), Ok(()));
|
|
assert_eq!(reader.position(), 0);
|
|
|
|
assert_eq!(reader.read_u8(1).unwrap(), 0b1);
|
|
|
|
assert_eq!(reader.align(1), Ok(()));
|
|
assert_eq!(reader.position(), 8);
|
|
|
|
assert!(reader.is_aligned(1));
|
|
assert!(!reader.is_aligned(2));
|
|
assert!(!reader.is_aligned(4));
|
|
|
|
assert_eq!(reader.align(2), Ok(()));
|
|
assert_eq!(reader.position(), 16);
|
|
assert!(reader.is_aligned(1));
|
|
assert!(reader.is_aligned(2));
|
|
assert!(!reader.is_aligned(4));
|
|
|
|
assert_eq!(reader.read_u8(7).unwrap(), 0b0101_0110);
|
|
assert_eq!(reader.align(4), Ok(()));
|
|
assert_eq!(reader.position(), 32);
|
|
assert!(reader.is_aligned(1));
|
|
assert!(reader.is_aligned(2));
|
|
assert!(reader.is_aligned(4));
|
|
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.position(), 0);
|
|
assert_eq!(reader.skip(1), Ok(()));
|
|
assert_eq!(reader.align(4), Ok(()));
|
|
assert_eq!(reader.position(), 32);
|
|
assert_eq!(reader.skip(7), Ok(()));
|
|
assert_eq!(reader.align(1), Ok(()));
|
|
assert_eq!(reader.position(), 40);
|
|
assert_eq!(reader.align(2), Ok(()));
|
|
assert_eq!(reader.position(), 48);
|
|
assert_eq!(reader.skip(5), Ok(()));
|
|
assert_eq!(reader.align(2), Ok(()));
|
|
assert_eq!(reader.position(), 64);
|
|
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.skip(1), Ok(()));
|
|
assert_eq!(reader.align(3), Ok(()));
|
|
assert_eq!(reader.position(), 24);
|
|
|
|
assert!(!reader.align(128).is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn try_all_sizes() {
|
|
let bytes = &[
|
|
0x4a, 0x1e, 0x39, 0xbb, 0xd0, 0x07, 0xca, 0x9a,
|
|
0xa6, 0xba, 0x25, 0x52, 0x6f, 0x0a, 0x6a, 0xba,
|
|
];
|
|
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.read_u64(64).unwrap(), 0x4a1e39bbd007ca9a);
|
|
assert_eq!(reader.read_u64(64).unwrap(), 0xa6ba25526f0a6aba);
|
|
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.read_u32(32).unwrap(), 0x4a1e39bb);
|
|
assert_eq!(reader.read_u32(32).unwrap(), 0xd007ca9a);
|
|
assert_eq!(reader.read_u32(32).unwrap(), 0xa6ba2552);
|
|
assert_eq!(reader.read_u32(32).unwrap(), 0x6f0a6aba);
|
|
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.read_u16(16).unwrap(), 0x4a1e);
|
|
assert_eq!(reader.read_u16(16).unwrap(), 0x39bb);
|
|
assert_eq!(reader.read_u16(16).unwrap(), 0xd007);
|
|
assert_eq!(reader.read_u16(16).unwrap(), 0xca9a);
|
|
assert_eq!(reader.read_u16(16).unwrap(), 0xa6ba);
|
|
assert_eq!(reader.read_u16(16).unwrap(), 0x2552);
|
|
assert_eq!(reader.read_u16(16).unwrap(), 0x6f0a);
|
|
assert_eq!(reader.read_u16(16).unwrap(), 0x6aba);
|
|
|
|
let mut reader = BitReader::new(&bytes[..]);
|
|
for byte in bytes {
|
|
assert_eq!(reader.read_u8(8).unwrap(), *byte);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn skipping_and_zero_reads() {
|
|
let bytes = &[
|
|
0b1011_0101, 0b1110_1010, 0b1010_1100, 0b0011_0101,
|
|
];
|
|
|
|
let mut reader = BitReader::new(bytes);
|
|
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b1011);
|
|
// Reading zero bits should be a no-op
|
|
assert_eq!(reader.read_u8(0).unwrap(), 0b0);
|
|
assert_eq!(reader.read_i8(0).unwrap(), 0b0);
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
|
|
reader.skip(3).unwrap(); // 0b111
|
|
assert_eq!(reader.read_u16(10).unwrap(), 0b0101010101);
|
|
assert_eq!(reader.read_u8(3).unwrap(), 0b100);
|
|
reader.skip(4).unwrap(); // 0b0011
|
|
assert_eq!(reader.read_u32(2).unwrap(), 0b01);
|
|
assert_eq!(reader.read_bool().unwrap(), false);
|
|
assert_eq!(reader.read_bool().unwrap(), true);
|
|
}
|
|
|
|
#[test]
|
|
fn errors() {
|
|
let bytes = &[
|
|
0b1011_0101, 0b1110_1010, 0b1010_1100,
|
|
];
|
|
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b1011);
|
|
assert_eq!(reader.read_u8(9).unwrap_err(), BitReaderError::TooManyBitsForType {
|
|
position: 4,
|
|
requested: 9,
|
|
allowed: 8
|
|
});
|
|
// If an error happens, it should be possible to resume as if nothing had happened
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
|
|
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b1011);
|
|
// Same with this error
|
|
assert_eq!(reader.read_u32(21).unwrap_err(), BitReaderError::NotEnoughData {
|
|
position: 4,
|
|
length: (bytes.len() * 8) as u64,
|
|
requested: 21
|
|
});
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
|
|
}
|
|
|
|
#[test]
|
|
fn signed_values() {
|
|
let from = -2048;
|
|
let to = 2048;
|
|
for x in from..to {
|
|
let bytes = &[
|
|
(x >> 8) as u8,
|
|
x as u8,
|
|
];
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.read_u8(4).unwrap(), if x < 0 { 0b1111 } else { 0 });
|
|
assert_eq!(reader.read_i16(12).unwrap(), x);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn boolean_values() {
|
|
let bytes: Vec<u8> = (0..16).collect();
|
|
let mut reader = BitReader::new(&bytes);
|
|
for v in &bytes {
|
|
assert_eq!(reader.read_bool().unwrap(), false);
|
|
reader.skip(3).unwrap();
|
|
assert_eq!(reader.read_bool().unwrap(), v & 0x08 == 8);
|
|
assert_eq!(reader.read_bool().unwrap(), v & 0x04 == 4);
|
|
assert_eq!(reader.read_bool().unwrap(), v & 0x02 == 2);
|
|
assert_eq!(reader.read_bool().unwrap(), v & 0x01 == 1);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn read_slice() {
|
|
let bytes = &[
|
|
0b1111_0000, 0b0000_1111, 0b1111_0000,
|
|
0b0000_1000, 0b0000_0100, 0b0000_0011,
|
|
0b1111_1100, 0b0000_0011, 0b1101_1000,
|
|
];
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b1111);
|
|
// Just some pattern that's definitely not in the bytes array
|
|
let mut output = [0b1010_1101; 3];
|
|
reader.read_u8_slice(&mut output).unwrap();
|
|
assert_eq!(&output, &[0u8, 255u8, 0u8]);
|
|
|
|
assert_eq!(reader.read_u8(1).unwrap(), 1);
|
|
|
|
reader.read_u8_slice(&mut output[1..2]).unwrap();
|
|
assert_eq!(&output, &[0u8, 0u8, 0u8]);
|
|
|
|
assert_eq!(reader.read_u8(1).unwrap(), 1);
|
|
|
|
output = [0b1010_1101; 3];
|
|
reader.read_u8_slice(&mut output).unwrap();
|
|
assert_eq!(&output, &[0u8, 255u8, 0u8]);
|
|
|
|
reader.read_u8_slice(&mut output[0..1]).unwrap();
|
|
assert_eq!(output[0], 0b1111_0110);
|
|
|
|
assert_eq!(reader.read_u8(2).unwrap(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn read_slice_too_much() {
|
|
let bytes = &[
|
|
0b1111_1111, 0b1111_1111, 0b1111_1111, 0b1111_1111,
|
|
];
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.read_u8(1).unwrap(), 1);
|
|
|
|
let mut output = [0u8; 4];
|
|
let should_be_error = reader.read_u8_slice(&mut output);
|
|
assert_eq!(should_be_error.unwrap_err(), BitReaderError::NotEnoughData {
|
|
position: 1,
|
|
length: (bytes.len() * 8) as u64,
|
|
requested: (&output.len() * 8) as u64
|
|
});
|
|
assert_eq!(&output, &[0u8; 4]);
|
|
}
|
|
|
|
#[test]
|
|
fn relative_reader() {
|
|
let bytes = &[
|
|
0b0001_0010, 0b0011_0100,
|
|
];
|
|
let mut reader = BitReader::new(bytes);
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b0001);
|
|
|
|
let mut relative_reader = reader.relative_reader();
|
|
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b0010);
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b0011);
|
|
assert_eq!(reader.read_u8(4).unwrap(), 0b0100);
|
|
|
|
assert_eq!(reader.read_u8(1).unwrap_err(), BitReaderError::NotEnoughData {
|
|
position: 16,
|
|
length: 16,
|
|
requested: 1
|
|
});
|
|
|
|
assert_eq!(relative_reader.read_u8(4).unwrap(), 0b0010);
|
|
assert_eq!(relative_reader.read_u8(4).unwrap(), 0b0011);
|
|
assert_eq!(relative_reader.read_u8(4).unwrap(), 0b0100);
|
|
|
|
assert_eq!(relative_reader.read_u8(1).unwrap_err(), BitReaderError::NotEnoughData {
|
|
position: 12,
|
|
length: 12,
|
|
requested: 1
|
|
});
|
|
}
|