Commit 4763fd3c authored by Titouan Soulard's avatar Titouan Soulard

common: implement a generic circular buffer

parent 6db88c78
#include "common/circular_buffer.h"
struct CommonCBBuffer *common_circular_buffer_create(uint32_t len, bool is_infinite) {
struct CommonCBBuffer *buffer = (struct CommonCBBuffer *) malloc(sizeof(struct CommonCBBuffer));
buffer->base_addr = malloc(len);
buffer->read_counter = 0;
buffer->write_counter = 0;
buffer->total_len = len;
buffer->readable_len = is_infinite ? -1 : 0;
return buffer;
}
void common_circular_buffer_write(struct CommonCBBuffer *buffer, void *bytes, uint32_t byte_count) {
uint32_t reduced_byte_count;
int32_t extra_byte_count;
extra_byte_count = buffer->write_counter + byte_count - buffer->total_len;
if(extra_byte_count < 0) reduced_byte_count = byte_count;
else reduced_byte_count = byte_count - extra_byte_count;
memcpy(buffer->base_addr + buffer->write_counter, bytes, reduced_byte_count);
if(extra_byte_count > 0) {
memcpy(buffer->base_addr, bytes + reduced_byte_count, extra_byte_count);
}
if(extra_byte_count >= 0) {
buffer->write_counter = extra_byte_count;
} else {
buffer->write_counter += reduced_byte_count;
}
// Finite buffers should have a mark of where to stop
if(buffer->readable_len >= 0) buffer->readable_len += byte_count;
}
uint32_t common_circular_buffer_read(struct CommonCBBuffer *buffer, void *bytes, uint32_t user_count) {
uint32_t byte_count;
uint32_t read_count;
uint32_t total_count;
byte_count = MINIF(user_count, buffer->readable_len, buffer->readable_len >= 0);
total_count = 0;
while(total_count < byte_count) {
read_count = MIN(byte_count - total_count, buffer->total_len - buffer->read_counter);
memcpy(bytes + total_count, buffer->base_addr + buffer->read_counter, read_count);
buffer->read_counter += read_count;
if(buffer->read_counter == buffer->total_len) buffer->read_counter = 0;
total_count += read_count;
}
return total_count;
}
void common_circular_buffer_free(struct CommonCBBuffer *buffer) {
free(buffer->base_addr);
free(buffer);
}
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MIN(a, b) (a > b ? b : a)
#define MINIF(a, b, c) ((a > b && c) ? b : a)
struct CommonCBBuffer {
void *base_addr;
uint32_t read_counter;
uint32_t write_counter;
uint32_t total_len;
int32_t readable_len;
};
struct CommonCBBuffer *common_circular_buffer_create(uint32_t len, bool is_infinite);
void common_circular_buffer_write(struct CommonCBBuffer *buffer, void *bytes, uint32_t byte_count);
uint32_t common_circular_buffer_read(struct CommonCBBuffer *buffer, void *bytes, uint32_t user_count);
void common_circular_buffer_free(struct CommonCBBuffer *buffer);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment