summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/CMakeLists.txt5
-rw-r--r--bin/common/ring-buffer.c78
-rw-r--r--bin/common/ring-buffer.h31
-rw-r--r--bin/gui/CMakeLists.txt1
-rw-r--r--bin/gui/control.c57
-rw-r--r--bin/tools/CMakeLists.txt2
-rw-r--r--bin/tools/grab.c26
-rw-r--r--src/CMakeLists.txt5
-rw-r--r--src/uca-ring-buffer.c246
-rw-r--r--src/uca-ring-buffer.h47
-rw-r--r--test/CMakeLists.txt2
11 files changed, 341 insertions, 159 deletions
diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt
index b600684..cb2d920 100644
--- a/bin/CMakeLists.txt
+++ b/bin/CMakeLists.txt
@@ -1,9 +1,4 @@
cmake_minimum_required(VERSION 2.6)
-add_library(ringbuffer
- ${CMAKE_CURRENT_SOURCE_DIR}/common/ring-buffer.c)
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common)
-
add_subdirectory(gui)
add_subdirectory(tools)
diff --git a/bin/common/ring-buffer.c b/bin/common/ring-buffer.c
deleted file mode 100644
index 850dfc0..0000000
--- a/bin/common/ring-buffer.c
+++ /dev/null
@@ -1,78 +0,0 @@
-
-#include <math.h>
-#include "ring-buffer.h"
-
-RingBuffer *
-ring_buffer_new (gsize block_size,
- gsize n_blocks)
-{
- RingBuffer *buffer;
-
- buffer = g_new0 (RingBuffer, 1);
- buffer->block_size = block_size;
- buffer->n_blocks_total = n_blocks;
- buffer->n_blocks_used = 0;
- buffer->current_index = 0;
- buffer->data = g_malloc0_n (n_blocks, block_size);
-
- return buffer;
-}
-
-void
-ring_buffer_free (RingBuffer *buffer)
-{
- g_free (buffer->data);
- g_free (buffer);
-}
-
-void
-ring_buffer_reset (RingBuffer *buffer)
-{
- buffer->n_blocks_used = 0;
- buffer->current_index = 0;
-}
-
-gsize
-ring_buffer_get_block_size (RingBuffer *buffer)
-{
- return buffer->block_size;
-}
-
-gpointer
-ring_buffer_get_current_pointer (RingBuffer *buffer)
-{
- return buffer->data + (buffer->current_index % buffer->n_blocks_total) * buffer->block_size;
-}
-
-void
-ring_buffer_set_current_pointer (RingBuffer *buffer,
- guint index)
-{
- g_assert (index < buffer->n_blocks_total);
- buffer->current_index = index;
-}
-
-gpointer
-ring_buffer_get_pointer (RingBuffer *buffer,
- guint index)
-{
- g_assert (index < buffer->n_blocks_total);
- return buffer->data + ((buffer->current_index - buffer->n_blocks_used + index) % buffer->n_blocks_total) * buffer->block_size;
-}
-
-guint
-ring_buffer_get_num_blocks (RingBuffer *buffer)
-{
- return buffer->n_blocks_used;
-}
-
-void
-ring_buffer_proceed (RingBuffer *buffer)
-{
- buffer->current_index++;
-
- if (buffer->n_blocks_used < buffer->n_blocks_total)
- buffer->n_blocks_used++;
- else
- buffer->current_index = buffer->current_index % buffer->n_blocks_total;
-}
diff --git a/bin/common/ring-buffer.h b/bin/common/ring-buffer.h
deleted file mode 100644
index fafe5ec..0000000
--- a/bin/common/ring-buffer.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef RING_BUFFER_H
-#define RING_BUFFER_H
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-typedef struct {
- guchar *data;
- gsize block_size;
- guint n_blocks_total;
- guint n_blocks_used;
- guint current_index;
-} RingBuffer;
-
-RingBuffer * ring_buffer_new (gsize block_size,
- gsize n_blocks);
-void ring_buffer_free (RingBuffer *buffer);
-void ring_buffer_reset (RingBuffer *buffer);
-gsize ring_buffer_get_block_size (RingBuffer *buffer);
-gpointer ring_buffer_get_current_pointer (RingBuffer *buffer);
-void ring_buffer_set_current_pointer (RingBuffer *buffer,
- guint index);
-gpointer ring_buffer_get_pointer (RingBuffer *buffer,
- guint index);
-guint ring_buffer_get_num_blocks (RingBuffer *buffer);
-void ring_buffer_proceed (RingBuffer *buffer);
-
-G_END_DECLS
-
-#endif
diff --git a/bin/gui/CMakeLists.txt b/bin/gui/CMakeLists.txt
index 8ee80ed..97ddddd 100644
--- a/bin/gui/CMakeLists.txt
+++ b/bin/gui/CMakeLists.txt
@@ -30,7 +30,6 @@ if (GTK2_FOUND)
target_link_libraries(${BINARY}
m
uca
- ringbuffer
${GTK2_LIBRARIES}
${GTHREAD2_LIBRARIES})
diff --git a/bin/gui/control.c b/bin/gui/control.c
index 38fcbca..af5cfe3 100644
--- a/bin/gui/control.c
+++ b/bin/gui/control.c
@@ -22,9 +22,9 @@
#include <math.h>
#include "config.h"
-#include "ring-buffer.h"
#include "uca-camera.h"
#include "uca-plugin-manager.h"
+#include "uca-ring-buffer.h"
#include "egg-property-tree-view.h"
#include "egg-histogram-view.h"
@@ -68,7 +68,7 @@ typedef struct {
GtkToggleButton *log_button;
GtkAdjustment *frame_slider;
- RingBuffer *buffer;
+ UcaRingBuffer *buffer;
guchar *pixels;
gint display_width, display_height;
gint colormap;
@@ -276,7 +276,7 @@ get_statistics (ThreadData *data, gdouble *mean, gdouble *sigma, guint *_max, gu
guint n = data->width * data->height;
if (data->pixel_size == 1) {
- guint8 *input = (guint8 *) ring_buffer_get_current_pointer (data->buffer);
+ guint8 *input = (guint8 *) uca_ring_buffer_get_current_pointer (data->buffer);
for (gint i = 0; i < n; i++) {
guint8 val = input[i];
@@ -292,7 +292,7 @@ get_statistics (ThreadData *data, gdouble *mean, gdouble *sigma, guint *_max, gu
}
}
else {
- guint16 *input = (guint16 *) ring_buffer_get_current_pointer (data->buffer);
+ guint16 *input = (guint16 *) uca_ring_buffer_get_current_pointer (data->buffer);
for (gint i = 0; i < n; i++) {
guint16 val = input[i];
@@ -345,7 +345,7 @@ on_motion_notify (GtkWidget *event_box, GdkEventMotion *event, ThreadData *data)
if ((data->state != RUNNING) || ((data->ev_x >= 0 && data->ev_y >= 0) && (data->ev_y <= data->display_height && data->ev_x <= data->display_width))) {
gpointer *buffer;
GString *string;
- buffer = ring_buffer_get_current_pointer (data->buffer);
+ buffer = uca_ring_buffer_get_current_pointer (data->buffer);
string = g_string_new_len (NULL, 32);
gint i = (data->ev_y / data->zoom_factor) * data->width + data->ev_x / data->zoom_factor;
@@ -384,7 +384,7 @@ update_pixbuf (ThreadData *data)
gtk_widget_queue_draw_area (data->image, 0, 0, data->display_width, data->display_height);
egg_histogram_view_update (EGG_HISTOGRAM_VIEW (data->histogram_view),
- ring_buffer_get_current_pointer (data->buffer));
+ uca_ring_buffer_get_current_pointer (data->buffer));
get_statistics (data, &mean, &sigma, &max, &min);
string = g_string_new_len (NULL, 32);
@@ -460,7 +460,7 @@ preview_frames (void *args)
while (data->state == RUNNING) {
gpointer *buffer;
- buffer = ring_buffer_get_current_pointer (data->buffer);
+ buffer = uca_ring_buffer_get_current_pointer (data->buffer);
uca_camera_grab (data->camera, buffer, &error);
@@ -515,7 +515,7 @@ record_frames (gpointer args)
GError *error = NULL;
data = (ThreadData *) args;
- ring_buffer_reset (data->buffer);
+ uca_ring_buffer_reset (data->buffer);
data->n_recorded = 0;
n_max = (guint) gtk_adjustment_get_value (data->count);
@@ -527,11 +527,11 @@ record_frames (gpointer args)
if (n_max > 0 && n_frames >= n_max)
break;
- buffer = ring_buffer_get_current_pointer (data->buffer);
+ buffer = uca_ring_buffer_get_current_pointer (data->buffer);
uca_camera_grab (data->camera, buffer, NULL);
if (error == NULL) {
- ring_buffer_proceed (data->buffer);
+ uca_ring_buffer_proceed (data->buffer);
n_frames++;
data->n_recorded++;
}
@@ -545,7 +545,7 @@ record_frames (gpointer args)
set_tool_button_state (data);
}
- n_frames = ring_buffer_get_num_blocks (data->buffer);
+ n_frames = uca_ring_buffer_get_num_blocks (data->buffer);
gdk_threads_enter ();
gtk_adjustment_set_upper (data->frame_slider, n_frames - 1);
@@ -566,8 +566,7 @@ on_destroy (GtkWidget *widget, ThreadData *data)
{
data->state = IDLE;
g_object_unref (data->camera);
- ring_buffer_free (data->buffer);
-
+ g_object_unref (data->buffer);
gtk_main_quit ();
}
@@ -579,15 +578,15 @@ update_current_frame (ThreadData *data)
guint n_max;
index = (guint) gtk_adjustment_get_value (data->frame_slider);
- n_max = ring_buffer_get_num_blocks (data->buffer);
+ n_max = uca_ring_buffer_get_num_blocks (data->buffer);
/* Shift index so that we always show the oldest frames first */
if (n_max > 0)
index = (index + data->n_recorded - n_max) % n_max;
- ring_buffer_set_current_pointer (data->buffer, index);
+ uca_ring_buffer_set_current_pointer (data->buffer, index);
- buffer = ring_buffer_get_current_pointer (data->buffer);
+ buffer = uca_ring_buffer_get_current_pointer (data->buffer);
up_and_down_scale (data, buffer);
update_pixbuf (data);
}
@@ -600,7 +599,7 @@ on_frame_slider_changed (GtkAdjustment *adjustment, ThreadData *data)
}
static gboolean
-write_raw_file (const gchar *filename, RingBuffer *buffer)
+write_raw_file (const gchar *filename, UcaRingBuffer *buffer)
{
FILE *fp;
guint n_blocks;
@@ -611,11 +610,11 @@ write_raw_file (const gchar *filename, RingBuffer *buffer)
if (fp == NULL)
return FALSE;
- n_blocks = ring_buffer_get_num_blocks (buffer);
- size = ring_buffer_get_block_size (buffer);
+ n_blocks = uca_ring_buffer_get_num_blocks (buffer);
+ size = uca_ring_buffer_get_block_size (buffer);
for (guint i = 0; i < n_blocks; i++)
- fwrite (ring_buffer_get_pointer (buffer, i), size , 1, fp);
+ fwrite (uca_ring_buffer_get_pointer (buffer, i), size , 1, fp);
fclose (fp);
return TRUE;
@@ -724,19 +723,19 @@ download_frames (ThreadData *data)
return NULL;
}
- ring_buffer_reset (data->buffer);
+ uca_ring_buffer_reset (data->buffer);
while (error == NULL) {
- buffer = ring_buffer_get_current_pointer (data->buffer);
+ buffer = uca_ring_buffer_get_current_pointer (data->buffer);
uca_camera_grab (data->camera, buffer, &error);
- ring_buffer_proceed (data->buffer);
+ uca_ring_buffer_proceed (data->buffer);
gdk_threads_enter ();
gtk_adjustment_set_value (data->download_adjustment, current_frame++);
gdk_threads_leave ();
}
if (error->code == UCA_CAMERA_ERROR_END_OF_STREAM) {
- guint n_frames = ring_buffer_get_num_blocks (data->buffer);
+ guint n_frames = uca_ring_buffer_get_num_blocks (data->buffer);
gtk_adjustment_set_upper (data->frame_slider, n_frames - 1);
gtk_adjustment_set_value (data->frame_slider, n_frames - 1);
@@ -803,7 +802,7 @@ on_zoom_changed (GtkComboBox *widget, ThreadData *data)
data->zoom_factor = factor;
update_pixbuf_dimensions (data);
- up_and_down_scale (data, ring_buffer_get_current_pointer (data->buffer));
+ up_and_down_scale (data, uca_ring_buffer_get_current_pointer (data->buffer));
update_pixbuf (data);
}
@@ -826,7 +825,7 @@ on_colormap_changed (GtkComboBox *widget, ThreadData *data)
data->colormap = map;
update_pixbuf_dimensions (data);
- up_and_down_scale (data, ring_buffer_get_current_pointer (data->buffer));
+ up_and_down_scale (data, uca_ring_buffer_get_current_pointer (data->buffer));
update_pixbuf (data);
}
@@ -856,7 +855,7 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
GdkPixbuf *pixbuf;
GtkBox *histogram_box;
GtkAdjustment *max_bin_adjustment;
- RingBuffer *ring_buffer;
+ UcaRingBuffer *ring_buffer;
gsize image_size;
guint n_frames;
guint bits_per_sample;
@@ -921,10 +920,10 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
pixel_size = bits_per_sample > 8 ? 2 : 1;
image_size = pixel_size * width * height;
n_frames = mem_size * 1024 * 1024 / image_size;
- ring_buffer = ring_buffer_new (image_size, n_frames);
+ ring_buffer = uca_ring_buffer_new (image_size, n_frames);
egg_histogram_view_update (EGG_HISTOGRAM_VIEW (histogram_view),
- ring_buffer_get_current_pointer (ring_buffer));
+ uca_ring_buffer_get_current_pointer (ring_buffer));
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
diff --git a/bin/tools/CMakeLists.txt b/bin/tools/CMakeLists.txt
index 4070523..b310321 100644
--- a/bin/tools/CMakeLists.txt
+++ b/bin/tools/CMakeLists.txt
@@ -26,7 +26,7 @@ target_link_libraries(uca-gen-doc ${libs})
#{{{ uca-grab
add_executable(uca-grab
grab.c common.c)
-target_link_libraries(uca-grab ringbuffer ${libs})
+target_link_libraries(uca-grab ${libs})
#}}}
#{{{ uca-benchmark
add_executable(uca-benchmark
diff --git a/bin/tools/grab.c b/bin/tools/grab.c
index 123b05e..50c70a8 100644
--- a/bin/tools/grab.c
+++ b/bin/tools/grab.c
@@ -22,7 +22,7 @@
#include <stdlib.h>
#include "uca-plugin-manager.h"
#include "uca-camera.h"
-#include "ring-buffer.h"
+#include "uca-ring-buffer.h"
#include "common.h"
#ifdef HAVE_LIBTIFF
@@ -48,7 +48,7 @@ get_bytes_per_pixel (guint bits_per_pixel)
#ifdef HAVE_LIBTIFF
static void
-write_tiff (RingBuffer *buffer,
+write_tiff (UcaRingBuffer *buffer,
Options *opts,
guint width,
guint height,
@@ -65,7 +65,7 @@ write_tiff (RingBuffer *buffer,
else
tif = TIFFOpen ("frames.tif", "w");
- n_frames = ring_buffer_get_num_blocks (buffer);
+ n_frames = uca_ring_buffer_get_num_blocks (buffer);
rows_per_strip = TIFFDefaultStripSize (tif, (guint32) - 1);
bytes_per_pixel = get_bytes_per_pixel (bits_per_pixel);
bits_per_sample = bits_per_pixel > 8 ? 16 : 8;
@@ -77,7 +77,7 @@ write_tiff (RingBuffer *buffer,
gpointer data;
gsize offset = 0;
- data = ring_buffer_get_pointer (buffer, i);
+ data = uca_ring_buffer_get_pointer (buffer, i);
TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField (tif, TIFFTAG_IMAGELENGTH, height);
@@ -99,14 +99,14 @@ write_tiff (RingBuffer *buffer,
#endif
static void
-write_raw (RingBuffer *buffer,
+write_raw (UcaRingBuffer *buffer,
Options *opts)
{
guint n_frames;
gsize size;
- size = ring_buffer_get_block_size (buffer);
- n_frames = ring_buffer_get_num_blocks (buffer);
+ size = uca_ring_buffer_get_block_size (buffer);
+ n_frames = uca_ring_buffer_get_num_blocks (buffer);
for (gint i = 0; i < n_frames; i++) {
FILE *fp;
@@ -119,7 +119,7 @@ write_raw (RingBuffer *buffer,
filename = g_strdup_printf ("frame-%08i.raw", i);
fp = fopen(filename, "wb");
- data = ring_buffer_get_pointer (buffer, i);
+ data = uca_ring_buffer_get_pointer (buffer, i);
fwrite (data, size, 1, fp);
fclose (fp);
@@ -138,7 +138,7 @@ record_frames (UcaCamera *camera, Options *opts)
gint n_frames;
guint n_allocated;
GTimer *timer;
- RingBuffer *buffer;
+ UcaRingBuffer *buffer;
GError *error = NULL;
gdouble last_printed;
@@ -151,7 +151,7 @@ record_frames (UcaCamera *camera, Options *opts)
pixel_size = get_bytes_per_pixel (bits);
size = roi_width * roi_height * pixel_size;
n_allocated = opts->n_frames > 0 ? opts->n_frames : 256;
- buffer = ring_buffer_new (size, n_allocated);
+ buffer = uca_ring_buffer_new (size, n_allocated);
timer = g_timer_new();
g_print("Start recording: %ix%i at %i bits/pixel\n",
@@ -169,8 +169,8 @@ record_frames (UcaCamera *camera, Options *opts)
while (1) {
gdouble elapsed;
- uca_camera_grab (camera, ring_buffer_get_current_pointer (buffer), &error);
- ring_buffer_proceed (buffer);
+ uca_camera_grab (camera, uca_ring_buffer_get_current_pointer (buffer), &error);
+ uca_ring_buffer_proceed (buffer);
if (error != NULL)
return error;
@@ -202,7 +202,7 @@ record_frames (UcaCamera *camera, Options *opts)
write_raw (buffer, opts);
#endif
- ring_buffer_free (buffer);
+ g_object_unref (buffer);
g_timer_destroy (timer);
return error;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3c7ed83..3fa1ed9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -5,11 +5,14 @@ project(uca C)
set(uca_SRCS
uca-camera.c
uca-plugin-manager.c
+ uca-ring-buffer.c
)
set(uca_HDRS
uca-camera.h
- uca-plugin-manager.h)
+ uca-plugin-manager.h
+ uca-ring-buffer.h
+ )
create_enums(uca-enums
${CMAKE_CURRENT_SOURCE_DIR}/uca-enums
diff --git a/src/uca-ring-buffer.c b/src/uca-ring-buffer.c
new file mode 100644
index 0000000..d2b40a4
--- /dev/null
+++ b/src/uca-ring-buffer.c
@@ -0,0 +1,246 @@
+/* Copyright (C) 2013 Matthias Vogelgesang <matthias.vogelgesang@kit.edu>
+ (Karlsruhe Institute of Technology)
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License along
+ with this library; if not, write to the Free Software Foundation, Inc., 51
+ Franklin St, Fifth Floor, Boston, MA 02110, USA */
+
+#include <math.h>
+#include "uca-ring-buffer.h"
+
+#define UCA_RING_BUFFER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_RING_BUFFER, UcaRingBufferPrivate))
+
+G_DEFINE_TYPE(UcaRingBuffer, uca_ring_buffer, G_TYPE_OBJECT)
+
+struct _UcaRingBufferPrivate {
+ guchar *data;
+ gsize block_size;
+ guint n_blocks_total;
+ guint n_blocks_used;
+ guint current_index;
+};
+
+enum {
+ PROP_0,
+ PROP_BLOCK_SIZE,
+ PROP_NUM_BLOCKS,
+ N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
+UcaRingBuffer *
+uca_ring_buffer_new (gsize block_size,
+ guint n_blocks)
+{
+ UcaRingBuffer *buffer;
+
+ buffer = g_object_new (UCA_TYPE_RING_BUFFER,
+ "block-size", (guint64) block_size,
+ "num-blocks", n_blocks);
+ return buffer;
+}
+
+void
+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;
+}
+
+gsize
+uca_ring_buffer_get_block_size (UcaRingBuffer *buffer)
+{
+ g_return_val_if_fail (UCA_IS_RING_BUFFER (buffer), 0);
+ return buffer->priv->block_size;
+}
+
+gpointer
+uca_ring_buffer_get_current_pointer (UcaRingBuffer *buffer)
+{
+ UcaRingBufferPrivate *priv;
+
+ 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;
+}
+
+void
+uca_ring_buffer_set_current_pointer (UcaRingBuffer *buffer,
+ guint index)
+{
+ g_return_if_fail (UCA_IS_RING_BUFFER (buffer));
+ g_assert (index < buffer->priv->n_blocks_total);
+ buffer->priv->current_index = index;
+}
+
+gpointer
+uca_ring_buffer_get_pointer (UcaRingBuffer *buffer,
+ guint index)
+{
+ 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;
+}
+
+guint
+uca_ring_buffer_get_num_blocks (UcaRingBuffer *buffer)
+{
+ g_return_val_if_fail (UCA_IS_RING_BUFFER (buffer), 0);
+ return buffer->priv->n_blocks_used;
+}
+
+void
+uca_ring_buffer_proceed (UcaRingBuffer *buffer)
+{
+ UcaRingBufferPrivate *priv;
+ g_return_if_fail (UCA_IS_RING_BUFFER (buffer));
+
+ 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;
+}
+
+static void
+realloc_mem (UcaRingBufferPrivate *priv)
+{
+ if (priv->data != NULL)
+ g_free (priv->data);
+
+ priv->data = g_malloc0_n (priv->n_blocks_total, priv->block_size);
+}
+
+static void
+uca_ring_buffer_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ UcaRingBufferPrivate *priv;
+
+ g_return_if_fail (UCA_IS_RING_BUFFER (object));
+ priv = UCA_RING_BUFFER_GET_PRIVATE (object);
+
+ switch (property_id) {
+ case PROP_BLOCK_SIZE:
+ g_value_set_uint64 (value, (guint64) priv->block_size);
+ break;
+
+ case PROP_NUM_BLOCKS:
+ g_value_set_uint (value, priv->n_blocks_total);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+uca_ring_buffer_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ UcaRingBufferPrivate *priv;
+
+ g_return_if_fail (UCA_IS_RING_BUFFER (object));
+ priv = UCA_RING_BUFFER_GET_PRIVATE (object);
+
+ switch (property_id) {
+ case PROP_BLOCK_SIZE:
+ priv->block_size = (gsize) g_value_get_uint64 (value);
+ realloc_mem (priv);
+ break;
+
+ case PROP_NUM_BLOCKS:
+ priv->n_blocks_total = g_value_get_uint (value);
+ realloc_mem (priv);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+uca_ring_buffer_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (uca_ring_buffer_parent_class)->dispose (object);
+}
+
+static void
+uca_ring_buffer_finalize (GObject *object)
+{
+ UcaRingBufferPrivate *priv;
+
+ priv = UCA_RING_BUFFER_GET_PRIVATE (object);
+ g_free (priv->data);
+ priv->data = NULL;
+ G_OBJECT_CLASS (uca_ring_buffer_parent_class)->finalize (object);
+}
+
+static void
+uca_ring_buffer_class_init (UcaRingBufferClass *klass)
+{
+ GObjectClass *oclass;
+
+ oclass = G_OBJECT_CLASS (klass);
+
+ oclass->get_property = uca_ring_buffer_get_property;
+ oclass->set_property = uca_ring_buffer_set_property;
+ oclass->dispose = uca_ring_buffer_dispose;
+ oclass->finalize = uca_ring_buffer_finalize;
+
+ properties[PROP_BLOCK_SIZE] =
+ g_param_spec_uint64 ("block-size",
+ "Block size in bytes",
+ "Number of bytes per block",
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+
+ properties[PROP_NUM_BLOCKS] =
+ g_param_spec_uint ("num-blocks",
+ "Number of pre-allocated blocks",
+ "Number of pre-allocated blocks",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+
+ for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++)
+ g_object_class_install_property (oclass, i, properties[i]);
+
+ g_type_class_add_private (klass, sizeof (UcaRingBufferPrivate));
+}
+
+static void
+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->data = NULL;
+}
diff --git a/src/uca-ring-buffer.h b/src/uca-ring-buffer.h
new file mode 100644
index 0000000..03e2cae
--- /dev/null
+++ b/src/uca-ring-buffer.h
@@ -0,0 +1,47 @@
+#ifndef UCA_RING_BUFFER_H
+#define UCA_RING_BUFFER_H
+
+#include <glib-object.h>
+
+#define UCA_TYPE_RING_BUFFER (uca_ring_buffer_get_type())
+#define UCA_RING_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_RING_BUFFER, UcaRingBuffer))
+#define UCA_IS_RING_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_RING_BUFFER))
+#define UCA_RING_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_RING_BUFFER, UcaRingBufferClass))
+#define UCA_IS_RING_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_RING_BUFFER))
+#define UCA_RING_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_RING_BUFFER, UcaRingBufferClass))
+
+G_BEGIN_DECLS
+
+typedef struct _UcaRingBuffer UcaRingBuffer;
+typedef struct _UcaRingBufferClass UcaRingBufferClass;
+typedef struct _UcaRingBufferPrivate UcaRingBufferPrivate;
+
+struct _UcaRingBuffer {
+ /*< private >*/
+ GObject parent;
+
+ UcaRingBufferPrivate *priv;
+};
+
+struct _UcaRingBufferClass {
+ /*< private >*/
+ GObjectClass parent;
+};
+
+UcaRingBuffer * uca_ring_buffer_new (gsize block_size,
+ guint n_blocks);
+void uca_ring_buffer_reset (UcaRingBuffer *buffer);
+gsize uca_ring_buffer_get_block_size (UcaRingBuffer *buffer);
+gpointer uca_ring_buffer_get_current_pointer (UcaRingBuffer *buffer);
+void uca_ring_buffer_set_current_pointer (UcaRingBuffer *buffer,
+ guint index);
+gpointer uca_ring_buffer_get_pointer (UcaRingBuffer *buffer,
+ guint index);
+guint uca_ring_buffer_get_num_blocks (UcaRingBuffer *buffer);
+void uca_ring_buffer_proceed (UcaRingBuffer *buffer);
+
+GType uca_ring_buffer_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index d9ce857..0e8cfad 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -4,5 +4,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gtester.xsl
${CMAKE_CURRENT_BINARY_DIR}/gtester.xsl)
add_executable(test-mock test-mock.c)
+add_executable(test-ring-buffer test-ring-buffer.c)
target_link_libraries(test-mock uca ${UCA_DEPS})
+target_link_libraries(test-ring-buffer uca ${UCA_DEPS})