Skip to main content

bincode_next/de/
read.rs

1//! This module contains reader-based structs and traits.
2//!
3//! Because `std::io::Read` is only limited to `std` and not `core`, we provide 2 alternative readers.
4//!
5//! [`Reader`\] is a reader for sources that do not own their data. It is assumed that the reader's data is dropped after the `read` method is called. This reader is incapable of reading borrowed data, like `&str` and `&[u8]`.
6//!
7//! [`BorrowReader`\] is an extension of `Reader` that also allows returning borrowed data. A `BorrowReader` allows reading `&str` and `&[u8]`.
8//!
9//! Specifically the `Reader` trait is used by [`Decode`\] and the `BorrowReader` trait is used by [`BorrowDecode`\].
10//!
11//! [Decode]: ../trait.Decode.html
12//! [BorrowDecode]: ../trait.BorrowDecode.html
13#![allow(unsafe_code)]
14
15use crate::error::DecodeError;
16
17/// A reader for owned data. See the module documentation for more information.
18pub trait Reader {
19    /// Fill the given `bytes` argument with values. Exactly the length of the given slice must be filled, or else an error must be returned.
20    ///
21    /// # Errors
22    ///
23    /// Returns `DecodeError::UnexpectedEnd` if the reader does not have enough bytes.
24    fn read(
25        &mut self,
26        bytes: &mut [u8],
27    ) -> Result<(), DecodeError>;
28
29    /// Read a single byte from the reader.
30    ///
31    /// # Errors
32    ///
33    /// Returns an error if the operation fails.
34    #[inline(always)]
35    fn read_u8(&mut self) -> Result<u8, DecodeError> {
36        let mut byte = [0u8; 1];
37        self.read(&mut byte)?;
38        Ok(byte[0])
39    }
40
41    /// Read a `u16` from the reader.
42    ///
43    /// # Errors
44    ///
45    /// Returns an error if the operation fails.
46    #[inline(always)]
47    fn read_u16(&mut self) -> Result<u16, DecodeError> {
48        let mut bytes = [0u8; 2];
49        self.read(&mut bytes)?;
50        Ok(u16::from_ne_bytes(bytes))
51    }
52
53    /// Read a `u32` from the reader.
54    ///
55    /// # Errors
56    ///
57    /// Returns an error if the operation fails.
58    #[inline(always)]
59    fn read_u32(&mut self) -> Result<u32, DecodeError> {
60        let mut bytes = [0u8; 4];
61        self.read(&mut bytes)?;
62        Ok(u32::from_ne_bytes(bytes))
63    }
64
65    /// Read a `u64` from the reader.
66    ///
67    /// # Errors
68    ///
69    /// Returns an error if the operation fails.
70    #[inline(always)]
71    fn read_u64(&mut self) -> Result<u64, DecodeError> {
72        let mut bytes = [0u8; 8];
73        self.read(&mut bytes)?;
74        Ok(u64::from_ne_bytes(bytes))
75    }
76
77    /// Read a `u128` from the reader.
78    ///
79    /// # Errors
80    ///
81    /// Returns an error if the operation fails.
82    #[inline(always)]
83    fn read_u128(&mut self) -> Result<u128, DecodeError> {
84        let mut bytes = [0u8; 16];
85        self.read(&mut bytes)?;
86        Ok(u128::from_ne_bytes(bytes))
87    }
88
89    /// If this reader wraps a buffer of any kind, this function lets callers access contents of
90    /// the buffer without passing data through a buffer first.
91    #[inline(always)]
92    fn peek_read(
93        &mut self,
94        _: usize,
95    ) -> Option<&[u8]> {
96        None
97    }
98
99    /// If an implementation of `peek_read` is provided, an implementation of this function
100    /// must be provided so that subsequent reads or peek-reads do not return the same bytes
101    #[inline(always)]
102    fn consume(
103        &mut self,
104        _: usize,
105    ) {
106    }
107
108    /// Returns the next byte without consuming it.
109    #[inline(always)]
110    fn peek_u8(&mut self) -> Option<u8> {
111        self.peek_read(1).map(|b| b[0])
112    }
113}
114
115impl<T> Reader for &mut T
116where
117    T: Reader,
118{
119    #[inline(always)]
120    fn read(
121        &mut self,
122        bytes: &mut [u8],
123    ) -> Result<(), DecodeError> {
124        (**self).read(bytes)
125    }
126
127    #[inline(always)]
128    fn peek_read(
129        &mut self,
130        n: usize,
131    ) -> Option<&[u8]> {
132        (**self).peek_read(n)
133    }
134
135    #[inline(always)]
136    fn consume(
137        &mut self,
138        n: usize,
139    ) {
140        (*self).consume(n);
141    }
142
143    #[inline(always)]
144    fn read_u16(&mut self) -> Result<u16, DecodeError> {
145        (**self).read_u16()
146    }
147
148    #[inline(always)]
149    fn read_u32(&mut self) -> Result<u32, DecodeError> {
150        (**self).read_u32()
151    }
152
153    #[inline(always)]
154    fn read_u64(&mut self) -> Result<u64, DecodeError> {
155        (**self).read_u64()
156    }
157
158    #[inline(always)]
159    fn read_u128(&mut self) -> Result<u128, DecodeError> {
160        (**self).read_u128()
161    }
162}
163
164/// A reader for borrowed data. Implementers of this must also implement the [`Reader`\] trait. See the module documentation for more information.
165pub trait BorrowReader<'storage>: Reader {
166    /// Read exactly `length` bytes and return a slice to this data. If not enough bytes could be read, an error should be returned.
167    ///
168    /// *note*: Exactly `length` bytes must be returned. If less bytes are returned, bincode may panic. If more bytes are returned, the excess bytes may be discarded.
169    ///
170    /// # Errors
171    ///
172    /// Returns `DecodeError::UnexpectedEnd` if the reader does not have enough bytes.
173    fn take_bytes(
174        &mut self,
175        length: usize,
176    ) -> Result<&'storage [u8], DecodeError>;
177}
178
179/// A reader type for `&[u8]` slices. Implements both [`Reader`\] and [`BorrowReader`\], and thus can be used for borrowed data.
180pub struct SliceReader<'storage> {
181    pub(crate) slice: &'storage [u8],
182}
183
184impl<'storage> SliceReader<'storage> {
185    /// Constructs a slice reader
186    #[must_use]
187    pub const fn new(bytes: &'storage [u8]) -> Self {
188        Self { slice: bytes }
189    }
190}
191
192impl<'storage> Reader for SliceReader<'storage> {
193    #[inline(always)]
194    fn read(
195        &mut self,
196        bytes: &mut [u8],
197    ) -> Result<(), DecodeError> {
198        if bytes.len() > self.slice.len() {
199            return crate::error::cold_decode_error_unexpected_end(bytes.len() - self.slice.len());
200        }
201        // SAFETY: `bytes.len() <= self.slice.len()` is checked above.
202        // `copy_nonoverlapping` is safe because pointers do not overlap and the lengths match.
203        // `get_unchecked` is safe because `bytes.len()` is <= the length of `self.slice`.
204        unsafe {
205            core::ptr::copy_nonoverlapping(self.slice.as_ptr(), bytes.as_mut_ptr(), bytes.len());
206            self.slice = self.slice.get_unchecked(bytes.len()..);
207        }
208
209        Ok(())
210    }
211
212    #[inline(always)]
213    fn peek_read(
214        &mut self,
215        n: usize,
216    ) -> Option<&'storage [u8]> {
217        self.slice.get(..n)
218    }
219
220    #[inline(always)]
221    fn consume(
222        &mut self,
223        n: usize,
224    ) {
225        if n >= self.slice.len() {
226            self.slice = &[];
227        } else {
228            self.slice = unsafe { self.slice.get_unchecked(n..) };
229        }
230    }
231
232    #[inline(always)]
233    fn peek_u8(&mut self) -> Option<u8> {
234        self.slice.first().copied()
235    }
236
237    #[inline(always)]
238    fn read_u8(&mut self) -> Result<u8, DecodeError> {
239        if self.slice.is_empty() {
240            return crate::error::cold_decode_error_unexpected_end(1);
241        }
242        let byte = unsafe { *self.slice.get_unchecked(0) };
243        self.slice = unsafe { self.slice.get_unchecked(1..) };
244        Ok(byte)
245    }
246
247    #[inline(always)]
248    fn read_u16(&mut self) -> Result<u16, DecodeError> {
249        if self.slice.len() < 2 {
250            return crate::error::cold_decode_error_unexpected_end(2 - self.slice.len());
251        }
252        let val = unsafe { core::ptr::read_unaligned(self.slice.as_ptr().cast::<u16>()) };
253        self.slice = unsafe { self.slice.get_unchecked(2..) };
254        Ok(val)
255    }
256
257    #[inline(always)]
258    fn read_u32(&mut self) -> Result<u32, DecodeError> {
259        if self.slice.len() < 4 {
260            return crate::error::cold_decode_error_unexpected_end(4 - self.slice.len());
261        }
262        let val = unsafe { core::ptr::read_unaligned(self.slice.as_ptr().cast::<u32>()) };
263        self.slice = unsafe { self.slice.get_unchecked(4..) };
264        Ok(val)
265    }
266
267    #[inline(always)]
268    fn read_u64(&mut self) -> Result<u64, DecodeError> {
269        if self.slice.len() < 8 {
270            return crate::error::cold_decode_error_unexpected_end(8 - self.slice.len());
271        }
272        let val = unsafe { core::ptr::read_unaligned(self.slice.as_ptr().cast::<u64>()) };
273        self.slice = unsafe { self.slice.get_unchecked(8..) };
274        Ok(val)
275    }
276
277    #[inline(always)]
278    fn read_u128(&mut self) -> Result<u128, DecodeError> {
279        if self.slice.len() < 16 {
280            return crate::error::cold_decode_error_unexpected_end(16 - self.slice.len());
281        }
282        let val = unsafe { core::ptr::read_unaligned(self.slice.as_ptr().cast::<u128>()) };
283        self.slice = unsafe { self.slice.get_unchecked(16..) };
284        Ok(val)
285    }
286}
287
288impl<'storage> BorrowReader<'storage> for SliceReader<'storage> {
289    #[inline(always)]
290    fn take_bytes(
291        &mut self,
292        length: usize,
293    ) -> Result<&'storage [u8], DecodeError> {
294        if length > self.slice.len() {
295            return crate::error::cold_decode_error_unexpected_end(length - self.slice.len());
296        }
297        // SAFETY: `length <= self.slice.len()` is checked above.
298        // `get_unchecked` is therefore safe for both the read portion and the remainder.
299        unsafe {
300            let read_slice = self.slice.get_unchecked(..length);
301            self.slice = self.slice.get_unchecked(length..);
302            Ok(read_slice)
303        }
304    }
305}