Skip to content

types: add decode_bytes_to_bytes for zero-copy bytes_fields decode#84

Open
iainmcgin wants to merge 1 commit intomainfrom
fix/bytes-decode-zerocopy
Open

types: add decode_bytes_to_bytes for zero-copy bytes_fields decode#84
iainmcgin wants to merge 1 commit intomainfrom
fix/bytes-decode-zerocopy

Conversation

@iainmcgin
Copy link
Copy Markdown
Collaborator

Closes #53. Partially addresses #76 (item b only — items a and d are deferred to 0.5.0, item c landed in #77).

What

  • New buffa::types::decode_bytes_to_bytes(buf: &mut impl Buf) -> Result<Bytes, DecodeError> reads a length-delimited bytes value via Buf::copy_to_bytes. When buf is Bytes-backed this is a zero-copy split_to; for &[u8] it falls back to alloc+copy (same cost as before).
  • The four bytes_fields codegen sites in impl_message.rs (singular implicit, singular optional, repeated, oneof) now emit decode_bytes_to_bytes(buf)? instead of Bytes::from(decode_bytes(buf)?).
  • view::bytes_from_source now uses checked_add instead of wrapping_add for the pointer-range containment check, so an overflowing end-pointer falls back to copy rather than reaching slice_ref's internal panic. Defensive only — unreachable on real allocators.
  • Regenerated buffa-types/src/generated/google.protobuf.any.rs (only WKT with a bytes_fields field).

Memory retention note

In the zero-copy case the resulting field aliases the source allocation, so the source buffer is freed only once every aliased field is dropped. Documented on the new helper and in the CHANGELOG.

Semver

Additive only (new public function; generated-code call sites switch to a function that ships in the same crate version). Suitable for 0.4.1.

Testing

  • Unit tests for decode_bytes_to_bytes: zero-copy aliasing from Bytes, &[u8] fallback, empty, truncated.
  • End-to-end test in buffa-test decodes BytesContexts from a Bytes buffer and asserts pointer aliasing for all four field shapes.
  • cargo +1.95 clippy --workspace --all-targets -- -D warnings, cargo +1.95 test --workspace, task check-nostd, task lint-md all pass.

Generated merge_field arms for bytes_fields-tagged fields now call
Buf::copy_to_bytes via the new helper instead of allocating a Vec and
wrapping it; decoding from a Bytes-backed buffer becomes a refcount bump.
Also hardens bytes_from_source's pointer-range containment check with
checked_add (closes #76 item b).
@github-actions
Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@iainmcgin iainmcgin requested a review from asacamano April 29, 2026 21:38
@iainmcgin iainmcgin marked this pull request as ready for review April 29, 2026 21:39
@iainmcgin iainmcgin enabled auto-merge (squash) April 29, 2026 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

decode_bytes could produce Bytes zero-copy via Buf::copy_to_bytes

1 participant