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
use byteorder::{LittleEndian as LE, ByteOrder};
use crate::{Encode, DecodeOwned, Error};
trait FixedEncDec: Sized {
const N: usize;
fn e(&self, buff: &mut [u8]) -> ();
fn d(buff: &[u8]) -> Self;
}
macro_rules! impl_encdec {
($t:ty, $n:literal, $d:expr, $e:expr) => {
impl DecodeOwned for $t {
type Output = $t;
type Error = Error;
#[inline]
fn decode_owned(buff: &[u8]) -> Result<(Self::Output, usize), Self::Error> {
if buff.len() < $n {
return Err(Error::Length);
}
let v = $d(&buff[..$n]);
Ok((v, $n))
}
}
impl Encode for $t {
type Error = Error;
#[inline]
fn encode_len(&self) -> Result<usize, Self::Error> {
Ok($n)
}
#[inline]
fn encode(&self, buff: &mut [u8]) -> Result<usize, Self::Error> {
if buff.len() < $n {
return Err(Error::Length);
}
$e(&mut buff[..$n], *self);
Ok($n)
}
}
};
}
impl_encdec!(u8, 1, get_u8, put_u8);
impl_encdec!(i8, 1, get_i8, put_i8);
impl_encdec!(u16, 2, LE::read_u16, LE::write_u16);
impl_encdec!(i16, 2, LE::read_i16, LE::write_i16);
impl_encdec!(u32, 4, LE::read_u32, LE::write_u32);
impl_encdec!(i32, 4, LE::read_i32, LE::write_i32);
impl_encdec!(u64, 8, LE::read_u64, LE::write_u64);
impl_encdec!(i64, 8, LE::read_i64, LE::write_i64);
impl_encdec!(f32, 4, LE::read_f32, LE::write_f32);
impl_encdec!(f64, 8, LE::read_f64, LE::write_f64);
#[inline]
fn get_u8(buff: &[u8]) -> u8 {
buff[0]
}
#[inline]
fn get_i8(buff: &[u8]) -> i8 {
buff[0] as i8
}
#[inline]
fn put_u8(buff: &mut [u8], val: u8) {
buff[0] = val;
}
#[inline]
fn put_i8(buff: &mut [u8], val: i8) {
buff[0] = val as u8;
}