Skip to main content

oximedia_bitstream/read/
byte_reader.rs

1// Copyright 2017 Brian Langenberger
2// Copyright 2024-2026 COOLJAPAN OU (Team Kitasan)
3//
4// Licensed under the Apache License, Version 2.0 or the MIT license,
5// at your option. See the LICENSE-APACHE / LICENSE-MIT files for details.
6
7//! `ByteReader` and the `ByteRead` trait for whole-byte input.
8
9use std::io;
10#[cfg(feature = "alloc")]
11use std::vec::Vec;
12
13use super::{
14    read_to_vec, skip_aligned, BitReader, Endianness, FromByteStream, FromByteStreamUsing,
15    FromByteStreamWith, PhantomData, Primitive,
16};
17
18/// A trait for anything that can read aligned values from an input stream
19pub trait ByteRead {
20    /// Reads whole numeric value from stream
21    ///
22    /// # Errors
23    ///
24    /// Passes along any I/O error from the underlying stream.
25    ///
26    /// # Examples
27    /// ```
28    /// use std::io::Read;
29    /// use oximedia_bitstream::{BigEndian, ByteReader, ByteRead};
30    /// let data = [0b00000000, 0b11111111];
31    /// let mut reader = ByteReader::endian(data.as_slice(), BigEndian);
32    /// assert_eq!(reader.read::<u16>().unwrap(), 0b0000000011111111);
33    /// ```
34    ///
35    /// ```
36    /// use std::io::Read;
37    /// use oximedia_bitstream::{LittleEndian, ByteReader, ByteRead};
38    /// let data = [0b00000000, 0b11111111];
39    /// let mut reader = ByteReader::endian(data.as_slice(), LittleEndian);
40    /// assert_eq!(reader.read::<u16>().unwrap(), 0b1111111100000000);
41    /// ```
42    fn read<V>(&mut self) -> Result<V, io::Error>
43    where
44        V: Primitive;
45
46    /// Reads whole numeric value from stream in a potentially different endianness
47    ///
48    /// # Errors
49    ///
50    /// Passes along any I/O error from the underlying stream.
51    ///
52    /// # Examples
53    /// ```
54    /// use std::io::Read;
55    /// use oximedia_bitstream::{BigEndian, ByteReader, ByteRead, LittleEndian};
56    /// let data = [0b00000000, 0b11111111];
57    /// let mut reader = ByteReader::endian(data.as_slice(), BigEndian);
58    /// assert_eq!(reader.read_as::<LittleEndian, u16>().unwrap(), 0b1111111100000000);
59    /// ```
60    ///
61    /// ```
62    /// use std::io::Read;
63    /// use oximedia_bitstream::{BigEndian, ByteReader, ByteRead, LittleEndian};
64    /// let data = [0b00000000, 0b11111111];
65    /// let mut reader = ByteReader::endian(data.as_slice(), LittleEndian);
66    /// assert_eq!(reader.read_as::<BigEndian, u16>().unwrap(), 0b0000000011111111);
67    /// ```
68    fn read_as<F, V>(&mut self) -> Result<V, io::Error>
69    where
70        F: Endianness,
71        V: Primitive;
72
73    /// Completely fills the given buffer with whole bytes.
74    ///
75    /// # Errors
76    ///
77    /// Passes along any I/O error from the underlying stream.
78    fn read_bytes(&mut self, buf: &mut [u8]) -> io::Result<()> {
79        for b in buf.iter_mut() {
80            *b = self.read()?;
81        }
82        Ok(())
83    }
84
85    /// Completely fills a whole buffer with bytes and returns it.
86    ///
87    /// # Errors
88    ///
89    /// Passes along any I/O error from the underlying stream.
90    #[inline(always)]
91    #[deprecated(since = "1.8.0", note = "use read() method instead")]
92    fn read_to_bytes<const SIZE: usize>(&mut self) -> io::Result<[u8; SIZE]> {
93        self.read()
94    }
95
96    /// Completely fills a vector of bytes and returns it.
97    ///
98    /// # Errors
99    ///
100    /// Passes along any I/O error from the underlying stream.
101    #[cfg(feature = "alloc")]
102    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
103    fn read_to_vec(&mut self, bytes: usize) -> io::Result<Vec<u8>> {
104        read_to_vec(|buf| self.read_bytes(buf), bytes)
105    }
106
107    /// Skips the given number of bytes in the stream.
108    ///
109    /// # Errors
110    ///
111    /// Passes along any I/O error from the underlying stream.
112    fn skip(&mut self, bytes: u32) -> io::Result<()>;
113
114    /// Parses and returns complex type
115    fn parse<F: FromByteStream>(&mut self) -> Result<F, F::Error> {
116        F::from_reader(self)
117    }
118
119    /// Parses and returns complex type with context
120    fn parse_with<'a, F: FromByteStreamWith<'a>>(
121        &mut self,
122        context: &F::Context,
123    ) -> Result<F, F::Error> {
124        F::from_reader(self, context)
125    }
126
127    /// Parses and returns complex type with owned context
128    fn parse_using<F: FromByteStreamUsing>(&mut self, context: F::Context) -> Result<F, F::Error> {
129        F::from_reader(self, context)
130    }
131
132    /// Returns mutable reference to underlying reader
133    fn reader_ref(&mut self) -> &mut dyn io::Read;
134}
135
136/// For reading aligned bytes from a stream of bytes in a given endianness.
137///
138/// This only reads aligned values and maintains no internal state.
139#[derive(Debug)]
140pub struct ByteReader<R: io::Read, E: Endianness> {
141    phantom: PhantomData<E>,
142    reader: R,
143}
144
145impl<R: io::Read, E: Endianness> ByteReader<R, E> {
146    /// Wraps a ByteReader around something that implements `Read`
147    pub fn new(reader: R) -> ByteReader<R, E> {
148        ByteReader {
149            phantom: PhantomData,
150            reader,
151        }
152    }
153
154    /// Wraps a ByteReader around something that implements `Read`
155    /// with the given endianness.
156    pub fn endian(reader: R, _endian: E) -> ByteReader<R, E> {
157        ByteReader {
158            phantom: PhantomData,
159            reader,
160        }
161    }
162
163    /// Unwraps internal reader and disposes of `ByteReader`.
164    #[inline]
165    pub fn into_reader(self) -> R {
166        self.reader
167    }
168
169    /// Provides mutable reference to internal reader
170    #[inline]
171    pub fn reader(&mut self) -> &mut R {
172        &mut self.reader
173    }
174
175    /// Converts `ByteReader` to `BitReader` in the same endianness.
176    #[inline]
177    pub fn into_bitreader(self) -> BitReader<R, E> {
178        BitReader::new(self.into_reader())
179    }
180
181    /// Provides temporary `BitReader` in the same endianness.
182    ///
183    /// # Warning
184    ///
185    /// Any unread bits left over when `BitReader` is dropped are lost.
186    #[inline]
187    pub fn bitreader(&mut self) -> BitReader<&mut R, E> {
188        BitReader::new(self.reader())
189    }
190}
191
192impl<R: io::Read, E: Endianness> ByteRead for ByteReader<R, E> {
193    #[inline]
194    fn read<V>(&mut self) -> Result<V, io::Error>
195    where
196        V: Primitive,
197    {
198        let mut buf = V::buffer();
199        self.read_bytes(buf.as_mut())?;
200        Ok(E::bytes_to_primitive(buf))
201    }
202
203    #[inline]
204    fn read_as<F, V>(&mut self) -> Result<V, io::Error>
205    where
206        F: Endianness,
207        V: Primitive,
208    {
209        let mut buf = V::buffer();
210        self.read_bytes(buf.as_mut())?;
211        Ok(F::bytes_to_primitive(buf))
212    }
213
214    #[inline]
215    fn read_bytes(&mut self, buf: &mut [u8]) -> io::Result<()> {
216        self.reader.read_exact(buf)
217    }
218
219    #[inline]
220    fn skip(&mut self, bytes: u32) -> io::Result<()> {
221        skip_aligned(&mut self.reader, bytes)
222    }
223
224    #[inline]
225    fn reader_ref(&mut self) -> &mut dyn io::Read {
226        &mut self.reader
227    }
228}
229
230impl<R: io::Read + io::Seek, E: Endianness> io::Seek for ByteReader<R, E> {
231    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
232        self.reader().seek(pos)
233    }
234}