byte_chisel/endian.rs
1use crate::*;
2
3macro_rules! ty_fn_endian {
4 ($ty: ident, $endian: ident, $doc_endian: ident) => {
5 #[doc =
6concat!(r"Reads a single [`", stringify!($ty), r"`] in [", stringify!($doc_endian), "-endian][Endianness::", stringify!($endian), "] byte order.
7
8## Errors
9
10If an error is returned, the chisel [breaks][crate#breaking].
11")]
12 #[inline]
13 pub fn $ty(&mut self) -> InfallibleFormatResult<$ty, S> {
14 self.0.$ty(Endianness::$endian)
15 }
16 };
17}
18
19/**
20 * A [`Chisel`], with little-endian byte order.
21 *
22 * See the [crate documentation](crate) for more information.
23 */
24#[repr(transparent)]
25pub struct ChiselLittleEndian<'a, S : ChiselSource>(pub(crate) &'a mut Chisel<S>);
26
27impl<'a, S : ChiselSource> ChiselLittleEndian<'a, S> {
28 /** Returns a reference to the inner `Chisel`. */
29 #[inline]
30 pub fn inner(&mut self) -> &mut Chisel<S> { self.0 }
31
32 /** Consumes the wrapper, returning the input chisel reference. */
33 #[inline]
34 pub fn into_inner(self) -> &'a mut Chisel<S> { self.0 }
35
36 /**
37 * Returns a format error that occurred `backstep` bytes ago.
38 *
39 * This is a convenience method for manually determining the appropriate byte offset and calling [ChiselError::format].
40 */
41 #[inline]
42 pub fn error<E>(&self, err: E, backstep: usize) -> ChiselError<E, S::Error> { self.0.error(err, backstep) }
43
44 /** Returns the current byte offset of the Chisel. */
45 #[inline]
46 pub fn offset(&self) -> usize { self.0.offset() }
47
48 /**
49 * Fills a provided buffer with bytes from the source.
50 *
51 * This operation is endian-independent.
52 *
53 * ## Errors
54 * This function returns an [`ChiselErrorData::EndOfInput`] if the end of the input is encountered
55 * before the buffer is completely filled.
56 *
57 * If an error is returned, the contents of `buf` are unspecified and the chisel [breaks][crate#breaking].
58 */
59 #[inline]
60 pub fn read_buf(&mut self, buf: &mut [u8]) -> InfallibleFormatResult<(), S> { self.0.read_buf(buf) }
61
62
63 /**
64 * Reads a single byte [`u8`].
65 *
66 * This operation is endian-independent.
67 */
68 #[inline]
69 pub fn u8(&mut self) -> InfallibleFormatResult<u8, S> { self.0.u8() }
70 ty_fn_endian!(u16, Little, little);
71 ty_fn_endian!(u32, Little, little);
72 ty_fn_endian!(u64, Little, little);
73
74 /**
75 * Reads a single _signed_ byte [`i8`].
76 *
77 * This operation is endian-independent.
78 */
79 #[inline]
80 pub fn i8(&mut self) -> InfallibleFormatResult<i8, S> { self.0.i8() }
81 ty_fn_endian!(i16, Little, little);
82 ty_fn_endian!(i32, Little, little);
83 ty_fn_endian!(i64, Little, little);
84
85 ty_fn_endian!(f32, Little, little);
86 ty_fn_endian!(f64, Little, little);
87
88 /**
89 * Skips `how_many` bytes of the underlying source.
90 *
91 * This operation is endian-independent.
92 *
93 * This is provided for optimization reasons. This hint is forwarded to the source.
94 *
95 * Exactly `how_many` bytes are skipped, as-if [`read_buf`][Self::read_buf] were called with a buffer
96 * of appropriate size, with the buffer being discarded.
97 *
98 * ## Errors
99 *
100 * If an end-of-input condition occurs before `how_many` bytes are skipped, an [`ChiselErrorData::EndOfInput`] error is returned.
101 *
102 * If an error is returned, the chisel [breaks][crate#breaking].
103 */
104 #[inline]
105 pub fn skip(&mut self, how_many: usize) -> InfallibleFormatResult<(), S> { self.0.skip(how_many) }
106
107 #[cfg(feature = "alloc")]
108 /**
109 * Reads bytes into the provided `dest` Vec until the `delimiter` byte is encountered.
110 *
111 * This operation is endian-independent.
112 *
113 * ## Errors
114 * If the end of the input is encountered before the delimiter is found, [`ChiselErrorData::EndOfInput`] is returned.
115 *
116 * If an error is returned, the chisel [breaks][crate#breaking].
117 */
118 #[inline]
119 pub fn read_until(&mut self, byte: u8, dest: &mut Vec<u8>) -> InfallibleFormatResult<(), S> { self.0.read_until(byte, dest) }
120
121 #[cfg(feature = "alloc")]
122 /**
123 * Reads bytes into the provided `dest` Vec until the `delimiter` byte or end-of-input is encountered.
124 *
125 * This operation is endian-independent.
126 * ## Errors
127 * If an error is returned, the chisel [breaks][crate#breaking].
128 */
129 #[inline]
130 pub fn read_until_or_end(&mut self, byte: u8, dest: &mut Vec<u8>) -> InfallibleFormatResult<ReadUntilStopReason, S> { self.0.read_until_or_end(byte, dest) }
131}
132
133/**
134 * A [`Chisel`], with big-endian byte order.
135 *
136 * See the [crate documentation](crate) for more information.
137 */
138#[repr(transparent)]
139pub struct ChiselBigEndian<'a, S : ChiselSource>(pub(crate) &'a mut Chisel<S>);
140
141impl<'a, S : ChiselSource> ChiselBigEndian<'a, S> {
142 /** Returns a reference to the inner `Chisel`. */
143 #[inline]
144 pub fn inner(&mut self) -> &mut Chisel<S> { self.0 }
145
146 /** Consumes the wrapper, returning the input chisel reference. */
147 #[inline]
148 pub fn into_inner(self) -> &'a mut Chisel<S> { self.0 }
149
150 /**
151 * Returns a format error that occurred `backstep` bytes ago.
152 *
153 * This is a convenience method for manually determining the appropriate byte offset and calling [ChiselError::format].
154 */
155 #[inline]
156 pub fn error<E>(&self, err: E, backstep: usize) -> ChiselError<E, S::Error> { self.0.error(err, backstep) }
157
158 /** Returns the current byte offset of the Chisel. */
159 #[inline]
160 pub fn offset(&self) -> usize { self.0.offset() }
161
162 /**
163 * Fills a provided buffer with bytes from the source.
164 *
165 * This operation is endian-independent.
166 *
167 * ## Errors
168 * This function returns an [`ChiselErrorData::EndOfInput`] if the end of the input is encountered
169 * before the buffer is completely filled.
170 *
171 * If an error is returned, the contents of `buf` are unspecified and the chisel [breaks][crate#breaking].
172 */
173 #[inline]
174 pub fn read_buf(&mut self, buf: &mut [u8]) -> InfallibleFormatResult<(), S> { self.0.read_buf(buf) }
175
176 /**
177 * Reads a single byte [`u8`].
178 *
179 * This operation is endian-independent.
180 */
181 #[inline]
182 pub fn u8(&mut self) -> InfallibleFormatResult<u8, S> { self.0.u8() }
183 ty_fn_endian!(u16, Big, big);
184 ty_fn_endian!(u32, Big, big);
185 ty_fn_endian!(u64, Big, big);
186
187 /**
188 * Reads a single _signed_ byte [`i8`].
189 *
190 * This operation is endian-independent.
191 */
192 #[inline]
193 pub fn i8(&mut self) -> InfallibleFormatResult<i8, S> { self.0.i8() }
194 ty_fn_endian!(i16, Big, big);
195 ty_fn_endian!(i32, Big, big);
196 ty_fn_endian!(i64, Big, big);
197
198 ty_fn_endian!(f32, Big, big);
199 ty_fn_endian!(f64, Big, big);
200
201 /**
202 * Skips `how_many` bytes of the underlying source.
203 *
204 * This operation is endian-independent.
205 *
206 * This is provided for optimization reasons. This hint is forwarded to the source.
207 *
208 * Exactly `how_many` bytes are skipped, as-if [`read_buf`][Self::read_buf] were called with a buffer
209 * of appropriate size, with the buffer being discarded.
210 *
211 * ## Errors
212 *
213 * If an end-of-input condition occurs before `how_many` bytes are skipped, an [`ChiselErrorData::EndOfInput`] error is returned.
214 *
215 * If an error is returned, the chisel [breaks][crate#breaking].
216 */
217 #[inline]
218 pub fn skip(&mut self, how_many: usize) -> InfallibleFormatResult<(), S> { self.0.skip(how_many) }
219
220 #[cfg(feature = "alloc")]
221 /**
222 * Reads bytes into the provided `dest` Vec until the `delimiter` byte is encountered.
223 *
224 * This operation is endian-independent.
225 *
226 * ## Errors
227 * If the end of the input is encountered before the delimiter is found, [`ChiselErrorData::EndOfInput`] is returned.
228 *
229 * If an error is returned, the chisel [breaks][crate#breaking].
230 */
231 #[inline]
232 pub fn read_until(&mut self, byte: u8, dest: &mut Vec<u8>) -> InfallibleFormatResult<(), S> { self.0.read_until(byte, dest) }
233
234 #[cfg(feature = "alloc")]
235 /**
236 * Reads bytes into the provided `dest` Vec until the `delimiter` byte or end-of-input is encountered.
237 *
238 * This operation is endian-independent.
239 * ## Errors
240 * If an error is returned, the chisel [breaks][crate#breaking].
241 */
242 #[inline]
243 pub fn read_until_or_end(&mut self, byte: u8, dest: &mut Vec<u8>) -> InfallibleFormatResult<ReadUntilStopReason, S> { self.0.read_until_or_end(byte, dest) }
244}