Skip to main content

qubit_io/ext/
leb128_read_ext.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 ******************************************************************************/
10
11use std::io::{
12    Read,
13    Result,
14};
15
16use crate::codec::{
17    Leb128Codec,
18    NonStrict,
19    Strict,
20};
21use crate::util::read_leb128_payload;
22
23macro_rules! read_leb128_value {
24    ($reader:expr, $ty:ty, $policy:ty) => {
25        read_leb128_payload::<{ Leb128Codec::<$ty, $policy>::REQUIRED_MIN_BUFFER_LEN }, _, _, _>($reader, |bytes| {
26            // SAFETY: The local buffer is exactly the codec's minimum buffer length,
27            // or it contains an earlier terminating byte before decoding.
28            unsafe { Leb128Codec::<$ty, $policy>::read_unchecked(bytes, 0) }
29        })
30    };
31}
32
33/// Extension methods for reading LEB128 integers from byte streams.
34///
35/// # Target-width integers
36///
37/// `usize` and `isize` methods use the current Rust target's pointer width.
38/// Prefer fixed-width integer methods such as [`Self::read_uleb_u64`] or
39/// [`Self::read_sleb_i64`] for persistent files and cross-platform protocols.
40pub trait Leb128ReadExt: Read {
41    /// Reads a non-strict unsigned LEB128 `u8`.
42    #[inline]
43    fn read_uleb_u8(&mut self) -> Result<u8> {
44        read_leb128_value!(self, u8, NonStrict)
45    }
46
47    /// Reads a strict unsigned LEB128 `u8`.
48    #[inline]
49    fn read_uleb_u8_strict(&mut self) -> Result<u8> {
50        read_leb128_value!(self, u8, Strict)
51    }
52
53    /// Reads a non-strict unsigned LEB128 `u16`.
54    #[inline]
55    fn read_uleb_u16(&mut self) -> Result<u16> {
56        read_leb128_value!(self, u16, NonStrict)
57    }
58
59    /// Reads a strict unsigned LEB128 `u16`.
60    #[inline]
61    fn read_uleb_u16_strict(&mut self) -> Result<u16> {
62        read_leb128_value!(self, u16, Strict)
63    }
64
65    /// Reads a non-strict unsigned LEB128 `u32`.
66    #[inline]
67    fn read_uleb_u32(&mut self) -> Result<u32> {
68        read_leb128_value!(self, u32, NonStrict)
69    }
70
71    /// Reads a strict unsigned LEB128 `u32`.
72    #[inline]
73    fn read_uleb_u32_strict(&mut self) -> Result<u32> {
74        read_leb128_value!(self, u32, Strict)
75    }
76
77    /// Reads a non-strict unsigned LEB128 `u64`.
78    #[inline]
79    fn read_uleb_u64(&mut self) -> Result<u64> {
80        read_leb128_value!(self, u64, NonStrict)
81    }
82
83    /// Reads a strict unsigned LEB128 `u64`.
84    #[inline]
85    fn read_uleb_u64_strict(&mut self) -> Result<u64> {
86        read_leb128_value!(self, u64, Strict)
87    }
88
89    /// Reads a non-strict unsigned LEB128 `u128`.
90    #[inline]
91    fn read_uleb_u128(&mut self) -> Result<u128> {
92        read_leb128_value!(self, u128, NonStrict)
93    }
94
95    /// Reads a strict unsigned LEB128 `u128`.
96    #[inline]
97    fn read_uleb_u128_strict(&mut self) -> Result<u128> {
98        read_leb128_value!(self, u128, Strict)
99    }
100
101    /// Reads a non-strict unsigned LEB128 `usize`.
102    #[inline]
103    fn read_uleb_usize(&mut self) -> Result<usize> {
104        read_leb128_value!(self, usize, NonStrict)
105    }
106
107    /// Reads a strict unsigned LEB128 `usize`.
108    #[inline]
109    fn read_uleb_usize_strict(&mut self) -> Result<usize> {
110        read_leb128_value!(self, usize, Strict)
111    }
112
113    /// Reads a non-strict signed LEB128 `i8`.
114    #[inline]
115    fn read_sleb_i8(&mut self) -> Result<i8> {
116        read_leb128_value!(self, i8, NonStrict)
117    }
118
119    /// Reads a strict signed LEB128 `i8`.
120    #[inline]
121    fn read_sleb_i8_strict(&mut self) -> Result<i8> {
122        read_leb128_value!(self, i8, Strict)
123    }
124
125    /// Reads a non-strict signed LEB128 `i16`.
126    #[inline]
127    fn read_sleb_i16(&mut self) -> Result<i16> {
128        read_leb128_value!(self, i16, NonStrict)
129    }
130
131    /// Reads a strict signed LEB128 `i16`.
132    #[inline]
133    fn read_sleb_i16_strict(&mut self) -> Result<i16> {
134        read_leb128_value!(self, i16, Strict)
135    }
136
137    /// Reads a non-strict signed LEB128 `i32`.
138    #[inline]
139    fn read_sleb_i32(&mut self) -> Result<i32> {
140        read_leb128_value!(self, i32, NonStrict)
141    }
142
143    /// Reads a strict signed LEB128 `i32`.
144    #[inline]
145    fn read_sleb_i32_strict(&mut self) -> Result<i32> {
146        read_leb128_value!(self, i32, Strict)
147    }
148
149    /// Reads a non-strict signed LEB128 `i64`.
150    #[inline]
151    fn read_sleb_i64(&mut self) -> Result<i64> {
152        read_leb128_value!(self, i64, NonStrict)
153    }
154
155    /// Reads a strict signed LEB128 `i64`.
156    #[inline]
157    fn read_sleb_i64_strict(&mut self) -> Result<i64> {
158        read_leb128_value!(self, i64, Strict)
159    }
160
161    /// Reads a non-strict signed LEB128 `i128`.
162    #[inline]
163    fn read_sleb_i128(&mut self) -> Result<i128> {
164        read_leb128_value!(self, i128, NonStrict)
165    }
166
167    /// Reads a strict signed LEB128 `i128`.
168    #[inline]
169    fn read_sleb_i128_strict(&mut self) -> Result<i128> {
170        read_leb128_value!(self, i128, Strict)
171    }
172
173    /// Reads a non-strict signed LEB128 `isize`.
174    #[inline]
175    fn read_sleb_isize(&mut self) -> Result<isize> {
176        read_leb128_value!(self, isize, NonStrict)
177    }
178
179    /// Reads a strict signed LEB128 `isize`.
180    #[inline]
181    fn read_sleb_isize_strict(&mut self) -> Result<isize> {
182        read_leb128_value!(self, isize, Strict)
183    }
184}
185
186impl<R> Leb128ReadExt for R where R: Read + ?Sized {}