2 changed files with 0 additions and 210 deletions
@ -1,20 +0,0 @@
@@ -1,20 +0,0 @@
|
||||
#ifndef RING_BUFFER_H |
||||
#define RING_BUFFER_H |
||||
|
||||
#include <stddef.h> |
||||
#include <stdint.h> |
||||
|
||||
struct ring_buffer; |
||||
|
||||
int ring_buffer__init(struct ring_buffer **buffer, size_t size); |
||||
int ring_buffer__fini(struct ring_buffer *buffer); |
||||
int ring_buffer__write(struct ring_buffer *buffer, uint8_t *data, |
||||
size_t datalen); |
||||
int ring_buffer__read(struct ring_buffer *buffer, uint8_t *data, |
||||
size_t *datalen); |
||||
int ring_buffer__unread(struct ring_buffer *buffer, size_t bytes); |
||||
int ring_buffer__ack(struct ring_buffer *buffer, size_t acked_bytes); |
||||
int ring_buffer__get_unread_bytes(struct ring_buffer *buffer, size_t *bytes); |
||||
int ring_buffer__get_free_bytes(struct ring_buffer *buffer, size_t *bytes); |
||||
|
||||
#endif /* RING_BUFFER_H */ |
||||
@ -1,190 +0,0 @@
@@ -1,190 +0,0 @@
|
||||
#include "ring_buffer.h" |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
struct ring_buffer |
||||
{ |
||||
uint8_t* buffer; |
||||
size_t size; |
||||
size_t write_ptr; |
||||
size_t read_ptr; |
||||
size_t ack_ptr; |
||||
}; |
||||
|
||||
static size_t min_size_t(size_t a, size_t b) |
||||
{ |
||||
return a < b ? a : b; |
||||
} |
||||
|
||||
int ring_buffer__init(struct ring_buffer** buffer, size_t size) |
||||
{ |
||||
if(!buffer || size == 0) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
struct ring_buffer* rb = (struct ring_buffer*)calloc(1, sizeof(struct ring_buffer)); |
||||
if(!rb) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
rb->buffer = (uint8_t*)malloc(size); |
||||
if(!rb->buffer) |
||||
{ |
||||
free(rb); |
||||
return -1; |
||||
} |
||||
|
||||
rb->size = size; |
||||
rb->write_ptr = 0; |
||||
rb->read_ptr = 0; |
||||
rb->ack_ptr = 0; |
||||
|
||||
*buffer = rb; |
||||
return 0; |
||||
} |
||||
|
||||
int ring_buffer__fini(struct ring_buffer* buffer) |
||||
{ |
||||
if(!buffer) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
if(buffer->buffer) |
||||
{ |
||||
free(buffer->buffer); |
||||
} |
||||
free(buffer); |
||||
return 0; |
||||
} |
||||
|
||||
int ring_buffer__write(struct ring_buffer* buffer, uint8_t* data, size_t datalen) |
||||
{ |
||||
if(!buffer || !data || datalen == 0) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
size_t free_space = (buffer->size - 1 - (buffer->write_ptr - buffer->ack_ptr)) % buffer->size; |
||||
if(free_space < datalen) |
||||
{ |
||||
return -1; // Недостаточно места
|
||||
} |
||||
|
||||
size_t part1 = buffer->size - (buffer->write_ptr % buffer->size); |
||||
if(datalen <= part1) |
||||
{ |
||||
memcpy(buffer->buffer + (buffer->write_ptr % buffer->size), data, datalen); |
||||
} |
||||
else |
||||
{ |
||||
memcpy(buffer->buffer + (buffer->write_ptr % buffer->size), data, part1); |
||||
memcpy(buffer->buffer, data + part1, datalen - part1); |
||||
} |
||||
|
||||
buffer->write_ptr = (buffer->write_ptr + datalen) % buffer->size; |
||||
return 0; |
||||
} |
||||
|
||||
int ring_buffer__read(struct ring_buffer* buffer, uint8_t* data, size_t* datalen) |
||||
{ |
||||
if(!buffer || !data || !datalen || *datalen == 0) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
size_t available = (buffer->write_ptr - buffer->read_ptr + buffer->size) % buffer->size; |
||||
if(available == 0) |
||||
{ |
||||
*datalen = 0; |
||||
return -1; // Нет данных для чтения
|
||||
} |
||||
|
||||
size_t to_read = min_size_t(*datalen, available); |
||||
size_t part1 = buffer->size - (buffer->read_ptr % buffer->size); |
||||
if(to_read <= part1) |
||||
{ |
||||
memcpy(data, buffer->buffer + (buffer->read_ptr % buffer->size), to_read); |
||||
} |
||||
else |
||||
{ |
||||
memcpy(data, buffer->buffer + (buffer->read_ptr % buffer->size), part1); |
||||
memcpy(data + part1, buffer->buffer, to_read - part1); |
||||
} |
||||
|
||||
buffer->read_ptr = (buffer->read_ptr + to_read) % buffer->size; |
||||
|
||||
*datalen = to_read; |
||||
return 0; |
||||
} |
||||
|
||||
int ring_buffer__unread(struct ring_buffer* buffer, size_t bytes) |
||||
{ |
||||
if(!buffer) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
buffer->read_ptr = (buffer->read_ptr - bytes) % buffer->size; |
||||
} |
||||
|
||||
int ring_buffer__ack(struct ring_buffer* buffer, size_t acked_bytes) |
||||
{ |
||||
if(!buffer || acked_bytes == 0) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
size_t available = (buffer->read_ptr - buffer->ack_ptr + buffer->size) % buffer->size; |
||||
if(acked_bytes > available) |
||||
{ |
||||
acked_bytes = available; // Защита от переполнения
|
||||
} |
||||
|
||||
buffer->ack_ptr = (buffer->ack_ptr + acked_bytes) % buffer->size; |
||||
return 0; |
||||
} |
||||
|
||||
int ring_buffer__get_unread_bytes(struct ring_buffer* buffer, size_t* bytes) |
||||
{ |
||||
if(!buffer || !bytes) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
size_t free_space = 0; |
||||
if(buffer->write_ptr >= buffer->read_ptr) |
||||
{ |
||||
free_space = buffer->write_ptr - buffer->read_ptr; |
||||
} |
||||
else |
||||
{ |
||||
free_space = buffer->size - (buffer->read_ptr - buffer->write_ptr); |
||||
} |
||||
|
||||
*bytes = free_space; |
||||
return 0; |
||||
} |
||||
int ring_buffer__get_free_bytes(struct ring_buffer* buffer, size_t* bytes) |
||||
{ |
||||
if(!buffer || !bytes) |
||||
{ |
||||
return -1; |
||||
} |
||||
|
||||
size_t free_space = 0; |
||||
if(buffer->write_ptr >= buffer->ack_ptr) |
||||
{ |
||||
free_space = buffer->size - 1 - (buffer->write_ptr - buffer->ack_ptr); |
||||
} |
||||
else |
||||
{ |
||||
free_space = (buffer->ack_ptr - buffer->write_ptr) - 1; |
||||
} |
||||
|
||||
*bytes = free_space; |
||||
return 0; |
||||
} |
||||
Loading…
Reference in new issue