rust - Rust 中 JavaScript 的 DataView 相当于什么?

标签 rust

在 JavaScript 中,当您需要通过以下方式访问内存块时,将使用 DataView:

  • 不同的宽度类型(uint8uint16uint32float32 等)
  • 未对齐的数据
  • 特定的字节顺序

DataView 通常用于网络代码、解析和创建二进制文件格式以及实现虚拟机。虽然前两个只能进行顺序访问,但使用 DataView 作为 RAM 的虚拟机需要能够自由访问(甚至随机!)

Rust中有对应的库吗?我见过bytesbyteorder但它们似乎更适合流式/顺序访问而不是免费随机访问。

最佳答案

作为一种系统语言,Rust 本身就有能力与原始内存交互,而不需要特定的包装器。

因此,阅读 u32内存不足只需要少量 unsafe :

fn read_u32(bytes: &[u8]) -> u32 {
    assert!(bytes.as_ptr() as usize % std::mem::align_of::<u32>() == 0);
    assert!(bytes.len() >= 4);

    unsafe { *(bytes.as_ptr() as *const u32) }
}

这种原始能力可用于构建更好的抽象。值得注意的是,抽象负责处理对齐和字节顺序。


byteorder crate 提供了这样的抽象:LitteEndianBigEndian类型都实现 ByteOrder 特质。

上述函数可以改进为:

fn read_u32(bytes: &[u8]) -> u32 { LittleEndian::read_u32(bytes) }

它将负责:

  • 正在执行转换。
  • 均匀地处理未对齐的访问,而不是出现 panic 。
  • 具有明确的字节顺序。

不过,它实际上只考虑了原始类型,这就是 bytes 的位置。 crate 介入。

例如,让我们解码 UDP Header :

use std::io::Cursor;
use bytes::buf::Buf;

struct UdpHeader {
    src_port: u16,
    dst_port: u16,
    length: u16,
    checksum: u16,
}

fn read_udp_header<T: AsRef<[u8]>>(bytes: &mut Cursor<T>) -> UdpHeader {
    UdpHeader {
        src_port: bytes.read_u16_be(),
        dst_port: bytes.read_u16_be(),
        length: bytes.read_u16_be(),
        checksum: bytes.read_u16_be(),
    }
}

它使用 Cursor 标准库中的结构及其 Buf 的实现来自bytes的特征.

您可以在从内存任意点开始的 byte slice ( &[u8] ) 周围创建光标;读取它会推进它,为下一次读取定位它,它将处理对齐、字节序和边界检查。

注意:不幸的是,似乎没有版本返回 Option<u16> ;如果这是一个问题,我可能会延长它。


因此,我认为您对列出的 crate 有正确的想法,它们涵盖了您提出的所有要求。

关于rust - Rust 中 JavaScript 的 DataView 相当于什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53137252/

相关文章:

rust - "the trait is not implemented for Self"尽管它完全是

rust - 是否可以连接迭代器?

rust - 在 Piston2d 中渲染文本的函数中的 GlyphCache 类型是什么

rust - 为什么我在 Rust Playground 上得到 "Response was not JSON"?

rust - extrinsics 选项卡中没有可用的 `kitties` 模块

rust - rustc 生成的 LLVM 在使用 lli 运​​行时会给出有关 main 参数类型的错误

rust - 如何离线阅读 Rust 文档?

windows - Rust:如何对SAFESEH图像进行链接不安全

rust - 是否可以在不实现 `Index` 特征的情况下通过字段名称获取结构中的值?

rust - 如何使用 Axum/Tower 压缩 HTML 内容?