| /* | |
| * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230) | |
| * | |
| * SPDX-License-Identifier: BSD-2-Clause | |
| */ | |
| /** | |
| * @file circular_buffer.h | |
| * @brief A circular buffer implementation | |
| */ | |
| #pragma once | |
| #include <stdbool.h> | |
| #include <sys/types.h> | |
| #include <stdint.h> | |
| #include <unistd.h> | |
| #include <stdlib.h> | |
| #include <errno.h> | |
| #include <utils/zf_log.h> | |
| /* Circular Buffer */ | |
| typedef struct circ_buf { | |
| off_t head; | |
| off_t tail; | |
| size_t size; | |
| uint8_t buf[]; | |
| } circ_buf_t; | |
| static inline off_t _next_pos(circ_buf_t *cb, off_t pos) | |
| { | |
| return (pos + 1) % cb->size; | |
| } | |
| /** | |
| * Initialise a new circular buffer | |
| * | |
| * @param size The size of the buffer in bytes. | |
| * @param[in] cb Circular buffer structure allocated by the user. | |
| * | |
| * @return NULL on failure. | |
| */ | |
| static inline int circ_buf_init(size_t size, circ_buf_t *cb) { | |
| if (size == 0 || !cb) { | |
| ZF_LOGE("Invalid arguments\n"); | |
| return EINVAL; | |
| } | |
| cb->head = 0; | |
| cb->tail = 0; | |
| cb->size = size; | |
| return 0; | |
| } | |
| /** | |
| * Check if the circular buffer is full | |
| * | |
| * @param cb Circular buffer to check | |
| * | |
| * @return true indicates the buffer is full, false otherwise. | |
| */ | |
| static inline bool circ_buf_is_full(circ_buf_t *cb) { | |
| return _next_pos(cb, cb->tail) == cb->head; | |
| } | |
| /** | |
| * Check if the circular buffer is empty | |
| * | |
| * @param cb Circular buffer to check | |
| * | |
| * @return true indicates the buffer is empty, false otherwise. | |
| */ | |
| static inline bool circ_buf_is_empty(circ_buf_t *cb) { | |
| return cb->tail == cb->head; | |
| } | |
| /** | |
| * Put a byte | |
| * | |
| * @param cb Circular buffer to put via. | |
| * @param c Byte to send. | |
| */ | |
| static inline void circ_buf_put(circ_buf_t *cb, uint8_t c) { | |
| cb->buf[cb->tail] = c; | |
| cb->tail = _next_pos(cb, cb->tail); | |
| } | |
| /** | |
| * Get a byte | |
| * | |
| * @param cb Circular buffer to get from. | |
| * | |
| * @return The byte received. | |
| */ | |
| static inline uint8_t circ_buf_get(circ_buf_t *cb) { | |
| uint8_t c = cb->buf[cb->head]; | |
| cb->head = _next_pos(cb, cb->head); | |
| return c; | |
| } | |