/**
 * Puts data into the ring buffer.  If there isn't enough free space
 * then the ring buffer will drop the data in FIFO fashion.  If you
 * attempt to put in more data than the ring buffer has capacity, it
 * will treat the data in FIFO fashion and will keep the latter portion
 * of the data given up to its capacity.
 * @param data The data to put into the buffer.
 * @param size The amount of data to put in from the buffer.
 */
size_t ring_buffer_put(struct ring_buff *rb, const void *data,
                       size_t size)
{
        /* If buffer size > capacity of ring buffer */
        const size_t cap = ring_buffer_capacity(rb);
        if (size > cap) {
                data += size - cap;
                size = cap;
        }

        /* If data is getting overwritten, update tail. */
        if (size > ring_buffer_bytes_free(rb))
                rb->tail = get_new_ptr_val(rb, rb->tail, size + 1);

        const size_t dist = rb->buff - rb->head + rb->size;
        if (size < dist) {
                memcpy(rb->head, data, size);
        } else {
                void *offset = (char*) data + dist;
                memcpy(rb->head, data, dist);
                memcpy(rb->buff, offset, size - dist);
        }

        rb->head = get_new_ptr_val(rb, rb->head, size);
        return size;
}
size_t ring_buffer_bytes_free(struct ring_buff *rb)
{
        if (rb->tail <= rb->head)
                return ring_buffer_capacity(rb) - (rb->head - rb->tail);
        else
                return rb->tail - rb->head - 1;
}
Example #3
0
static void
test_init_buffer_state()
{
  RingBuffer rb;

  _ringbuffer_init(&rb);

  assert_false(ring_buffer_is_full(&rb), "buffer should not be full");
  assert_true(ring_buffer_is_empty(&rb), "buffer should be empty");
  assert_true(ring_buffer_count(&rb) == 0, "buffer should be empty");
  assert_true(ring_buffer_capacity(&rb) == capacity, "invalid buffer capacity");

  ring_buffer_free(&rb);
}
size_t ring_buffer_bytes_used(struct ring_buff *rb)
{
        return ring_buffer_capacity(rb) - ring_buffer_bytes_free(rb);
}