From f15d21389a81f8df36b00113aed5c81d27143861 Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Fri, 14 Feb 2014 14:28:59 +0100 Subject: Use read-write ring buffer --- src/uca-ring-buffer.c | 92 +++++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 43 deletions(-) (limited to 'src/uca-ring-buffer.c') diff --git a/src/uca-ring-buffer.c b/src/uca-ring-buffer.c index 40d7a25..98ede8f 100644 --- a/src/uca-ring-buffer.c +++ b/src/uca-ring-buffer.c @@ -26,8 +26,11 @@ struct _UcaRingBufferPrivate { guchar *data; gsize block_size; guint n_blocks_total; - guint n_blocks_used; - guint current_index; + guint write_index; + guint read_index; + guint read; + guint written; + gboolean full; }; enum { @@ -57,8 +60,9 @@ uca_ring_buffer_reset (UcaRingBuffer *buffer) { g_return_if_fail (UCA_IS_RING_BUFFER (buffer)); - buffer->priv->n_blocks_used = 0; - buffer->priv->current_index = 0; + buffer->priv->write_index = 0; + buffer->priv->read_index = 0; + buffer->priv->full = FALSE; } gsize @@ -68,6 +72,13 @@ uca_ring_buffer_get_block_size (UcaRingBuffer *buffer) return buffer->priv->block_size; } +gboolean +uca_ring_buffer_available (UcaRingBuffer *buffer) +{ + g_return_val_if_fail (UCA_IS_RING_BUFFER (buffer), FALSE); + return buffer->priv->read_index < buffer->priv->write_index; +} + /** * uca_ring_buffer_get_current_pointer: * @buffer: A #UcaRingBuffer object @@ -79,66 +90,63 @@ uca_ring_buffer_get_block_size (UcaRingBuffer *buffer) * Return value: (transfer none): Pointer to data block */ gpointer -uca_ring_buffer_get_current_pointer (UcaRingBuffer *buffer) +uca_ring_buffer_get_read_pointer (UcaRingBuffer *buffer) { UcaRingBufferPrivate *priv; + gpointer data; g_return_val_if_fail (UCA_IS_RING_BUFFER (buffer), NULL); priv = buffer->priv; - return priv->data + (priv->current_index % priv->n_blocks_total) * priv->block_size; + data = priv->data + (priv->read_index % priv->n_blocks_total) * priv->block_size; + priv->read_index++; + return data; } -void -uca_ring_buffer_set_current_pointer (UcaRingBuffer *buffer, - guint index) +gpointer +uca_ring_buffer_get_write_pointer (UcaRingBuffer *buffer) { - g_return_if_fail (UCA_IS_RING_BUFFER (buffer)); - g_assert (index < buffer->priv->n_blocks_total); - buffer->priv->current_index = index; + UcaRingBufferPrivate *priv; + gpointer data; + + g_return_val_if_fail (UCA_IS_RING_BUFFER (buffer), NULL); + + priv = buffer->priv; + data = priv->data + (priv->write_index % priv->n_blocks_total) * priv->block_size; + priv->write_index++; + + if ((priv->write_index - priv->read_index) == priv->n_blocks_total) + priv->full = TRUE; + + return data; } -/** - * uca_ring_buffer_get_pointer: - * @buffer: A #UcaRingBuffer object - * @index: Block index to get the pointer for - * - * Get a pointer to the data for @index block. @index must be less than - * :num-blocks. - * - * Return value: (transfer none): Pointer to data block - */ gpointer -uca_ring_buffer_get_pointer (UcaRingBuffer *buffer, - guint index) +uca_ring_buffer_peek_pointer (UcaRingBuffer *buffer) { UcaRingBufferPrivate *priv; - g_return_val_if_fail (UCA_IS_RING_BUFFER (buffer), NULL); - g_assert (index < buffer->priv->n_blocks_total); priv = buffer->priv; - return priv->data + ((priv->current_index - priv->n_blocks_used + index) % priv->n_blocks_total) * priv->block_size; + return ((guint8 *) priv->data) + ((priv->write_index % priv->n_blocks_total) * priv->block_size); } -guint -uca_ring_buffer_get_num_blocks (UcaRingBuffer *buffer) +gpointer +uca_ring_buffer_get_pointer (UcaRingBuffer *buffer, + guint index) { - g_return_val_if_fail (UCA_IS_RING_BUFFER (buffer), 0); - return buffer->priv->n_blocks_used; + UcaRingBufferPrivate *priv; + g_return_val_if_fail (UCA_IS_RING_BUFFER (buffer), NULL); + priv = buffer->priv; + return ((guint8 *) priv->data) + (((priv->read_index + index) % priv->n_blocks_total) * priv->block_size); } -void -uca_ring_buffer_proceed (UcaRingBuffer *buffer) +guint +uca_ring_buffer_get_num_blocks (UcaRingBuffer *buffer) { UcaRingBufferPrivate *priv; - g_return_if_fail (UCA_IS_RING_BUFFER (buffer)); + g_return_val_if_fail (UCA_IS_RING_BUFFER (buffer), 0); priv = buffer->priv; - priv->current_index++; - - if (priv->n_blocks_used < priv->n_blocks_total) - priv->n_blocks_used++; - else - priv->current_index = priv->current_index % priv->n_blocks_total; + return priv->write_index < priv->n_blocks_total ? priv->write_index : priv->n_blocks_total; } static void @@ -259,9 +267,7 @@ uca_ring_buffer_init (UcaRingBuffer *buffer) UcaRingBufferPrivate *priv; priv = buffer->priv = UCA_RING_BUFFER_GET_PRIVATE (buffer); - priv->n_blocks_used = 0; - priv->current_index = 0; - priv->block_size = 0; priv->n_blocks_total = 0; + priv->block_size = 0; priv->data = NULL; } -- cgit v1.2.3