pw_stream/integer.rs
1// Copyright 2023 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15use pw_status::Result;
16
17/// A trait for reading integers from a stream.
18///
19/// Allows reading signed and unsigned integers from 8 to 128 bits in
20/// either big or little endian byte order.
21///
22/// # Example
23///
24/// ```
25/// use pw_stream::{Cursor, ReadInteger};
26///
27/// let mut cursor = Cursor::new([0x3, 0x4, 0x5, 0x80]);
28/// let value = cursor.read_u32_le().unwrap();
29/// assert_eq!(value, 0x8005_0403);
30/// ```
31///
32/// # Future Work
33///
34/// In order to allow for optimized non-generic implementations, there is
35/// no blanket implementation over the [`crate::Read`] trait. An `IntegerReader`
36/// adapter could be written to allow this functionality.
37pub trait ReadInteger {
38 /// Reads a little-endian i8 returning it's value or an Error.
39 ///
40 /// Errors that may be returned are dependant on the underlying
41 /// implementation.
42 fn read_i8_le(&mut self) -> Result<i8>;
43
44 /// Reads a little-endian u8 returning it's value or an Error.
45 ///
46 /// Errors that may be returned are dependant on the underlying
47 /// implementation.
48 fn read_u8_le(&mut self) -> Result<u8>;
49
50 /// Reads a big-endian i8 returning it's value or an Error.
51 ///
52 /// Errors that may be returned are dependant on the underlying
53 /// implementation.
54 fn read_i8_be(&mut self) -> Result<i8>;
55
56 /// Reads a big-endian u8 returning it's value or an Error.
57 ///
58 /// Errors that may be returned are dependant on the underlying
59 /// implementation.
60 fn read_u8_be(&mut self) -> Result<u8>;
61
62 /// Reads a little-endian i16 returning it's value or an Error.
63 ///
64 /// Errors that may be returned are dependant on the underlying
65 /// implementation.
66 fn read_i16_le(&mut self) -> Result<i16>;
67
68 /// Reads a little-endian u16 returning it's value or an Error.
69 ///
70 /// Errors that may be returned are dependant on the underlying
71 /// implementation.
72 ///
73 fn read_u16_le(&mut self) -> Result<u16>;
74
75 /// Reads a big-endian i16 returning it's value or an Error.
76 ///
77 /// Errors that may be returned are dependant on the underlying
78 /// implementation.
79 fn read_i16_be(&mut self) -> Result<i16>;
80
81 /// Reads a big-endian u16 returning it's value or an Error.
82 ///
83 /// Errors that may be returned are dependant on the underlying
84 /// implementation.
85 ///
86 fn read_u16_be(&mut self) -> Result<u16>;
87
88 /// Reads a little-endian i32 returning it's value or an Error.
89 ///
90 /// Errors that may be returned are dependant on the underlying
91 /// implementation.
92 fn read_i32_le(&mut self) -> Result<i32>;
93
94 /// Reads a little-endian u32 returning it's value or an Error.
95 ///
96 /// Errors that may be returned are dependant on the underlying
97 /// implementation.
98 fn read_u32_le(&mut self) -> Result<u32>;
99
100 /// Reads a big-endian i32 returning it's value or an Error.
101 ///
102 /// Errors that may be returned are dependant on the underlying
103 /// implementation.
104 fn read_i32_be(&mut self) -> Result<i32>;
105
106 /// Reads a big-endian u32 returning it's value or an Error.
107 ///
108 /// Errors that may be returned are dependant on the underlying
109 /// implementation.
110 fn read_u32_be(&mut self) -> Result<u32>;
111
112 /// Reads a little-endian i64 returning it's value or an Error.
113 ///
114 /// Errors that may be returned are dependant on the underlying
115 /// implementation.
116 fn read_i64_le(&mut self) -> Result<i64>;
117
118 /// Reads a little-endian u64 returning it's value or an Error.
119 ///
120 /// Errors that may be returned are dependant on the underlying
121 /// implementation.
122 fn read_u64_le(&mut self) -> Result<u64>;
123
124 /// Reads a big-endian i64 returning it's value or an Error.
125 ///
126 /// Errors that may be returned are dependant on the underlying
127 /// implementation.
128 fn read_i64_be(&mut self) -> Result<i64>;
129
130 /// Reads a big-endian u64 returning it's value or an Error.
131 ///
132 /// Errors that may be returned are dependant on the underlying
133 /// implementation.
134 fn read_u64_be(&mut self) -> Result<u64>;
135
136 /// Reads a little-endian i128 returning it's value or an Error.
137 ///
138 /// Errors that may be returned are dependant on the underlying
139 /// implementation.
140 fn read_i128_le(&mut self) -> Result<i128>;
141
142 /// Reads a little-endian u128 returning it's value or an Error.
143 ///
144 /// Errors that may be returned are dependant on the underlying
145 /// implementation.
146 fn read_u128_le(&mut self) -> Result<u128>;
147
148 /// Reads a big-endian i128 returning it's value or an Error.
149 ///
150 /// Errors that may be returned are dependant on the underlying
151 /// implementation.
152 fn read_i128_be(&mut self) -> Result<i128>;
153
154 /// Reads a big-endian u128 returning it's value or an Error.
155 ///
156 /// Errors that may be returned are dependant on the underlying
157 /// implementation.
158 fn read_u128_be(&mut self) -> Result<u128>;
159}
160
161/// A trait for writing integers toa stream.
162///
163/// Allows writing signed and unsigned integers from 8 to 128 bits in
164/// either big or little endian byte order.
165///
166/// # Example
167///
168/// ```
169/// use pw_stream::{Cursor, WriteInteger};
170///
171/// let mut cursor = Cursor::new([0u8; 8]);
172/// cursor.write_u32_le(&0x8005_0403).unwrap();
173/// let buffer = cursor.into_inner();
174/// assert_eq!(buffer, [0x3, 0x4, 0x5, 0x80, 0x0, 0x0, 0x0, 0x0]);
175/// ```
176///
177/// # Future Work
178///
179/// In order to allow for optimized non-generic implementations, there is
180/// no blanket implementation over the [`crate::Write`] trait. An `IntegerWriter`
181/// adapter could be written to allow this functionality.
182pub trait WriteInteger {
183 /// Writes a little-endian i8.
184 ///
185 /// Errors that may be returned are dependant on the underlying
186 /// implementation.
187 fn write_i8_le(&mut self, value: &i8) -> Result<()>;
188
189 /// Writes a little-endian u8.
190 ///
191 /// Errors that may be returned are dependant on the underlying
192 /// implementation.
193 fn write_u8_le(&mut self, value: &u8) -> Result<()>;
194
195 /// Writes a big-endian i8.
196 ///
197 /// Errors that may be returned are dependant on the underlying
198 /// implementation.
199 fn write_i8_be(&mut self, value: &i8) -> Result<()>;
200
201 /// Writes a big-endian u8.
202 ///
203 /// Errors that may be returned are dependant on the underlying
204 /// implementation.
205 fn write_u8_be(&mut self, value: &u8) -> Result<()>;
206
207 /// Writes a little-endian i16.
208 ///
209 /// Errors that may be returned are dependant on the underlying
210 /// implementation.
211 fn write_i16_le(&mut self, value: &i16) -> Result<()>;
212
213 /// Writes a little-endian u16.
214 ///
215 /// Errors that may be returned are dependant on the underlying
216 /// implementation.
217 fn write_u16_le(&mut self, value: &u16) -> Result<()>;
218
219 /// Writes a big-endian i16.
220 ///
221 /// Errors that may be returned are dependant on the underlying
222 /// implementation.
223 fn write_i16_be(&mut self, value: &i16) -> Result<()>;
224
225 /// Writes a big-endian u16.
226 ///
227 /// Errors that may be returned are dependant on the underlying
228 /// implementation.
229 fn write_u16_be(&mut self, value: &u16) -> Result<()>;
230
231 /// Writes a little-endian i32.
232 ///
233 /// Errors that may be returned are dependant on the underlying
234 /// implementation.
235 fn write_i32_le(&mut self, value: &i32) -> Result<()>;
236
237 /// Writes a little-endian u32.
238 ///
239 /// Errors that may be returned are dependant on the underlying
240 /// implementation.
241 fn write_u32_le(&mut self, value: &u32) -> Result<()>;
242
243 /// Writes a big-endian i32.
244 ///
245 /// Errors that may be returned are dependant on the underlying
246 /// implementation.
247 fn write_i32_be(&mut self, value: &i32) -> Result<()>;
248
249 /// Writes a big-endian u32.
250 ///
251 /// Errors that may be returned are dependant on the underlying
252 /// implementation.
253 fn write_u32_be(&mut self, value: &u32) -> Result<()>;
254
255 /// Writes a little-endian i64.
256 ///
257 /// Errors that may be returned are dependant on the underlying
258 /// implementation.
259 fn write_i64_le(&mut self, value: &i64) -> Result<()>;
260
261 /// Writes a little-endian u64.
262 ///
263 /// Errors that may be returned are dependant on the underlying
264 /// implementation.
265 fn write_u64_le(&mut self, value: &u64) -> Result<()>;
266
267 /// Writes a big-endian i64.
268 ///
269 /// Errors that may be returned are dependant on the underlying
270 /// implementation.
271 fn write_i64_be(&mut self, value: &i64) -> Result<()>;
272
273 /// Writes a big-endian u64.
274 ///
275 /// Errors that may be returned are dependant on the underlying
276 /// implementation.
277 fn write_u64_be(&mut self, value: &u64) -> Result<()>;
278
279 /// Writes a little-endian i128.
280 ///
281 /// Errors that may be returned are dependant on the underlying
282 /// implementation.
283 fn write_i128_le(&mut self, value: &i128) -> Result<()>;
284
285 /// Writes a little-endian u128.
286 ///
287 /// Errors that may be returned are dependant on the underlying
288 /// implementation.
289 fn write_u128_le(&mut self, value: &u128) -> Result<()>;
290
291 /// Writes a big-endian i128.
292 ///
293 /// Errors that may be returned are dependant on the underlying
294 /// implementation.
295 fn write_i128_be(&mut self, value: &i128) -> Result<()>;
296
297 /// Writes a big-endian u128.
298 ///
299 /// Errors that may be returned are dependant on the underlying
300 /// implementation.
301 fn write_u128_be(&mut self, value: &u128) -> Result<()>;
302}
303
304/// A trait for reading varint integers from a stream.
305///
306/// The API here is explicitly limited to `u64` and `i64` in order to reduce
307/// code size.
308///
309/// # Example
310///
311/// ```
312/// use pw_stream::{Cursor, ReadVarint};
313///
314/// let mut cursor = Cursor::new(vec![0xfe, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f]);
315/// let unsigned_value = cursor.read_varint().unwrap();
316/// let signed_value = cursor.read_signed_varint().unwrap();
317/// assert_eq!(unsigned_value, 0xffff_fffe);
318/// assert_eq!(signed_value, i32::MIN.into());
319/// ```
320pub trait ReadVarint {
321 /// Read an unsigned varint from the stream.
322 ///
323 /// Errors that may be returned are dependant on the underlying
324 /// implementation.
325 fn read_varint(&mut self) -> Result<u64>;
326
327 /// Read a signed varint from the stream.
328 ///
329 /// Errors that may be returned are dependant on the underlying
330 /// implementation.
331 fn read_signed_varint(&mut self) -> Result<i64>;
332}
333
334/// A trait for writing varint integers from a stream.
335///
336/// The API here is explicitly limited to `u64` and `i64` in order to reduce
337/// code size.
338///
339/// # Example
340///
341/// ```
342/// use pw_stream::{Cursor, WriteVarint};
343///
344/// let mut cursor = Cursor::new(vec![0x0; 16]);
345///
346/// cursor.write_varint(0xffff_fffe).unwrap();
347/// cursor.write_signed_varint(i32::MIN.into()).unwrap();
348///
349/// let buffer = cursor.into_inner();
350/// assert_eq!(buffer,vec![
351/// 0xfe, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff,
352/// 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
353/// ```
354pub trait WriteVarint {
355 /// Write an unsigned varint to the stream.
356 ///
357 /// Errors that may be returned are dependant on the underlying
358 /// implementation.
359 fn write_varint(&mut self, value: u64) -> Result<()>;
360
361 /// Write a signed varint to the stream.
362 ///
363 /// Errors that may be returned are dependant on the underlying
364 /// implementation.
365 fn write_signed_varint(&mut self, value: i64) -> Result<()>;
366}