1use std::mem;
2use std::str;
3use std::io::{Read, Write, Error, ErrorKind};
4use std::ffi::{CString, CStr};
5use core::hardware_address::HardwareAddress;
6use ::errors::Result;
7
8use byteorder::{ByteOrder, NativeEndian, ReadBytesExt, WriteBytesExt};
9
10pub trait NativeRead: Sized {
11 fn read<R: Read>(reader: &mut R) -> Result<Self>;
12}
13
14pub trait NativeWrite: Sized {
15 fn write<W: Write>(&self, writer: &mut W) -> Result<()>;
16}
17
18pub trait NativeParse: Sized {
19 fn parse(buffer: &[u8]) -> Result<Self>;
20}
21
22pub trait MultiValue: Sized {
23 fn read<R: Read>(reader: &mut R, size: usize) -> Result<Self>;
24 fn write<W: Write>(&self, writer: &mut W) -> Result<()>;
25 fn size(&self) -> usize;
26}
27
28impl NativeRead for u8 {
29 fn read<R: Read>(reader: &mut R) -> Result<Self> {
30 Ok(reader.read_u8()?)
31 }
32}
33impl NativeWrite for u8 {
34 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
35 writer.write_u8(*self)?;
36 Ok(())
37 }
38}
39impl NativeParse for u8 {
40 fn parse(buffer: &[u8]) -> Result<Self> {
41 if buffer.len() < mem::size_of::<u8>() {
42 return Err(Error::new(ErrorKind::InvalidData, "").into());
43 }
44 Ok(buffer[0])
45 }
46}
47
48impl NativeRead for u16 {
49 fn read<R: Read>(reader: &mut R) -> Result<Self> {
50 Ok(reader.read_u16::<NativeEndian>()?)
51 }
52}
53impl NativeWrite for u16 {
54 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
55 writer.write_u16::<NativeEndian>(*self)?;
56 Ok(())
57 }
58}
59impl NativeParse for u16 {
60 fn parse(buffer: &[u8]) -> Result<Self> {
61 if buffer.len() < mem::size_of::<Self>() {
62 return Err(Error::new(ErrorKind::InvalidData, "").into());
63 }
64 Ok(NativeEndian::read_u16(buffer))
65 }
66}
67
68impl NativeRead for u32 {
69 fn read<R: Read>(reader: &mut R) -> Result<Self> {
70 Ok(reader.read_u32::<NativeEndian>()?)
71 }
72}
73impl NativeWrite for u32 {
74 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
75 writer.write_u32::<NativeEndian>(*self)?;
76 Ok(())
77 }
78}
79impl NativeParse for u32 {
80 fn parse(buffer: &[u8]) -> Result<Self> {
81 if buffer.len() < mem::size_of::<Self>() {
82 return Err(Error::new(ErrorKind::InvalidData, "").into());
83 }
84 Ok(NativeEndian::read_u32(buffer))
85 }
86}
87
88impl NativeRead for u64 {
89 fn read<R: Read>(reader: &mut R) -> Result<Self> {
90 Ok(reader.read_u64::<NativeEndian>()?)
91 }
92}
93impl NativeWrite for u64 {
94 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
95 writer.write_u64::<NativeEndian>(*self)?;
96 Ok(())
97 }
98}
99impl NativeParse for u64 {
100 fn parse(buffer: &[u8]) -> Result<Self> {
101 if buffer.len() < mem::size_of::<Self>() {
102 return Err(Error::new(ErrorKind::InvalidData, "").into());
103 }
104 Ok(NativeEndian::read_u64(buffer))
105 }
106}
107
108impl NativeRead for i8 {
109 fn read<R: Read>(reader: &mut R) -> Result<Self> {
110 Ok(reader.read_i8()?)
111 }
112}
113impl NativeWrite for i8 {
114 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
115 writer.write_i8(*self)?;
116 Ok(())
117 }
118}
119impl NativeParse for i8 {
120 fn parse(buffer: &[u8]) -> Result<Self> {
121 if buffer.len() < mem::size_of::<Self>() {
122 return Err(Error::new(ErrorKind::InvalidData, "").into());
123 }
124 Ok(buffer[0] as i8)
125 }
126}
127
128impl NativeRead for i16 {
129 fn read<R: Read>(reader: &mut R) -> Result<Self> {
130 Ok(reader.read_i16::<NativeEndian>()?)
131 }
132}
133impl NativeWrite for i16 {
134 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
135 writer.write_i16::<NativeEndian>(*self)?;
136 Ok(())
137 }
138}
139impl NativeParse for i16 {
140 fn parse(buffer: &[u8]) -> Result<Self> {
141 if buffer.len() < mem::size_of::<Self>() {
142 return Err(Error::new(ErrorKind::InvalidData, "").into());
143 }
144 Ok(NativeEndian::read_i16(buffer))
145 }
146}
147
148impl NativeRead for i32 {
149 fn read<R: Read>(reader: &mut R) -> Result<Self> {
150 Ok(reader.read_i32::<NativeEndian>()?)
151 }
152}
153impl NativeWrite for i32 {
154 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
155 writer.write_i32::<NativeEndian>(*self)?;
156 Ok(())
157 }
158}
159impl NativeParse for i32 {
160 fn parse(buffer: &[u8]) -> Result<Self> {
161 if buffer.len() < mem::size_of::<Self>() {
162 return Err(Error::new(ErrorKind::InvalidData, "").into());
163 }
164 Ok(NativeEndian::read_i32(buffer))
165 }
166}
167
168impl NativeRead for i64 {
169 fn read<R: Read>(reader: &mut R) -> Result<Self> {
170 Ok(reader.read_i64::<NativeEndian>()?)
171 }
172}
173impl NativeWrite for i64 {
174 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
175 writer.write_i64::<NativeEndian>(*self)?;
176 Ok(())
177 }
178}
179impl NativeParse for i64 {
180 fn parse(buffer: &[u8]) -> Result<Self> {
181 if buffer.len() < mem::size_of::<Self>() {
182 return Err(Error::new(ErrorKind::InvalidData, "").into());
183 }
184 Ok(NativeEndian::read_i64(buffer))
185 }
186}
187
188impl NativeRead for f32 {
189 fn read<R: Read>(reader: &mut R) -> Result<Self> {
190 Ok(reader.read_f32::<NativeEndian>()?)
191 }
192}
193impl NativeWrite for f32 {
194 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
195 writer.write_f32::<NativeEndian>(*self)?;
196 Ok(())
197 }
198}
199impl NativeParse for f32 {
200 fn parse(buffer: &[u8]) -> Result<Self> {
201 if buffer.len() < mem::size_of::<Self>() {
202 return Err(Error::new(ErrorKind::InvalidData, "").into());
203 }
204 Ok(NativeEndian::read_f32(buffer))
205 }
206}
207
208impl NativeRead for f64 {
209 fn read<R: Read>(reader: &mut R) -> Result<Self> {
210 Ok(reader.read_f64::<NativeEndian>()?)
211 }
212}
213impl NativeWrite for f64 {
214 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
215 writer.write_f64::<NativeEndian>(*self)?;
216 Ok(())
217 }
218}
219impl NativeParse for f64 {
220 fn parse(buffer: &[u8]) -> Result<Self> {
221 if buffer.len() < mem::size_of::<Self>() {
222 return Err(Error::new(ErrorKind::InvalidData, "").into());
223 }
224 Ok(NativeEndian::read_f64(buffer))
225 }
226}
227
228impl NativeRead for HardwareAddress {
229 fn read<R: Read>(reader: &mut R) -> Result<Self> {
230 let mut data = vec![0u8; 6];
231 reader.read_exact(&mut data)?;
232 Ok(HardwareAddress::from(data.as_slice()))
233 }
234}
235impl NativeWrite for HardwareAddress {
236 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
237 writer.write(&self.bytes())?;
238 Ok(())
239 }
240}
241impl NativeParse for HardwareAddress {
242 fn parse(buffer: &[u8]) -> Result<Self> {
243 if buffer.len() < mem::size_of::<Self>() {
244 return Err(Error::new(ErrorKind::InvalidData, "").into());
245 }
246 Ok(HardwareAddress::from(&buffer[0..6]))
247 }
248}
249
250impl MultiValue for String {
251 fn read<R: Read>(reader: &mut R, size: usize) -> Result<Self> {
252 let mut data = vec![0u8; size];
253 reader.read_exact(&mut data)?;
254 match CStr::from_bytes_with_nul(&data) {
255 Ok(bytes) => {
256 let s = bytes.to_str()?;
257 Ok(String::from(s))
258 },
259 Err(_) => {
260 let s = str::from_utf8(&data)?;
261 Ok(String::from(s))
262 }
263 }
264 }
265
266 fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
267 let c_string = CString::new((*self).clone())?;
268 let bytes = c_string.into_bytes_with_nul();
269 writer.write(&bytes)?;
270 Ok(())
271 }
272
273 fn size(&self) -> usize {
274 self.len() + 1
275 }
276}
277
278
279#[cfg(test)]
280mod tests {
281 use std::io;
282 use super::*;
283 use std::fmt;
284 use std::cmp;
285
286 fn read_write_test<T: NativeRead + NativeWrite + NativeParse + fmt::Debug + cmp::PartialEq>(bytes: &[u8], value: T) {
287 let value_size = mem::size_of::<T>();
288 assert_eq!(bytes.len(), mem::size_of::<T>());
289 let mut reader = io::Cursor::new(bytes);
290 assert_eq!(T::read(&mut reader).unwrap(), value);
291 let mut writer = io::Cursor::new(vec![0u8; value_size]);
292 value.write(&mut writer).unwrap();
293 assert_eq!(writer.into_inner(), Vec::from(bytes));
294 assert_eq!(T::parse(bytes).unwrap(), value);
295 }
296
297 #[test]
298 fn read_write_u8() {
299 read_write_test(&[0x5a], 0x5au8);
300 }
301
302 #[test]
303 fn read_write_i8() {
304 read_write_test(&[0xa5], -91i8);
305 }
306
307 #[test]
308 fn read_write_u16() {
309 read_write_test(&[0x22, 0xaa], 0xaa22u16.to_le());
310 }
311
312 #[test]
313 fn read_write_u32() {
314 read_write_test(&[0x44, 0x33, 0x22, 0x11], 0x11223344u32.to_le());
315 }
316
317 #[test]
318 fn read_write_u64() {
319 read_write_test(&[0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11],
320 0x1122334455667788u64.to_le());
321 }
322
323 #[test]
324 fn read_write_i16() {
325 read_write_test(&[0x55, 0xaa], (-21931i16).to_le());
326 }
327
328 #[test]
329 fn read_write_i32() {
330 read_write_test(&[0x11, 0x22, 0x33, 0xa4], (-1540152815i32).to_le());
331 }
332
333 #[test]
334 fn read_write_i64() {
335 read_write_test(&[0x11, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x88],
336 (-8637284766759618799i64).to_le());
337 }
338
339 #[test]
340 fn read_write_hardware_address() {
341 let bytes = vec![0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff];
342 let hwa = HardwareAddress::from(bytes.as_slice());
343 read_write_test(bytes.as_slice(), hwa);
344 }
345
346 #[test]
347 fn read_string() {
348 let bytes = vec![0xf0, 0x9f, 0x9b, 0xa0];
349 let mut reader = io::Cursor::new(bytes);
350 assert_eq!(String::read(&mut reader, 4).unwrap(), String::from("🛠"));
351
352 let bytes = vec![0xf0, 0x9f, 0x9b, 0xa0, 0x00];
353 let mut reader = io::Cursor::new(bytes);
354 assert_eq!(String::read(&mut reader, 5).unwrap(), String::from("🛠"));
355
356 let bytes = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x00];
357 let mut reader = io::Cursor::new(bytes);
358 assert_eq!(String::read(&mut reader, 6).unwrap(),
359 String::from("Hello"));
360
361 let bytes = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f];
362 let mut reader = io::Cursor::new(bytes);
363 assert_eq!(String::read(&mut reader, 5).unwrap(),
364 String::from("Hello"));
365
366 let bytes = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f,
368 0x00, 0x00, 0x00, 0x00, 0x00];
369 let mut reader = io::Cursor::new(bytes);
370 assert_eq!(String::read(&mut reader, 10).unwrap(),
371 String::from("Hello\0\0\0\0\0"));
372 }
373
374 #[test]
375 fn write_string() {
376 let string = String::from("🛠");
377 let mut writer = io::Cursor::new(vec![0u8; 4]);
378 string.write(&mut writer).unwrap();
379 assert_eq!(writer.into_inner(), vec![0xf0, 0x9f, 0x9b, 0xa0, 0x00]);
380
381 let string = String::from("Hello");
382 let mut writer = io::Cursor::new(vec![0u8; 5]);
383 string.write(&mut writer).unwrap();
384 assert_eq!(writer.into_inner(), vec![0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x00]);
385 }
386}
387
388#[cfg(all(test, target_endian = "little"))]
389mod tests_le {
390 use std::io;
392 use super::*;
393
394 #[test]
395 fn read_f32() {
396 let bytes = vec![82, 15, 73, 192];
397 let mut reader = io::Cursor::new(bytes);
398 assert_eq!(f32::read(&mut reader).unwrap(), -3.14156);
399 }
400
401 #[test]
402 fn read_f64() {
403 let bytes = vec![105, 87, 20, 139, 10, 191, 5, 192];
404 let mut reader = io::Cursor::new(bytes);
405 assert_eq!(f64::read(&mut reader).unwrap(), -2.718281828459045);
406 }
407
408 #[test]
409 fn write_f32() {
410 let mut writer = io::Cursor::new(vec![0u8; 4]);
411 (-3.14156f32).write(&mut writer).unwrap();
412 assert_eq!(writer.into_inner(), vec![82, 15, 73, 192]);
413 }
414
415 #[test]
416 fn write_f64() {
417 let mut writer = io::Cursor::new(vec![0u8; 8]);
418 (-2.718281828459045f64).write(&mut writer).unwrap();
419 assert_eq!(writer.into_inner(), vec![105, 87, 20, 139, 10, 191, 5, 192]);
420 }
421}