1use crate::Endianness;
2use std::io::{Error, ErrorKind, Read, Result};
3use std::mem;
4
5pub trait ReadEndianness: Sized {
7 fn read_endianness_bytes_with_callback<F, R: Read>(
8 reader: &mut R,
9 callback: F,
10 endianness: Endianness,
11 ) -> Result<Self>
12 where
13 F: Fn(&mut [u8]);
14
15 fn read_be_bytes<R: Read>(reader: &mut R) -> Result<Self> {
17 Self::read_endianness_bytes_with_callback(reader, |_| {}, Endianness::BE)
18 }
19 fn read_le_bytes<R: Read>(reader: &mut R) -> Result<Self> {
21 Self::read_endianness_bytes_with_callback(reader, |_| {}, Endianness::LE)
22 }
23 fn read_ne_bytes<R: Read>(reader: &mut R) -> Result<Self> {
27 Self::read_endianness_bytes_with_callback(reader, |_| {}, Endianness::NE)
28 }
29}
30
31macro_rules! read_endianness_impl {
32 ( $( $t:ty ),* ) => ($(
33 impl ReadEndianness for $t {
34 fn read_endianness_bytes_with_callback<F, R: Read>(reader: &mut R, callback: F, endianness: Endianness) -> Result<Self> where F: Fn(&mut [u8]) {
35 let mut buf = [0; mem::size_of::<$t>()];
36 reader.read_exact(&mut buf)?;
37 callback(&mut buf);
38 Ok(
39 match endianness {
40 Endianness::BE => <$t>::from_be_bytes(buf),
41 Endianness::LE => <$t>::from_le_bytes(buf),
42 Endianness::NE => <$t>::from_ne_bytes(buf),
43 })
44 }
45 }
46 )*)
47}
48
49read_endianness_impl!(f32, f64);
50read_endianness_impl!(isize, i8, i16, i32, i64, i128);
51read_endianness_impl!(usize, u8, u16, u32, u64, u128);
52
53pub trait ReadVariable: Sized {
55 fn read_variable_bytes_with_callback<F, R: Read>(
56 reader: &mut R,
57 callback: F,
58 length: usize,
59 ) -> Result<Self>
60 where
61 F: Fn(&mut [u8]);
62
63 fn read_variable_bytes<R: Read>(reader: &mut R, length: usize) -> Result<Self> {
64 Self::read_variable_bytes_with_callback(reader, |_| {}, length)
65 }
66}
67impl ReadVariable for Vec<u8> {
68 fn read_variable_bytes_with_callback<F, R: Read>(
69 reader: &mut R,
70 callback: F,
71 length: usize,
72 ) -> Result<Vec<u8>>
73 where
74 F: Fn(&mut [u8]),
75 {
76 let mut buf = vec![0; length];
77 reader.read_exact(&mut buf)?;
78 callback(&mut buf);
79 Ok(buf)
80 }
81}
82impl ReadVariable for String {
83 fn read_variable_bytes_with_callback<F, R: Read>(
84 reader: &mut R,
85 callback: F,
86 length: usize,
87 ) -> Result<String>
88 where
89 F: Fn(&mut [u8]),
90 {
91 let vec = Vec::<u8>::read_variable_bytes_with_callback(reader, callback, length)?;
92 let s = String::from_utf8(vec);
93 match s {
94 Ok(s) => Ok(s),
95 Err(e) => Err(Error::new(ErrorKind::InvalidData, e)),
96 }
97 }
98}
99
100pub trait ReadConstant<const LENGTH: usize>: Sized {
102 fn read_constant_bytes_with_callback<F, R: Read>(reader: &mut R, callback: F) -> Result<Self>
103 where
104 F: Fn(&mut [u8]);
105
106 fn read_constant_bytes<R: Read>(reader: &mut R) -> Result<Self> {
107 Self::read_constant_bytes_with_callback(reader, |_| {})
108 }
109}
110impl<const LENGTH: usize> ReadConstant<LENGTH> for [u8; LENGTH] {
111 fn read_constant_bytes_with_callback<F, R: Read>(reader: &mut R, callback: F) -> Result<Self>
112 where
113 F: Fn(&mut [u8]),
114 {
115 let mut buf = [0; LENGTH];
116 reader.read_exact(&mut buf)?;
117 callback(&mut buf);
118 Ok(buf)
119 }
120}
121impl<const LENGTH: usize> ReadConstant<LENGTH> for String {
122 fn read_constant_bytes_with_callback<F, R: Read>(reader: &mut R, callback: F) -> Result<Self>
123 where
124 F: Fn(&mut [u8]),
125 {
126 let bytes = <[u8; LENGTH]>::read_constant_bytes_with_callback(reader, callback)?;
127 let s = String::from_utf8(bytes.to_vec());
128
129 match s {
130 Ok(s) => Ok(s),
131 Err(e) => Err(Error::new(ErrorKind::InvalidData, e)),
132 }
133 }
134}