1 use crate::error::{Error, Result}; 2 3 use bytes::BufMut; 4 5 // returns the padding required to make the length a multiple of 4 6 pub(crate) fn get_padding_size(len: usize) -> usize { 7 if len % 4 == 0 { 8 0 9 } else { 10 4 - (len % 4) 11 } 12 } 13 14 pub(crate) fn put_padding(mut buf: &mut [u8], len: usize) { 15 let padding_size = get_padding_size(len); 16 for i in 0..padding_size { 17 if i == padding_size - 1 { 18 buf.put_u8(padding_size as u8); 19 } else { 20 buf.put_u8(0); 21 } 22 } 23 } 24 25 // set_nbits_of_uint16 will truncate the value to size, left-shift to start_index position and set 26 pub(crate) fn set_nbits_of_uint16( 27 src: u16, 28 size: u16, 29 start_index: u16, 30 mut val: u16, 31 ) -> Result<u16> { 32 if start_index + size > 16 { 33 return Err(Error::InvalidSizeOrStartIndex); 34 } 35 36 // truncate val to size bits 37 val &= (1 << size) - 1; 38 39 Ok(src | (val << (16 - size - start_index))) 40 } 41 42 // appendBit32 will left-shift and append n bits of val 43 pub(crate) fn append_nbits_to_uint32(src: u32, n: u32, val: u32) -> u32 { 44 (src << n) | (val & (0xFFFFFFFF >> (32 - n))) 45 } 46 47 // getNBit get n bits from 1 byte, begin with a position 48 pub(crate) fn get_nbits_from_byte(b: u8, begin: u16, n: u16) -> u16 { 49 let end_shift = 8 - (begin + n); 50 let mask = (0xFF >> begin) & (0xFF << end_shift) as u8; 51 (b & mask) as u16 >> end_shift 52 } 53 54 // get24BitFromBytes get 24bits from `[3]byte` slice 55 pub(crate) fn get_24bits_from_bytes(b: &[u8]) -> u32 { 56 ((b[0] as u32) << 16) + ((b[1] as u32) << 8) + (b[2] as u32) 57 } 58 59 #[cfg(test)] 60 mod test { 61 use super::*; 62 63 #[test] 64 fn test_get_padding() -> Result<()> { 65 let tests = vec![(0, 0), (1, 3), (2, 2), (3, 1), (4, 0), (100, 0), (500, 0)]; 66 67 for (n, p) in tests { 68 assert_eq!( 69 get_padding_size(n), 70 p, 71 "Test case returned wrong value for input {}", 72 n 73 ); 74 } 75 76 Ok(()) 77 } 78 79 #[test] 80 fn test_set_nbits_of_uint16() -> Result<()> { 81 let tests = vec![ 82 ("setOneBit", 0, 1, 8, 1, 128, None), 83 ("setStatusVectorBit", 0, 1, 0, 1, 32768, None), 84 ("setStatusVectorSecondBit", 32768, 1, 1, 1, 49152, None), 85 ( 86 "setStatusVectorInnerBitsAndCutValue", 87 49152, 88 2, 89 6, 90 11111, 91 49920, 92 None, 93 ), 94 ("setRunLengthSecondTwoBit", 32768, 2, 1, 1, 40960, None), 95 ( 96 "setOneBitOutOfBounds", 97 32768, 98 2, 99 15, 100 1, 101 0, 102 Some("invalid size or startIndex"), 103 ), 104 ]; 105 106 for (name, source, size, index, value, result, err) in tests { 107 let res = set_nbits_of_uint16(source, size, index, value); 108 if err.is_some() { 109 assert!(res.is_err(), "setNBitsOfUint16 {} : should be error", name); 110 } else if let Ok(got) = res { 111 assert_eq!(got, result, "setNBitsOfUint16 {}", name); 112 } else { 113 panic!("setNBitsOfUint16 {} :unexpected error result", name); 114 } 115 } 116 117 Ok(()) 118 } 119 } 120