Motivation
NIO-based callers (channels, networking, mmap via FileChannel.map) hold data in ByteBuffer. Today they must extract a byte[] to use the API. A direct ByteBuffer is off-heap and can be wrapped as a MemorySegment with no copy — a natural fit for this binding's zero-copy story.
Proposal
Add ByteBuffer overloads (on Zstd, or a small dedicated entry point):
public static ByteBuffer compress(ByteBuffer src, int level);
public static ByteBuffer decompress(ByteBuffer src, int maxSize);
- For a direct buffer: wrap
MemorySegment.ofBuffer(src) — zero copy in.
- For a heap buffer: fall back to the array path.
- Respect
position()/limit(); advance position like other NIO ops.
Acceptance criteria
- Both direct and heap buffers handled; position/limit semantics documented and tested.
/// javadoc per CLAUDE.md; javadoc build clean.
- Tests cover direct + heap, empty, and a round-trip against the existing
byte[] path.
Notes
See docs/zero-copy.md for the segment-first philosophy this should follow.
Pointers
zstd/src/main/java/io/github/dfa1/zstd/Zstd.java
Motivation
NIO-based callers (channels, networking, mmap via
FileChannel.map) hold data inByteBuffer. Today they must extract abyte[]to use the API. A directByteBufferis off-heap and can be wrapped as aMemorySegmentwith no copy — a natural fit for this binding's zero-copy story.Proposal
Add
ByteBufferoverloads (onZstd, or a small dedicated entry point):MemorySegment.ofBuffer(src)— zero copy in.position()/limit(); advancepositionlike other NIO ops.Acceptance criteria
///javadoc perCLAUDE.md; javadoc build clean.byte[]path.Notes
See
docs/zero-copy.mdfor the segment-first philosophy this should follow.Pointers
zstd/src/main/java/io/github/dfa1/zstd/Zstd.java