Skip to main content

jetstreamer_firehose/
utils.rs

1use {
2    crate::SharedError,
3    base64::engine::{Engine, general_purpose::STANDARD},
4    std::{
5        io::{self, Read},
6        vec::Vec,
7    },
8};
9
10const MAX_VARINT_LEN_64: usize = 10;
11
12/// Reads an unsigned LEB128-encoded integer from the provided reader.
13pub fn read_uvarint<R: Read>(reader: &mut R) -> io::Result<u64> {
14    let mut x = 0u64;
15    let mut s = 0u32;
16    let mut buffer = [0u8; 1];
17    for i in 0..MAX_VARINT_LEN_64 {
18        reader.read_exact(&mut buffer)?;
19        let b = buffer[0];
20        if b < 0x80 {
21            if i == MAX_VARINT_LEN_64 - 1 && b > 1 {
22                return Err(io::Error::new(
23                    io::ErrorKind::InvalidData,
24                    "uvarint overflow",
25                ));
26            }
27            return Ok(x | ((b as u64) << s));
28        }
29        x |= ((b & 0x7f) as u64) << s;
30        s += 7;
31
32        if s > 63 {
33            return Err(io::Error::new(
34                io::ErrorKind::InvalidData,
35                "uvarint too long",
36            ));
37        }
38    }
39    Err(io::Error::new(
40        io::ErrorKind::InvalidData,
41        "uvarint overflow",
42    ))
43}
44
45/// Owner type for 32-byte hashes that renders them as lowercase hex.
46#[derive(Clone, PartialEq, Eq, Hash)]
47pub struct Hash(#[doc = "Underlying bytes comprising the hash."] pub Vec<u8>);
48
49// debug converts the hash to hex
50impl std::fmt::Debug for Hash {
51    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52        let mut hex = String::new();
53        for byte in &self.0 {
54            hex.push_str(&format!("{:02x}", byte));
55        }
56        write!(f, "{}", hex)
57    }
58}
59
60// implement stringer for hash
61impl std::fmt::Display for Hash {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        let mut hex = String::new();
64        for byte in &self.0 {
65            hex.push_str(&format!("{:02x}", byte));
66        }
67        write!(f, "{}", hex)
68    }
69}
70
71// implement serde serialization for hash
72impl serde::Serialize for Hash {
73    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74    where
75        S: serde::ser::Serializer,
76    {
77        let mut hex = String::new();
78        for byte in &self.0 {
79            hex.push_str(&format!("{:02x}", byte));
80        }
81        serializer.serialize_str(&hex)
82    }
83}
84
85// implement serde deserialization for hash
86impl<'de> serde::Deserialize<'de> for Hash {
87    fn deserialize<D>(deserializer: D) -> Result<Hash, D::Error>
88    where
89        D: serde::de::Deserializer<'de>,
90    {
91        let hex = String::deserialize(deserializer)?;
92        let mut bytes = vec![];
93        for i in 0..hex.len() / 2 {
94            bytes.push(u8::from_str_radix(&hex[2 * i..2 * i + 2], 16).unwrap());
95        }
96        Ok(Hash(bytes))
97    }
98}
99
100impl Hash {
101    /// Returns the hash bytes as a `Vec<u8>`.
102    pub fn to_vec(&self) -> Vec<u8> {
103        self.0.clone()
104    }
105
106    /// Constructs a [`struct@Hash`] from owned bytes.
107    pub const fn from_vec(data: Vec<u8>) -> Hash {
108        Hash(data)
109    }
110
111    /// Returns the hash as a 32-byte array.
112    ///
113    /// # Panics
114    ///
115    /// Panics if the underlying byte slice is shorter than 32 bytes.
116    pub fn to_bytes(&self) -> [u8; 32] {
117        let mut bytes = [0u8; 32];
118        bytes[..32].copy_from_slice(&self.0[..32]);
119        bytes
120    }
121}
122
123/// Growable binary buffer with base64 formatting helpers.
124#[derive(Default, Clone, PartialEq, Eq, Hash)]
125pub struct Buffer(#[doc = "Owned bytes stored in the buffer."] Vec<u8>);
126
127impl Buffer {
128    /// Creates an empty buffer.
129    pub const fn new() -> Buffer {
130        Buffer(vec![])
131    }
132
133    /// Appends `data` to the buffer.
134    pub fn write(&mut self, data: Vec<u8>) {
135        self.0.extend(data);
136    }
137
138    /// Removes and returns `len` bytes from the front of the buffer.
139    ///
140    /// # Panics
141    ///
142    /// Panics if `len` exceeds the available bytes.
143    pub fn read(&mut self, len: usize) -> Vec<u8> {
144        let mut data = vec![];
145        for _ in 0..len {
146            data.push(self.0.remove(0));
147        }
148        data
149    }
150
151    /// Returns the buffer length in bytes.
152    pub const fn len(&self) -> usize {
153        self.0.len()
154    }
155
156    /// Returns `true` if the buffer is empty.
157    pub const fn is_empty(&self) -> bool {
158        self.len() == 0
159    }
160
161    /// Returns the buffer contents as a borrowed slice.
162    pub fn as_slice(&self) -> &[u8] {
163        &self.0
164    }
165
166    /// Returns the buffer contents as a `Vec<u8>`.
167    pub fn to_vec(&self) -> Vec<u8> {
168        self.0.clone()
169    }
170
171    /// Creates a buffer from owned bytes.
172    pub const fn from_vec(data: Vec<u8>) -> Buffer {
173        Buffer(data)
174    }
175}
176
177impl std::fmt::Debug for Buffer {
178    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
179        f.debug_struct("Buffer").field("data", &self.0).finish()
180    }
181}
182
183// base64
184impl std::fmt::Display for Buffer {
185    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
186        STANDARD.encode(&self.0).fmt(f)
187    }
188}
189
190impl serde::Serialize for Buffer {
191    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
192    where
193        S: serde::ser::Serializer,
194    {
195        STANDARD.encode(&self.0).serialize(serializer)
196    }
197}
198
199impl<'de> serde::Deserialize<'de> for Buffer {
200    fn deserialize<D>(deserializer: D) -> Result<Buffer, D::Error>
201    where
202        D: serde::de::Deserializer<'de>,
203    {
204        let base64 = String::deserialize(deserializer)?;
205        Ok(Buffer(STANDARD.decode(base64).unwrap()))
206    }
207}
208
209/// Maximum Old Faithful CAR section size permitted while parsing (32 MiB).
210pub const MAX_ALLOWED_SECTION_SIZE: usize = 32 << 20; // 32MiB
211
212/// Decompresses a Zstandard byte stream.
213pub fn decompress_zstd(data: &[u8]) -> Result<Vec<u8>, SharedError> {
214    let mut decoder = zstd::Decoder::new(data)?;
215    let mut decompressed = Vec::new();
216    decoder.read_to_end(&mut decompressed)?;
217    Ok(decompressed)
218}