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}