Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  endianity.rs   Sprache: unbekannt

 
//! Types for compile-time and run-time endianity.

use core::convert::TryInto;
use core::fmt::Debug;

/// A trait describing the endianity of some buffer.
pub trait Endianity: Debug + Default + Clone + Copy + PartialEq + Eq {
    /// 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()
    }

    /// Reads an unsigned 16 bit integer from `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 2`.
    #[inline]
    fn read_u16(self, buf: &[u8]) -> u16 {
        let bytes: &[u8; 2] = buf[..2].try_into().unwrap();
        if self.is_big_endian() {
            u16::from_be_bytes(*bytes)
        } else {
            u16::from_le_bytes(*bytes)
        }
    }

    /// Reads an unsigned 32 bit integer from `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 4`.
    #[inline]
    fn read_u32(self, buf: &[u8]) -> u32 {
        let bytes: &[u8; 4] = buf[..4].try_into().unwrap();
        if self.is_big_endian() {
            u32::from_be_bytes(*bytes)
        } else {
            u32::from_le_bytes(*bytes)
        }
    }

    /// Reads an unsigned 64 bit integer from `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 8`.
    #[inline]
    fn read_u64(self, buf: &[u8]) -> u64 {
        let bytes: &[u8; 8] = buf[..8].try_into().unwrap();
        if self.is_big_endian() {
            u64::from_be_bytes(*bytes)
        } else {
            u64::from_le_bytes(*bytes)
        }
    }

    /// Read an unsigned n-bytes integer u64.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 1` or `buf.len() > 8`.
    #[inline]
    fn read_uint(&mut self, buf: &[u8]) -> u64 {
        let mut tmp = [0; 8];
        if self.is_big_endian() {
            tmp[8 - buf.len()..].copy_from_slice(buf);
        } else {
            tmp[..buf.len()].copy_from_slice(buf);
        }
        self.read_u64(&tmp)
    }

    /// Reads a signed 16 bit integer from `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 2`.
    #[inline]
    fn read_i16(self, buf: &[u8]) -> i16 {
        self.read_u16(buf) as i16
    }

    /// Reads a signed 32 bit integer from `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 4`.
    #[inline]
    fn read_i32(self, buf: &[u8]) -> i32 {
        self.read_u32(buf) as i32
    }

    /// Reads a signed 64 bit integer from `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 8`.
    #[inline]
    fn read_i64(self, buf: &[u8]) -> i64 {
        self.read_u64(buf) as i64
    }

    /// Reads a 32 bit floating point number from `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 8`.
    #[inline]
    fn read_f32(self, buf: &[u8]) -> f32 {
        f32::from_bits(self.read_u32(buf))
    }

    /// Reads a 32 bit floating point number from `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 8`.
    #[inline]
    fn read_f64(self, buf: &[u8]) -> f64 {
        f64::from_bits(self.read_u64(buf))
    }

    /// Writes an unsigned 16 bit integer `n` to `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 2`.
    #[inline]
    fn write_u16(self, buf: &mut [u8], n: u16) {
        let bytes = if self.is_big_endian() {
            n.to_be_bytes()
        } else {
            n.to_le_bytes()
        };
        buf[..2].copy_from_slice(&bytes);
    }

    /// Writes an unsigned 32 bit integer `n` to `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 4`.
    #[inline]
    fn write_u32(self, buf: &mut [u8], n: u32) {
        let bytes = if self.is_big_endian() {
            n.to_be_bytes()
        } else {
            n.to_le_bytes()
        };
        buf[..4].copy_from_slice(&bytes);
    }

    /// Writes an unsigned 64 bit integer `n` to `buf`.
    ///
    /// # Panics
    ///
    /// Panics when `buf.len() < 8`.
    #[inline]
    fn write_u64(self, buf: &mut [u8], n: u64) {
        let bytes = if self.is_big_endian() {
            n.to_be_bytes()
        } else {
            n.to_le_bytes()
        };
        buf[..8].copy_from_slice(&bytes);
    }
}

/// Byte order that is selectable at runtime.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RunTimeEndian {
    /// Little endian byte order.
    Little,
    /// Big endian byte order.
    Big,
}

impl Default for RunTimeEndian {
    #[cfg(target_endian = "little")]
    #[inline]
    fn default() -> RunTimeEndian {
        RunTimeEndian::Little
    }

    #[cfg(target_endian = "big")]
    #[inline]
    fn default() -> RunTimeEndian {
        RunTimeEndian::Big
    }
}

impl Endianity for RunTimeEndian {
    #[inline]
    fn is_big_endian(self) -> bool {
        self != RunTimeEndian::Little
    }
}

/// Little endian byte order.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct LittleEndian;

impl Default for LittleEndian {
    #[inline]
    fn default() -> LittleEndian {
        LittleEndian
    }
}

impl Endianity for LittleEndian {
    #[inline]
    fn is_big_endian(self) -> bool {
        false
    }
}

/// Big endian byte order.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct BigEndian;

impl Default for BigEndian {
    #[inline]
    fn default() -> BigEndian {
        BigEndian
    }
}

impl Endianity for BigEndian {
    #[inline]
    fn is_big_endian(self) -> bool {
        true
    }
}

/// The native endianity for the target platform.
#[cfg(target_endian = "little")]
pub type NativeEndian = LittleEndian;

#[cfg(target_endian = "little")]
#[allow(non_upper_case_globals)]
#[doc(hidden)]
pub const NativeEndian: LittleEndian = LittleEndian;

/// The native endianity for the target platform.
#[cfg(target_endian = "big")]
pub type NativeEndian = BigEndian;

#[cfg(target_endian = "big")]
#[allow(non_upper_case_globals)]
#[doc(hidden)]
pub const NativeEndian: BigEndian = BigEndian;

[ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge