1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
//! Type definitions for byte order handling.
use crate::BinResult;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
pub use Endian::{Big as BE, Little as LE};
/// Defines the order of bytes in a multi-byte type.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Endian {
/// The most significant byte is stored first.
Big,
/// The least significant byte is stored first.
Little,
}
impl Endian {
#[cfg(target_endian = "big")]
/// The target platform’s native endianness.
pub const NATIVE: Self = Endian::Big;
#[cfg(target_endian = "little")]
/// The target platform’s native endianness.
pub const NATIVE: Self = Endian::Little;
/// Converts a byte array containing a UTF-16 [byte order mark] into an
/// `Endian` value.
///
/// [byte order mark]: https://en.wikipedia.org/wiki/Byte_order_mark
///
/// # Errors
///
/// Returns an error if the input does not contain a byte order mark.
pub fn from_utf16_bom_bytes(bom: [u8; 2]) -> BinResult<Self> {
match u16::from_le_bytes(bom) {
BOM => Ok(Self::Little),
REVERSE_BOM => Ok(Self::Big),
_ => Err(crate::Error::BadMagic {
pos: u64::MAX,
found: Box::new("Invalid UTF-16 BOM"),
}),
}
}
/// Converts an `Endian` value into an array containing a UTF-16
/// [byte order mark](https://en.wikipedia.org/wiki/Byte_order_mark).
#[must_use]
pub fn into_utf16_bom_bytes(self) -> [u8; 2] {
match self {
Self::Little => u16::to_le_bytes(BOM),
Self::Big => u16::to_be_bytes(BOM),
}
}
}
impl core::fmt::Display for Endian {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Big => write!(f, "Big"),
Self::Little => write!(f, "Little"),
}
}
}
const BOM: u16 = 0xFEFF;
const REVERSE_BOM: u16 = 0xFFFE;