Skip to main content

qubit_io/codecs/
binary_reader.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use std::io::{
11    BufRead,
12    Read,
13    Result,
14    Seek,
15    SeekFrom,
16};
17
18use crate::{
19    BinaryReadExt,
20    ByteOrder,
21    StringReadExt,
22};
23
24/// Reader wrapper for binary scalar and length-prefixed string decoding.
25///
26/// Multi-byte methods use the configured [`ByteOrder`].
27///
28/// # Examples
29/// ```
30/// use std::io::Cursor;
31///
32/// use qubit_io::{
33///     BinaryReader,
34///     BinaryWriter,
35///     ByteOrder,
36/// };
37///
38/// let mut output = BinaryWriter::new(Vec::new(), ByteOrder::BigEndian);
39/// output.write_u16(0x1234)?;
40///
41/// let mut input = BinaryReader::new(Cursor::new(output.into_inner()), ByteOrder::BigEndian);
42/// assert_eq!(0x1234, input.read_u16()?);
43/// # Ok::<(), std::io::Error>(())
44/// ```
45pub struct BinaryReader<R> {
46    inner: R,
47    byte_order: ByteOrder,
48}
49
50impl<R> BinaryReader<R> {
51    /// Creates a binary reader.
52    ///
53    /// # Parameters
54    /// - `inner`: Reader to wrap.
55    /// - `byte_order`: Byte order used by multi-byte reads.
56    ///
57    /// # Returns
58    /// A new binary reader.
59    #[inline]
60    pub fn new(inner: R, byte_order: ByteOrder) -> Self {
61        Self { inner, byte_order }
62    }
63
64    /// Returns an immutable reference to the wrapped reader.
65    ///
66    /// # Returns
67    /// The wrapped reader reference.
68    #[inline]
69    pub fn get_ref(&self) -> &R {
70        &self.inner
71    }
72
73    /// Returns a mutable reference to the wrapped reader.
74    ///
75    /// # Returns
76    /// The wrapped reader reference.
77    #[inline]
78    pub fn get_mut(&mut self) -> &mut R {
79        &mut self.inner
80    }
81
82    /// Consumes this wrapper and returns the wrapped reader.
83    ///
84    /// # Returns
85    /// The wrapped reader.
86    #[inline]
87    pub fn into_inner(self) -> R {
88        self.inner
89    }
90
91    /// Returns the byte order used by multi-byte reads.
92    ///
93    /// # Returns
94    /// The configured byte order.
95    #[inline]
96    pub fn byte_order(&self) -> ByteOrder {
97        self.byte_order
98    }
99
100    /// Changes the byte order used by multi-byte reads.
101    ///
102    /// # Parameters
103    /// - `byte_order`: New byte order.
104    #[inline]
105    pub fn set_byte_order(&mut self, byte_order: ByteOrder) {
106        self.byte_order = byte_order;
107    }
108}
109
110impl<R> BinaryReader<R>
111where
112    R: Read,
113{
114    /// Reads one unsigned byte.
115    ///
116    /// # Errors
117    /// Returns an I/O error from the wrapped reader.
118    #[inline]
119    pub fn read_u8(&mut self) -> Result<u8> {
120        self.inner.read_u8()
121    }
122
123    /// Reads one signed byte.
124    ///
125    /// # Errors
126    /// Returns an I/O error from the wrapped reader.
127    #[inline]
128    pub fn read_i8(&mut self) -> Result<i8> {
129        self.inner.read_i8()
130    }
131
132    /// Reads a `u16` using the configured byte order.
133    ///
134    /// # Errors
135    /// Returns an I/O error from the wrapped reader.
136    #[inline]
137    pub fn read_u16(&mut self) -> Result<u16> {
138        self.inner.read_u16(self.byte_order)
139    }
140
141    /// Reads an `i16` using the configured byte order.
142    ///
143    /// # Errors
144    /// Returns an I/O error from the wrapped reader.
145    #[inline]
146    pub fn read_i16(&mut self) -> Result<i16> {
147        self.inner.read_i16(self.byte_order)
148    }
149
150    /// Reads a `u32` using the configured byte order.
151    ///
152    /// # Errors
153    /// Returns an I/O error from the wrapped reader.
154    #[inline]
155    pub fn read_u32(&mut self) -> Result<u32> {
156        self.inner.read_u32(self.byte_order)
157    }
158
159    /// Reads an `i32` using the configured byte order.
160    ///
161    /// # Errors
162    /// Returns an I/O error from the wrapped reader.
163    #[inline]
164    pub fn read_i32(&mut self) -> Result<i32> {
165        self.inner.read_i32(self.byte_order)
166    }
167
168    /// Reads a `u64` using the configured byte order.
169    ///
170    /// # Errors
171    /// Returns an I/O error from the wrapped reader.
172    #[inline]
173    pub fn read_u64(&mut self) -> Result<u64> {
174        self.inner.read_u64(self.byte_order)
175    }
176
177    /// Reads an `i64` using the configured byte order.
178    ///
179    /// # Errors
180    /// Returns an I/O error from the wrapped reader.
181    #[inline]
182    pub fn read_i64(&mut self) -> Result<i64> {
183        self.inner.read_i64(self.byte_order)
184    }
185
186    /// Reads a `u128` using the configured byte order.
187    ///
188    /// # Errors
189    /// Returns an I/O error from the wrapped reader.
190    #[inline]
191    pub fn read_u128(&mut self) -> Result<u128> {
192        self.inner.read_u128(self.byte_order)
193    }
194
195    /// Reads an `i128` using the configured byte order.
196    ///
197    /// # Errors
198    /// Returns an I/O error from the wrapped reader.
199    #[inline]
200    pub fn read_i128(&mut self) -> Result<i128> {
201        self.inner.read_i128(self.byte_order)
202    }
203
204    /// Reads an `f32` using the configured byte order.
205    ///
206    /// # Errors
207    /// Returns an I/O error from the wrapped reader.
208    #[inline]
209    pub fn read_f32(&mut self) -> Result<f32> {
210        self.inner.read_f32(self.byte_order)
211    }
212
213    /// Reads an `f64` using the configured byte order.
214    ///
215    /// # Errors
216    /// Returns an I/O error from the wrapped reader.
217    #[inline]
218    pub fn read_f64(&mut self) -> Result<f64> {
219        self.inner.read_f64(self.byte_order)
220    }
221
222    /// Reads a UTF-8 string with a `u16` byte-length prefix.
223    ///
224    /// # Parameters
225    /// - `max_len`: Maximum accepted UTF-8 payload length in bytes.
226    ///
227    /// # Errors
228    /// Returns an I/O error from the wrapped reader, or `InvalidData` when the
229    /// payload length exceeds `max_len` or the payload is not valid UTF-8.
230    #[inline]
231    pub fn read_utf8_string_u16(&mut self, max_len: usize) -> Result<String> {
232        match self.byte_order {
233            ByteOrder::BigEndian => self.inner.read_utf8_string_u16_be(max_len),
234            ByteOrder::LittleEndian => self.inner.read_utf8_string_u16_le(max_len),
235        }
236    }
237
238    /// Reads a UTF-8 string with a `u32` byte-length prefix.
239    ///
240    /// # Parameters
241    /// - `max_len`: Maximum accepted UTF-8 payload length in bytes.
242    ///
243    /// # Errors
244    /// Returns an I/O error from the wrapped reader, or `InvalidData` when the
245    /// payload length exceeds `max_len` or the payload is not valid UTF-8.
246    #[inline]
247    pub fn read_utf8_string_u32(&mut self, max_len: usize) -> Result<String> {
248        match self.byte_order {
249            ByteOrder::BigEndian => self.inner.read_utf8_string_u32_be(max_len),
250            ByteOrder::LittleEndian => self.inner.read_utf8_string_u32_le(max_len),
251        }
252    }
253}
254
255impl<R> Read for BinaryReader<R>
256where
257    R: Read,
258{
259    #[inline]
260    fn read(&mut self, buffer: &mut [u8]) -> Result<usize> {
261        self.inner.read(buffer)
262    }
263}
264
265impl<R> BufRead for BinaryReader<R>
266where
267    R: BufRead,
268{
269    #[inline]
270    fn fill_buf(&mut self) -> Result<&[u8]> {
271        self.inner.fill_buf()
272    }
273
274    #[inline]
275    fn consume(&mut self, amount: usize) {
276        self.inner.consume(amount);
277    }
278}
279
280impl<R> Seek for BinaryReader<R>
281where
282    R: Seek,
283{
284    #[inline]
285    fn seek(&mut self, position: SeekFrom) -> Result<u64> {
286        self.inner.seek(position)
287    }
288}