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
get_padding_size(len: usize) -> usize6 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
put_padding(mut buf: &mut [u8], len: usize)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
set_nbits_of_uint16( src: u16, size: u16, start_index: u16, mut val: u16, ) -> Result<u16>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
append_nbits_to_uint32(src: u32, n: u32, val: u32) -> u3243 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
get_nbits_from_byte(b: u8, begin: u16, n: u16) -> u1648 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
get_24bits_from_bytes(b: &[u8]) -> u3255 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]
test_get_padding() -> Result<()>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 {n}"
72 );
73 }
74
75 Ok(())
76 }
77
78 #[test]
test_set_nbits_of_uint16() -> Result<()>79 fn test_set_nbits_of_uint16() -> Result<()> {
80 let tests = vec![
81 ("setOneBit", 0, 1, 8, 1, 128, None),
82 ("setStatusVectorBit", 0, 1, 0, 1, 32768, None),
83 ("setStatusVectorSecondBit", 32768, 1, 1, 1, 49152, None),
84 (
85 "setStatusVectorInnerBitsAndCutValue",
86 49152,
87 2,
88 6,
89 11111,
90 49920,
91 None,
92 ),
93 ("setRunLengthSecondTwoBit", 32768, 2, 1, 1, 40960, None),
94 (
95 "setOneBitOutOfBounds",
96 32768,
97 2,
98 15,
99 1,
100 0,
101 Some("invalid size or startIndex"),
102 ),
103 ];
104
105 for (name, source, size, index, value, result, err) in tests {
106 let res = set_nbits_of_uint16(source, size, index, value);
107 if err.is_some() {
108 assert!(res.is_err(), "setNBitsOfUint16 {name} : should be error");
109 } else if let Ok(got) = res {
110 assert_eq!(got, result, "setNBitsOfUint16 {name}");
111 } else {
112 panic!("setNBitsOfUint16 {name} :unexpected error result");
113 }
114 }
115
116 Ok(())
117 }
118 }
119