Revision control

Copy as Markdown

Other Tools

// Copyright 2015 Ilkka Rauta
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// <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
});
}