//! Types for compile-time and run-time endianness.
usecrate::pod::Pod; use core::fmt::{self, Debug}; use core::marker::PhantomData;
/// A trait for using an endianness specification. /// /// Provides methods for converting between the specified endianness and /// the native endianness of the target machine. /// /// This trait does not require that the endianness is known at compile time. pubtrait Endian: Debug + Default + Clone + Copy + PartialEq + Eq + 'static { /// Construct a specification for the endianness of some values. /// /// Returns `None` if the type does not support specifying the given endianness. fn from_big_endian(big_endian: bool) -> Option<Self>;
/// Construct a specification for the endianness of some values. /// /// Returns `None` if the type does not support specifying the given endianness. fn from_little_endian(little_endian: bool) -> Option<Self> { Self::from_big_endian(!little_endian)
}
/// Return true for big endian byte order. fn is_big_endian(self) -> bool;
/// Return true for little endian byte order. #[inline] fn is_little_endian(self) -> bool {
!self.is_big_endian()
}
/// Converts an unsigned 16 bit integer to native endian. #[inline] fn read_u16(self, n: u16) -> u16 { ifself.is_big_endian() {
u16::from_be(n)
} else {
u16::from_le(n)
}
}
/// Converts an unsigned 32 bit integer to native endian. #[inline] fn read_u32(self, n: u32) -> u32 { ifself.is_big_endian() {
u32::from_be(n)
} else {
u32::from_le(n)
}
}
/// Converts an unsigned 64 bit integer to native endian. #[inline] fn read_u64(self, n: u64) -> u64 { ifself.is_big_endian() {
u64::from_be(n)
} else {
u64::from_le(n)
}
}
/// Converts a signed 16 bit integer to native endian. #[inline] fn read_i16(self, n: i16) -> i16 { ifself.is_big_endian() {
i16::from_be(n)
} else {
i16::from_le(n)
}
}
/// Converts a signed 32 bit integer to native endian. #[inline] fn read_i32(self, n: i32) -> i32 { ifself.is_big_endian() {
i32::from_be(n)
} else {
i32::from_le(n)
}
}
/// Converts a signed 64 bit integer to native endian. #[inline] fn read_i64(self, n: i64) -> i64 { ifself.is_big_endian() {
i64::from_be(n)
} else {
i64::from_le(n)
}
}
/// Converts an unaligned unsigned 16 bit integer to native endian. #[inline] fn read_u16_bytes(self, n: [u8; 2]) -> u16 { ifself.is_big_endian() {
u16::from_be_bytes(n)
} else {
u16::from_le_bytes(n)
}
}
/// Converts an unaligned unsigned 32 bit integer to native endian. #[inline] fn read_u32_bytes(self, n: [u8; 4]) -> u32 { ifself.is_big_endian() {
u32::from_be_bytes(n)
} else {
u32::from_le_bytes(n)
}
}
/// Converts an unaligned unsigned 64 bit integer to native endian. #[inline] fn read_u64_bytes(self, n: [u8; 8]) -> u64 { ifself.is_big_endian() {
u64::from_be_bytes(n)
} else {
u64::from_le_bytes(n)
}
}
/// Converts an unaligned signed 16 bit integer to native endian. #[inline] fn read_i16_bytes(self, n: [u8; 2]) -> i16 { ifself.is_big_endian() {
i16::from_be_bytes(n)
} else {
i16::from_le_bytes(n)
}
}
/// Converts an unaligned signed 32 bit integer to native endian. #[inline] fn read_i32_bytes(self, n: [u8; 4]) -> i32 { ifself.is_big_endian() {
i32::from_be_bytes(n)
} else {
i32::from_le_bytes(n)
}
}
/// Converts an unaligned signed 64 bit integer to native endian. #[inline] fn read_i64_bytes(self, n: [u8; 8]) -> i64 { ifself.is_big_endian() {
i64::from_be_bytes(n)
} else {
i64::from_le_bytes(n)
}
}
/// Converts an unsigned 16 bit integer from native endian. #[inline] fn write_u16(self, n: u16) -> u16 { ifself.is_big_endian() {
u16::to_be(n)
} else {
u16::to_le(n)
}
}
/// Converts an unsigned 32 bit integer from native endian. #[inline] fn write_u32(self, n: u32) -> u32 { ifself.is_big_endian() {
u32::to_be(n)
} else {
u32::to_le(n)
}
}
/// Converts an unsigned 64 bit integer from native endian. #[inline] fn write_u64(self, n: u64) -> u64 { ifself.is_big_endian() {
u64::to_be(n)
} else {
u64::to_le(n)
}
}
/// Converts a signed 16 bit integer from native endian. #[inline] fn write_i16(self, n: i16) -> i16 { ifself.is_big_endian() {
i16::to_be(n)
} else {
i16::to_le(n)
}
}
/// Converts a signed 32 bit integer from native endian. #[inline] fn write_i32(self, n: i32) -> i32 { ifself.is_big_endian() {
i32::to_be(n)
} else {
i32::to_le(n)
}
}
/// Converts a signed 64 bit integer from native endian. #[inline] fn write_i64(self, n: i64) -> i64 { ifself.is_big_endian() {
i64::to_be(n)
} else {
i64::to_le(n)
}
}
/// Converts an unaligned unsigned 16 bit integer from native endian. #[inline] fn write_u16_bytes(self, n: u16) -> [u8; 2] { ifself.is_big_endian() {
u16::to_be_bytes(n)
} else {
u16::to_le_bytes(n)
}
}
/// Converts an unaligned unsigned 32 bit integer from native endian. #[inline] fn write_u32_bytes(self, n: u32) -> [u8; 4] { ifself.is_big_endian() {
u32::to_be_bytes(n)
} else {
u32::to_le_bytes(n)
}
}
/// Converts an unaligned unsigned 64 bit integer from native endian. #[inline] fn write_u64_bytes(self, n: u64) -> [u8; 8] { ifself.is_big_endian() {
u64::to_be_bytes(n)
} else {
u64::to_le_bytes(n)
}
}
/// Converts an unaligned signed 16 bit integer from native endian. #[inline] fn write_i16_bytes(self, n: i16) -> [u8; 2] { ifself.is_big_endian() {
i16::to_be_bytes(n)
} else {
i16::to_le_bytes(n)
}
}
/// Converts an unaligned signed 32 bit integer from native endian. #[inline] fn write_i32_bytes(self, n: i32) -> [u8; 4] { ifself.is_big_endian() {
i32::to_be_bytes(n)
} else {
i32::to_le_bytes(n)
}
}
/// Converts an unaligned signed 64 bit integer from native endian. #[inline] fn write_i64_bytes(self, n: i64) -> [u8; 8] { ifself.is_big_endian() {
i64::to_be_bytes(n)
} else {
i64::to_le_bytes(n)
}
}
}
/// An endianness that is selectable at run-time. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pubenum Endianness { /// Little endian byte order.
Little, /// Big endian byte order.
Big,
}
macro_rules! unsafe_impl_endian_pod {
($($struct_name:ident),+ $(,)?) => {
$( unsafeimpl<E: Endian> Pod for $struct_name<E> { }
)+
}
}
#[cfg(not(feature = "unaligned"))] mod aligned { usesuper::{fmt, Endian, PhantomData, Pod};
/// A `u16` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct U16<E: Endian>(u16, PhantomData<E>);
impl<E: Endian> U16<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 2]) -> Self { Self(u16::from_ne_bytes(n), PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: u16) -> Self { Self(e.write_u16(n), PhantomData)
}
/// Return the value as a native endian value. pubfn get(self, e: E) -> u16 {
e.read_u16(self.0)
}
/// Set the value given a native endian value. pubfn set(&mutself, e: E, n: u16) { self.0 = e.write_u16(n);
}
}
/// A `u32` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct U32<E: Endian>(u32, PhantomData<E>);
impl<E: Endian> U32<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 4]) -> Self { Self(u32::from_ne_bytes(n), PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: u32) -> Self { Self(e.write_u32(n), PhantomData)
} /// Return the value as a native endian value. pubfn get(self, e: E) -> u32 {
e.read_u32(self.0)
} /// Set the value given a native endian value. pubfn set(&mutself, e: E, n: u32) { self.0 = e.write_u32(n);
}
}
/// A `u64` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct U64<E: Endian>(u64, PhantomData<E>);
impl<E: Endian> U64<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 8]) -> Self { Self(u64::from_ne_bytes(n), PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: u64) -> Self { Self(e.write_u64(n), PhantomData)
} /// Return the value as a native endian value. pubfn get(self, e: E) -> u64 {
e.read_u64(self.0)
} /// Set the value given a native endian value. pubfn set(&mutself, e: E, n: u64) { self.0 = e.write_u64(n);
}
}
/// An `i16` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct I16<E: Endian>(i16, PhantomData<E>);
impl<E: Endian> I16<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 2]) -> Self { Self(i16::from_ne_bytes(n), PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: i16) -> Self { Self(e.write_i16(n), PhantomData)
} /// Return the value as a native endian value. pubfn get(self, e: E) -> i16 {
e.read_i16(self.0)
} /// Set the value given a native endian value. pubfn set(&mutself, e: E, n: i16) { self.0 = e.write_i16(n);
}
}
/// An `i32` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct I32<E: Endian>(i32, PhantomData<E>);
impl<E: Endian> I32<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 4]) -> Self { Self(i32::from_ne_bytes(n), PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: i32) -> Self { Self(e.write_i32(n), PhantomData)
} /// Return the value as a native endian value. pubfn get(self, e: E) -> i32 {
e.read_i32(self.0)
} /// Set the value given a native endian value. pubfn set(&mutself, e: E, n: i32) { self.0 = e.write_i32(n);
}
}
/// An `i64` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct I64<E: Endian>(i64, PhantomData<E>);
impl<E: Endian> I64<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 8]) -> Self { Self(i64::from_ne_bytes(n), PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: i64) -> Self { Self(e.write_i64(n), PhantomData)
} /// Return the value as a native endian value. pubfn get(self, e: E) -> i64 {
e.read_i64(self.0)
} /// Set the value given a native endian value. pubfn set(&mutself, e: E, n: i64) { self.0 = e.write_i64(n);
}
}
/// A `u16` value with an externally specified endianness of type `E`. #[cfg(feature = "unaligned")] pubtype U16<E> = U16Bytes<E>;
/// A `u32` value with an externally specified endianness of type `E`. #[cfg(feature = "unaligned")] pubtype U32<E> = U32Bytes<E>;
/// A `u64` value with an externally specified endianness of type `E`. #[cfg(feature = "unaligned")] pubtype U64<E> = U64Bytes<E>;
/// An `i16` value with an externally specified endianness of type `E`. #[cfg(feature = "unaligned")] pubtype I16<E> = I16Bytes<E>;
/// An `i32` value with an externally specified endianness of type `E`. #[cfg(feature = "unaligned")] pubtype I32<E> = I32Bytes<E>;
/// An `i64` value with an externally specified endianness of type `E`. #[cfg(feature = "unaligned")] pubtype I64<E> = I64Bytes<E>;
/// An unaligned `u16` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct U16Bytes<E: Endian>([u8; 2], PhantomData<E>);
impl<E: Endian> U16Bytes<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 2]) -> Self { Self(n, PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: u16) -> Self { Self(e.write_u16_bytes(n), PhantomData)
}
/// Return the value as a native endian value. pubfn get(self, e: E) -> u16 {
e.read_u16_bytes(self.0)
}
/// Set the value given a native endian value. pubfn set(&mutself, e: E, n: u16) { self.0 = e.write_u16_bytes(n);
}
}
/// An unaligned `u32` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct U32Bytes<E: Endian>([u8; 4], PhantomData<E>);
impl<E: Endian> U32Bytes<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 4]) -> Self { Self(n, PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: u32) -> Self { Self(e.write_u32_bytes(n), PhantomData)
}
/// Return the value as a native endian value. pubfn get(self, e: E) -> u32 {
e.read_u32_bytes(self.0)
}
/// Set the value given a native endian value. pubfn set(&mutself, e: E, n: u32) { self.0 = e.write_u32_bytes(n);
}
}
/// An unaligned `u64` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct U64Bytes<E: Endian>([u8; 8], PhantomData<E>);
impl<E: Endian> U64Bytes<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 8]) -> Self { Self(n, PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: u64) -> Self { Self(e.write_u64_bytes(n), PhantomData)
}
/// Return the value as a native endian value. pubfn get(self, e: E) -> u64 {
e.read_u64_bytes(self.0)
}
/// Set the value given a native endian value. pubfn set(&mutself, e: E, n: u64) { self.0 = e.write_u64_bytes(n);
}
}
/// An unaligned `i16` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct I16Bytes<E: Endian>([u8; 2], PhantomData<E>);
impl<E: Endian> I16Bytes<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 2]) -> Self { Self(n, PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: i16) -> Self { Self(e.write_i16_bytes(n), PhantomData)
}
/// Return the value as a native endian value. pubfn get(self, e: E) -> i16 {
e.read_i16_bytes(self.0)
}
/// Set the value given a native endian value. pubfn set(&mutself, e: E, n: i16) { self.0 = e.write_i16_bytes(n);
}
}
/// An unaligned `i32` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct I32Bytes<E: Endian>([u8; 4], PhantomData<E>);
impl<E: Endian> I32Bytes<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 4]) -> Self { Self(n, PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: i32) -> Self { Self(e.write_i32_bytes(n), PhantomData)
}
/// Return the value as a native endian value. pubfn get(self, e: E) -> i32 {
e.read_i32_bytes(self.0)
}
/// Set the value given a native endian value. pubfn set(&mutself, e: E, n: i32) { self.0 = e.write_i32_bytes(n);
}
}
/// An unaligned `i64` value with an externally specified endianness of type `E`. #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] pubstruct I64Bytes<E: Endian>([u8; 8], PhantomData<E>);
impl<E: Endian> I64Bytes<E> { /// Construct a new value given bytes that already have the required endianness. pubconstfn from_bytes(n: [u8; 8]) -> Self { Self(n, PhantomData)
}
/// Construct a new value given a native endian value. pubfn new(e: E, n: i64) -> Self { Self(e.write_i64_bytes(n), PhantomData)
}
/// Return the value as a native endian value. pubfn get(self, e: E) -> i64 {
e.read_i64_bytes(self.0)
}
/// Set the value given a native endian value. pubfn set(&mutself, e: E, n: i64) { self.0 = e.write_i64_bytes(n);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.