Loading...
Searching...
No Matches
chunked_ringbuffer.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2021 ML!PA Consulting GmbH
3 *
4 * This file is subject to the terms and conditions of the GNU Lesser
5 * General Public License v2.1. See the file LICENSE in the top level
6 * directory for more details.
7 */
8
23#ifndef CHUNKED_RINGBUFFER_H
24#define CHUNKED_RINGBUFFER_H
25
26#include <stdbool.h>
27#include <stdint.h>
28#include <stddef.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
38#ifndef CONFIG_CHUNK_NUM_MAX
39#define CONFIG_CHUNK_NUM_MAX (4)
40#endif
41
46typedef struct {
47 uint8_t *buffer;
48 uint8_t *buffer_end;
49 uint8_t *cur;
50 uint8_t *cur_start;
51 uint8_t *protect;
52 uint8_t *chunk_start[CONFIG_CHUNK_NUM_MAX];
53 uint16_t chunk_len[CONFIG_CHUNK_NUM_MAX];
54 uint8_t chunk_cur;
56
64typedef void (*crb_foreach_callback_t)(void *ctx, uint8_t *bytes, size_t len);
65
73void crb_init(chunk_ringbuf_t *rb, void *buffer, size_t len);
74
88bool crb_end_chunk(chunk_ringbuf_t *rb, bool valid);
89
103static inline bool crb_start_chunk(chunk_ringbuf_t *rb)
104{
105 /* discard stale chunk */
106 if (rb->cur_start) {
107 crb_end_chunk(rb, false);
108 }
109
110 /* pointing to the start of the first chunk */
111 if (rb->cur == rb->protect) {
112 return false;
113 }
114
115 rb->cur_start = rb->cur;
116
117 if (rb->protect == NULL) {
118 rb->protect = rb->cur_start;
119 }
120
121 return true;
122}
123
138static inline bool crb_add_byte(chunk_ringbuf_t *rb, uint8_t b)
139{
140 /* if this is the first chunk, protect will be at start */
141 if (rb->cur == rb->protect &&
142 rb->cur != rb->cur_start) {
143 return false;
144 }
145
146 *rb->cur = b;
147
148 /* handle wrap around */
149 if (rb->cur == rb->buffer_end) {
150 rb->cur = rb->buffer;
151 } else {
152 ++rb->cur;
153 }
154
155 return true;
156}
157
173bool crb_add_bytes(chunk_ringbuf_t *rb, const void *data, size_t len);
174
191bool crb_add_chunk(chunk_ringbuf_t *rb, const void *data, size_t len);
192
202bool crb_get_chunk_size(chunk_ringbuf_t *rb, size_t *len);
203
215bool crb_peek_bytes(chunk_ringbuf_t *rb, void *dst, size_t offset, size_t len);
216
229bool crb_consume_chunk(chunk_ringbuf_t *rb, void *dst, size_t len);
230
245
246#ifdef __cplusplus
247}
248#endif
249
250#endif /* CHUNKED_RINGBUFFER_H */
bool crb_end_chunk(chunk_ringbuf_t *rb, bool valid)
Close the current chunk.
bool crb_peek_bytes(chunk_ringbuf_t *rb, void *dst, size_t offset, size_t len)
Get a number of bytes from the first valid chunk without consuming it.
static bool crb_add_byte(chunk_ringbuf_t *rb, uint8_t b)
Insert a byte into the current chunk.
void crb_init(chunk_ringbuf_t *rb, void *buffer, size_t len)
Initialize a Chunked Ringbuffer.
static bool crb_start_chunk(chunk_ringbuf_t *rb)
Start a new chunk on the ringbuffer.
void(* crb_foreach_callback_t)(void *ctx, uint8_t *bytes, size_t len)
Callback function for crb_chunk_foreach.
bool crb_add_bytes(chunk_ringbuf_t *rb, const void *data, size_t len)
Insert a number of bytes into the current chunk.
bool crb_get_chunk_size(chunk_ringbuf_t *rb, size_t *len)
Get the size of the first valid chunk.
bool crb_add_chunk(chunk_ringbuf_t *rb, const void *data, size_t len)
Add a complete chunk to the Ringbuffer.
#define CONFIG_CHUNK_NUM_MAX
The maximum number of chunks that can be stored in a Chunked Ringbuffer.
bool crb_consume_chunk(chunk_ringbuf_t *rb, void *dst, size_t len)
Remove a chunk from the valid chunk array.
bool crb_chunk_foreach(chunk_ringbuf_t *rb, crb_foreach_callback_t func, void *ctx)
Execute a callback for each byte in the first valid chunk The callback function may be called twice i...
A chunked ringbuffer.
uint8_t chunk_cur
Index of the first valid chunk.
uint8_t * cur_start
start of the currently written chunk
uint8_t * buffer_end
last data element
uint8_t * buffer
pointer to the memory to hold the data
uint8_t * cur
current write pointer
uint8_t * protect
start of the first valid chunk