1#![no_std]
7#![deny(rustdoc::broken_intra_doc_links)]
9#![deny(missing_docs)]
10#![deny(unsafe_code)]
11
12#[cfg_attr(test, macro_use)]
13extern crate alloc;
14
15use alloc::vec::Vec;
16
17use core::iter::FromIterator;
18use core2::io::{self, Read, Write};
19
20use nonempty::NonEmpty;
21
22pub const MAX_COMPACT_SIZE: u32 = 0x02000000;
24
25pub struct CompactSize;
30
31impl CompactSize {
32 pub fn read<R: Read>(mut reader: R) -> io::Result<u64> {
34 let mut flag_bytes = [0; 1];
35 reader.read_exact(&mut flag_bytes)?;
36 let flag = flag_bytes[0];
37
38 let result = if flag < 253 {
39 Ok(flag as u64)
40 } else if flag == 253 {
41 let mut bytes = [0; 2];
42 reader.read_exact(&mut bytes)?;
43 match u16::from_le_bytes(bytes) {
44 n if n < 253 => Err(io::Error::new(
45 io::ErrorKind::InvalidInput,
46 "non-canonical CompactSize",
47 )),
48 n => Ok(n as u64),
49 }
50 } else if flag == 254 {
51 let mut bytes = [0; 4];
52 reader.read_exact(&mut bytes)?;
53 match u32::from_le_bytes(bytes) {
54 n if n < 0x10000 => Err(io::Error::new(
55 io::ErrorKind::InvalidInput,
56 "non-canonical CompactSize",
57 )),
58 n => Ok(n as u64),
59 }
60 } else {
61 let mut bytes = [0; 8];
62 reader.read_exact(&mut bytes)?;
63 match u64::from_le_bytes(bytes) {
64 n if n < 0x100000000 => Err(io::Error::new(
65 io::ErrorKind::InvalidInput,
66 "non-canonical CompactSize",
67 )),
68 n => Ok(n),
69 }
70 }?;
71
72 match result {
73 s if s > <u64>::from(MAX_COMPACT_SIZE) => Err(io::Error::new(
74 io::ErrorKind::InvalidInput,
75 "CompactSize too large",
76 )),
77 s => Ok(s),
78 }
79 }
80
81 pub fn read_t<R: Read, T: TryFrom<u64>>(mut reader: R) -> io::Result<T> {
84 let n = Self::read(&mut reader)?;
85 <T>::try_from(n).map_err(|_| {
86 io::Error::new(
87 io::ErrorKind::InvalidInput,
88 "CompactSize value exceeds range of target type.",
89 )
90 })
91 }
92
93 pub fn write<W: Write>(mut writer: W, size: usize) -> io::Result<()> {
95 match size {
96 s if s < 253 => writer.write_all(&[s as u8]),
97 s if s <= 0xFFFF => {
98 writer.write_all(&[253])?;
99 writer.write_all(&(s as u16).to_le_bytes())
100 }
101 s if s <= 0xFFFFFFFF => {
102 writer.write_all(&[254])?;
103 writer.write_all(&(s as u32).to_le_bytes())
104 }
105 s => {
106 writer.write_all(&[255])?;
107 writer.write_all(&(s as u64).to_le_bytes())
108 }
109 }
110 }
111
112 pub fn serialized_size(size: usize) -> usize {
114 match size {
115 s if s < 253 => 1,
116 s if s <= 0xFFFF => 3,
117 s if s <= 0xFFFFFFFF => 5,
118 _ => 9,
119 }
120 }
121}
122
123pub struct Vector;
128
129impl Vector {
130 pub fn read<R: Read, E, F>(reader: R, func: F) -> io::Result<Vec<E>>
133 where
134 F: Fn(&mut R) -> io::Result<E>,
135 {
136 Self::read_collected(reader, func)
137 }
138
139 pub fn read_collected<R: Read, E, F, O: FromIterator<E>>(reader: R, func: F) -> io::Result<O>
142 where
143 F: Fn(&mut R) -> io::Result<E>,
144 {
145 Self::read_collected_mut(reader, func)
146 }
147
148 pub fn read_collected_mut<R: Read, E, F, O: FromIterator<E>>(
151 mut reader: R,
152 func: F,
153 ) -> io::Result<O>
154 where
155 F: FnMut(&mut R) -> io::Result<E>,
156 {
157 let count: usize = CompactSize::read_t(&mut reader)?;
158 Array::read_collected_mut(reader, count, func)
159 }
160
161 pub fn write<W: Write, E, F>(writer: W, vec: &[E], func: F) -> io::Result<()>
165 where
166 F: Fn(&mut W, &E) -> io::Result<()>,
167 {
168 Self::write_sized(writer, vec.iter(), func)
169 }
170
171 pub fn write_nonempty<W: Write, E, F>(
174 mut writer: W,
175 vec: &NonEmpty<E>,
176 func: F,
177 ) -> io::Result<()>
178 where
179 F: Fn(&mut W, &E) -> io::Result<()>,
180 {
181 CompactSize::write(&mut writer, vec.len())?;
182 vec.iter().try_for_each(|e| func(&mut writer, e))
183 }
184
185 pub fn write_sized<W: Write, E, F, I: Iterator<Item = E> + ExactSizeIterator>(
189 mut writer: W,
190 mut items: I,
191 func: F,
192 ) -> io::Result<()>
193 where
194 F: Fn(&mut W, E) -> io::Result<()>,
195 {
196 CompactSize::write(&mut writer, items.len())?;
197 items.try_for_each(|e| func(&mut writer, e))
198 }
199
200 pub fn serialized_size_of_u8_vec(vec: &[u8]) -> usize {
202 let length = vec.len();
203 CompactSize::serialized_size(length) + length
204 }
205}
206
207pub struct Array;
213
214impl Array {
215 pub fn read<R: Read, E, F>(reader: R, count: usize, func: F) -> io::Result<Vec<E>>
218 where
219 F: Fn(&mut R) -> io::Result<E>,
220 {
221 Self::read_collected(reader, count, func)
222 }
223
224 pub fn read_collected<R: Read, E, F, O: FromIterator<E>>(
227 reader: R,
228 count: usize,
229 func: F,
230 ) -> io::Result<O>
231 where
232 F: Fn(&mut R) -> io::Result<E>,
233 {
234 Self::read_collected_mut(reader, count, func)
235 }
236
237 pub fn read_collected_mut<R: Read, E, F, O: FromIterator<E>>(
240 mut reader: R,
241 count: usize,
242 mut func: F,
243 ) -> io::Result<O>
244 where
245 F: FnMut(&mut R) -> io::Result<E>,
246 {
247 (0..count).map(|_| func(&mut reader)).collect()
248 }
249
250 pub fn write<W: Write, E, I: IntoIterator<Item = E>, F>(
253 mut writer: W,
254 vec: I,
255 func: F,
256 ) -> io::Result<()>
257 where
258 F: Fn(&mut W, &E) -> io::Result<()>,
259 {
260 vec.into_iter().try_for_each(|e| func(&mut writer, &e))
261 }
262}
263
264pub struct Optional;
266
267impl Optional {
268 pub fn read<R: Read, T, F>(mut reader: R, func: F) -> io::Result<Option<T>>
271 where
272 F: Fn(R) -> io::Result<T>,
273 {
274 let mut bytes = [0; 1];
275 reader.read_exact(&mut bytes)?;
276 match bytes[0] {
277 0 => Ok(None),
278 1 => Ok(Some(func(reader)?)),
279 _ => Err(io::Error::new(
280 io::ErrorKind::InvalidInput,
281 "non-canonical Option<T>",
282 )),
283 }
284 }
285
286 pub fn write<W: Write, T, F>(mut writer: W, val: Option<T>, func: F) -> io::Result<()>
290 where
291 F: Fn(W, T) -> io::Result<()>,
292 {
293 match val {
294 None => writer.write_all(&[0]),
295 Some(e) => {
296 writer.write_all(&[1])?;
297 func(writer, e)
298 }
299 }
300 }
301}
302
303#[cfg(test)]
304mod tests {
305 use super::*;
306 use core::fmt::Debug;
307
308 #[test]
309 fn compact_size() {
310 fn eval<T: TryFrom<u64> + TryInto<usize> + Eq + Debug + Copy>(value: T, expected: &[u8])
311 where
312 <T as TryInto<usize>>::Error: Debug,
313 {
314 let mut data = vec![];
315 let value_usize: usize = value.try_into().unwrap();
316 CompactSize::write(&mut data, value_usize).unwrap();
317 assert_eq!(&data[..], expected);
318 let serialized_size = CompactSize::serialized_size(value_usize);
319 assert_eq!(serialized_size, expected.len());
320 let result: io::Result<T> = CompactSize::read_t(&data[..]);
321 match result {
322 Ok(n) => assert_eq!(n, value),
323 Err(e) => panic!("Unexpected error: {:?}", e),
324 }
325 }
326
327 eval(0, &[0]);
328 eval(1, &[1]);
329 eval(252, &[252]);
330 eval(253, &[253, 253, 0]);
331 eval(254, &[253, 254, 0]);
332 eval(255, &[253, 255, 0]);
333 eval(256, &[253, 0, 1]);
334 eval(256, &[253, 0, 1]);
335 eval(65535, &[253, 255, 255]);
336 eval(65536, &[254, 0, 0, 1, 0]);
337 eval(65537, &[254, 1, 0, 1, 0]);
338
339 eval(33554432, &[254, 0, 0, 0, 2]);
340
341 {
342 let value = 33554433;
343 let encoded = &[254, 1, 0, 0, 2][..];
344 let mut data = vec![];
345 CompactSize::write(&mut data, value).unwrap();
346 assert_eq!(&data[..], encoded);
347 let serialized_size = CompactSize::serialized_size(value);
348 assert_eq!(serialized_size, encoded.len());
349 assert!(CompactSize::read(encoded).is_err());
350 }
351 }
352
353 #[allow(clippy::useless_vec)]
354 #[test]
355 fn vector() {
356 macro_rules! eval {
357 ($value:expr, $expected:expr) => {
358 let mut data = vec![];
359 Vector::write(&mut data, &$value, |w, e| w.write_all(&[*e])).unwrap();
360 assert_eq!(&data[..], &$expected[..]);
361 let serialized_size = Vector::serialized_size_of_u8_vec(&$value);
362 assert_eq!(serialized_size, $expected.len());
363 match Vector::read(&data[..], |r| {
364 let mut bytes = [0; 1];
365 r.read_exact(&mut bytes).map(|_| bytes[0])
366 }) {
367 Ok(v) => assert_eq!(v, $value),
368 Err(e) => panic!("Unexpected error: {:?}", e),
369 }
370 };
371 }
372
373 eval!(vec![], [0]);
374 eval!(vec![0], [1, 0]);
375 eval!(vec![1], [1, 1]);
376 eval!(vec![5; 8], [8, 5, 5, 5, 5, 5, 5, 5, 5]);
377
378 {
379 let mut expected = vec![7; 263];
381 expected[0] = 253;
382 expected[1] = 4;
383 expected[2] = 1;
384
385 eval!(vec![7; 260], expected);
386 }
387 }
388
389 #[test]
390 fn optional() {
391 macro_rules! eval {
392 ($value:expr, $expected:expr, $write:expr, $read:expr) => {
393 let mut data = vec![];
394 Optional::write(&mut data, $value, $write).unwrap();
395 assert_eq!(&data[..], &$expected[..]);
396 match Optional::read(&data[..], $read) {
397 Ok(v) => assert_eq!(v, $value),
398 Err(e) => panic!("Unexpected error: {:?}", e),
399 }
400 };
401 }
402
403 macro_rules! eval_u8 {
404 ($value:expr, $expected:expr) => {
405 eval!($value, $expected, |w, e| w.write_all(&[e]), |mut r| {
406 let mut bytes = [0; 1];
407 r.read_exact(&mut bytes).map(|_| bytes[0])
408 })
409 };
410 }
411
412 macro_rules! eval_vec {
413 ($value:expr, $expected:expr) => {
414 eval!(
415 $value,
416 $expected,
417 |w, v| Vector::write(w, &v, |w, e| w.write_all(&[*e])),
418 |r| Vector::read(r, |r| {
419 let mut bytes = [0; 1];
420 r.read_exact(&mut bytes).map(|_| bytes[0])
421 })
422 )
423 };
424 }
425
426 eval_u8!(None, [0]);
427 eval_u8!(Some(0), [1, 0]);
428 eval_u8!(Some(1), [1, 1]);
429 eval_u8!(Some(5), [1, 5]);
430
431 eval_vec!(None as Option<Vec<_>>, [0]);
432 eval_vec!(Some(vec![]), [1, 0]);
433 eval_vec!(Some(vec![0]), [1, 1, 0]);
434 eval_vec!(Some(vec![1]), [1, 1, 1]);
435 eval_vec!(Some(vec![5; 8]), [1, 8, 5, 5, 5, 5, 5, 5, 5, 5]);
436 }
437}