blob: 08be424d93a3133bcf74f6727a683be8f08be4b5 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
byteorder::{BigEndian, ByteOrder},
zerocopy::{AsBytes, FromBytes, FromZeros, NoCell, Unaligned},
};
macro_rules! big_endian_inttype {
($struct_name:ident, $inttype:ty, $read_fn:ident, $write_fn:ident, $width:expr) => {
#[repr(C)]
#[derive(
Clone,
Copy,
Debug,
Default,
AsBytes,
FromZeros,
FromBytes,
NoCell,
Unaligned,
PartialEq,
Eq,
)]
pub struct $struct_name(pub [u8; $width]);
impl $struct_name {
pub fn from_native(native: $inttype) -> Self {
let mut buf = [0u8; $width];
BigEndian::$write_fn(&mut buf, native);
$struct_name(buf)
}
pub fn to_native(&self) -> $inttype {
BigEndian::$read_fn(&self.0)
}
pub fn set_from_native(&mut self, value: $inttype) {
BigEndian::$write_fn(&mut self.0, value);
}
}
};
}
big_endian_inttype!(BigEndianU16, u16, read_u16, write_u16, 2);
big_endian_inttype!(BigEndianU32, u32, read_u32, write_u32, 4);
big_endian_inttype!(BigEndianU64, u64, read_u64, write_u64, 8);
big_endian_inttype!(BigEndianU128, u128, read_u128, write_u128, 16);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn big_endian_u16() {
let mut x = BigEndianU16::from_native(0x1234);
assert_eq!([0x12, 0x34], x.0);
assert_eq!(0x1234, x.to_native());
x.set_from_native(0x5678);
assert_eq!([0x56, 0x78], x.0);
assert_eq!(0x5678, x.to_native());
}
#[test]
fn big_endian_u32() {
let mut x = BigEndianU32::from_native(0x12345678);
assert_eq!([0x12, 0x34, 0x56, 0x78], x.0);
assert_eq!(0x12345678, x.to_native());
x.set_from_native(0x12345678);
assert_eq!([0x12, 0x34, 0x56, 0x78], x.0);
assert_eq!(0x12345678, x.to_native());
}
#[test]
fn big_endian_u64() {
let mut x = BigEndianU64::from_native(0x0123456789abcdef);
assert_eq!([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], x.0);
assert_eq!(0x0123456789abcdef, x.to_native());
x.set_from_native(0x0123456789abcdef);
assert_eq!([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], x.0);
assert_eq!(0x0123456789abcdef, x.to_native());
}
#[test]
fn big_endian_u128() {
let mut x = BigEndianU128::from_native(0x0123456789abcdef0000111122223333);
assert_eq!(
[
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x11, 0x11, 0x22, 0x22,
0x33, 0x33,
],
x.0
);
assert_eq!(0x0123456789abcdef0000111122223333, x.to_native());
x.set_from_native(0x0123456789abcdef0000111122223333);
assert_eq!(
[
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x11, 0x11, 0x22, 0x22,
0x33, 0x33,
],
x.0
);
assert_eq!(0x0123456789abcdef0000111122223333, x.to_native());
}
}