Overview
A lightweight library for reading and writing binary buffers. Although originally designed to work with Channels and part of the same project, it has no dependency on it and can be used independently.
Design
Buffer instances are always specialized for either reading or writing, never both.
- Use
IReadableByteBufferfor reading - Use
IWritableByteBufferfor writing
This separation simplifies the API surface and allows each implementation to be optimized for its specific purpose.
Using buffers
Outside of Channels, or when needed explicitly:
- Use
WritableByteBufferto create a writable buffer. - Use
ReadableByteBufferto wrap abyte[].
Reading Data
There are four ways to retrieve data:
- Get does not change the current offset
- Read advances the offset
- TryRead performs tentative reads that only advance the offset if successful
- Checkpoints allow speculative multi-step reads with rollback support
IReadableByteBuffer buffer = ...;
// Reads at a custom offset (does not change buffer offset)
var b1 = buffer.GetByte( customOffset );
// Reads at current offset and advances it by 1
// Throws an exception if insufficient data exists
var b2 = buffer.ReadByte();
// Attempts to read without throwing if insufficient data exists
if ( buffer.TryReadInt32( out var value ) )
{
// value successfully read
}
// Speculative read with rollback support
using var checkpoint = buffer.Checkpoint();
try
{
var b3 = buffer.ReadByte();
var i1 = buffer.ReadInt32();
// Commit the checkpoint to make the offset changes permanent
checkpoint.Commit();
}
catch ( ArgumentOutOfRangeException )
{
// Rollback to the checkpointed offset if not committed
}
Good to know...
ReadableBytesexposes how many bytes remain unread.ResetOffsetresets the read offset to the beginning.ToArray()returns the full logical contents of the buffer (respecting view boundaries).GetByteBufferandReadByteBufferreturn zero-copy views.- Except for reading/getting methods, the API follows a fluent design.
IWritableByteBufferis not expected in the input pipeline middleware.