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

Typedefs

typedef bool(* bufringZCCB) (const uint8 *buf, size_t bytes, void *ctx)
 
typedef size_t(* bufringFeedCB) (uint8 *buf, size_t maxbytes, void *ctx)
 

Functions

void bufringInit (BufRing *ring, size_t segsz)
 
size_t bufringRead (BufRing *ring, uint8 *buf, size_t bytes)
 
size_t bufringReadBuf (BufRing *ring, Buffer buf, size_t maxbytes)
 
size_t bufringPeek (BufRing *ring, uint8 *buf, size_t off, size_t bytes)
 
size_t bufringPeekBuf (BufRing *ring, Buffer buf, size_t off, size_t maxbytes)
 
size_t bufringSkip (BufRing *ring, size_t bytes)
 
size_t bufringReadZC (BufRing *ring, size_t bytes, bufringZCCB cb, void *ctx)
 
void bufringWrite (BufRing *ring, const uint8 *buf, size_t bytes)
 
void bufringWriteBuf (BufRing *ring, Buffer buf)
 
void bufringWriteZC (BufRing *ring, Buffer *buf)
 
size_t bufringWriteSpace (BufRing *ring)
 
size_t bufringFeed (BufRing *ring, bufringFeedCB feed, size_t bytes, void *ctx)
 
void bufringDestroy (BufRing *ring)
 

Detailed Description

A ring buffer that provides efficient streaming I/O with minimal memory allocation overhead and automatic capacity expansion. Data is read from the head and written to the tail, with automatic capacity expansion and cleanup as needed.

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:

BufRing ring;
bufringInit(&ring, 4096);
// Write data
bufringWrite(&ring, data, dataLen);
// Read data
uint8 buffer[1024];
size_t nread = bufringRead(&ring, buffer, sizeof(buffer));
void bufringWrite(BufRing *ring, const uint8 *buf, size_t bytes)
void bufringInit(BufRing *ring, size_t segsz)
size_t bufringRead(BufRing *ring, uint8 *buf, size_t bytes)
void bufringDestroy(BufRing *ring)

Typedef Documentation

◆ bufringFeedCB

typedef size_t(* bufringFeedCB) (uint8 *buf, size_t maxbytes, void *ctx)

Callback for feeding data into a ring buffer.

The callback is invoked to write data directly into the ring buffer's internal storage. This enables efficient data transfer without intermediate copying. The callback should write up to maxbytes into the provided buffer and return the actual number of bytes written.

If the callback returns 0, the feed operation stops. The callback may be invoked multiple times to fill the requested amount.

Parameters
bufPointer to the buffer where data should be written
maxbytesMaximum number of bytes that can be written
ctxUser-defined context pointer
Returns
Number of bytes actually written (0 to stop feeding)

Definition at line 89 of file bufring.h.

◆ bufringZCCB

typedef bool(* bufringZCCB) (const uint8 *buf, size_t bytes, void *ctx)

Callback for zero-copy buffer reads.

The callback is invoked for each contiguous segment of data in the ring buffer. It must consistently return the same value (true or false) for all invocations during a single read operation, as the ring buffer only supports all-or-nothing consumption.

Parameters
bufPointer to the contiguous data buffer segment
bytesNumber of valid bytes in this buffer segment
ctxUser-defined context pointer
Returns
true to consume all data from the read operation, false to retain all data

Definition at line 72 of file bufring.h.

Function Documentation

◆ bufringDestroy()

void bufringDestroy ( BufRing *  ring)

Destroy a ring buffer and free all associated resources.

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

Parameters
ringPointer to the ring buffer to destroy

◆ bufringFeed()

size_t bufringFeed ( BufRing *  ring,
bufringFeedCB  feed,
size_t  bytes,
void *  ctx 
)

Feed data into a ring buffer using a callback.

Allows a callback to write data directly into the ring buffer's internal storage, avoiding intermediate copying. The callback is invoked one or more times with pointers to available buffer space. This is particularly useful for reading from files, network sockets, or other data sources directly into the buffer.

The function attempts to feed up to 'bytes' amount of data. The callback may be invoked multiple times to reach this goal, and can return 0 to stop the operation early. New segments are automatically allocated as needed.

Parameters
ringPointer to the ring buffer to feed data into
feedCallback function that writes data to the buffer
bytesMaximum number of bytes to feed
ctxUser-defined context pointer passed to the callback
Returns
Total number of bytes actually fed into the buffer
Note
The callback can return 0 to stop feeding. Writes are automatically split at segment boundaries to maintain ring buffer integrity.

◆ bufringInit()

void bufringInit ( BufRing *  ring,
size_t  segsz 
)

Initialize an empty ring buffer.

Creates an empty ring buffer 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
ringPointer to the ring buffer to initialize
segszSize of each buffer segment in bytes (minimum 64)

◆ bufringPeek()

size_t bufringPeek ( BufRing *  ring,
uint8 *  buf,
size_t  off,
size_t  bytes 
)

Peek at data in a ring buffer without removing it.

Reads data from the ring buffer without consuming it. The data remains in the buffer 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
ringPointer to the ring buffer to peek into
bufPointer to the user buffer to copy data into
offOffset within the ring buffer to start peeking from
bytesNumber of bytes to peek at
Returns
Number of bytes actually copied (may be less if buffer has insufficient data)

Referenced by bufringPeekBuf().

◆ bufringPeekBuf()

size_t bufringPeekBuf ( BufRing *  ring,
Buffer  buf,
size_t  off,
size_t  maxbytes 
)
inline

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

Convenience function that peeks data from the ring buffer 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
ringPointer to the ring buffer to peek into
bufBuffer object to copy data into
offOffset within the ring buffer to start peeking from
maxbytesMaximum number of bytes to peek at
Returns
Number of bytes actually copied (stored in buf->len)

Definition at line 156 of file bufring.h.

References bufringPeek().

◆ bufringRead()

size_t bufringRead ( BufRing *  ring,
uint8 *  buf,
size_t  bytes 
)

Read data from a ring buffer into a user buffer.

Reads up to the specified number of bytes from the ring buffer and removes them from the buffer. Data is read sequentially from the head. Exhausted capacity is automatically freed, except the base segment which is retained for reuse.

Parameters
ringPointer to the ring buffer 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 buffer has insufficient data)

Referenced by bufringReadBuf().

◆ bufringReadBuf()

size_t bufringReadBuf ( BufRing *  ring,
Buffer  buf,
size_t  maxbytes 
)
inline

Read data from a ring buffer into a buffer object.

Convenience function that reads data from the ring buffer 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
ringPointer to the ring buffer 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 124 of file bufring.h.

References bufringRead().

◆ bufringReadZC()

size_t bufringReadZC ( BufRing *  ring,
size_t  bytes,
bufringZCCB  cb,
void *  ctx 
)

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

Reads data from the ring buffer by invoking a callback for each contiguous segment, passing pointers directly to the internal buffer data without copying. This is the most efficient way to process data in the buffer.

The callback must consistently return the same value (true or false) for all segments in a single read operation. If the callback returns true for all segments, the data is consumed and removed from the buffer. If it returns false for any segment, all data is retained (all-or-nothing semantics).

Parameters
cringPointer to the ring buffer to read from
bytesMaximum number of bytes to read
cbCallback function to process each buffer segment
ctxUser-defined context pointer passed to the callback
Returns
Number of bytes actually sent to the callback
Note
The callback must return the same value consistently across all invocations during a single read operation.

◆ bufringSkip()

size_t bufringSkip ( BufRing *  ring,
size_t  bytes 
)

Skip data in a ring buffer.

Discards data from the head of the ring buffer without copying it. This is more efficient than reading into a dummy buffer when you need to discard data. Exhausted capacity is automatically freed, except the base segment which is retained for reuse.

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

◆ bufringWrite()

void bufringWrite ( BufRing *  ring,
const uint8 *  buf,
size_t  bytes 
)

Write data from a user buffer into a ring buffer.

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

Parameters
ringPointer to the ring buffer to write to
bufPointer to the user buffer containing data to write
bytesNumber of bytes to write

Referenced by bufringWriteBuf().

◆ bufringWriteBuf()

void bufringWriteBuf ( BufRing *  ring,
Buffer  buf 
)
inline

Write data from a buffer object into a ring buffer.

Convenience function that writes the contents of a buffer object to the ring buffer. 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
ringPointer to the ring buffer to write to
bufBuffer object containing data to write

Definition at line 213 of file bufring.h.

References bufringWrite().

◆ bufringWriteSpace()

size_t bufringWriteSpace ( BufRing *  ring)

Get available write space in the ring buffer without expansion.

Returns the number of bytes that can be written to the current tail segment without allocating a new segment. This is useful for determining if a write operation can complete without triggering expansion, or for optimizing feed operations.

Parameters
ringPointer to the ring buffer to query
Returns
Number of bytes available for writing in the current tail segment (0 if empty)

◆ bufringWriteZC()

void bufringWriteZC ( BufRing *  ring,
Buffer buf 
)

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

Appends a pre-allocated buffer object to the tail of the ring buffer without copying. This is the most efficient way to add data to the buffer when you already have it in a buffer object. The ring buffer takes ownership of the buffer object and will destroy it when the data is consumed or when the ring buffer 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.

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