Skip to content

Instantly share code, notes, and snippets.

@adamse
Last active November 15, 2022 23:47
Show Gist options
  • Save adamse/17a27c3631e3e9de002c05bac269704c to your computer and use it in GitHub Desktop.
Save adamse/17a27c3631e3e9de002c05bac269704c to your computer and use it in GitHub Desktop.
#![feature(split_array)]
// https://rust.godbolt.org/z/6o5T55K9v
/// Consume a value which implements `from_le_bytes` from a buffer, advancing
/// the buffer beyond the bytes that were consumed
#[macro_export]
macro_rules! consume {
($buf:expr, $ty:ty) => {{
const SIZE: usize = std::mem::size_of::<$ty>();
// check that we have enough bytes to extract a $ty
// + 1 instead of >= because >= confuses llvm/rustc so it
// refuses to fuse multiple checks with multiple consume! calls
if $buf.len() + 1 > SIZE {
// split into &[u8; SIZE] and &[u8]
let (x, rest) = $buf.split_array_ref::<SIZE>();
// get the val
let val = <$ty>::from_le_bytes(*x);
// advance the buffer
$buf = rest;
Some(val)
} else {
None
}
}}
}
pub fn parse(mut ptr: &[u8]) -> Option<(u32, u64, u32, u32)> {
Some((
consume!(ptr, u32)?,
consume!(ptr, u64)?,
consume!(ptr, u32)?,
consume!(ptr, u32)?,
))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment