add read_bits_l
parent
9bea0d895f
commit
f5ceea654e
|
@ -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});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue