ringbuff.c File Reference

Ring buffer implementation An IO buffer that attempts to minimize moving buffered data around. More...

#include "ctl/ctldef.h"
#include "ctl/debug.h"
#include "ctl/ctlnew.h"
#include "ctl/ringbuff.h"

Include dependency graph for ringbuff.c:

Go to the source code of this file.

Functions

void RingBuff_Init (RingBuff *self, void *buff, size_t size)
 Initialize a ring buffer with a buffer.
bool RingBuff_Space (RingBuff *self, uint8 **buff, size_t count)
bool RingBuff_Peek (RingBuff *self, const uint8 **buff, size_t count)
 Peek at read position.
bool RingBuff_Consume (RingBuff *self, size_t count)
 Consume bytes we peeked at.
bool RingBuff_Add (RingBuff *self, uint8 **buff, size_t count)
 Add data to the ring buffer.
bool RingBuff_Pop (RingBuff *self, const uint8 **buff, size_t count)
 Read data from current read position.
bool RingBuff_CopyTo (RingBuff *self, const void *buff, size_t count)
 Write data to the buffer.
bool RingBuff_CopyFrom (RingBuff *self, void *buff, size_t count)
 Read data from the buffer, wrapping it transparently.
bool RingBuff_AddSerial (RingBuff *self, ctl_serial *serial, size_t reserve)
 Reserve space for serial data in an atomic manner.
bool RingBuff_PeekSerial (RingBuff *self, ctl_serial *serial)
 Peek at serial packet data on queue.
bool RingBuff_PopSerial (RingBuff *self, ctl_serial *serial)
 Pop a packet of serial data off the stack.


Detailed Description

Ring buffer implementation An IO buffer that attempts to minimize moving buffered data around.

Ring buffer Re-uses the same buffer without moving data around much.

Author:
David Mace

Definition in file ringbuff.c.


Function Documentation

bool RingBuff_Add ( RingBuff *  self,
uint8 **  buff,
size_t  count 
)

Add data to the ring buffer.

Parameters:
self Pointer to instance of ring buffer
count Number of bytes to reserve
Returns:
true on success, false on failure

Definition at line 105 of file ringbuff.c.

References RingBuff_Space().

Referenced by RingBuff_AddSerial().

00106 {
00107     if( RingBuff_Space( self, buff, count ) )
00108     {   // Consume free space
00109         self->tail += count;
00110         return true;
00111     }
00112     return false;
00113 }

Here is the call graph for this function:

bool RingBuff_AddSerial ( RingBuff *  self,
ctl_serial serial,
size_t  reserve 
)

Reserve space for serial data in an atomic manner.

Parameters:
self Pointer to instance of ring buffer
serial Pointer to serial data to be filled in by this
reserve Amount of space to reserve in serial data
Returns:
true if there is enough space, false if not Guarantees if enough data is available, the serial packet will be in one piece

Definition at line 182 of file ringbuff.c.

References ctl_serial_init, RingBuff_Add(), and uint16_serial_write().

Referenced by Socket_Alloc_Serial().

00183 {
00184     uint8* space;
00185     uint16 size = 2 + reserve;
00186     if( RingBuff_Add( self, &space, size ) )
00187     {
00188         ctl_serial_init( serial, space, space + size );
00189         uint16_serial_write(&size, serial );
00190         return true;
00191     }
00192     return false;
00193 }

Here is the call graph for this function:

bool RingBuff_Consume ( RingBuff *  self,
size_t  count 
)

Consume bytes we peeked at.

Parameters:
self Pointer to instance of ring buffer
count Number of bytes to get
Returns:
true on success, false on failure

Definition at line 83 of file ringbuff.c.

References assert, and assertobjptr.

00084 {
00085     assertobjptr(self);
00086     assert( self->tail >= self->head );
00087     if( self->head + count > self->tail )
00088     {
00089         return false;
00090     }
00091     self->head += count;
00092     if( self->head == self->tail )
00093     {   // Reset if we use up the data
00094         RingBuff_Reset(self);
00095     }
00096     return true;
00097 }

bool RingBuff_CopyFrom ( RingBuff *  self,
void *  buff,
size_t  count 
)

Read data from the buffer, wrapping it transparently.

Parameters:
self Pointer to instance of ring buffer
buff Buffer to copy to, or NULL just to consume bytes
count Number of bytes to get
Returns:
true on success, false on failure (not enough data)

Definition at line 162 of file ringbuff.c.

References RingBuff_Peek().

00163 {
00164     const uint8* data;
00165     if( RingBuff_Peek( self, &data, count ) )
00166     {   // Consume data
00167         memcpy(buff,data,count);
00168         self->head += count;
00169         return true;
00170     }
00171     return false;
00172 }

Here is the call graph for this function:

bool RingBuff_CopyTo ( RingBuff *  self,
const void *  buff,
size_t  count 
)

Write data to the buffer.

Parameters:
self Pointer to instance of ring buffer
buff Buffer to copy from
count Number of bytes to set
Returns:
true on success, false on failure (not enough room)

Definition at line 143 of file ringbuff.c.

References RingBuff_Space().

Referenced by Socket_Write(), and Socket_Write_Serial().

00144 {
00145     uint8* space;
00146     if( RingBuff_Space( self, &space, count ) )
00147     {   // Consume free space
00148         memcpy(space,buff,count);
00149         self->tail += count;
00150         return true;
00151     }
00152     return false;
00153 }

Here is the call graph for this function:

void RingBuff_Init ( RingBuff *  self,
void *  buff,
size_t  size 
)

Initialize a ring buffer with a buffer.

Parameters:
self Pointer to instance of ring buffer
buff Buffer into which we'll be stuffing things
size Size of that buffer

Definition at line 20 of file ringbuff.c.

References assertobjptr, and assertptr.

Referenced by Socket_Customize().

00021 {
00022     assertobjptr(self);
00023     assertptr(buff,size);
00024     self->buff = (const uint8*)buff;
00025     self->end = self->buff + size;
00026     self->head = self->tail = (uint8*)self->buff;
00027 }

bool RingBuff_Peek ( RingBuff *  self,
const uint8 **  buff,
size_t  count 
)

Peek at read position.

Parameters:
self Pointer to instance of ring buffer
buff Pointer to variable to receive pointer to data
count Number of bytes to get
Returns:
true on success, false on failure (not enough data to return count)

Definition at line 65 of file ringbuff.c.

References assert, and assertobjptr.

Referenced by RingBuff_CopyFrom(), RingBuff_PeekSerial(), RingBuff_Pop(), and RingBuff_PopSerial().

00066 {
00067     assertobjptr(self);
00068     assert( self->tail >= self->head );
00069     if( self->head + count > self->tail )
00070     {   /* Not enough data left */
00071         return false;
00072     }
00073     *buff = self->head;
00074     return true;
00075 }

bool RingBuff_PeekSerial ( RingBuff *  self,
ctl_serial serial 
)

Peek at serial packet data on queue.

Parameters:
self Pointer to instance of ring buffer
serial Pointer to serial data to be filled in by this
Returns:
true if there is a whole packet to pop Guarantees if enough data is available, the serial packet will be in one piece

Definition at line 202 of file ringbuff.c.

References ctl_serial_init, RingBuff_Peek(), and uint16_serial_read().

00203 {
00204     const uint8* data;
00205     if( RingBuff_Peek( self, &data, 2 ) )
00206     {
00207         ctl_serial_init( serial, (uint8*)data, data+2 );
00208         uint16 size;
00209         uint16_serial_read(&size, serial );
00210         ctl_serial_init( serial, data, data + size );
00211         return true;
00212     }
00213     return false;
00214 }

Here is the call graph for this function:

bool RingBuff_Pop ( RingBuff *  self,
const uint8 **  buff,
size_t  count 
)

Read data from current read position.

Parameters:
self Pointer to instance of ring buffer
count Number of bytes to get
Returns:
true on success, false on failure

Definition at line 121 of file ringbuff.c.

References RingBuff_Peek().

Referenced by RingBuff_PopSerial(), and Socket_Raw_Consume().

00122 {
00123     if( RingBuff_Peek( self, buff, count ) )
00124     {   // Consume data
00125         self->head += count;
00126         if( self->head == self->tail )
00127         {   // Reset if we use up the data
00128             RingBuff_Reset(self);
00129         }
00130         return true;
00131     }
00132     /* Not enough data left */
00133     return false;
00134 }

Here is the call graph for this function:

bool RingBuff_PopSerial ( RingBuff *  self,
ctl_serial serial 
)

Pop a packet of serial data off the stack.

Parameters:
self Pointer to instance of ring buffer
serial Pointer to serial data to be filled in by this
Returns:
true if there is a whole packet to pop Guarantees serial packet will be in one piece

Definition at line 223 of file ringbuff.c.

References ctl_serial_init, ctl_serial::curr, RingBuff_Peek(), RingBuff_Pop(), and uint16_serial_read().

00224 {
00225     const uint8* data;
00226     if( RingBuff_Peek( self, &data, 2 ) )
00227     {
00228         uint16 size;
00229         ctl_serial_init( serial, data, data+2 );
00230         uint16_serial_read(&size, serial );
00231         /* Pop the packet off, once it's available */
00232         if( RingBuff_Pop( self, &data, size ) )
00233         {
00234             ctl_serial_init( serial, data, data + size );
00235             /* Parse past length; it can be had by rewinding, but in most cases app won't want it. */
00236             serial->curr += 2;
00237             return true;
00238         }
00239     }
00240     return false;
00241 }

Here is the call graph for this function:

bool RingBuff_Space ( RingBuff *  self,
uint8 **  buff,
size_t  count 
)

Get a pointer to free space in ring buffer writeable in one write

Parameters:
self Pointer to instance of ring buffer
buff Pointer to variable to receive pointer to data
count Size of data demanded
Returns:
True on success, false on failure

Definition at line 36 of file ringbuff.c.

References assert, and assertobjconst.

Referenced by RingBuff_Add(), and RingBuff_CopyTo().

00037 {
00038     assertobjconst(self);
00039     assert( self->head <= self->tail );
00040     if( self->tail + count <= self->end )
00041     {
00042         *buff = (uint8*)self->tail;
00043         return true;
00044     }
00045     else if( self->head > self->buff && (count <= RingBuff_Free(self) ) )
00046     {
00047         size_t used = self->tail - self->head;
00048         memmove( (uint8*)self->buff, self->head, used );
00049         self->head = (uint8*)self->buff;
00050         self->tail = (uint8*)self->buff + used;
00051         *buff = (uint8*)self->tail;
00052         return true;
00053     }
00054     *buff = NULL;
00055     return false;
00056 }


Generated on Fri Jan 2 15:28:36 2009 for Squat by  doxygen 1.5.6