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}