RUST中的字节序的大小端变换

本文摘自《深入RUST标准库》,已经全网发售,恳请支持

#无符号整形类型标准库代码分析
代码如下:

macro_rules! uint_impl {
    ($SelfT:ty, $ActualT:ident, $SignedT:ident, $BITS:expr, $MaxV:expr,
        $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
        $reversed:expr, $le_bytes:expr, $be_bytes:expr,
        $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
        
        pub const MIN: Self = 0;

        pub const MAX: Self = !0;

        pub const BITS: u32 = $BITS;
        
        //由字符串解析
        pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
            from_str_radix(src, radix)
        }
        
        //利用intrinsics的位函数完成整数的位需求,这里举一个例子,其他请参考标准库手册
        pub const fn count_ones(self) -> u32 {
            intrinsics::ctpop(self as $ActualT) as u32
        }
        ...
        ...

        //字节序调整,后继大小端变换使用
        pub const fn swap_bytes(self) -> Self {
            intrinsics::bswap(self as $ActualT) as Self
        }
        
        //big endian 到硬件架构字节序
        pub const fn from_be(x: Self) -> Self {
            #[cfg(target_endian = "big")]
            {
                x
            }
            #[cfg(not(target_endian = "big"))]
            {
                x.swap_bytes()
            }
        }

        //little endian 转换为硬件架构字节序
        pub const fn from_le(x: Self) -> Self {
            #[cfg(target_endian = "little")]
            {
                x
            }
            #[cfg(not(target_endian = "little"))]
            {
                x.swap_bytes()
            }
        }

        //硬件架构字节序到big endian
        pub const fn to_be(self) -> Self { // or not to be?
            #[cfg(target_endian = "big")]
            {
                self
            }
            #[cfg(not(target_endian = "big"))]
            {
                self.swap_bytes()
            }
        }

        //硬件架构字节序到little endian
        pub const fn to_le(self) -> Self {
            #[cfg(target_endian = "little")]
            {
                self
            }
            #[cfg(not(target_endian = "little"))]
            {
                self.swap_bytes()
            }
        }

        //获得大端字节序字节数组
        pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
            self.to_be().to_ne_bytes()
        }
        
        //获得小端
        pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
            self.to_le().to_ne_bytes()
        }
        
        //硬件平台字节序
        pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
            unsafe { mem::transmute(self) }
        }
        
        //从big endian 字节数组获得类型值
        pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
            Self::from_be(Self::from_ne_bytes(bytes))
        }

        //从little endian 字节数组获得类型值
        pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
            Self::from_le(Self::from_ne_bytes(bytes))
        }

        //从硬件架构字节序字节数组获得类型值
        pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
            unsafe { mem::transmute(bytes) }
        }

        //对溢出做检查的加法运算
        //这里每种类型运算都以加法为例,其他诸如减、乘、除、幂次请参考官方标准库手册
        //
        pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
            let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
            (a as Self, b)
        }
        //其他的对溢出做检查的数学运算,略
        ...
        ...
        
        //以边界值取余的加法
        pub const fn wrapping_add(self, rhs: Self) -> Self {
            intrinsics::wrapping_add(self, rhs)
        }
        //以边界值取余的其他数学运算行为,略
        ...
        ...

        //饱和加法,超过边界值结果为边界值
        pub const fn saturating_add(self, rhs: Self) -> Self {
            intrinsics::saturating_add(self, rhs)
        }
        //其他饱和型的数学运算,略
        ...
        ...

        //对加法有效性检查的加法运算,如发生溢出,则返回异常
        pub const fn checked_add(self, rhs: Self) -> Option<Self> {
            let (a, b) = self.overflowing_add(rhs);
            if unlikely!(b) {None} else {Some(a)}
        }

        //无检查add,  是 + 符号的默认调用函数。
        pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
            // 调用者要保证不发生错误
            unsafe { intrinsics::unchecked_add(self, rhs) }
        }
        //其他对有效性检查的数学运算, 略
        ...
        ...
        
        pub const fn min_value() -> Self { Self::MIN }

        pub const fn max_value() -> Self { Self::MAX }
}

impl u8 {
    //利用宏实现 u8类型的行为
    uint_impl! { u8, u8, i8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
    "[0x12]", "", "" }
    
    pub const fn is_ascii(&self) -> bool {
        *self & 128 == 0
    }
    
    //其他ASCII相关函数,请参考标准库手册,略
    ...
    ...
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

任成珺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值