如何使用字节顺序板条箱读取usize?

时间:2018-11-05 19:58:35

标签: rust

我正在编写一个编码库,我想将slice转换为usize

我看到一个read_uint方法看起来很有希望,尽管我不确定如何将寄存器大小作为变量获取,因此可以将其放入函数中。

例如,我想在32位处理器上获得32,在64位处理器上获得64

2 个答案:

答案 0 :(得分:3)

一种方法是使用mem::size_of获得usize的大小:

use byteorder::{ByteOrder, ReadBytesExt};

fn read_usize<B, R>(mut b: R) -> Result<usize, std::io::Error>
where
    B: ByteOrder,
    R: ReadBytesExt,
{
    b.read_uint::<B>(std::mem::size_of::<usize>()).map(|v| v as usize)
}

另一种是针对不同的体系结构具有不同的功能或功能实现:

fn read_usize<B, R>(mut b: R) -> Result<usize, std::io::Error>
where
    B: ByteOrder,
    R: ReadBytesExt,
{
    if cfg!(target_pointer_width = "64") {
        b.read_u64::<B>().map(|v| v as usize)
    } else if cfg!(target_pointer_width = "32") {
        b.read_u32::<B>().map(|v| v as usize)
    } else {
        b.read_u16::<B>().map(|v| v as usize)
    }
}

另请参阅:

答案 1 :(得分:3)

TL; DR有一个不提供read_usize函数的充分理由,因为它在不同的cpu架构上不一致。


这是一个坏主意。通常,您要尝试反序列化某种协议。此格式应独立于cpu架构,因此您不能读取usize,因为它取决于cpu。

我们假设您有一个简单的协议,首先要拥有一个数组的大小,然后是n个元素。

+------+---------+
| size | ....... |
+------+---------+

让我们假设该协议说您的大小为4字节长。现在,您要执行Shepmaster建议的操作,并阅读取决于您的体系结构的usize。

在x86_64操作系统上,您现在将读取8个字节,因此吞噬了数组中的第一个元素。
在Atmega8上,您的大小为2个字节,因此仅占用您大小的前2个字节(如果少于65k的元素和BigEndian字节顺序,则为零)。

这就是为什么没有read_usize函数并且它是正确的原因。您需要确定大小,从片中读取确切的字节数,然后我们as将其转换为usize