0 Tage Serie
rust / expert
Snippet

Zero-Copy-Parsing von Binär-Headern über Lebenszeit-Referenzabbildung

Veranschaulicht das performante Parsen von Binärprotokollen ohne Allokation. Durch die direkte Verknüpfung der Lebenszeit des parsenden Struct-Felds mit dem Eingabe-Slice wird Speicherallokation vollständig vermieden.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
use std::convert::TryInto;
#[derive(Debug)]
pub struct BinaryPacket<'a> {
pub magic: &'a [u8; 4],
pub payload_len: u32,
pub payload: &'a [u8],
}
impl<'a> BinaryPacket<'a> {
pub fn parse(data: &'a [u8]) -> Result<Self, &'static str> {
if data.len() < 8 {
return Err("Data too short to contain header");
}
let magic: &'a [u8; 4] = data[0..4].try_into()
.map_err(|_| "Failed to parse magic bytes")?;
let len_bytes = data[4..8].try_into()
.map_err(|_| "Failed to parse length bytes")?;
let payload_len = u32::from_be_bytes(len_bytes);
let end_idx = 8 + payload_len as usize;
if data.len() < end_idx {
return Err("Data length does not match payload header length");
}
let payload = &data[8..end_idx];
Ok(Self { magic, payload_len, payload })
}
}
Erklärung
1
pub struct BinaryPacket<'a> {
Definiert eine Struktur mit lebenszeitgebundenen Referenzen auf den Quellpuffer.
2
let magic: &'a [u8; 4] = data[0..4].try_into()
Konvertiert den Sub-Slice in eine feste Array-Referenz von genau 4 Bytes.
3
let payload_len = u32::from_be_bytes(len_bytes);
Parst Big-Endian-Bytes zur Kompilierzeit in eine standardmäßige vorzeichenlose 32-Bit-Ganzzahl.
4
let payload = &data[8..end_idx];
Leiht den Nutzlastbereich des Original-Slices aus, ohne Daten zu kopieren.