diff --git a/README.md b/README.md index 350f1f3..36a6655 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ maintained with the occasional fix for edge cases and depends on Tokio v0.2. `FixedInt` casts integers to bytes by either copying the underlying memory or performing a transmutation. The encoded values use machine endianness -(little-endian on x86). +(little-endian on x86, big-endian where applicable). ## VarInt diff --git a/src/fixed.rs b/src/fixed.rs index fd0a24d..1f0eb33 100644 --- a/src/fixed.rs +++ b/src/fixed.rs @@ -49,12 +49,37 @@ macro_rules! impl_fixedint { fn encode_fixed(self, dst: &mut [u8]) { assert_eq!(dst.len(), Self::REQUIRED_SPACE); - let encoded = unsafe { &*(&self as *const $t as *const [u8; $sz]) }; + + #[allow(unused_mut)] + let mut encoded = unsafe { &*(&self as *const $t as *const [u8; $sz]) }; + + #[cfg(target_endian = "big")] + { + let mut encoded_rev = [0 as u8; Self::REQUIRED_SPACE]; + encoded_rev.copy_from_slice(encoded); + encoded_rev.reverse(); + dst.clone_from_slice(&encoded_rev); + return; + } + dst.clone_from_slice(encoded); } + fn decode_fixed(src: &[u8]) -> $t { assert_eq!(src.len(), Self::REQUIRED_SPACE); - return unsafe { (src.as_ptr() as *const $t).read_unaligned() }; + #[cfg(target_endian = "little")] + let src_fin = src; + + #[cfg(target_endian = "big")] + let mut src_fin = [0 as u8; Self::REQUIRED_SPACE]; + + #[cfg(target_endian = "big")] + { + src_fin.copy_from_slice(src); + src_fin.reverse(); + } + + return unsafe { (src_fin.as_ptr() as *const $t).read_unaligned() }; } } }; diff --git a/src/fixed_tests.rs b/src/fixed_tests.rs index b2d75c3..83af0b4 100644 --- a/src/fixed_tests.rs +++ b/src/fixed_tests.rs @@ -13,21 +13,33 @@ mod tests { #[test] fn test_u32_enc() { let result = (32 as u32).encode_fixed_vec(); + #[cfg(target_endian = "big")] + assert_eq!(result, vec![0, 0, 0, 32]); + #[cfg(target_endian = "little")] assert_eq!(result, vec![32, 0, 0, 0]); } #[test] fn test_u16_enc() { let result = (256 as u16).encode_fixed_vec(); + #[cfg(target_endian = "big")] + assert_eq!(result, vec![1, 0]); + #[cfg(target_endian = "little")] assert_eq!(result, vec![0, 1]); } #[test] fn test_i16_enc() { let result = (-32768 as i16).encode_fixed_vec(); + #[cfg(target_endian = "big")] + assert_eq!(result, vec![128, 0]); + #[cfg(target_endian = "little")] assert_eq!(result, vec![0, 128]); } #[test] fn test_i32_enc() { let result = (-32767 as i32).encode_fixed_vec(); + #[cfg(target_endian = "big")] + assert_eq!(result, vec![255, 255, 128, 1]); + #[cfg(target_endian = "little")] assert_eq!(result, vec![1, 128, 255, 255]); } @@ -45,6 +57,9 @@ mod tests { fn test_i32_enc_light() { let int = -32767 as i32; let result = int.encode_fixed_light(); + #[cfg(target_endian = "big")] + assert_eq!(result, &[255, 255, 128, 1]); + #[cfg(target_endian = "little")] assert_eq!(result, &[1, 128, 255, 255]); } #[test] diff --git a/src/reader.rs b/src/reader.rs index aaee8f0..8910783 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -5,7 +5,7 @@ use crate::fixed::FixedInt; use crate::varint::{VarInt, VarIntMaxSize, MSB}; #[cfg(feature = "tokio_async")] -use tokio::io::{AsyncReadExt, AsyncRead}; +use tokio::io::{AsyncRead, AsyncReadExt}; #[cfg(feature = "futures_async")] use futures_util::{io::AsyncRead, io::AsyncReadExt}; @@ -40,7 +40,10 @@ pub struct VarIntProcessor { impl VarIntProcessor { fn new() -> VarIntProcessor { - VarIntProcessor { maxsize: VI::varint_max_size(), ..VarIntProcessor::default() } + VarIntProcessor { + maxsize: VI::varint_max_size(), + ..VarIntProcessor::default() + } } fn push(&mut self, b: u8) -> Result<()> { if self.i >= self.maxsize { diff --git a/src/varint.rs b/src/varint.rs index 20069fc..0fd319a 100644 --- a/src/varint.rs +++ b/src/varint.rs @@ -72,7 +72,7 @@ pub(crate) trait VarIntMaxSize { impl VarIntMaxSize for VI { fn varint_max_size() -> usize { - (size_of::()*8+7)/7 + (size_of::() * 8 + 7) / 7 } } diff --git a/src/varint_tests.rs b/src/varint_tests.rs index 432e2a0..ba70e86 100644 --- a/src/varint_tests.rs +++ b/src/varint_tests.rs @@ -204,6 +204,9 @@ mod tests { #[test] fn test_regression_22() { let mut encoded: Vec = (0x112233 as u64).encode_var_vec(); - assert_eq!(encoded.as_slice().read_varint::().unwrap_err().kind(), std::io::ErrorKind::InvalidData); + assert_eq!( + encoded.as_slice().read_varint::().unwrap_err().kind(), + std::io::ErrorKind::InvalidData + ); } }