Trait packet::TargetBuffer

source ·
pub trait TargetBuffer: GrowBufferMut {
    // Required method
    fn with_parts<O, F>(&mut self, f: F) -> O
       where F: for<'a, 'b> FnOnce(&'a mut [u8], FragmentedBytesMut<'a, 'b>, &'a mut [u8]) -> O;

    // Provided method
    fn serialize<B: PacketBuilder>(&mut self, c: PacketConstraints, builder: B) { ... }
Expand description

A buffer that can be serialized into.

TargetBuffer is a GrowBufferMut that can be serialized into. A TargetBuffer MAY have a fragmented body but it MUST NOT have a fragmented prefix or suffix. That is a requirement to be able to generate a SerializeBuffer, creating a contiguous header and footer from the TargetBuffer’s contiguous prefix and suffix, respectively.

This guarantee allows for complex buffer setups that reuse a body from incoming data, but need to serialize a new header or footer around that body, e.g., a scatter-gather buffer that has dedicated space for serializing new headers and footers and reuses the body from another buffer.

Because TargetBuffer is a sub-trait of GrowBufferMut but NOT of ShrinkBuffer, implementers may guarantee a correct implementation that always provides a contiguous prefix and suffix without resorting to runtime panics. [1]

[1] If TargetBuffer were also a sub-trait of ShrinkBuffer, then it would be possible to start off with a buffer with a fragmented body, and then shrink the buffer such that the prefix or suffix would become fragmented, which would be a violation of TargetBuffer’s invariants. The only option, in this case, would be to panic.

Required Methods§


fn with_parts<O, F>(&mut self, f: F) -> Owhere F: for<'a, 'b> FnOnce(&'a mut [u8], FragmentedBytesMut<'a, 'b>, &'a mut [u8]) -> O,

Gets a view into the parts of this TargetBuffer.

Calls f, passing the prefix, body, and suffix as arguments (in that order).

Provided Methods§


fn serialize<B: PacketBuilder>(&mut self, c: PacketConstraints, builder: B)

Serializes a packet in the buffer.

serialize serializes the packet with constraints c described in builder into the buffer. The body of the buffer is used as the body of the packet, and the prefix and suffix of the buffer are used to serialize the packet’s header and footer. This is a low-level function; you probably want the Serializer trait instead.

If builder has a minimum body size which is larger than the current body, then serialize first grows the body to the right (towards the end of the buffer) with padding bytes in order to meet the minimum body size. This is transparent to the builder - it always just sees a body which meets the minimum body size requirement.

The added padding is zeroed in order to avoid leaking the contents of packets previously stored in the buffer.


serialize assumes that c came from builder. If it didn’t, then builder.serialize() may be called with arguments that cause unspecified behavior, possibly including panicking.

serialize also panics if there are not enough prefix or suffix bytes to serialize the packet. In particular, b.serialize(c, builder) panics if either of the following hold:

  • b.prefix_len() < c.header_len()
  • b.len() + b.suffix_len() < c.min_body_bytes() + c.footer_len()

Implementations on Foreign Types§


impl TargetBuffer for Never


fn with_parts<O, F>(&mut self, _f: F) -> Owhere F: for<'a, 'b> FnOnce(&'a mut [u8], FragmentedBytesMut<'a, 'b>, &'a mut [u8]) -> O,