1use std::io;
2
3use bitstream_io::{BitRead, BitReader, Endianness};
4
5use crate::cell::{MapTonCellError, TonCellError};
6
7pub trait BitReadExt {
8 fn read_bits(&mut self, num_bits: usize, slice: &mut [u8]) -> Result<(), TonCellError>;
9}
10
11impl<R: io::Read, E: Endianness> BitReadExt for BitReader<R, E> {
12 fn read_bits(&mut self, num_bits: usize, slice: &mut [u8]) -> Result<(), TonCellError> {
13 let total_bytes = num_bits.div_ceil(8);
14 if total_bytes > slice.len() {
15 let msg = format!(
16 "Attempt to read {} bits into buffer {} bytes",
17 num_bits,
18 slice.len()
19 );
20 return Err(TonCellError::CellParserError(msg));
21 }
22 let full_bytes = (num_bits) / 8;
23 self.read_bytes(&mut slice[0..full_bytes])
24 .map_cell_parser_error()?;
25 let last_byte_len = num_bits % 8;
26 if last_byte_len != 0 {
27 let last_byte = self
28 .read_var::<u8>(last_byte_len as u32)
29 .map_cell_parser_error()?;
30 slice[full_bytes] = last_byte << (8 - last_byte_len);
31 }
32 Ok(())
33 }
34}
35
36pub fn rewrite_bits(
38 src: &[u8],
39 src_offset_bits: usize,
40 dst: &mut [u8],
41 dst_offset_bits: usize,
42 len: usize,
43) -> bool {
44 let src_total_bits = src.len() * 8;
46 let dst_total_bits = dst.len() * 8;
47
48 if src_offset_bits + len > src_total_bits || dst_offset_bits + len > dst_total_bits {
50 return false;
51 }
52
53 for i in 0..len {
54 let src_bit_pos = src_offset_bits + i;
56 let src_byte_index = src_bit_pos / 8;
57 let src_bit_offset = 7 - (src_bit_pos % 8); let src_bit = (src[src_byte_index] >> src_bit_offset) & 1;
59
60 let dst_bit_pos = dst_offset_bits + i;
62 let dst_byte_index = dst_bit_pos / 8;
63 let dst_bit_offset = 7 - (dst_bit_pos % 8); dst[dst_byte_index] &= !(1 << dst_bit_offset); dst[dst_byte_index] |= src_bit << dst_bit_offset; }
69
70 true
71}
72
73#[cfg(test)]
74mod tests {
75 use crate::cell::rewrite_bits;
76
77 #[test]
78 fn test_rewrite_bits() {
79 let src = vec![0b11001100, 0b10101010]; let mut dst = vec![0b00000000, 0b00000000]; assert!(rewrite_bits(&src, 4, &mut dst, 8, 8));
82 assert_eq!(dst, vec![0b00000000, 0b11001010]);
83
84 let src = vec![0b11001100, 0b10101010]; let mut dst = vec![0b00000000, 0b00000000]; assert!(rewrite_bits(&src, 0, &mut dst, 0, 16));
87 assert_eq!(dst, src);
88
89 let src = vec![0b11001100, 0b10101010]; let mut dst = vec![0b00000000, 0b00000000]; assert!(rewrite_bits(&src, 0, &mut dst, 0, 8));
92 assert_eq!(dst[0], src[0]);
93 assert_eq!(dst[1], 0b00000000);
94
95 assert!(!rewrite_bits(&src, 14, &mut dst, 6, 10));
96 }
97}