1use core::marker::PhantomData;
12use std::io::{
13 Error,
14 ErrorKind,
15 Read,
16 Result,
17 Seek,
18 SeekFrom,
19};
20
21use crate::codec::{
22 DecodePolicy,
23 Leb128Codec,
24 Leb128DecodeError,
25 NonStrict,
26 Strict,
27};
28use crate::stream::BufferedInput;
29use crate::util::read_utf8_payload;
30
31pub struct BufferedLeb128Reader<R, P = NonStrict> {
49 input: BufferedInput<R>,
50 marker: PhantomData<fn() -> P>,
51}
52
53impl<R, P> BufferedLeb128Reader<R, P>
54where
55 P: DecodePolicy,
56{
57 #[must_use]
59 #[inline]
60 pub fn new(inner: R) -> Self {
61 Self {
62 input: BufferedInput::new(inner),
63 marker: PhantomData,
64 }
65 }
66
67 #[must_use]
69 #[inline]
70 pub fn with_capacity(inner: R, capacity: usize) -> Self {
71 Self {
72 input: BufferedInput::with_capacity(inner, capacity),
73 marker: PhantomData,
74 }
75 }
76
77 #[must_use]
79 #[inline]
80 pub const fn is_strict(&self) -> bool {
81 P::STRICT
82 }
83
84 #[must_use]
89 #[inline]
90 pub const fn inner(&self) -> &R {
91 self.input.inner()
92 }
93
94 #[must_use]
99 #[inline]
100 pub fn inner_mut(&mut self) -> &mut R {
101 self.input.inner_mut()
102 }
103
104 #[must_use]
109 #[inline]
110 pub fn into_inner(self) -> R {
111 self.input.into_inner()
112 }
113}
114
115macro_rules! impl_read_value {
116 ($policy:ty, $method:ident, $ty:ty, $doc:literal) => {
117 #[doc = $doc]
118 #[inline]
119 pub fn $method(&mut self) -> Result<$ty> {
120 type Codec = Leb128Codec<$ty, $policy>;
121
122 self.input
123 .read_variable_decoded::<{ Codec::REQUIRED_MIN_BUFFER_LEN }, _, _, _, _>(
124 |bytes, index, available| {
125 unsafe { Codec::read_available_unchecked(bytes, index, available) }
129 },
130 map_leb128_decode_error,
131 )
132 }
133 };
134}
135
136macro_rules! impl_for_policy {
137 ($policy:ty) => {
138 impl<R> BufferedLeb128Reader<R, $policy>
139 where
140 R: Read,
141 {
142 impl_read_value!($policy, read_u8, u8, "Reads an unsigned LEB128 `u8`.");
143 impl_read_value!($policy, read_u16, u16, "Reads an unsigned LEB128 `u16`.");
144 impl_read_value!($policy, read_u32, u32, "Reads an unsigned LEB128 `u32`.");
145 impl_read_value!($policy, read_u64, u64, "Reads an unsigned LEB128 `u64`.");
146 impl_read_value!($policy, read_u128, u128, "Reads an unsigned LEB128 `u128`.");
147 impl_read_value!($policy, read_usize, usize, "Reads an unsigned LEB128 `usize`.");
148 impl_read_value!($policy, read_i8, i8, "Reads a signed LEB128 `i8`.");
149 impl_read_value!($policy, read_i16, i16, "Reads a signed LEB128 `i16`.");
150 impl_read_value!($policy, read_i32, i32, "Reads a signed LEB128 `i32`.");
151 impl_read_value!($policy, read_i64, i64, "Reads a signed LEB128 `i64`.");
152 impl_read_value!($policy, read_i128, i128, "Reads a signed LEB128 `i128`.");
153 impl_read_value!($policy, read_isize, isize, "Reads a signed LEB128 `isize`.");
154
155 #[inline]
161 pub fn read_utf8_string(&mut self, max_len: usize) -> Result<String> {
162 let len = self.read_usize()?;
163 read_utf8_payload(&mut self.input, len, max_len)
164 }
165 }
166 };
167}
168
169impl_for_policy!(NonStrict);
170impl_for_policy!(Strict);
171
172impl<R, P> Read for BufferedLeb128Reader<R, P>
173where
174 R: Read,
175{
176 #[inline]
178 fn read(&mut self, buffer: &mut [u8]) -> Result<usize> {
179 self.input.read_raw(buffer)
180 }
181}
182
183impl<R, P> Seek for BufferedLeb128Reader<R, P>
184where
185 R: Read + Seek,
186{
187 #[inline]
189 fn seek(&mut self, position: SeekFrom) -> Result<u64> {
190 self.input.seek_raw(position)
191 }
192}
193
194#[inline]
196fn map_leb128_decode_error(error: Leb128DecodeError) -> Error {
197 Error::new(ErrorKind::InvalidData, error)
198}