| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- // Author: Ershov V.
- // Modified: Sychov. A / 12/2020
- #ifndef RING_BUFFER_H
- #define RING_BUFFER_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- #define RING_BUFFER_HC
- #include "my_assert.h"
- #include <stdbool.h>
- #include <stdint.h>
- #ifndef RINGBUF_ASSERT
- #define RINGBUF_ASSERT(CONDITION) my_assert(CONDITION)
- #endif
- #ifndef RING_BUFFER_RC_TYPE
- #define RING_BUFFER_RC_TYPE int16_t
- #endif
- #ifndef RING_BUFFER_SIZE_TYPE
- #define RING_BUFFER_SIZE_TYPE int16_t
- #endif
- #ifndef RING_BUFFER_ELEMENT_TYPE
- #define RING_BUFFER_ELEMENT_TYPE unsigned char
- #endif
- #ifndef RING_BUFFER_ELEMENT_SIZE
- #define RING_BUFFER_ELEMENT_SIZE sizeof(RING_BUFFER_ELEMENT_TYPE)
- #endif
- typedef RING_BUFFER_RC_TYPE (*pfRingbuf_predicate_t)(
- void * context,
- RING_BUFFER_ELEMENT_TYPE element);
- typedef void (*pfRingbuf_visitor_t)(void * context,
- RING_BUFFER_ELEMENT_TYPE element);
- typedef enum ringbuf_rc_t
- {
- RINGBUF_RC_NO_ERROR = 0,
- RINGBUF_RC_BAD_PARAM = -1,
- RINGBUF_RC_NO_DATA = -2,
- RINGBUF_RC_OVERFLOW = -3
- }ringbuf_rc_t;
- typedef struct ringbuf_t
- {
- RING_BUFFER_ELEMENT_TYPE * buffer;
- RING_BUFFER_SIZE_TYPE capacity;
- RING_BUFFER_SIZE_TYPE size;
- RING_BUFFER_SIZE_TYPE writeIndex;
- RING_BUFFER_SIZE_TYPE readIndex;
- }ringbuf_t;
- ///
- /// \brief Initializing ring buffer.
- /// \param self Pointer to the ring buffer.
- /// \param buffer Pointer to the memory block for the ring buffer.
- /// \param capacity Size of the memory block.
- /// \return RINGBUF_RC_NO_ERROR if success, error code otherwise.
- ///
- RING_BUFFER_RC_TYPE ringbuf_init(ringbuf_t * self,
- void * buffer,
- RING_BUFFER_SIZE_TYPE capacity);
- ///
- /// \brief Getting data with size \p from ring buffer to buffer \p buffer
- /// without extracting them.
- /// \param self Pointer to the ring buffer.
- /// \param buffer Pointer to the buffer for storing data.
- /// \param size Capacity of the buffer for storing data.
- /// \param offset Reading offset from the begining of the ringbuf (amount of bytes to skip).
- /// \return size of received data or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_peek_offset(const ringbuf_t * self,
- void * buffer,
- RING_BUFFER_SIZE_TYPE size,
- RING_BUFFER_SIZE_TYPE offset);
- ///
- /// \brief Getting data with size \p from ring buffer to buffer \p buffer
- /// without extracting them.
- /// \param self Pointer to the ring buffer.
- /// \param buffer Pointer to the buffer for storing data.
- /// \param size Capacity of the buffer for storing data.
- /// \return size of received data or error code.
- ///
- static inline RING_BUFFER_RC_TYPE ringbuf_peek(const ringbuf_t * self,
- void * buffer,
- RING_BUFFER_SIZE_TYPE size)
- {
- return ringbuf_peek_offset( self, buffer, size, 0 );
- }
- ///
- /// \brief Extracting data with size \p from ring buffer to buffer \p buffer.
- /// \param self Pointer to the ring buffer.
- /// \param buffer Pointer to the buffer for storing data.
- /// \param size Capacity of the buffer for storing data.
- /// \return size of received data or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_read(ringbuf_t * self,
- void * buffer,
- RING_BUFFER_SIZE_TYPE size);
- ///
- /// \brief Writing data in \p buffer with size \p size into the end of a ring
- /// buffer.
- /// \param self Pointer to the ring buffer.
- /// \param buffer Pointer to the data for writing.
- /// \param size Size of data for writing.
- /// \return Size of written data or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_write(ringbuf_t * self,
- const void * buffer,
- RING_BUFFER_SIZE_TYPE size);
- ///
- /// \brief Writing data in \p buffer with size \p size into the front of a ring
- /// buffer.
- /// \param self Pointer to the ring buffer.
- /// \param buffer Pointer to the data for writing.
- /// \param size Size of data for writing.
- /// \return Size of written data or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_write_front(ringbuf_t * self,
- const void * buffer,
- RING_BUFFER_SIZE_TYPE size);
- ///
- /// \brief Getting the first element in ring buffer without extracting it.
- /// \param self Pointer to the ring buffer.
- /// \return The first element or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_front(const ringbuf_t * self);
- ///
- /// \brief Getting the last element in ring buffer without extracting it.
- /// \param self Pointer to the ring buffer.
- /// \return The last element or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_back(const ringbuf_t * self);
- ///
- /// \brief Adding element to the end of ring buffer.
- /// \param self Pointer to the ring buffer.
- /// \param element Element for adding.
- /// \return Size of element or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_push(ringbuf_t * self,
- RING_BUFFER_ELEMENT_TYPE element);
- ///
- /// \brief Extracting the first element from a ring buffer.
- /// \param self Pointer to the ring buffer.
- /// \return Extracted element or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_pop(ringbuf_t * self);
- //RING_BUFFER_RC_TYPE ringbuf_push_front(ringbuf_t * self,
- // RING_BUFFER_ELEMENT_TYPE element);
- //RING_BUFFER_RC_TYPE ringbuf_pop_front(rb_t * rb);
- //RING_BUFFER_RC_TYPE ringbuf_push_back(ringbuf_t * self,
- // RING_BUFFER_ELEMENT_TYPE element);
- //RING_BUFFER_RC_TYPE ringbuf_pop_back(ringbuf_t * self);
- ///
- /// \brief Direct access to the underlying array.
- /// \param self Pointer to the ring buffer.
- /// \return Pointer to the underlying array.
- ///
- static inline const void * ringbuf_buffer_const(const ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- return self->buffer;
- }
- ///
- /// \brief Direct access to the underlying array.
- /// \param self Pointer to the ring buffer.
- /// \return Pointer to the underlying array.
- ///
- static inline void * ringbuf_buffer(ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- return self->buffer;
- }
- ///
- /// \brief Getting the sprecified by \p index element from a ring buffer.
- /// \param self Pointer to the ring buffer.
- /// \param index Position of the element to return.
- /// \return Requested element or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_at(const ringbuf_t * self,
- RING_BUFFER_SIZE_TYPE index);
- ///
- /// \brief Checking whether the container is full.
- /// \param self Pointer to the ring buffer.
- /// \return true if conrainer if full, false otherwise.
- ///
- static inline bool ringbuf_is_full(const ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- return self->size >= self->capacity;
- }
- ///
- /// \brief Checking whether the container is empty.
- /// \param self Pointer to the ring buffer.
- /// \return true if conrainer if empty, false otherwise.
- ///
- static inline bool ringbuf_is_empty(const ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- return !self->size;
- }
- ///
- /// \brief Returns the number of elements that can be held in an underlying
- /// storage.
- /// \param self Pointer to the ring buffer.
- /// \return number of elements.
- ///
- static inline RING_BUFFER_RC_TYPE ringbuf_capacity(const ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- return self->capacity;
- }
- ///
- /// \brief Returns the number of elements in a ring buffer.
- /// \param self Pointer to the ring buffer.
- /// \return number of elements.
- ///
- static inline RING_BUFFER_RC_TYPE ringbuf_size(const ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- return self->size;
- }
- ///
- /// \brief Returns free space in an underlying ring buffer storage.
- /// \param self Pointer to the ring buffer.
- /// \return number of elements.
- ///
- static inline RING_BUFFER_RC_TYPE ringbuf_free_space(const ringbuf_t * self)
- {
- RINGBUF_ASSERT(self);
- return self->capacity - self->size;
- }
- ///
- /// \brief Clears the contents of ring buffer.
- /// \param self Pointer to the ring buffer.
- ///
- void ringbuf_clear(ringbuf_t * self);
- ///
- /// \brief Erases the first \p count element from the begging (front) of a
- /// ring buffer.
- /// \param self Pointer to the ring buffer.
- /// \param count Number of elements to remove.
- /// \return Number of removed elements.
- ///
- RING_BUFFER_RC_TYPE ringbuf_erase(ringbuf_t * self,
- RING_BUFFER_SIZE_TYPE count);
- ///
- /// \brief Copyies elements from \p rhs ring buffer to the end of \p lhs ring
- /// buffer.
- /// \param lhs Pointer to the ring buffer. Destination.
- /// \param rhs Pointer to the ring buffer. Source.
- /// \return number of copied elements or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_copy(ringbuf_t * lhs, ringbuf_t * rhs);
- ///
- /// \brief Moving elements from \p rhs ring buffer to the end of \p lhs ring
- /// buffer.
- /// \note After moving procedure rhs buffer is empty (== uninitialized).
- /// \param lhs Pointer to the ring buffer. Destination.
- /// \param rhs Pointer to the ring buffer. Source.
- /// \return number of moved elements or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_move(ringbuf_t * lhs, ringbuf_t * rhs);
- ///
- /// \brief Realizes search algorithm for a ring buffer container.
- /// \param self Pointer to the ring buffer.
- /// \param context Pointer to the user context.
- /// \param predicate Pointer to the user search functor.
- /// \return index of found element or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_find(ringbuf_t * self,
- void * context,
- pfRingbuf_predicate_t predicate);
- ///
- /// \brief Realized visitor algorithm for a ring buffer container.
- /// \param self Pointer to the ring buffer.
- /// \param context Pointer to the user context.
- /// \param visitor Pointer to the visitor function. It is called on each
- /// ring buffer element.
- /// \return number of iterated elements or error code.
- ///
- RING_BUFFER_RC_TYPE ringbuf_visit(ringbuf_t * self,
- void * context,
- pfRingbuf_visitor_t visitor);
- //RING_BUFFER_RC_TYPE ringbuf_linearize(ringbuf_t * self);
- //RING_BUFFER_RC_TYPE ringbuf_is_linearized(ringbuf_t * self);
- #ifdef __cplusplus
- }
- #endif
- #endif
|