| // 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); |
| } |
| } |
| |
| #[cfg(feature = "std")] |
| #[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 |
| }); |
| } |
| |
| #[test] |
| fn test_read_u64_max() { |
| let bytes = &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]; |
| let mut reader = BitReader::new(bytes); |
| assert_eq!(reader.read_u64(64).unwrap(), u64::MAX); |
| } |
| |
| #[test] |
| fn test_read_i64_max() { |
| let bytes = &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]; |
| let mut reader = BitReader::new(bytes); |
| assert_eq!(reader.read_i64(64).unwrap(), -1); |
| } |