In JavaScript, a DataView
is used when you need to access a block of memory with:
uint8
, uint16
, uint32
, float32
etc) DataView
s are commonly used for networking code, parsing and creating binary file formats, and for implementing virtual machines. While the first two could make do with only sequential access, virtual machines which use a DataView
as their RAM need to be able to access it freely (randomly even!)
Is there a corresponding library in Rust? I've seen bytes and byteorder but they seem more designed for streaming/sequential access rather than free random access.
As a systems language, Rust natively has the ability to interact with raw memory, without requiring a specific wrapper.
Therefore, reading a u32
out of memory simply requires a sprinkling of 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) }
}
This raw ability can be used to build better abstractions. Notably, abstractions taking care of alignment and endianness.
The byteorder
crate provides such abstraction: the LitteEndian
and BigEndian
types both implement the ByteOrder
trait.
The above function can be improved to:
fn read_u32(bytes: &[u8]) -> u32 { LittleEndian::read_u32(bytes) }
which will take care of:
It only really accounts for primitive types, though, which is where the bytes
crate steps in.
For example, let's decode a 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(),
}
}
Which uses the Cursor
struct from standard library and its implementation of the Buf
trait from bytes
.
You can create the cursor around a slice of bytes ( &[u8]
) starting at any point of memory; reading from it advances it, positioning it for the next read, and it will handle alignment, endianness and bounds-checking.
Note: unfortunately, there doesn't appear to be a version returning Option<u16>
; I'd probably extend it if this was a concern.
Thus I think you've got the right idea with the listed crates, they cover all the requirements you laid out.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.