CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
Buffer Chain

Typedefs

typedef bool(* bufchainZCCB) (Buffer buf, size_t off, void *ctx)
 

Functions

void bufchainInit (BufChain *chain, size_t segsz)
 
size_t bufchainRead (BufChain *chain, uint8 *buf, size_t bytes)
 
size_t bufchainReadBuf (BufChain *chain, Buffer buf, size_t maxbytes)
 
size_t bufchainPeek (BufChain *chain, uint8 *buf, size_t off, size_t bytes)
 
size_t bufchainPeekBuf (BufChain *chain, Buffer buf, size_t off, size_t maxbytes)
 
size_t bufchainSkip (BufChain *chain, size_t bytes)
 
size_t bufchainReadZC (BufChain *chain, size_t maxbytes, bufchainZCCB cb, void *ctx)
 
void bufchainWrite (BufChain *chain, const uint8 *buf, size_t bytes)
 
void bufchainWriteBuf (BufChain *chain, Buffer buf)
 
void bufchainWriteZC (BufChain *chain, Buffer *buf)
 
void bufchainDestroy (BufChain *chain)
 

Detailed Description

A buffer chain that provides efficient streaming I/O with true zero-copy semantics. Data is read from the head and written to the tail as complete buffer segments, with automatic capacity expansion and cleanup as needed.

Unlike BufRing, BufChain uses simple sequential buffers rather than ring buffers, making it less efficient for repeated small read/write operations on raw bytes, but more efficient for zero-copy operations since it can transfer buffer ownership directly to consumers.

As a tradeoff, when performing zero-copy reads, the callback only receives complete buffers rather than a byte range, and cannot operate in peek mode. If a partial read has been performed on the head segment (using bufchainRead), the zero-copy callback will receive an offset indicating where the valid data begins in that buffer.

Key features:

The minimum segment size is 64 bytes. Smaller values will be clamped to this minimum.

Note
For optimal performance, this implementation is not thread-safe. If access from multiple threads is required, wrap operations with an appropriate lock.

Example:

BufChain chain;
bufchainInit(&chain, 4096);
// Write data
bufchainWrite(&chain, data, dataLen);
// Read data
uint8 buffer[1024];
size_t nread = bufchainRead(&chain, buffer, sizeof(buffer));
void bufchainInit(BufChain *chain, size_t segsz)
void bufchainWrite(BufChain *chain, const uint8 *buf, size_t bytes)
void bufchainDestroy(BufChain *chain)
size_t bufchainRead(BufChain *chain, uint8 *buf, size_t bytes)

Typedef Documentation

◆ bufchainZCCB

typedef bool(* bufchainZCCB) (Buffer buf, size_t off, void *ctx)

Callback for zero-copy buffer reads.

The callback is invoked for each complete buffer segment in the chain. Unlike BufRing's zero-copy callback, this callback receives ownership of the buffer object and MUST destroy it or otherwise dispose of it. This enables true zero-copy operation.

The callback is only invoked for complete segments; partial segments are not sent to preserve the ability to transfer ownership. If data has been previously read from the buffer using bufchainRead(), the offset parameter indicates where the valid data starts.

Parameters
bufBuffer object to process (ownership transferred to callback, must destroy)
offOffset within buffer where valid data starts (may be nonzero)
ctxUser-defined context pointer
Returns
true to continue reading more segments, false to stop

Definition at line 82 of file bufchain.h.

Function Documentation

◆ bufchainDestroy()

void bufchainDestroy ( BufChain *  chain)

Destroy a buffer chain and free all associated resources.

Frees all segments and their associated data buffers, then resets the chain structure to an empty state. After calling this function, the chain must be reinitialized with bufchainInit() before it can be used again.

Parameters
chainPointer to the buffer chain to destroy

◆ bufchainInit()

void bufchainInit ( BufChain *  chain,
size_t  segsz 
)

Initialize an empty buffer chain.

Creates an empty buffer chain with the specified segment size. Additional capacity will be allocated as needed when data is written. The segment size will be clamped to a minimum of 64 bytes.

Parameters
chainPointer to the buffer chain to initialize
segszSize of each buffer segment in bytes (minimum 64)

◆ bufchainPeek()

size_t bufchainPeek ( BufChain *  chain,
uint8 *  buf,
size_t  off,
size_t  bytes 
)

Peek at data in a buffer chain without removing it.

Reads data from the buffer chain without consuming it. The data remains in the chain and the read position is not advanced. This is useful for protocol parsing where you need to examine data before deciding whether to consume it.

Parameters
chainPointer to the buffer chain to peek into
bufPointer to the user buffer to copy data into
offOffset within the buffer chain to start peeking from
bytesNumber of bytes to peek at
Returns
Number of bytes actually copied (may be less if chain has insufficient data)

Referenced by bufchainPeekBuf().

◆ bufchainPeekBuf()

size_t bufchainPeekBuf ( BufChain *  chain,
Buffer  buf,
size_t  off,
size_t  maxbytes 
)
inline

Peek at data in a buffer chain into a buffer object.

Convenience function that peeks data from the buffer chain into an existing buffer object without consuming it. Updates the buffer's length field to reflect the number of bytes actually copied. The maximum bytes copied is limited by both maxbytes and the buffer's allocated size.

Parameters
chainPointer to the buffer chain to peek into
bufBuffer object to copy data into
offOffset within the buffer chain to start peeking from
maxbytesMaximum number of bytes to peek at
Returns
Number of bytes actually copied (stored in buf->len)

Definition at line 148 of file bufchain.h.

References bufchainPeek().

◆ bufchainRead()

size_t bufchainRead ( BufChain *  chain,
uint8 *  buf,
size_t  bytes 
)

Read data from a buffer chain into a user buffer.

Reads up to the specified number of bytes from the buffer chain and removes them from the chain. Data is read sequentially from the head. Exhausted segments are automatically freed.

Parameters
chainPointer to the buffer chain to read from
bufPointer to the user buffer to read data into
bytesMaximum number of bytes to read
Returns
Number of bytes actually read (may be less if chain has insufficient data)

Referenced by bufchainReadBuf().

◆ bufchainReadBuf()

size_t bufchainReadBuf ( BufChain *  chain,
Buffer  buf,
size_t  maxbytes 
)
inline

Read data from a buffer chain into a buffer object.

Convenience function that reads data from the buffer chain into an existing buffer object. Updates the buffer's length field to reflect the number of bytes actually read. The maximum bytes read is limited by both maxbytes and the buffer's allocated size.

Parameters
chainPointer to the buffer chain to read from
bufBuffer object to read data into
maxbytesMaximum number of bytes to read
Returns
Number of bytes actually read (stored in buf->len)

Definition at line 116 of file bufchain.h.

References bufchainRead().

◆ bufchainReadZC()

size_t bufchainReadZC ( BufChain *  chain,
size_t  maxbytes,
bufchainZCCB  cb,
void *  ctx 
)

Read data from a buffer chain in zero-copy mode.

Reads data from the buffer chain by invoking a callback for each complete buffer segment, transferring ownership of the buffer object to the callback. This is the most efficient way to process data in the chain as it avoids copying entirely. The callback MUST destroy or otherwise dispose of each buffer it receives.

Unlike BufRing's zero-copy function, this only sends complete segments to the callback (not partial buffers), as partial reads cannot transfer ownership. The callback can stop reading by returning false.

Parameters
chainPointer to the buffer chain to read from
maxbytesMaximum number of bytes to read (limit, may read less)
cbCallback function that receives ownership of each buffer segment
ctxUser-defined context pointer passed to the callback
Returns
Number of bytes actually sent to the callback
Note
The callback receives buffer ownership and MUST destroy each buffer. Only complete segments are sent; partial buffers are not transferred.

◆ bufchainSkip()

size_t bufchainSkip ( BufChain *  chain,
size_t  bytes 
)

Skip data in a buffer chain.

Discards data from the head of the buffer chain without copying it. This is more efficient than reading into a dummy buffer when you need to discard data. Exhausted segments are automatically freed.

Parameters
chainPointer to the buffer chain to skip data in
bytesNumber of bytes to skip
Returns
Number of bytes actually skipped (may be less if chain has insufficient data)

◆ bufchainWrite()

void bufchainWrite ( BufChain *  chain,
const uint8 *  buf,
size_t  bytes 
)

Write data from a user buffer into a buffer chain.

Appends data to the tail of the buffer chain. If the current capacity is insufficient, additional capacity is automatically allocated as needed. Data is copied into the buffer chain.

Parameters
chainPointer to the buffer chain to write to
bufPointer to the user buffer containing data to write
bytesNumber of bytes to write

Referenced by bufchainWriteBuf().

◆ bufchainWriteBuf()

void bufchainWriteBuf ( BufChain *  chain,
Buffer  buf 
)
inline

Write data from a buffer object into a buffer chain.

Convenience function that writes the contents of a buffer object to the buffer chain. The data is copied and the buffer object remains owned by the caller. Uses the buffer's length field to determine how many bytes to write.

Parameters
chainPointer to the buffer chain to write to
bufBuffer object containing data to write

Definition at line 206 of file bufchain.h.

References bufchainWrite().

◆ bufchainWriteZC()

void bufchainWriteZC ( BufChain *  chain,
Buffer buf 
)

Append a buffer to a buffer chain for zero-copy mode.

Appends a pre-allocated buffer object to the tail of the buffer chain without copying. This is the most efficient way to add data to the chain when you already have it in a buffer object. The buffer chain takes ownership of the buffer object and will destroy it when the data is consumed or when the chain is destroyed. The buffer pointer is set to NULL after transfer.

The buffer's length field (buf->len) is used to determine how much valid data is in the buffer. The entire buffer is added as a segment.

Parameters
chainPointer to the existing buffer chain
bufPointer to buffer object to append (ownership transferred, set to NULL on return)
Note
The buffer chain takes ownership of the buffer object and will destroy it. After this call, *buf will be NULL.