solana_tx_parser/
binary_reader.rs1use thiserror::Error;
4
5#[derive(Error, Debug)]
6pub enum BinaryReaderError {
7 #[error("buffer overflow: tried to read {requested} bytes at offset {offset} in buffer of length {length}")]
8 Overflow {
9 requested: usize,
10 offset: usize,
11 length: usize,
12 },
13}
14
15pub struct BinaryReader<'a> {
16 data: &'a [u8],
17 offset: usize,
18}
19
20impl<'a> BinaryReader<'a> {
21 pub fn new(data: &'a [u8]) -> Self {
22 Self { data, offset: 0 }
23 }
24
25 fn check_bounds(&self, length: usize) -> Result<(), BinaryReaderError> {
26 if self.offset + length > self.data.len() {
27 return Err(BinaryReaderError::Overflow {
28 requested: length,
29 offset: self.offset,
30 length: self.data.len(),
31 });
32 }
33 Ok(())
34 }
35
36 pub fn read_fixed_array(&mut self, length: usize) -> Result<&'a [u8], BinaryReaderError> {
37 self.check_bounds(length)?;
38 let slice = &self.data[self.offset..self.offset + length];
39 self.offset += length;
40 Ok(slice)
41 }
42
43 pub fn read_u8(&mut self) -> Result<u8, BinaryReaderError> {
44 self.check_bounds(1)?;
45 let v = self.data[self.offset];
46 self.offset += 1;
47 Ok(v)
48 }
49
50 pub fn read_u16_le(&mut self) -> Result<u16, BinaryReaderError> {
51 self.check_bounds(2)?;
52 let v = u16::from_le_bytes(self.data[self.offset..self.offset + 2].try_into().unwrap());
53 self.offset += 2;
54 Ok(v)
55 }
56
57 pub fn read_u64_le(&mut self) -> Result<u64, BinaryReaderError> {
58 self.check_bounds(8)?;
59 let v = u64::from_le_bytes(self.data[self.offset..self.offset + 8].try_into().unwrap());
60 self.offset += 8;
61 Ok(v)
62 }
63
64 pub fn read_i64_le(&mut self) -> Result<i64, BinaryReaderError> {
65 self.check_bounds(8)?;
66 let v = i64::from_le_bytes(self.data[self.offset..self.offset + 8].try_into().unwrap());
67 self.offset += 8;
68 Ok(v)
69 }
70
71 pub fn read_string_u32_len(&mut self) -> Result<String, BinaryReaderError> {
72 let len = self.read_u32_le()? as usize;
73 self.check_bounds(len)?;
74 let s = String::from_utf8_lossy(&self.data[self.offset..self.offset + len]).into_owned();
75 self.offset += len;
76 Ok(s)
77 }
78
79 pub fn read_pubkey(&mut self) -> Result<String, BinaryReaderError> {
80 let slice = self.read_fixed_array(32)?;
81 Ok(bs58::encode(slice).into_string())
82 }
83
84 pub fn remaining(&self) -> usize {
85 self.data.len().saturating_sub(self.offset)
86 }
87
88 pub fn offset(&self) -> usize {
89 self.offset
90 }
91}
92
93impl BinaryReader<'_> {
95 pub fn read_u32_le(&mut self) -> Result<u32, BinaryReaderError> {
96 self.check_bounds(4)?;
97 let v = u32::from_le_bytes(self.data[self.offset..self.offset + 4].try_into().unwrap());
98 self.offset += 4;
99 Ok(v)
100 }
101}