core: ringbuffer: update from simple struct to a b_object type
This commit is contained in:
@@ -1,32 +1,25 @@
|
|||||||
#ifndef BLUELIB_CORE_RINGBUFFER_H_
|
#ifndef BLUE_CORE_RINGBUFFER_H_
|
||||||
#define BLUELIB_CORE_RINGBUFFER_H_
|
#define BLUE_CORE_RINGBUFFER_H_
|
||||||
|
|
||||||
|
#include <blue/core/macros.h>
|
||||||
#include <blue/core/misc.h>
|
#include <blue/core/misc.h>
|
||||||
#include <blue/core/status.h>
|
#include <blue/core/status.h>
|
||||||
|
|
||||||
typedef enum b_ringbuffer_flags {
|
B_DECLS_BEGIN;
|
||||||
B_RINGBUFFER_SELF_MALLOC = 0x01u,
|
|
||||||
B_RINGBUFFER_BUFFER_MALLOC = 0x02u,
|
|
||||||
B_RINGBUFFER_READ_LOCKED = 0x04u,
|
|
||||||
B_RINGBUFFER_WRITE_LOCKED = 0x08u,
|
|
||||||
} b_ringbuffer_flags;
|
|
||||||
|
|
||||||
typedef struct b_ringbuffer {
|
#define B_TYPE_RINGBUFFER (b_ringbuffer_get_type())
|
||||||
b_ringbuffer_flags r_flags;
|
|
||||||
void *r_buf, *r_opened_buf;
|
B_DECLARE_TYPE(b_ringbuffer);
|
||||||
unsigned long r_capacity, r_opened_capacity;
|
|
||||||
unsigned long r_write_ptr, r_read_ptr;
|
B_TYPE_CLASS_DECLARATION_BEGIN(b_ringbuffer)
|
||||||
} b_ringbuffer;
|
B_TYPE_CLASS_DECLARATION_END(b_ringbuffer)
|
||||||
|
|
||||||
|
BLUE_API b_type b_ringbuffer_get_type(void);
|
||||||
|
|
||||||
BLUE_API b_ringbuffer *b_ringbuffer_create(size_t capacity);
|
BLUE_API b_ringbuffer *b_ringbuffer_create(size_t capacity);
|
||||||
BLUE_API b_ringbuffer *b_ringbuffer_create_with_buffer(void *ptr, size_t capacity);
|
BLUE_API b_ringbuffer *b_ringbuffer_create_with_buffer(void *ptr, size_t capacity);
|
||||||
|
|
||||||
BLUE_API b_status b_ringbuffer_init(b_ringbuffer *buf, size_t capacity);
|
BLUE_API b_status b_ringbuffer_clear(b_ringbuffer *buf);
|
||||||
BLUE_API b_status b_ringbuffer_init_with_buffer(
|
|
||||||
b_ringbuffer *buf, void *ptr, size_t capacity);
|
|
||||||
|
|
||||||
BLUE_API b_status b_ringbuffer_reset(b_ringbuffer *buf);
|
|
||||||
BLUE_API b_status b_ringbuffer_destroy(b_ringbuffer *buf);
|
|
||||||
|
|
||||||
BLUE_API b_status b_ringbuffer_read(
|
BLUE_API b_status b_ringbuffer_read(
|
||||||
b_ringbuffer *buf, void *p, size_t count, size_t *nr_read);
|
b_ringbuffer *buf, void *p, size_t count, size_t *nr_read);
|
||||||
@@ -49,4 +42,6 @@ BLUE_API b_status b_ringbuffer_open_write_buffer(
|
|||||||
BLUE_API b_status b_ringbuffer_close_write_buffer(
|
BLUE_API b_status b_ringbuffer_close_write_buffer(
|
||||||
b_ringbuffer *buf, void **ptr, size_t nr_written);
|
b_ringbuffer *buf, void **ptr, size_t nr_written);
|
||||||
|
|
||||||
|
B_DECLS_END;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,78 +2,28 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define BUF_LOCKED(buf) \
|
#define BUF_LOCKED(buf) \
|
||||||
(((buf)->r_flags & (B_RINGBUFFER_READ_LOCKED | B_RINGBUFFER_WRITE_LOCKED)) \
|
(((buf)->r_flags & (RINGBUFFER_READ_LOCKED | RINGBUFFER_WRITE_LOCKED)) \
|
||||||
!= 0)
|
!= 0)
|
||||||
|
|
||||||
struct b_ringbuffer *b_ringbuffer_create(size_t capacity)
|
/*** PRIVATE DATA *************************************************************/
|
||||||
{
|
|
||||||
struct b_ringbuffer *buf = malloc(sizeof *buf);
|
|
||||||
if (!buf) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *p = malloc(capacity);
|
enum ringbuffer_flags {
|
||||||
if (!p) {
|
RINGBUFFER_BUFFER_MALLOC = 0x02u,
|
||||||
free(buf);
|
RINGBUFFER_READ_LOCKED = 0x04u,
|
||||||
return NULL;
|
RINGBUFFER_WRITE_LOCKED = 0x08u,
|
||||||
}
|
};
|
||||||
|
|
||||||
memset(buf, 0x0, sizeof *buf);
|
struct b_ringbuffer_p {
|
||||||
|
enum ringbuffer_flags r_flags;
|
||||||
|
void *r_buf, *r_opened_buf;
|
||||||
|
unsigned long r_capacity, r_opened_capacity;
|
||||||
|
unsigned long r_write_ptr, r_read_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
buf->r_flags = B_RINGBUFFER_SELF_MALLOC | B_RINGBUFFER_BUFFER_MALLOC;
|
/*** PRIVATE FUNCTIONS ********************************************************/
|
||||||
buf->r_buf = p;
|
|
||||||
buf->r_capacity = capacity;
|
|
||||||
|
|
||||||
return buf;
|
static enum b_status ringbuffer_clear(struct b_ringbuffer_p *buf)
|
||||||
}
|
|
||||||
|
|
||||||
struct b_ringbuffer *b_ringbuffer_create_with_buffer(void *ptr, size_t capacity)
|
|
||||||
{
|
|
||||||
struct b_ringbuffer *buf = malloc(sizeof *buf);
|
|
||||||
if (!buf) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buf, 0x0, sizeof *buf);
|
|
||||||
|
|
||||||
buf->r_flags = B_RINGBUFFER_SELF_MALLOC;
|
|
||||||
buf->r_buf = ptr;
|
|
||||||
buf->r_capacity = capacity;
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum b_status b_ringbuffer_init(struct b_ringbuffer *buf, size_t capacity)
|
|
||||||
{
|
|
||||||
void *p = malloc(capacity);
|
|
||||||
if (!p) {
|
|
||||||
free(buf);
|
|
||||||
return B_ERR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buf, 0x0, sizeof *buf);
|
|
||||||
|
|
||||||
buf->r_flags = B_RINGBUFFER_BUFFER_MALLOC;
|
|
||||||
buf->r_buf = p;
|
|
||||||
buf->r_capacity = capacity;
|
|
||||||
|
|
||||||
return B_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum b_status b_ringbuffer_init_with_buffer(
|
|
||||||
struct b_ringbuffer *buf, void *ptr, size_t capacity)
|
|
||||||
{
|
|
||||||
memset(buf, 0x0, sizeof *buf);
|
|
||||||
|
|
||||||
buf->r_flags = 0;
|
|
||||||
buf->r_buf = ptr;
|
|
||||||
buf->r_capacity = capacity;
|
|
||||||
|
|
||||||
return B_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum b_status b_ringbuffer_reset(struct b_ringbuffer *buf)
|
|
||||||
{
|
{
|
||||||
if (BUF_LOCKED(buf)) {
|
if (BUF_LOCKED(buf)) {
|
||||||
return B_ERR_BUSY;
|
return B_ERR_BUSY;
|
||||||
@@ -84,144 +34,7 @@ enum b_status b_ringbuffer_reset(struct b_ringbuffer *buf)
|
|||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum b_status b_ringbuffer_destroy(struct b_ringbuffer *buf)
|
static size_t ringbuffer_write_capacity_remaining(const struct b_ringbuffer_p *buf)
|
||||||
{
|
|
||||||
if (BUF_LOCKED(buf)) {
|
|
||||||
return B_ERR_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf->r_flags & B_RINGBUFFER_BUFFER_MALLOC) {
|
|
||||||
free(buf->r_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf->r_flags & B_RINGBUFFER_SELF_MALLOC) {
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum b_status b_ringbuffer_read(
|
|
||||||
struct b_ringbuffer *buf, void *p, size_t count, size_t *nr_read)
|
|
||||||
{
|
|
||||||
if (BUF_LOCKED(buf)) {
|
|
||||||
return B_ERR_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t r = 0;
|
|
||||||
unsigned char *dest = p;
|
|
||||||
size_t remaining = count;
|
|
||||||
|
|
||||||
while (remaining > 0) {
|
|
||||||
const void *src;
|
|
||||||
size_t available;
|
|
||||||
enum b_status status
|
|
||||||
= b_ringbuffer_open_read_buffer(buf, &src, &available);
|
|
||||||
|
|
||||||
if (status == B_ERR_NO_DATA) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!B_OK(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t to_copy = remaining;
|
|
||||||
if (to_copy > available) {
|
|
||||||
to_copy = available;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dest, src, to_copy);
|
|
||||||
|
|
||||||
remaining -= to_copy;
|
|
||||||
dest += to_copy;
|
|
||||||
r += to_copy;
|
|
||||||
|
|
||||||
b_ringbuffer_close_read_buffer(buf, &src, to_copy);
|
|
||||||
}
|
|
||||||
|
|
||||||
*nr_read = r;
|
|
||||||
return B_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum b_status b_ringbuffer_write(
|
|
||||||
struct b_ringbuffer *buf, const void *p, size_t count, size_t *nr_written)
|
|
||||||
{
|
|
||||||
if (BUF_LOCKED(buf)) {
|
|
||||||
return B_ERR_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t w = 0;
|
|
||||||
const unsigned char *src = p;
|
|
||||||
size_t remaining = count;
|
|
||||||
|
|
||||||
while (remaining > 0) {
|
|
||||||
void *dest;
|
|
||||||
size_t available;
|
|
||||||
enum b_status status
|
|
||||||
= b_ringbuffer_open_write_buffer(buf, &dest, &available);
|
|
||||||
|
|
||||||
if (status == B_ERR_NO_SPACE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!B_OK(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t to_copy = remaining;
|
|
||||||
if (to_copy > available) {
|
|
||||||
to_copy = available;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dest, src, to_copy);
|
|
||||||
|
|
||||||
remaining -= to_copy;
|
|
||||||
src += to_copy;
|
|
||||||
w += to_copy;
|
|
||||||
|
|
||||||
b_ringbuffer_close_write_buffer(buf, &dest, to_copy);
|
|
||||||
}
|
|
||||||
|
|
||||||
*nr_written = w;
|
|
||||||
return B_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int b_ringbuffer_getc(struct b_ringbuffer *buf)
|
|
||||||
{
|
|
||||||
size_t available = b_ringbuffer_available_data_remaining(buf);
|
|
||||||
if (available == 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *p = buf->r_buf;
|
|
||||||
char c = p[buf->r_read_ptr++];
|
|
||||||
|
|
||||||
if (buf->r_read_ptr >= buf->r_capacity) {
|
|
||||||
buf->r_read_ptr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum b_status b_ringbuffer_putc(struct b_ringbuffer *buf, int c)
|
|
||||||
{
|
|
||||||
size_t available = b_ringbuffer_write_capacity_remaining(buf);
|
|
||||||
if (available == 0) {
|
|
||||||
return B_ERR_NO_SPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *p = buf->r_buf;
|
|
||||||
p[buf->r_write_ptr++] = c;
|
|
||||||
|
|
||||||
if (buf->r_write_ptr >= buf->r_capacity) {
|
|
||||||
buf->r_write_ptr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t b_ringbuffer_write_capacity_remaining(const struct b_ringbuffer *buf)
|
|
||||||
{
|
{
|
||||||
if (buf->r_read_ptr > buf->r_write_ptr) {
|
if (buf->r_read_ptr > buf->r_write_ptr) {
|
||||||
return buf->r_read_ptr - buf->r_write_ptr - 1;
|
return buf->r_read_ptr - buf->r_write_ptr - 1;
|
||||||
@@ -230,7 +43,7 @@ size_t b_ringbuffer_write_capacity_remaining(const struct b_ringbuffer *buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t b_ringbuffer_available_data_remaining(const struct b_ringbuffer *buf)
|
static size_t ringbuffer_available_data_remaining(const struct b_ringbuffer_p *buf)
|
||||||
{
|
{
|
||||||
if (buf->r_read_ptr < buf->r_write_ptr) {
|
if (buf->r_read_ptr < buf->r_write_ptr) {
|
||||||
return buf->r_write_ptr - buf->r_read_ptr;
|
return buf->r_write_ptr - buf->r_read_ptr;
|
||||||
@@ -241,8 +54,8 @@ size_t b_ringbuffer_available_data_remaining(const struct b_ringbuffer *buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum b_status b_ringbuffer_open_read_buffer(
|
static enum b_status ringbuffer_open_read_buffer(
|
||||||
struct b_ringbuffer *buf, const void **ptr, size_t *length)
|
struct b_ringbuffer_p *buf, const void **ptr, size_t *length)
|
||||||
{
|
{
|
||||||
if (BUF_LOCKED(buf)) {
|
if (BUF_LOCKED(buf)) {
|
||||||
return B_ERR_BUSY;
|
return B_ERR_BUSY;
|
||||||
@@ -262,17 +75,17 @@ enum b_status b_ringbuffer_open_read_buffer(
|
|||||||
buf->r_opened_buf = (char *)buf->r_buf + buf->r_read_ptr;
|
buf->r_opened_buf = (char *)buf->r_buf + buf->r_read_ptr;
|
||||||
buf->r_opened_capacity = contiguous_capacity;
|
buf->r_opened_capacity = contiguous_capacity;
|
||||||
|
|
||||||
buf->r_flags |= B_RINGBUFFER_READ_LOCKED;
|
buf->r_flags |= RINGBUFFER_READ_LOCKED;
|
||||||
*ptr = buf->r_opened_buf;
|
*ptr = buf->r_opened_buf;
|
||||||
*length = contiguous_capacity;
|
*length = contiguous_capacity;
|
||||||
|
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum b_status b_ringbuffer_close_read_buffer(
|
static enum b_status ringbuffer_close_read_buffer(
|
||||||
struct b_ringbuffer *buf, const void **ptr, size_t nr_read)
|
struct b_ringbuffer_p *buf, const void **ptr, size_t nr_read)
|
||||||
{
|
{
|
||||||
if (!(buf->r_flags & B_RINGBUFFER_READ_LOCKED)) {
|
if (!(buf->r_flags & RINGBUFFER_READ_LOCKED)) {
|
||||||
return B_ERR_BAD_STATE;
|
return B_ERR_BAD_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,13 +112,13 @@ enum b_status b_ringbuffer_close_read_buffer(
|
|||||||
|
|
||||||
buf->r_opened_buf = NULL;
|
buf->r_opened_buf = NULL;
|
||||||
buf->r_opened_capacity = 0;
|
buf->r_opened_capacity = 0;
|
||||||
buf->r_flags &= ~B_RINGBUFFER_READ_LOCKED;
|
buf->r_flags &= ~RINGBUFFER_READ_LOCKED;
|
||||||
|
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum b_status b_ringbuffer_open_write_buffer(
|
static enum b_status ringbuffer_open_write_buffer(
|
||||||
struct b_ringbuffer *buf, void **ptr, size_t *capacity)
|
struct b_ringbuffer_p *buf, void **ptr, size_t *capacity)
|
||||||
{
|
{
|
||||||
if (BUF_LOCKED(buf)) {
|
if (BUF_LOCKED(buf)) {
|
||||||
return B_ERR_BUSY;
|
return B_ERR_BUSY;
|
||||||
@@ -329,17 +142,17 @@ enum b_status b_ringbuffer_open_write_buffer(
|
|||||||
buf->r_opened_buf = (char *)buf->r_buf + buf->r_write_ptr;
|
buf->r_opened_buf = (char *)buf->r_buf + buf->r_write_ptr;
|
||||||
buf->r_opened_capacity = contiguous_capacity;
|
buf->r_opened_capacity = contiguous_capacity;
|
||||||
|
|
||||||
buf->r_flags |= B_RINGBUFFER_WRITE_LOCKED;
|
buf->r_flags |= RINGBUFFER_WRITE_LOCKED;
|
||||||
*ptr = buf->r_opened_buf;
|
*ptr = buf->r_opened_buf;
|
||||||
*capacity = contiguous_capacity;
|
*capacity = contiguous_capacity;
|
||||||
|
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum b_status b_ringbuffer_close_write_buffer(
|
static enum b_status ringbuffer_close_write_buffer(
|
||||||
struct b_ringbuffer *buf, void **ptr, size_t nr_written)
|
struct b_ringbuffer_p *buf, void **ptr, size_t nr_written)
|
||||||
{
|
{
|
||||||
if (!(buf->r_flags & B_RINGBUFFER_WRITE_LOCKED)) {
|
if (!(buf->r_flags & RINGBUFFER_WRITE_LOCKED)) {
|
||||||
return B_ERR_BAD_STATE;
|
return B_ERR_BAD_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +171,272 @@ enum b_status b_ringbuffer_close_write_buffer(
|
|||||||
|
|
||||||
buf->r_opened_buf = NULL;
|
buf->r_opened_buf = NULL;
|
||||||
buf->r_opened_capacity = 0;
|
buf->r_opened_capacity = 0;
|
||||||
buf->r_flags &= ~B_RINGBUFFER_WRITE_LOCKED;
|
buf->r_flags &= ~RINGBUFFER_WRITE_LOCKED;
|
||||||
|
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum b_status ringbuffer_read(
|
||||||
|
struct b_ringbuffer_p *buf, void *p, size_t count, size_t *nr_read)
|
||||||
|
{
|
||||||
|
if (BUF_LOCKED(buf)) {
|
||||||
|
return B_ERR_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t r = 0;
|
||||||
|
unsigned char *dest = p;
|
||||||
|
size_t remaining = count;
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
const void *src;
|
||||||
|
size_t available;
|
||||||
|
enum b_status status
|
||||||
|
= ringbuffer_open_read_buffer(buf, &src, &available);
|
||||||
|
|
||||||
|
if (status == B_ERR_NO_DATA) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!B_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t to_copy = remaining;
|
||||||
|
if (to_copy > available) {
|
||||||
|
to_copy = available;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dest, src, to_copy);
|
||||||
|
|
||||||
|
remaining -= to_copy;
|
||||||
|
dest += to_copy;
|
||||||
|
r += to_copy;
|
||||||
|
|
||||||
|
ringbuffer_close_read_buffer(buf, &src, to_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
*nr_read = r;
|
||||||
|
return B_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum b_status ringbuffer_write(
|
||||||
|
struct b_ringbuffer_p *buf, const void *p, size_t count, size_t *nr_written)
|
||||||
|
{
|
||||||
|
if (BUF_LOCKED(buf)) {
|
||||||
|
return B_ERR_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t w = 0;
|
||||||
|
const unsigned char *src = p;
|
||||||
|
size_t remaining = count;
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
void *dest;
|
||||||
|
size_t available;
|
||||||
|
enum b_status status
|
||||||
|
= ringbuffer_open_write_buffer(buf, &dest, &available);
|
||||||
|
|
||||||
|
if (status == B_ERR_NO_SPACE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!B_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t to_copy = remaining;
|
||||||
|
if (to_copy > available) {
|
||||||
|
to_copy = available;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dest, src, to_copy);
|
||||||
|
|
||||||
|
remaining -= to_copy;
|
||||||
|
src += to_copy;
|
||||||
|
w += to_copy;
|
||||||
|
|
||||||
|
ringbuffer_close_write_buffer(buf, &dest, to_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
*nr_written = w;
|
||||||
|
return B_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ringbuffer_getc(struct b_ringbuffer_p *buf)
|
||||||
|
{
|
||||||
|
size_t available = ringbuffer_available_data_remaining(buf);
|
||||||
|
if (available == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *p = buf->r_buf;
|
||||||
|
char c = p[buf->r_read_ptr++];
|
||||||
|
|
||||||
|
if (buf->r_read_ptr >= buf->r_capacity) {
|
||||||
|
buf->r_read_ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum b_status ringbuffer_putc(struct b_ringbuffer_p *buf, int c)
|
||||||
|
{
|
||||||
|
size_t available = ringbuffer_write_capacity_remaining(buf);
|
||||||
|
if (available == 0) {
|
||||||
|
return B_ERR_NO_SPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *p = buf->r_buf;
|
||||||
|
p[buf->r_write_ptr++] = c;
|
||||||
|
|
||||||
|
if (buf->r_write_ptr >= buf->r_capacity) {
|
||||||
|
buf->r_write_ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** PUBLIC FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
b_ringbuffer *b_ringbuffer_create(size_t capacity)
|
||||||
|
{
|
||||||
|
b_ringbuffer *ringbuf = b_object_create(B_TYPE_RINGBUFFER);
|
||||||
|
if (!ringbuf) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct b_ringbuffer_p *p
|
||||||
|
= b_object_get_private(ringbuf, B_TYPE_RINGBUFFER);
|
||||||
|
|
||||||
|
void *buffer = malloc(capacity);
|
||||||
|
if (!buffer) {
|
||||||
|
b_ringbuffer_unref(ringbuf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->r_flags = RINGBUFFER_BUFFER_MALLOC;
|
||||||
|
p->r_buf = buffer;
|
||||||
|
p->r_capacity = capacity;
|
||||||
|
|
||||||
|
return ringbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_ringbuffer *b_ringbuffer_create_with_buffer(void *ptr, size_t capacity)
|
||||||
|
{
|
||||||
|
b_ringbuffer *ringbuf = b_object_create(B_TYPE_RINGBUFFER);
|
||||||
|
if (!ringbuf) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct b_ringbuffer_p *p
|
||||||
|
= b_object_get_private(ringbuf, B_TYPE_RINGBUFFER);
|
||||||
|
|
||||||
|
p->r_flags = 0;
|
||||||
|
p->r_buf = ptr;
|
||||||
|
p->r_capacity = capacity;
|
||||||
|
|
||||||
|
return ringbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_ringbuffer_clear(b_ringbuffer *buf)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC_0(B_TYPE_RINGBUFFER, ringbuffer_clear, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_ringbuffer_read(
|
||||||
|
b_ringbuffer *buf, void *p, size_t count, size_t *nr_read)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC(
|
||||||
|
B_TYPE_RINGBUFFER, ringbuffer_read, buf, p, count, nr_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_ringbuffer_write(
|
||||||
|
b_ringbuffer *buf, const void *p, size_t count, size_t *nr_written)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC(
|
||||||
|
B_TYPE_RINGBUFFER, ringbuffer_write, buf, p, count, nr_written);
|
||||||
|
}
|
||||||
|
|
||||||
|
int b_ringbuffer_getc(b_ringbuffer *buf)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC_0(B_TYPE_RINGBUFFER, ringbuffer_getc, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_ringbuffer_putc(b_ringbuffer *buf, int c)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC(B_TYPE_RINGBUFFER, ringbuffer_putc, buf, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t b_ringbuffer_write_capacity_remaining(const b_ringbuffer *buf)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC_0(
|
||||||
|
B_TYPE_RINGBUFFER, ringbuffer_write_capacity_remaining, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t b_ringbuffer_available_data_remaining(const b_ringbuffer *buf)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC_0(
|
||||||
|
B_TYPE_RINGBUFFER, ringbuffer_available_data_remaining, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_ringbuffer_open_read_buffer(
|
||||||
|
b_ringbuffer *buf, const void **ptr, size_t *length)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC(
|
||||||
|
B_TYPE_RINGBUFFER, ringbuffer_open_read_buffer, buf, ptr, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_ringbuffer_close_read_buffer(
|
||||||
|
b_ringbuffer *buf, const void **ptr, size_t nr_read)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC(
|
||||||
|
B_TYPE_RINGBUFFER, ringbuffer_close_read_buffer, buf, ptr, nr_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_ringbuffer_open_write_buffer(
|
||||||
|
b_ringbuffer *buf, void **ptr, size_t *capacity)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC(
|
||||||
|
B_TYPE_RINGBUFFER, ringbuffer_open_write_buffer, buf, ptr,
|
||||||
|
capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_ringbuffer_close_write_buffer(
|
||||||
|
b_ringbuffer *buf, void **ptr, size_t nr_written)
|
||||||
|
{
|
||||||
|
B_CLASS_DISPATCH_STATIC(
|
||||||
|
B_TYPE_RINGBUFFER, ringbuffer_close_write_buffer, buf, ptr,
|
||||||
|
nr_written);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** VIRTUAL FUNCTIONS ********************************************************/
|
||||||
|
|
||||||
|
static void ringbuffer_init(b_object *obj, void *priv)
|
||||||
|
{
|
||||||
|
struct b_ringbuffer_p *buf = priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ringbuffer_fini(b_object *obj, void *priv)
|
||||||
|
{
|
||||||
|
struct b_ringbuffer_p *buf = priv;
|
||||||
|
|
||||||
|
if (buf->r_flags & RINGBUFFER_BUFFER_MALLOC) {
|
||||||
|
free(buf->r_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** CLASS DEFINITION *********************************************************/
|
||||||
|
|
||||||
|
B_TYPE_CLASS_DEFINITION_BEGIN(b_ringbuffer)
|
||||||
|
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
|
||||||
|
B_INTERFACE_ENTRY(to_string) = NULL;
|
||||||
|
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
|
||||||
|
B_TYPE_CLASS_DEFINITION_END(b_ringbuffer)
|
||||||
|
|
||||||
|
B_TYPE_DEFINITION_BEGIN(b_ringbuffer)
|
||||||
|
B_TYPE_ID(0xb0493774, 0xef13, 0x4905, 0xa865, 0x1595607ccad9);
|
||||||
|
B_TYPE_CLASS(b_ringbuffer_class);
|
||||||
|
B_TYPE_INSTANCE_PRIVATE(struct b_ringbuffer_p);
|
||||||
|
B_TYPE_INSTANCE_INIT(ringbuffer_init);
|
||||||
|
B_TYPE_INSTANCE_FINI(ringbuffer_fini);
|
||||||
|
B_TYPE_DEFINITION_END(b_ringbuffer)
|
||||||
|
|||||||
Reference in New Issue
Block a user