wlan_common/
big_endian.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use byteorder::{BigEndian, ByteOrder};
6use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
7
8macro_rules! big_endian_inttype {
9    ($struct_name:ident, $inttype:ty, $read_fn:ident, $write_fn:ident, $width:expr) => {
10        #[repr(C)]
11        #[derive(
12            Clone,
13            Copy,
14            Debug,
15            Default,
16            IntoBytes,
17            FromBytes,
18            KnownLayout,
19            Immutable,
20            Unaligned,
21            PartialEq,
22            Eq,
23        )]
24        pub struct $struct_name(pub [u8; $width]);
25        impl $struct_name {
26            pub fn from_native(native: $inttype) -> Self {
27                let mut buf = [0u8; $width];
28                BigEndian::$write_fn(&mut buf, native);
29                $struct_name(buf)
30            }
31
32            pub fn to_native(&self) -> $inttype {
33                BigEndian::$read_fn(&self.0)
34            }
35
36            pub fn set_from_native(&mut self, value: $inttype) {
37                BigEndian::$write_fn(&mut self.0, value);
38            }
39        }
40    };
41}
42
43big_endian_inttype!(BigEndianU16, u16, read_u16, write_u16, 2);
44big_endian_inttype!(BigEndianU32, u32, read_u32, write_u32, 4);
45big_endian_inttype!(BigEndianU64, u64, read_u64, write_u64, 8);
46big_endian_inttype!(BigEndianU128, u128, read_u128, write_u128, 16);
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn big_endian_u16() {
54        let mut x = BigEndianU16::from_native(0x1234);
55        assert_eq!([0x12, 0x34], x.0);
56        assert_eq!(0x1234, x.to_native());
57
58        x.set_from_native(0x5678);
59        assert_eq!([0x56, 0x78], x.0);
60        assert_eq!(0x5678, x.to_native());
61    }
62
63    #[test]
64    fn big_endian_u32() {
65        let mut x = BigEndianU32::from_native(0x12345678);
66        assert_eq!([0x12, 0x34, 0x56, 0x78], x.0);
67        assert_eq!(0x12345678, x.to_native());
68
69        x.set_from_native(0x12345678);
70        assert_eq!([0x12, 0x34, 0x56, 0x78], x.0);
71        assert_eq!(0x12345678, x.to_native());
72    }
73
74    #[test]
75    fn big_endian_u64() {
76        let mut x = BigEndianU64::from_native(0x0123456789abcdef);
77        assert_eq!([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], x.0);
78        assert_eq!(0x0123456789abcdef, x.to_native());
79
80        x.set_from_native(0x0123456789abcdef);
81        assert_eq!([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef], x.0);
82        assert_eq!(0x0123456789abcdef, x.to_native());
83    }
84
85    #[test]
86    fn big_endian_u128() {
87        let mut x = BigEndianU128::from_native(0x0123456789abcdef0000111122223333);
88        assert_eq!(
89            [
90                0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x11, 0x11, 0x22, 0x22,
91                0x33, 0x33,
92            ],
93            x.0
94        );
95        assert_eq!(0x0123456789abcdef0000111122223333, x.to_native());
96
97        x.set_from_native(0x0123456789abcdef0000111122223333);
98        assert_eq!(
99            [
100                0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x11, 0x11, 0x22, 0x22,
101                0x33, 0x33,
102            ],
103            x.0
104        );
105        assert_eq!(0x0123456789abcdef0000111122223333, x.to_native());
106    }
107}