Skip to content

A (Try)FromBytes #[length] field attribute #1328

@jswrenn

Description

@jswrenn

See also: #5 (comment)

Addresses #1289. Discussion of alternative solutions should occur there, or in their own issues.

Many formats include a length field in their header that describes the length of a variable-sized body; e.g., UDP:

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
    src_port: [u8; 2],
    dst_port: [u8; 2],
    length: [u8; 2],
    checksum: [u8; 2],
    body: [u8],
}

Such types are inconvenient to correctly parse in zerocopy; the length must first be parsed, and only then FromBytes::try_ref_from_prefix_with_elems can be invoked with that length. Alternatively, the entire buffer can be parsed with try_ref_from_prefix, and then truncated thereafter. These approaches are inconvenient.

We could potentially simplify this with a #[length] field attribute; e.g.:

#[derive(FromBytes, KnownLayout, Immutable)]
#[repr(C)]
struct Packet {
    src_port: [u8; 2],
    dst_port: [u8; 2],
    #[zerocopy::length]
    length: [u8; 2],
    checksum: [u8; 2],
    body: [u8],
}

...such that FromBytes::ref_from_prefix would respect the length attribute.

Some considerations:

  • This attribute should accept a function for cases in which the length in bytes must be computed
  • This approach should also work on TryFromBytes, where excess data might be invalid
  • Should we attempt to support the case where the length is factored into a different, fixed-sized header type?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions