Skip to content

Commit

Permalink
[libringbuffer] fix split buffer read/write
Browse files Browse the repository at this point in the history
  • Loading branch information
gozfree committed Dec 14, 2019
1 parent cb32540 commit b916cf6
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 24 deletions.
69 changes: 51 additions & 18 deletions gear-lib/libringbuffer/libringbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define CALLOC(size, type) (type *)calloc(size, sizeof(type))

int rb_get_space_free(struct ringbuffer *rb)
size_t rb_get_space_free(struct ringbuffer *rb)
{
if (!rb) {
return -1;
Expand All @@ -40,7 +40,7 @@ int rb_get_space_free(struct ringbuffer *rb)
}
}

int rb_get_space_used(struct ringbuffer *rb)
size_t rb_get_space_used(struct ringbuffer *rb)
{
if (!rb) {
return -1;
Expand Down Expand Up @@ -95,13 +95,24 @@ ssize_t rb_write(struct ringbuffer *rb, const void *buf, size_t len)
if (!rb) {
return -1;
}
int left = rb_get_space_free(rb);
if ((int)len > left) {
printf("Not enough space: %zu request, %d available\n", len, left);
size_t left = rb_get_space_free(rb);
if (len > left) {
printf("Not enough space: %zu request, %zu available\n", len, left);
return -1;
}
memcpy(rb_end_ptr(rb), buf, len);
rb->end = (rb->end + len) % rb->length;

if ((rb->length - rb->end) < len) {
int half_tail = rb->length - rb->end;
memcpy(rb_end_ptr(rb), buf, half_tail);
rb->end = (rb->end + half_tail) % rb->length;

int half_head = len - half_tail;
memcpy(rb_end_ptr(rb), buf+half_tail, half_head);
rb->end = (rb->end + half_head) % rb->length;
} else {
memcpy(rb_end_ptr(rb), buf, len);
rb->end = (rb->end + len) % rb->length;
}
return len;
}

Expand All @@ -111,30 +122,52 @@ ssize_t rb_read(struct ringbuffer *rb, void *buf, size_t len)
return -1;
}
size_t rlen = MIN(len, rb_get_space_used(rb));
memcpy(buf, rb_start_ptr(rb), rlen);
rb->start = (rb->start + rlen) % rb->length;

if ((rb->length - rb->start) < rlen) {
int half_tail = rb->length - rb->start;
memcpy(buf, rb_start_ptr(rb), half_tail);
rb->start = (rb->start + half_tail) % rb->length;

int half_head = rlen - half_tail;
memcpy(buf+half_tail, rb_start_ptr(rb), half_head);
rb->start = (rb->start + half_head) % rb->length;
} else {
memcpy(buf, rb_start_ptr(rb), rlen);
rb->start = (rb->start + rlen) % rb->length;
}

if ((rb->start == rb->end) || (rb_get_space_used(rb) == 0)) {
rb->start = rb->end = 0;
}
return rlen;
}

void *rb_dump(struct ringbuffer *rb, int *blen)
void *rb_dump(struct ringbuffer *rb, size_t *blen)
{
if (!rb) {
return NULL;
}
void *buf = NULL;
int len = rb_get_space_used(rb);
if (len > 0) {
buf = calloc(1, len);
if (!buf) {
printf("malloc %d failed!\n", len);
return NULL;
}
size_t len = rb_get_space_used(rb);
if (len <= 0) {
return NULL;
}
buf = calloc(1, len);
if (!buf) {
printf("malloc %zu failed!\n", len);
return NULL;
}
*blen = len;
memcpy(buf, rb_start_ptr(rb), len);

if ((rb->length - rb->start) < len) {
int half_tail = rb->length - rb->start;
memcpy(buf, rb_start_ptr(rb), half_tail);

int half_head = len - half_tail;
memcpy(buf+half_tail, rb->buffer, half_head);
} else {
memcpy(buf, rb_start_ptr(rb), len);
}
return buf;
}

Expand Down
6 changes: 3 additions & 3 deletions gear-lib/libringbuffer/libringbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ struct ringbuffer *rb_create(int len);
void rb_destroy(struct ringbuffer *rb);
ssize_t rb_write(struct ringbuffer *rb, const void *buf, size_t len);
ssize_t rb_read(struct ringbuffer *rb, void *buf, size_t len);
void *rb_dump(struct ringbuffer *rb, int *len);
void *rb_dump(struct ringbuffer *rb, size_t *len);
void rb_cleanup(struct ringbuffer *rb);
int rb_get_space_free(struct ringbuffer *rb);
int rb_get_space_used(struct ringbuffer *rb);
size_t rb_get_space_free(struct ringbuffer *rb);
size_t rb_get_space_used(struct ringbuffer *rb);

#ifdef __cplusplus
}
Expand Down
6 changes: 3 additions & 3 deletions gear-lib/libringbuffer/test_libringbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ int foo()
struct ringbuffer *rb = rb_create(1024);
const char *tmp = "hello world";
ssize_t ret = 0;
int len = 0;
size_t len = 0;
for (int i = 0; i < 100; i++) {
printf("free=%d, used=%d\n", rb_get_space_free(rb), rb_get_space_used(rb));
printf("free=%zu, used=%zu\n", rb_get_space_free(rb), rb_get_space_used(rb));
ret = rb_write(rb, tmp, strlen(tmp));
if (ret < 0) {
break;
}
}
printf("dump = %s\n", (char *)rb_dump(rb, &len));
printf("rb_write len=%d\n", len);
printf("rb_write len=%zu\n", len);
char tmp2[9];
memset(tmp2, 0, sizeof(tmp2));
rb_read(rb, tmp2, sizeof(tmp2)-1);
Expand Down

0 comments on commit b916cf6

Please sign in to comment.