blob: dfe8b4caa3de78a09ccaf734ce5984c8549ac66f [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001#include <inttypes.h>
2#include <stddef.h>
3#include <assert.h>
4/**
5 * @file
6 * Prototypes and structures for the ring buffer module.
7 */
8
9#ifndef RINGBUFFER_H
10#define RINGBUFFER_H
11
12#ifdef __cplusplus
13extern "C"
14{
15#endif
16
17#define RING_BUFFER_ASSERT(x) assert(x)
18
19/**
20 * Checks if the buffer_size is a power of two.
21 * Due to the design only <tt> RING_BUFFER_SIZE-1 </tt> items
22 * can be contained in the buffer.
23 * buffer_size must be a power of two.
24*/
25#define RING_BUFFER_IS_POWER_OF_TWO(buffer_size) ((buffer_size & (buffer_size - 1)) == 0)
26
27/**
28 * The type which is used to hold the size
29 * and the indicies of the buffer.
30 */
31typedef size_t ring_buffer_size_t;
32
33/**
34 * Used as a modulo operator
35 * as <tt> a % b = (a & (b − 1)) </tt>
36 * where \c a is a positive index in the buffer and
37 * \c b is the (power of two) size of the buffer.
38 */
39#define RING_BUFFER_MASK(rb) (rb->buffer_mask)
40
41/**
42 * Simplifies the use of <tt>struct ring_buffer_t</tt>.
43 */
44typedef struct ring_buffer_t ring_buffer_t;
45
46/**
47 * Structure which holds a ring buffer.
48 * The buffer contains a buffer array
49 * as well as metadata for the ring buffer.
50 */
51struct ring_buffer_t {
52 /** Buffer memory. */
53 char *buffer;
54 /** Buffer mask. */
55 ring_buffer_size_t buffer_mask;
56 /** Index of tail. */
57 ring_buffer_size_t tail_index;
58 /** Index of head. */
59 ring_buffer_size_t head_index;
60};
61
62/**
63 * Initializes the ring buffer pointed to by <em>buffer</em>.
64 * This function can also be used to empty/reset the buffer.
65 * @param buffer The ring buffer to initialize.
66 * @param buf The buffer allocated for the ringbuffer.
67 * @param buf_size The size of the allocated ringbuffer.
68 */
69void ring_buffer_init(ring_buffer_t *buffer, char *buf, size_t buf_size);
70
71/**
72 * Adds a byte to a ring buffer.
73 * @param buffer The buffer in which the data should be placed.
74 * @param data The byte to place.
75 */
76void ring_buffer_queue(ring_buffer_t *buffer, char data);
77
78/**
79 * Adds an array of bytes to a ring buffer.
80 * @param buffer The buffer in which the data should be placed.
81 * @param data A pointer to the array of bytes to place in the queue.
82 * @param size The size of the array.
83 */
84void ring_buffer_queue_arr(ring_buffer_t *buffer, const char *data, ring_buffer_size_t size);
85
86/**
87 * Returns the oldest byte in a ring buffer.
88 * @param buffer The buffer from which the data should be returned.
89 * @param data A pointer to the location at which the data should be placed.
90 * @return 1 if data was returned; 0 otherwise.
91 */
92uint8_t ring_buffer_dequeue(ring_buffer_t *buffer, char *data);
93
94/**
95 * Returns the <em>len</em> oldest bytes in a ring buffer.
96 * @param buffer The buffer from which the data should be returned.
97 * @param data A pointer to the array at which the data should be placed.
98 * @param len The maximum number of bytes to return.
99 * @return The number of bytes returned.
100 */
101ring_buffer_size_t ring_buffer_dequeue_arr(ring_buffer_t *buffer, char *data, ring_buffer_size_t len);
102/**
103 * Peeks a ring buffer, i.e. returns an element without removing it.
104 * @param buffer The buffer from which the data should be returned.
105 * @param data A pointer to the location at which the data should be placed.
106 * @param index The index to peek.
107 * @return 1 if data was returned; 0 otherwise.
108 */
109uint8_t ring_buffer_peek(ring_buffer_t *buffer, char *data, ring_buffer_size_t index);
110
111
112/**
113 * Returns whether a ring buffer is empty.
114 * @param buffer The buffer for which it should be returned whether it is empty.
115 * @return 1 if empty; 0 otherwise.
116 */
117uint8_t ring_buffer_is_empty(ring_buffer_t *buffer);
118/**
119 * Returns whether a ring buffer is full.
120 * @param buffer The buffer for which it should be returned whether it is full.
121 * @return 1 if full; 0 otherwise.
122 */
123uint8_t ring_buffer_is_full(ring_buffer_t *buffer);
124
125/**
126 * Returns the number of items in a ring buffer.
127 * @param buffer The buffer for which the number of items should be returned.
128 * @return The number of items in the ring buffer.
129 */
130ring_buffer_size_t ring_buffer_num_items(ring_buffer_t *buffer);
131
132void ring_buffer_clean(ring_buffer_t *buffer);
133
134#ifdef __cplusplus
135}
136#endif
137
138#endif /* RINGBUFFER_H */