From f5ceea654ea5884bb12e004f8cc6e27250cf5db8 Mon Sep 17 00:00:00 2001 From: Marrub Date: Sun, 10 Mar 2019 01:27:56 -0500 Subject: [PATCH] add read_bits_l --- source/durandal/bit.rs | 102 ++++++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 26 deletions(-) diff --git a/source/durandal/bit.rs b/source/durandal/bit.rs index 3ca1b5b..a23289d 100644 --- a/source/durandal/bit.rs +++ b/source/durandal/bit.rs @@ -2,13 +2,14 @@ use crate::durandal::err::*; -/// Reads `width` bits from `b` starting at bit `cr_bit` into an integer. +/// Reads `width` bits from `b` starting at bit `cr_bit` into an integer, most +/// significant bit first. /// /// # Errors /// /// The function will return an error if `width` is 0 or more than 64, or if /// `(cr_bit + width - 1) / 8` would overflow an index into `b`. -pub fn read_bits(b: &[u8], cr_bit: usize, width: u8) -> ResultS<(usize, u64)> +pub fn read_bits_b(b: &[u8], cr_bit: usize, width: u8) -> ResultS<(usize, u64)> { if width < 1 || width > 64 { bail!("invalid number of bits"); @@ -47,59 +48,108 @@ pub fn read_bits(b: &[u8], cr_bit: usize, width: u8) -> ResultS<(usize, u64)> } } +/// The same as `read_bits_b`, but least-significant bit first. +pub fn read_bits_l(b: &[u8], cr_bit: usize, width: u8) -> ResultS<(usize, u64)> +{ + let (nx_bit, res) = read_bits_b(b, cr_bit, width)?; + + Ok((nx_bit, reverse_bits(res) >> (64 - width))) +} + +fn reverse_bits(v: u64) -> u64 +{ + // TODO: change this to u64::reverse_bits when stabilized + let v = v >> 1 & 0x5555_5555_5555_5555 | ((v & 0x5555_5555_5555_5555) << 1); + let v = v >> 2 & 0x3333_3333_3333_3333 | ((v & 0x3333_3333_3333_3333) << 2); + let v = v >> 4 & 0x0F0F_0F0F_0F0F_0F0F | ((v & 0x0F0F_0F0F_0F0F_0F0F) << 4); + v.swap_bytes() +} + fn get_bytes(b: &[u8], num_bytes: usize, f: usize) -> [u8; 8] { match num_bytes { 8 | 7 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], b[f+5], b[f+6], b[f+7]], - 6 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], b[f+5], b[f+6], 0], - 5 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], b[f+5], 0, 0], - 4 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], 0, 0, 0], - 3 => [b[f], b[f+1], b[f+2], b[f+3], 0, 0, 0, 0], - 2 => [b[f], b[f+1], b[f+2], 0, 0, 0, 0, 0], - 1 => [b[f], b[f+1], 0, 0, 0, 0, 0, 0], - 0 => [b[f], 0, 0, 0, 0, 0, 0, 0], - _ => panic!("invalid number of bytes to read ({})", num_bytes), + 6 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], b[f+5], b[f+6], 0 ], + 5 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], b[f+5], 0, 0 ], + 4 => [b[f], b[f+1], b[f+2], b[f+3], b[f+4], 0, 0, 0 ], + 3 => [b[f], b[f+1], b[f+2], b[f+3], 0, 0, 0, 0 ], + 2 => [b[f], b[f+1], b[f+2], 0, 0, 0, 0, 0 ], + 1 => [b[f], b[f+1], 0, 0, 0, 0, 0, 0 ], + 0 => [b[f], 0, 0, 0, 0, 0, 0, 0 ], + _ => { + panic!("invalid number of bytes to read ({})", num_bytes); + } } } #[test] fn bit_tests() { - const INPUT: &[u8] = &[0b011_00101, 0b10101010, 0b00010000, 0b00000000, - 0b11111111, 0b11100001, 0b10101100, 0b00110011, + const INPUT: &[u8] = &[0b011_00101, 0b10101010, 0b00010000, 0b00000000, + 0b11111111, 0b11100001, 0b10101100, 0b00110011, 0b10_1001_01, 0b11100_000, 0b00000111, 0b000000_01, - 0b11001010, 0b10101111, 0b00101011, 0b0_1101010, - 0b11010101, 0b10100011, 0b01010101, 0b11_000001]; + 0b11001010, 0b10101111, 0b00101011, 0b0_1101010, + 0b11010101, 0b10100011, 0b01010101, 0b11_000001]; - let (p, n) = read_bits(INPUT, 0, 3).unwrap(); + let (p, n) = read_bits_b(INPUT, 0, 3).unwrap(); assert_eq!(n, 0b011); - let (p, n) = read_bits(INPUT, p, 63).unwrap(); - assert_eq!(n, 0x16A8_4003_FF86_B0CE); + let (p, n) = read_bits_b(INPUT, p, 63).unwrap(); + assert_eq!(n, 0b001011010101000010000000000001111111111100001101011000011001110); - let (p, n) = read_bits(INPUT, p, 4).unwrap(); + let (p, n) = read_bits_b(INPUT, p, 4).unwrap(); assert_eq!(n, 0b1001); - let (p, n) = read_bits(INPUT, p, 7).unwrap(); + let (p, n) = read_bits_b(INPUT, p, 7).unwrap(); assert_eq!(n, 0b0111100); - let (p, n) = read_bits(INPUT, p, 17).unwrap(); + let (p, n) = read_bits_b(INPUT, p, 17).unwrap(); assert_eq!(n, 0b00000000111000000); - let (p, n) = read_bits(INPUT, p, 27).unwrap(); + let (p, n) = read_bits_b(INPUT, p, 27).unwrap(); assert_eq!(n, 0b011100101010101111001010110); - let (p, n) = read_bits(INPUT, p, 33).unwrap(); + let (p, n) = read_bits_b(INPUT, p, 33).unwrap(); assert_eq!(n, 0b110101011010101101000110101010111); - let (p, n) = read_bits(INPUT, p, 6).unwrap(); - assert_eq!(n, 1); + let (p, n) = read_bits_b(INPUT, p, 6).unwrap(); + assert_eq!(n, 0b000001); - let e = read_bits(INPUT, p, 1); + let e = read_bits_b(INPUT, p, 1); assert!(if let Err(_) = e {true} else {false}); - let e = read_bits(INPUT, p, 2); + let e = read_bits_b(INPUT, p, 2); + assert!(if let Err(_) = e {true} else {false}); + + let (p, n) = read_bits_l(INPUT, 0, 3).unwrap(); + assert_eq!(n, 0b110); + + let (p, n) = read_bits_l(INPUT, p, 63).unwrap(); + assert_eq!(n, 0b011100110000110101100001111111111100000000000010000101010110100); + + let (p, n) = read_bits_l(INPUT, p, 4).unwrap(); + assert_eq!(n, 0b1001); + + let (p, n) = read_bits_l(INPUT, p, 7).unwrap(); + assert_eq!(n, 0b0011110); + + let (p, n) = read_bits_l(INPUT, p, 17).unwrap(); + assert_eq!(n, 0b00000011100000000); + + let (p, n) = read_bits_l(INPUT, p, 27).unwrap(); + assert_eq!(n, 0b011010100111101010101001110); + + let (p, n) = read_bits_l(INPUT, p, 33).unwrap(); + assert_eq!(n, 0b111010101011000101101010110101011); + + let (p, n) = read_bits_l(INPUT, p, 6).unwrap(); + assert_eq!(n, 0b100000); + + let e = read_bits_l(INPUT, p, 1); + assert!(if let Err(_) = e {true} else {false}); + + let e = read_bits_l(INPUT, p, 2); assert!(if let Err(_) = e {true} else {false}); }