zerocopy
zerocopy copied to clipboard
Request: Add FromBytes::read_from_prefix_split and read_from_suffix_split
It would be handy to have a FromBytes::read_from_(prefix/suffix)_split that returns a tuple of the T and the unused portion of the byte slice. Ref::new_from_prefix isn't quite the same in case the byte slice is unaligned, but we don't want to derive Unaligned on the type.
Something like this (playground)?
fn read_from_prefix_split<T>(bytes: &[u8]) -> Option<(T, &[u8])>
where
T: Sized + FromBytes,
{
Ref::<_, Unalign<T>>::new_unaligned_from_prefix(bytes)
.map(|(r, s)| (r.read().into_inner(), s))
}
Yeah that looks about right. I mean there's a number of ways to do it, you can just call FromBytes::read_from_prefix and then index into your byte buffer by sizeof<T>, but having it provided on FromBytes and able to be used in a small oneliner would be nice.
In our code, we often parse structures with fixed headers and then some dynamic portion, from a potentially unaligned buffer. To support this, it has been nice to have both options readily available (both preserving the suffix bytes and not), without having to reach for Ref
.
Ref
is powerful, but it's certainly more tedious to use. And it's arguably more dangerous (from a correctness perspective, not a safety one): since reading from an unaligned buffer requires even more typing than reading from/aliasing an aligned one, developers get lazy and just assume their buffer is aligned. And in their testing, it is. Then something subtle changes in the code, possibly far away from the call site, and runtime checks start failing.
Or developers write something like let foo = Foo::read_from_prefix(buf)?
followed by let buf = &buf[..size_of::<Foo>()]
, which is error prone from the type name duplication. (I guess size_of_val(&foo)
would also fix this, but it's still tedious to write.)
To solve this, we have a private crate that provides these kind of extra methods for use with zerocopy
, but we'd love to just standardize on a single crate. Since these methods aren't already in zerocopy
, I'm curious if we're "holding it wrong"--maybe there's a better way to do this kind of parsing? Do most users have aligned buffers? Or have unaligned struct definitions?
@jstarks Is that private crate open source? It'd be great to see what else you're needing to work around so that we can support your use cases!
Closed in https://github.com/google/zerocopy/pull/1059