1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use {Parcel, Error, Settings};
use hint;
use std::io::prelude::*;
use num_traits::{FromPrimitive, ToPrimitive};
use byteorder::{ReadBytesExt, WriteBytesExt};
pub trait Integer : Parcel + FromPrimitive + ToPrimitive { }
impl Parcel for bool
{
const TYPE_NAME: &'static str = "bool";
fn read_field(read: &mut dyn Read,
_: &Settings,
_: &mut hint::Hints) -> Result<Self, Error> {
if read.read_u8()? == 0 { Ok(false) } else { Ok(true) }
}
fn write_field(&self, write: &mut dyn Write,
_: &Settings,
_: &mut hint::Hints) -> Result<(), Error> {
write.write_u8(if *self { 1 } else { 0 })?;
Ok(())
}
}
impl Parcel for u8
{
const TYPE_NAME: &'static str = "u8";
fn read_field(read: &mut dyn Read,
_: &Settings,
_: &mut hint::Hints) -> Result<Self, Error> { Ok(read.read_u8()?) }
fn write_field(&self, write: &mut dyn Write,
_: &Settings,
_: &mut hint::Hints)
-> Result<(), Error> { write.write_u8(*self)?; Ok(()) }
}
impl Parcel for i8
{
const TYPE_NAME: &'static str = "i8";
fn read_field(read: &mut dyn Read,
_: &Settings,
_: &mut hint::Hints) -> Result<Self, Error> { Ok(read.read_i8()?) }
fn write_field(&self, write: &mut dyn Write,
_: &Settings,
_: &mut hint::Hints)
-> Result<(), Error> { write.write_i8(*self)?; Ok(()) }
}
macro_rules! impl_parcel_for_numeric {
($ty:ident => [$read_fn:ident : $write_fn:ident]) => {
impl Parcel for $ty {
const TYPE_NAME: &'static str = stringify!($ty);
fn read_field(read: &mut dyn Read,
settings: &Settings,
_: &mut hint::Hints) -> Result<Self, Error> {
Ok(settings.byte_order.$read_fn(read)?)
}
fn write_field(&self, write: &mut dyn Write,
settings: &Settings,
_: &mut hint::Hints) -> Result<(), Error> {
settings.byte_order.$write_fn(*self, write)?; Ok(())
}
}
};
}
impl_parcel_for_numeric!(u16 => [read_u16 : write_u16]);
impl_parcel_for_numeric!(i16 => [read_i16 : write_i16]);
impl_parcel_for_numeric!(u32 => [read_u32 : write_u32]);
impl_parcel_for_numeric!(i32 => [read_i32 : write_i32]);
impl_parcel_for_numeric!(u64 => [read_u64 : write_u64]);
impl_parcel_for_numeric!(i64 => [read_i64 : write_i64]);
impl_parcel_for_numeric!(f32 => [read_f32 : write_f32]);
impl_parcel_for_numeric!(f64 => [read_f64 : write_f64]);
impl Integer for u8 { }
impl Integer for i8 { }
impl Integer for u16 { }
impl Integer for i16 { }
impl Integer for u32 { }
impl Integer for i32 { }
impl Integer for u64 { }
impl Integer for i64 { }