tonlib_core/cell/
slice.rs1use std::io::Cursor;
2use std::sync::Arc;
3
4use bitstream_io::{BigEndian, BitRead, BitReader};
5
6use crate::cell::util::BitReadExt;
7use crate::cell::{ArcCell, Cell, MapTonCellError, TonCellError};
8
9#[derive(Debug, Clone, PartialEq)]
10pub struct CellSlice {
11 pub cell: ArcCell,
12 pub start_bit: usize,
13 pub end_bit: usize,
14 pub start_ref: usize,
15 pub end_ref: usize,
16}
17
18impl CellSlice {
19 pub fn new(
20 cell: &ArcCell,
21 start_bit: usize,
22 end_bit: usize,
23 start_ref: usize,
24 end_ref: usize,
25 ) -> Result<CellSlice, TonCellError> {
26 if end_bit < start_bit || end_bit > cell.bit_len {
27 return Err(TonCellError::CellParserError(format!(
28 "Invalid bit offsets: start: {}, end: {}, bit_len: {}",
29 start_bit, end_bit, cell.bit_len
30 )));
31 }
32 if end_ref < start_ref || end_ref > cell.references.len() {
33 return Err(TonCellError::CellParserError(format!(
34 "Invalid references: start: {}, end: {}, count: {}",
35 start_bit,
36 end_bit,
37 cell.references.len()
38 )));
39 }
40 Ok(CellSlice {
41 cell: cell.clone(),
42 start_bit,
43 end_bit,
44 start_ref,
45 end_ref,
46 })
47 }
48
49 pub fn new_with_offset(cell: &Cell, offset: usize) -> Result<CellSlice, TonCellError> {
50 CellSlice::new(
51 &Arc::new(cell.clone()),
52 offset,
53 cell.bit_len,
54 0,
55 cell.references.len(),
56 )
57 }
58
59 pub fn full_cell(cell: Cell) -> Result<CellSlice, TonCellError> {
60 let bit_len = cell.bit_len;
61 let ref_count = cell.references.len();
62 Ok(CellSlice {
63 cell: Arc::new(cell),
64 start_bit: 0,
65 end_bit: bit_len,
66 start_ref: 0,
67 end_ref: ref_count,
68 })
69 }
70
71 pub fn reference(&self, idx: usize) -> Result<&ArcCell, TonCellError> {
72 if idx > self.end_ref - self.start_ref {
73 return Err(TonCellError::InvalidIndex {
74 idx,
75 ref_count: self.end_ref - self.start_ref,
76 });
77 }
78 self.cell
79 .references
80 .get(self.start_ref + idx)
81 .ok_or(TonCellError::InvalidIndex {
82 idx,
83 ref_count: self.end_ref - self.start_ref,
84 })
85 }
86
87 pub fn into_cell(&self) -> Result<Cell, TonCellError> {
89 let bit_len = self.end_bit - self.start_bit;
90 let total_bytes = bit_len.div_ceil(8);
91 let mut data = vec![0u8; total_bytes];
92 let cursor = Cursor::new(&self.cell.data);
93 let mut bit_reader: BitReader<Cursor<&Vec<u8>>, BigEndian> =
94 BitReader::endian(cursor, BigEndian);
95 bit_reader
96 .skip(self.start_bit as u32)
97 .map_cell_parser_error()?;
98 bit_reader.read_bits(bit_len, data.as_mut_slice())?;
99
100 Cell::new(
101 data,
102 bit_len,
103 self.cell.references[self.start_ref..self.end_ref].to_vec(),
104 false,
105 )
106 }
107}