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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
#![no_std] use core::mem::transmute as xmut; macro_rules! to_uns { ($n:expr, $bs:expr, $ns:expr) => ({ assert_eq!($bs.len() << $n, $ns.len()); for (bs, np) in Iterator::zip($bs.chunks(1 << $n), $ns.iter_mut()) { *np = Self::read_u(bs) as _; } }) } macro_rules! from_uns { ($n:expr, $ns:expr, $bs:expr) => ({ assert_eq!($bs.len() << $n, $ns.len()); for (np, bs) in Iterator::zip($ns.iter(), $bs.chunks_mut(1 << $n)) { Self::write_u(bs, *np as _); } }) } pub trait Endian: private::Sealed { const is_big: bool = !Self::is_lil; const is_lil: bool = !Self::is_big; fn read_u(&[u8]) -> u64; #[inline] fn read_i(bs: &[u8]) -> i64 { Self::read_u(bs) as _ } fn write_u(&mut [u8], n: u64); #[inline] fn write_i(bs: &mut [u8], n: i64) { Self::write_u(bs, n as _) } #[inline] fn to_u16s(bs: &[u8], ns: &mut [u16]) { to_uns!(2, bs, ns) } #[inline] fn to_i16s(bs: &[u8], ns: &mut [i16]) { Self::to_u16s(bs, unsafe { xmut(ns) }) } #[inline] fn from_u16s(ns: &[u16], bs: &mut [u8]) { from_uns!(2, ns, bs) } #[inline] fn from_i16s(ns: &[i16], bs: &mut [u8]) { Self::from_u16s(unsafe { xmut(ns) }, bs) } #[inline] fn to_u32s(bs: &[u8], ns: &mut [u32]) { to_uns!(4, bs, ns) } #[inline] fn to_i32s(bs: &[u8], ns: &mut [i32]) { Self::to_u32s(bs, unsafe { xmut(ns) }) } #[inline] fn from_u32s(ns: &[u32], bs: &mut [u8]) { from_uns!(4, ns, bs) } #[inline] fn from_i32s(ns: &[i32], bs: &mut [u8]) { Self::from_u32s(unsafe { xmut(ns) }, bs) } #[inline] fn to_u64s(bs: &[u8], ns: &mut [u64]) { to_uns!(8, bs, ns) } #[inline] fn to_i64s(bs: &[u8], ns: &mut [i64]) { Self::to_u64s(bs, unsafe { xmut(ns) }) } #[inline] fn from_u64s(ns: &[u64], bs: &mut [u8]) { from_uns!(8, ns, bs) } #[inline] fn from_i64s(ns: &[i64], bs: &mut [u8]) { Self::from_u64s(unsafe { xmut(ns) }, bs) } } mod private { pub trait Sealed {} } #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Big; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Lil; impl private::Sealed for Big {} impl private::Sealed for Lil {} impl Endian for Big { const is_big: bool = true; #[inline] fn read_u(bs: &[u8]) -> u64 { assert!(8 >= bs.len()); let mut n = 0; for &b in bs { n <<= 8; n += b as u64; } n } #[inline] fn write_u(bs: &mut [u8], mut n: u64) { assert!(8 >= bs.len()); for bp in bs.iter_mut().rev() { *bp = n as _; n >>= 8; } } } impl Endian for Lil { const is_lil: bool = true; #[inline] fn read_u(bs: &[u8]) -> u64 { assert!(8 >= bs.len()); let mut n = 0; for &b in bs.iter().rev() { n <<= 8; n += b as u64; } n } #[inline] fn write_u(bs: &mut [u8], mut n: u64) { assert!(8 >= bs.len()); for bp in bs { *bp = n as _; n >>= 8; } } }