1use core::convert::TryInto;
2
3pub trait ByteOrder {
4 fn read_u16(buf: &[u8]) -> u16;
5 fn read_u32(buf: &[u8]) -> u32;
6 fn read_u64(buf: &[u8]) -> u64;
7 fn read_uint(buf: &[u8], nbytes: usize) -> u64;
8 fn write_u16(buf: &mut [u8], n: u16);
9 fn write_u32(buf: &mut [u8], n: u32);
10 fn write_u64(buf: &mut [u8], n: u64);
11 fn write_uint(buf: &mut [u8], n: u64, nbytes: usize);
12}
13
14pub enum BigEndian {}
15pub enum LittleEndian {}
16pub enum NativeEndian {}
17
18macro_rules! impl_endian {
19 ($t:ty, $from_endian:ident, $to_endian:ident) => {
20 impl ByteOrder for $t {
21 #[inline]
22 fn read_u16(buf: &[u8]) -> u16 {
23 u16::$from_endian(buf[0..2].try_into().unwrap())
24 }
25
26 #[inline]
27 fn read_u32(buf: &[u8]) -> u32 {
28 u32::$from_endian(buf[0..4].try_into().unwrap())
29 }
30
31 #[inline]
32 fn read_u64(buf: &[u8]) -> u64 {
33 u64::$from_endian(buf[0..8].try_into().unwrap())
34 }
35
36 #[inline]
37 fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
38 let mut dst = [0u8; 8];
39 dst[..nbytes].copy_from_slice(&buf[..nbytes]);
40 u64::$from_endian(dst)
41 }
42
43 #[inline]
44 fn write_u16(buf: &mut [u8], n: u16) {
45 buf[0..2].copy_from_slice(&n.$to_endian()[..]);
46 }
47
48 #[inline]
49 fn write_u32(buf: &mut [u8], n: u32) {
50 buf[0..4].copy_from_slice(&n.$to_endian()[..]);
51 }
52
53 #[inline]
54 fn write_u64(buf: &mut [u8], n: u64) {
55 buf[0..8].copy_from_slice(&n.$to_endian()[..]);
56 }
57
58 #[inline]
59 fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
60 buf[..nbytes].copy_from_slice(&n.$to_endian()[..nbytes]);
61 }
62 }
63 };
64}
65
66impl_endian! {
67 BigEndian, from_be_bytes, to_be_bytes
68}
69
70impl_endian! {
71 LittleEndian, from_le_bytes, to_le_bytes
72}
73
74impl_endian! {
75 NativeEndian, from_ne_bytes, to_ne_bytes
76}
77