ring_buffer.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. // Author: Ershov V.
  2. // Modified: Sychov. A / 12/2020
  3. #ifndef RING_BUFFER_H
  4. #define RING_BUFFER_H
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. #define RING_BUFFER_HC
  9. #include "my_assert.h"
  10. #include <stdbool.h>
  11. #include <stdint.h>
  12. #ifndef RINGBUF_ASSERT
  13. #define RINGBUF_ASSERT(CONDITION) my_assert(CONDITION)
  14. #endif
  15. #ifndef RING_BUFFER_RC_TYPE
  16. #define RING_BUFFER_RC_TYPE int16_t
  17. #endif
  18. #ifndef RING_BUFFER_SIZE_TYPE
  19. #define RING_BUFFER_SIZE_TYPE int16_t
  20. #endif
  21. #ifndef RING_BUFFER_ELEMENT_TYPE
  22. #define RING_BUFFER_ELEMENT_TYPE unsigned char
  23. #endif
  24. #ifndef RING_BUFFER_ELEMENT_SIZE
  25. #define RING_BUFFER_ELEMENT_SIZE sizeof(RING_BUFFER_ELEMENT_TYPE)
  26. #endif
  27. typedef RING_BUFFER_RC_TYPE (*pfRingbuf_predicate_t)(
  28. void * context,
  29. RING_BUFFER_ELEMENT_TYPE element);
  30. typedef void (*pfRingbuf_visitor_t)(void * context,
  31. RING_BUFFER_ELEMENT_TYPE element);
  32. typedef enum ringbuf_rc_t
  33. {
  34. RINGBUF_RC_NO_ERROR = 0,
  35. RINGBUF_RC_BAD_PARAM = -1,
  36. RINGBUF_RC_NO_DATA = -2,
  37. RINGBUF_RC_OVERFLOW = -3
  38. }ringbuf_rc_t;
  39. typedef struct ringbuf_t
  40. {
  41. RING_BUFFER_ELEMENT_TYPE * buffer;
  42. RING_BUFFER_SIZE_TYPE capacity;
  43. RING_BUFFER_SIZE_TYPE size;
  44. RING_BUFFER_SIZE_TYPE writeIndex;
  45. RING_BUFFER_SIZE_TYPE readIndex;
  46. }ringbuf_t;
  47. ///
  48. /// \brief Initializing ring buffer.
  49. /// \param self Pointer to the ring buffer.
  50. /// \param buffer Pointer to the memory block for the ring buffer.
  51. /// \param capacity Size of the memory block.
  52. /// \return RINGBUF_RC_NO_ERROR if success, error code otherwise.
  53. ///
  54. RING_BUFFER_RC_TYPE ringbuf_init(ringbuf_t * self,
  55. void * buffer,
  56. RING_BUFFER_SIZE_TYPE capacity);
  57. ///
  58. /// \brief Getting data with size \p from ring buffer to buffer \p buffer
  59. /// without extracting them.
  60. /// \param self Pointer to the ring buffer.
  61. /// \param buffer Pointer to the buffer for storing data.
  62. /// \param size Capacity of the buffer for storing data.
  63. /// \param offset Reading offset from the begining of the ringbuf (amount of bytes to skip).
  64. /// \return size of received data or error code.
  65. ///
  66. RING_BUFFER_RC_TYPE ringbuf_peek_offset(const ringbuf_t * self,
  67. void * buffer,
  68. RING_BUFFER_SIZE_TYPE size,
  69. RING_BUFFER_SIZE_TYPE offset);
  70. ///
  71. /// \brief Getting data with size \p from ring buffer to buffer \p buffer
  72. /// without extracting them.
  73. /// \param self Pointer to the ring buffer.
  74. /// \param buffer Pointer to the buffer for storing data.
  75. /// \param size Capacity of the buffer for storing data.
  76. /// \return size of received data or error code.
  77. ///
  78. static inline RING_BUFFER_RC_TYPE ringbuf_peek(const ringbuf_t * self,
  79. void * buffer,
  80. RING_BUFFER_SIZE_TYPE size)
  81. {
  82. return ringbuf_peek_offset( self, buffer, size, 0 );
  83. }
  84. ///
  85. /// \brief Extracting data with size \p from ring buffer to buffer \p buffer.
  86. /// \param self Pointer to the ring buffer.
  87. /// \param buffer Pointer to the buffer for storing data.
  88. /// \param size Capacity of the buffer for storing data.
  89. /// \return size of received data or error code.
  90. ///
  91. RING_BUFFER_RC_TYPE ringbuf_read(ringbuf_t * self,
  92. void * buffer,
  93. RING_BUFFER_SIZE_TYPE size);
  94. ///
  95. /// \brief Writing data in \p buffer with size \p size into the end of a ring
  96. /// buffer.
  97. /// \param self Pointer to the ring buffer.
  98. /// \param buffer Pointer to the data for writing.
  99. /// \param size Size of data for writing.
  100. /// \return Size of written data or error code.
  101. ///
  102. RING_BUFFER_RC_TYPE ringbuf_write(ringbuf_t * self,
  103. const void * buffer,
  104. RING_BUFFER_SIZE_TYPE size);
  105. ///
  106. /// \brief Writing data in \p buffer with size \p size into the front of a ring
  107. /// buffer.
  108. /// \param self Pointer to the ring buffer.
  109. /// \param buffer Pointer to the data for writing.
  110. /// \param size Size of data for writing.
  111. /// \return Size of written data or error code.
  112. ///
  113. RING_BUFFER_RC_TYPE ringbuf_write_front(ringbuf_t * self,
  114. const void * buffer,
  115. RING_BUFFER_SIZE_TYPE size);
  116. ///
  117. /// \brief Getting the first element in ring buffer without extracting it.
  118. /// \param self Pointer to the ring buffer.
  119. /// \return The first element or error code.
  120. ///
  121. RING_BUFFER_RC_TYPE ringbuf_front(const ringbuf_t * self);
  122. ///
  123. /// \brief Getting the last element in ring buffer without extracting it.
  124. /// \param self Pointer to the ring buffer.
  125. /// \return The last element or error code.
  126. ///
  127. RING_BUFFER_RC_TYPE ringbuf_back(const ringbuf_t * self);
  128. ///
  129. /// \brief Adding element to the end of ring buffer.
  130. /// \param self Pointer to the ring buffer.
  131. /// \param element Element for adding.
  132. /// \return Size of element or error code.
  133. ///
  134. RING_BUFFER_RC_TYPE ringbuf_push(ringbuf_t * self,
  135. RING_BUFFER_ELEMENT_TYPE element);
  136. ///
  137. /// \brief Extracting the first element from a ring buffer.
  138. /// \param self Pointer to the ring buffer.
  139. /// \return Extracted element or error code.
  140. ///
  141. RING_BUFFER_RC_TYPE ringbuf_pop(ringbuf_t * self);
  142. //RING_BUFFER_RC_TYPE ringbuf_push_front(ringbuf_t * self,
  143. // RING_BUFFER_ELEMENT_TYPE element);
  144. //RING_BUFFER_RC_TYPE ringbuf_pop_front(rb_t * rb);
  145. //RING_BUFFER_RC_TYPE ringbuf_push_back(ringbuf_t * self,
  146. // RING_BUFFER_ELEMENT_TYPE element);
  147. //RING_BUFFER_RC_TYPE ringbuf_pop_back(ringbuf_t * self);
  148. ///
  149. /// \brief Direct access to the underlying array.
  150. /// \param self Pointer to the ring buffer.
  151. /// \return Pointer to the underlying array.
  152. ///
  153. static inline const void * ringbuf_buffer_const(const ringbuf_t * self)
  154. {
  155. RINGBUF_ASSERT(self);
  156. return self->buffer;
  157. }
  158. ///
  159. /// \brief Direct access to the underlying array.
  160. /// \param self Pointer to the ring buffer.
  161. /// \return Pointer to the underlying array.
  162. ///
  163. static inline void * ringbuf_buffer(ringbuf_t * self)
  164. {
  165. RINGBUF_ASSERT(self);
  166. return self->buffer;
  167. }
  168. ///
  169. /// \brief Getting the sprecified by \p index element from a ring buffer.
  170. /// \param self Pointer to the ring buffer.
  171. /// \param index Position of the element to return.
  172. /// \return Requested element or error code.
  173. ///
  174. RING_BUFFER_RC_TYPE ringbuf_at(const ringbuf_t * self,
  175. RING_BUFFER_SIZE_TYPE index);
  176. ///
  177. /// \brief Checking whether the container is full.
  178. /// \param self Pointer to the ring buffer.
  179. /// \return true if conrainer if full, false otherwise.
  180. ///
  181. static inline bool ringbuf_is_full(const ringbuf_t * self)
  182. {
  183. RINGBUF_ASSERT(self);
  184. return self->size >= self->capacity;
  185. }
  186. ///
  187. /// \brief Checking whether the container is empty.
  188. /// \param self Pointer to the ring buffer.
  189. /// \return true if conrainer if empty, false otherwise.
  190. ///
  191. static inline bool ringbuf_is_empty(const ringbuf_t * self)
  192. {
  193. RINGBUF_ASSERT(self);
  194. return !self->size;
  195. }
  196. ///
  197. /// \brief Returns the number of elements that can be held in an underlying
  198. /// storage.
  199. /// \param self Pointer to the ring buffer.
  200. /// \return number of elements.
  201. ///
  202. static inline RING_BUFFER_RC_TYPE ringbuf_capacity(const ringbuf_t * self)
  203. {
  204. RINGBUF_ASSERT(self);
  205. return self->capacity;
  206. }
  207. ///
  208. /// \brief Returns the number of elements in a ring buffer.
  209. /// \param self Pointer to the ring buffer.
  210. /// \return number of elements.
  211. ///
  212. static inline RING_BUFFER_RC_TYPE ringbuf_size(const ringbuf_t * self)
  213. {
  214. RINGBUF_ASSERT(self);
  215. return self->size;
  216. }
  217. ///
  218. /// \brief Returns free space in an underlying ring buffer storage.
  219. /// \param self Pointer to the ring buffer.
  220. /// \return number of elements.
  221. ///
  222. static inline RING_BUFFER_RC_TYPE ringbuf_free_space(const ringbuf_t * self)
  223. {
  224. RINGBUF_ASSERT(self);
  225. return self->capacity - self->size;
  226. }
  227. ///
  228. /// \brief Clears the contents of ring buffer.
  229. /// \param self Pointer to the ring buffer.
  230. ///
  231. void ringbuf_clear(ringbuf_t * self);
  232. ///
  233. /// \brief Erases the first \p count element from the begging (front) of a
  234. /// ring buffer.
  235. /// \param self Pointer to the ring buffer.
  236. /// \param count Number of elements to remove.
  237. /// \return Number of removed elements.
  238. ///
  239. RING_BUFFER_RC_TYPE ringbuf_erase(ringbuf_t * self,
  240. RING_BUFFER_SIZE_TYPE count);
  241. ///
  242. /// \brief Copyies elements from \p rhs ring buffer to the end of \p lhs ring
  243. /// buffer.
  244. /// \param lhs Pointer to the ring buffer. Destination.
  245. /// \param rhs Pointer to the ring buffer. Source.
  246. /// \return number of copied elements or error code.
  247. ///
  248. RING_BUFFER_RC_TYPE ringbuf_copy(ringbuf_t * lhs, ringbuf_t * rhs);
  249. ///
  250. /// \brief Moving elements from \p rhs ring buffer to the end of \p lhs ring
  251. /// buffer.
  252. /// \note After moving procedure rhs buffer is empty (== uninitialized).
  253. /// \param lhs Pointer to the ring buffer. Destination.
  254. /// \param rhs Pointer to the ring buffer. Source.
  255. /// \return number of moved elements or error code.
  256. ///
  257. RING_BUFFER_RC_TYPE ringbuf_move(ringbuf_t * lhs, ringbuf_t * rhs);
  258. ///
  259. /// \brief Realizes search algorithm for a ring buffer container.
  260. /// \param self Pointer to the ring buffer.
  261. /// \param context Pointer to the user context.
  262. /// \param predicate Pointer to the user search functor.
  263. /// \return index of found element or error code.
  264. ///
  265. RING_BUFFER_RC_TYPE ringbuf_find(ringbuf_t * self,
  266. void * context,
  267. pfRingbuf_predicate_t predicate);
  268. ///
  269. /// \brief Realized visitor algorithm for a ring buffer container.
  270. /// \param self Pointer to the ring buffer.
  271. /// \param context Pointer to the user context.
  272. /// \param visitor Pointer to the visitor function. It is called on each
  273. /// ring buffer element.
  274. /// \return number of iterated elements or error code.
  275. ///
  276. RING_BUFFER_RC_TYPE ringbuf_visit(ringbuf_t * self,
  277. void * context,
  278. pfRingbuf_visitor_t visitor);
  279. //RING_BUFFER_RC_TYPE ringbuf_linearize(ringbuf_t * self);
  280. //RING_BUFFER_RC_TYPE ringbuf_is_linearized(ringbuf_t * self);
  281. #ifdef __cplusplus
  282. }
  283. #endif
  284. #endif