Created
January 27, 2022 23:55
-
-
Save yushijinhun/45fde239e511330bc8f9933eddc6987f to your computer and use it in GitHub Desktop.
Ring Buffer in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "ring_buffer.h" | |
#include <string.h> | |
#include <sys/param.h> | |
void ringbuf_init(ringbuf_t *rb, uint8_t *buf, size_t buf_size) { | |
rb->buf = buf; | |
rb->size = buf_size; | |
rb->begin = rb->end = 0; | |
} | |
void ringbuf_reset(ringbuf_t *rb) { | |
rb->begin = rb->end = 0; | |
} | |
size_t ringbuf_bytes_used(const ringbuf_t *rb) { | |
if (rb->begin <= rb->end) { | |
return rb->end - rb->begin; | |
} else { | |
return rb->size - rb->begin + rb->end; | |
} | |
} | |
size_t ringbuf_bytes_free(const ringbuf_t *rb) { | |
if (rb->begin <= rb->end) { | |
return rb->size - rb->end + rb->begin - 1; | |
} else { | |
return rb->begin - rb->end - 1; | |
} | |
} | |
size_t ringbuf_capacity(const ringbuf_t *rb) { | |
return rb->size - 1; | |
} | |
size_t ringbuf_write(ringbuf_t *rb, const uint8_t *from, size_t n) { | |
size_t free_size = ringbuf_bytes_free(rb); | |
size_t overwritten = free_size >= n ? 0 : n - free_size; | |
size_t written; | |
while (n > 0) { | |
written = MIN(n, rb->size - rb->end); | |
memcpy(rb->buf + rb->end, from, written); | |
from += written; | |
n -= written; | |
rb->end += written; | |
if (rb->end == rb->size) | |
rb->end = 0; | |
} | |
if (overwritten > 0) { | |
if (rb->end == rb->size - 1) | |
rb->begin = 0; | |
else | |
rb->begin = rb->end + 1; | |
} | |
return overwritten; | |
} | |
size_t ringbuf_read(ringbuf_t *rb, uint8_t *to, size_t n) { | |
size_t available = ringbuf_bytes_used(rb); | |
size_t read; | |
if (rb->begin > rb->end) { | |
read = MIN(rb->size - rb->begin, n); | |
memcpy(to, rb->buf + rb->begin, read); | |
rb->begin += read; | |
if (rb->begin == rb->size) | |
rb->begin = 0; | |
if (read == n) | |
return read; | |
to += read; | |
n -= read; | |
} | |
read = MIN(rb->end - rb->begin, n); | |
memcpy(to, rb->buf + rb->begin, read); | |
rb->begin += read; | |
return MIN(available, n); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <stddef.h> | |
#include <stdint.h> | |
typedef struct { | |
uint8_t *buf; | |
size_t size; | |
size_t begin; | |
size_t end; | |
} ringbuf_t; | |
/** | |
* Initializes a ring buffer with a pre-allocated memory area. | |
* Capacity of the ring buffer = memory size - 1. | |
* @param rb the ring buffer to initialize | |
* @param buf the address of the pre-allocated memory | |
* @param buf_size the size of the memory, must be larger than 1 | |
*/ | |
void ringbuf_init(ringbuf_t *rb, uint8_t *buf, size_t buf_size); | |
/** | |
* Discards all data in the ring buffer. | |
*/ | |
void ringbuf_reset(ringbuf_t *rb); | |
/** | |
* Calculates the used space size of the ring buffer. | |
*/ | |
size_t ringbuf_bytes_used(const ringbuf_t *rb); | |
/** | |
* Calculates the free space size of the ring buffer. | |
*/ | |
size_t ringbuf_bytes_free(const ringbuf_t *rb); | |
/** | |
* Gets the capacity of the ring buffer. | |
*/ | |
size_t ringbuf_capacity(const ringbuf_t *rb); | |
/** | |
* Writes n bytes to the ring buffer. | |
* Old data will be overwritten if there is no enough space in the ring buffer. | |
* @returns the number of discarded bytes | |
*/ | |
size_t ringbuf_write(ringbuf_t *rb, const uint8_t *from, size_t n); | |
/** | |
* Reads n bytes from the ring buffer. | |
* Fewer than n bytes is read if there is no enough data in the ring buffer. | |
* @returns the number of bytes read | |
*/ | |
size_t ringbuf_read(ringbuf_t *rb, uint8_t *to, size_t n); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment