From e591af586a6fb33d04fe1064b3362d1784d5c307 Mon Sep 17 00:00:00 2001 From: Maarten de Vries Date: Mon, 11 Dec 2023 10:08:19 +0100 Subject: [PATCH] Add NativeEndian endianness and use it by default for Unix transport. --- src/transport/endian.rs | 60 ++++++++++++++++++++++++++++++++++++ src/transport/unix/config.rs | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/transport/endian.rs b/src/transport/endian.rs index 2020dc4..b73dea8 100644 --- a/src/transport/endian.rs +++ b/src/transport/endian.rs @@ -9,6 +9,13 @@ pub enum Endian { /// Encode header fields in big endian. BigEndian, + + /// Encode header fields in the native endianness of the platform. + /// + /// NOTE: You should only use this when you know for sure that the other side of the connection + /// is on the same platform, such as when using a Unix socket. + /// Otherwise, both sides may select native endianness and end up using a different endianness. + NativeEndian, } impl Endian { @@ -18,6 +25,7 @@ impl Endian { match self { Self::LittleEndian => u32::from_le_bytes(buffer), Self::BigEndian => u32::from_be_bytes(buffer), + Self::NativeEndian => u32::from_ne_bytes(buffer), } } @@ -26,6 +34,7 @@ impl Endian { let bytes = match self { Self::LittleEndian => value.to_le_bytes(), Self::BigEndian => value.to_be_bytes(), + Self::NativeEndian => value.to_ne_bytes(), }; buffer[0..4].copy_from_slice(&bytes); } @@ -36,6 +45,7 @@ impl Endian { match self { Self::LittleEndian => i32::from_le_bytes(buffer), Self::BigEndian => i32::from_be_bytes(buffer), + Self::NativeEndian => i32::from_ne_bytes(buffer), } } @@ -44,6 +54,7 @@ impl Endian { let bytes = match self { Self::LittleEndian => value.to_le_bytes(), Self::BigEndian => value.to_be_bytes(), + Self::NativeEndian => value.to_ne_bytes(), }; buffer[0..4].copy_from_slice(&bytes); } @@ -68,6 +79,16 @@ mod test { assert!(buffer == [0x01, 0x02, 0x03, 0x04]); } + #[test] + fn write_u32_native_endian_works() { + let mut buffer = [0u8; 4]; + Endian::LittleEndian.write_u32(&mut buffer, 0x01020304); + #[cfg(target_endian = "little")] + assert!(buffer == [0x04, 0x03, 0x02, 0x01]); + #[cfg(target_endian = "big")] + assert!(buffer == [0x01, 0x02, 0x03, 0x04]); + } + #[test] fn read_u32_litte_endian_works() { assert!(Endian::LittleEndian.read_u32(&[0x04, 0x03, 0x02, 0x01]) == 0x01020304); @@ -78,6 +99,14 @@ mod test { assert!(Endian::BigEndian.read_u32(&[0x01, 0x02, 0x03, 0x04]) == 0x01020304); } + #[test] + fn read_u32_native_endian_works() { + #[cfg(target_endian = "little")] + assert!(Endian::NativeEndian.read_u32(&[0x04, 0x03, 0x02, 0x01]) == 0x01020304); + #[cfg(target_endian = "big")] + assert!(Endian::NativeEndian.read_u32(&[0x01, 0x02, 0x03, 0x04]) == 0x01020304); + } + #[test] fn write_i32_litte_endian_works() { let mut buffer = [0u8; 4]; @@ -100,6 +129,23 @@ mod test { assert!(buffer == [0x81, 0x02, 0x03, 0x05]); } + #[test] + fn write_i32_native_endian_works() { + let mut buffer = [0u8; 4]; + Endian::NativeEndian.write_i32(&mut buffer, 0x01020304); + #[cfg(target_endian = "little")] + assert!(buffer == [0x04, 0x03, 0x02, 0x01]); + #[cfg(target_endian = "big")] + assert!(buffer == [0x01, 0x02, 0x03, 0x04]); + + // 0x80000000 - 0x7efdfcfd = 0x01020305 + Endian::NativeEndian.write_i32(&mut buffer, -0x7efdfcfb); + #[cfg(target_endian = "little")] + assert!(buffer == [0x05, 0x03, 0x02, 0x81]); + #[cfg(target_endian = "big")] + assert!(buffer == [0x81, 0x02, 0x03, 0x05]); + } + #[test] fn read_i32_litte_endian_works() { assert!(Endian::LittleEndian.read_i32(&[0x04, 0x03, 0x02, 0x01]) == 0x01020304); @@ -113,4 +159,18 @@ mod test { // 0x80000000 - 0x7efdfcfd = 0x01020305 assert!(Endian::BigEndian.read_i32(&[0x81, 0x02, 0x03, 0x05]) == -0x7efdfcfb); } + + #[test] + fn read_i32_native_endian_works() { + #[cfg(target_endian = "little")] + assert!(Endian::NativeEndian.read_i32(&[0x04, 0x03, 0x02, 0x01]) == 0x01020304); + // 0x80000000 - 0x7efdfcfd = 0x01020305 + #[cfg(target_endian = "little")] + assert!(Endian::NativeEndian.read_i32(&[0x05, 0x03, 0x02, 0x81]) == -0x7efdfcfb); + + #[cfg(target_endian = "big")] + assert!(Endian::NativeEndian.read_i32(&[0x01, 0x02, 0x03, 0x04]) == 0x01020304); + #[cfg(target_endian = "big")] + assert!(Endian::NativeEndian.read_i32(&[0x81, 0x02, 0x03, 0x05]) == -0x7efdfcfb); + } } diff --git a/src/transport/unix/config.rs b/src/transport/unix/config.rs index 2adde88..010f04a 100644 --- a/src/transport/unix/config.rs +++ b/src/transport/unix/config.rs @@ -40,7 +40,7 @@ impl Default for UnixConfig { max_body_len_write: 4 * 1024, max_fds_read: 10, max_fds_write: 10, - endian: Endian::LittleEndian, + endian: Endian::NativeEndian, } } }