ring_buffer.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. // Author: Ershov V.
  2. // Modified: Sychov. A / 12/2020
  3. #include "ringbuffer/ring_buffer.h"
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "my_assert.h"
  7. STATIC_ASSERT(sizeof(RING_BUFFER_RC_TYPE) >= sizeof(RING_BUFFER_RC_TYPE),
  8. error);
  9. //see ringbuf_pop
  10. STATIC_ASSERT(sizeof(RING_BUFFER_RC_TYPE) > RING_BUFFER_ELEMENT_SIZE, error);
  11. //ToDo ring buffer with power of 2 buffer size
  12. RING_BUFFER_RC_TYPE ringbuf_write_s(ringbuf_t * self,
  13. const RING_BUFFER_ELEMENT_TYPE * buffer,
  14. RING_BUFFER_SIZE_TYPE size);
  15. static inline RING_BUFFER_SIZE_TYPE ringbuf_wr_index_to_tail_s(const ringbuf_t * self);
  16. static inline RING_BUFFER_SIZE_TYPE ringbuf_rd_index_to_tail_s(const ringbuf_t * self);
  17. static inline void ringbuf_add_index_s(RING_BUFFER_SIZE_TYPE * index,
  18. RING_BUFFER_SIZE_TYPE capacity,
  19. RING_BUFFER_SIZE_TYPE add);
  20. static inline void ringbuf_add_write_index_s(ringbuf_t * self,
  21. RING_BUFFER_SIZE_TYPE add);
  22. static inline void ringbuf_add_read_index_s(ringbuf_t * self,
  23. RING_BUFFER_SIZE_TYPE add);
  24. static inline void ringbuf_reset_s(ringbuf_t * self);
  25. RING_BUFFER_RC_TYPE ringbuf_init(ringbuf_t * self,
  26. void * buffer,
  27. RING_BUFFER_SIZE_TYPE capacity)
  28. {
  29. RINGBUF_ASSERT(self);
  30. if(NULL == buffer || 0 >= capacity)
  31. {
  32. return RINGBUF_RC_BAD_PARAM;
  33. }
  34. memset(self, 0x00, sizeof(*self));
  35. self->buffer = buffer;
  36. self->capacity = capacity;
  37. return RINGBUF_RC_NO_ERROR;
  38. }
  39. RING_BUFFER_RC_TYPE ringbuf_peek_offset(const ringbuf_t * self,
  40. void * buffer,
  41. RING_BUFFER_SIZE_TYPE size,
  42. RING_BUFFER_SIZE_TYPE offset )
  43. {
  44. RINGBUF_ASSERT(self && buffer);
  45. if(NULL == buffer || 0 >= size)
  46. {
  47. return RINGBUF_RC_BAD_PARAM;
  48. }
  49. char * buf = buffer;
  50. RING_BUFFER_RC_TYPE rc = self->size;
  51. if( offset >= rc )
  52. {
  53. return RINGBUF_RC_NO_DATA;
  54. }
  55. if(rc > size + offset)
  56. {
  57. rc = size;
  58. }
  59. else
  60. {
  61. size = rc - offset;
  62. rc -= offset;
  63. }
  64. RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
  65. ringbuf_add_index_s(&readIndex, self->capacity, offset);
  66. while(size)
  67. {
  68. RING_BUFFER_SIZE_TYPE bytes = self->capacity - readIndex;
  69. if(bytes > size)
  70. {
  71. bytes = size;
  72. }
  73. memcpy(buf, &self->buffer[readIndex], bytes);
  74. buf += bytes;
  75. size -= bytes;
  76. ringbuf_add_index_s(&readIndex, self->capacity, bytes);
  77. }
  78. return rc;
  79. }
  80. RING_BUFFER_RC_TYPE ringbuf_read(ringbuf_t * self,
  81. void * buffer,
  82. RING_BUFFER_SIZE_TYPE size)
  83. {
  84. RINGBUF_ASSERT(self);
  85. if(NULL == buffer || 0 >= size)
  86. {
  87. return RINGBUF_RC_BAD_PARAM;
  88. }
  89. char * buf = buffer;
  90. RING_BUFFER_RC_TYPE rc = self->size;
  91. if(rc > size)
  92. {
  93. rc = size;
  94. }
  95. else
  96. {
  97. size = rc;
  98. }
  99. while(size)
  100. {
  101. RING_BUFFER_SIZE_TYPE bytes = ringbuf_rd_index_to_tail_s(self);
  102. if(bytes > size)
  103. {
  104. bytes = size;
  105. }
  106. memcpy(buf, &self->buffer[self->readIndex], bytes);
  107. buf += bytes;
  108. size -= bytes;
  109. ringbuf_add_read_index_s(self, bytes);
  110. }
  111. self->size -= rc;
  112. #if 0 // refactoring
  113. RING_BUFFER_SIZE_TYPE tail = ringbuf_bytes_to_tail_s(self);
  114. if(tail < size)
  115. {
  116. memcpy(buffer, &self->buffer[self->readIndex], tail);
  117. buffer += tail;
  118. size -= tail;
  119. self->readIndex = 0;
  120. }
  121. if(size)
  122. {
  123. memcpy(buffer, &self->buffer[self->readIndex], size);
  124. }
  125. ringbuf_add_read_index_s(self, size);
  126. self->size -= rc;
  127. #endif
  128. return rc;
  129. }
  130. RING_BUFFER_RC_TYPE ringbuf_write(ringbuf_t * self,
  131. const void * buffer,
  132. RING_BUFFER_SIZE_TYPE size)
  133. {
  134. RINGBUF_ASSERT(self);
  135. if(NULL == buffer || 0 >= size)
  136. {
  137. return RINGBUF_RC_BAD_PARAM;
  138. }
  139. RING_BUFFER_RC_TYPE rc = ringbuf_free_space(self);
  140. #if 0 // refactoring
  141. if(rc > size)
  142. {
  143. rc = size;
  144. }
  145. else
  146. {
  147. size = rc;
  148. }
  149. #endif
  150. if(size > rc)
  151. {
  152. size = rc;
  153. }
  154. return ringbuf_write_s(self, buffer, size);
  155. #if 0 // refactoring
  156. while(size)
  157. {
  158. RING_BUFFER_SIZE_TYPE bytes = ringbuf_wr_index_to_tail_s(self);
  159. if(bytes > size)
  160. {
  161. bytes = size;
  162. }
  163. memcpy(&self->buffer[self->writeIndex], buffer, bytes);
  164. buffer += bytes;
  165. size -= bytes;
  166. ringbuf_add_write_index_s(self, bytes);
  167. }
  168. self->size += rc;
  169. #endif
  170. #if 0 // refactoring
  171. RING_BUFFER_SIZE_TYPE tail = ringbuf_space_to_tail_s(self);
  172. if(tail < size)
  173. {
  174. memcpy(&self->buffer[self->writeIndex], buffer, tail);
  175. buffer += tail;
  176. size -= tail;
  177. self->writeIndex = 0;
  178. }
  179. if(size)
  180. {
  181. memcpy(&self->buffer[self->writeIndex], buffer, size);
  182. }
  183. ringbuf_add_write_index_s(self, size);
  184. self->size += rc;
  185. #endif
  186. //return rc;
  187. }
  188. RING_BUFFER_RC_TYPE ringbuf_write_front(ringbuf_t * self,
  189. const void * buffer,
  190. RING_BUFFER_SIZE_TYPE size)
  191. {
  192. RINGBUF_ASSERT(self);
  193. if(NULL == buffer || 0 >= size)
  194. {
  195. return RINGBUF_RC_BAD_PARAM;
  196. }
  197. const char * buf = buffer;
  198. RING_BUFFER_RC_TYPE rc = ringbuf_free_space(self);
  199. if(size > rc)
  200. {
  201. size = rc;
  202. }
  203. // Caching return value.
  204. rc = size;
  205. // Using read index instead of write index because it is a front writing.
  206. // Shifting read index into initial position.
  207. self->readIndex -= size;
  208. if(self->readIndex < 0)
  209. {
  210. self->readIndex += self->capacity;
  211. }
  212. RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
  213. while(size)
  214. {
  215. RING_BUFFER_SIZE_TYPE bytes = ringbuf_rd_index_to_tail_s(self);
  216. if(bytes > size)
  217. {
  218. bytes = size;
  219. }
  220. memcpy(&self->buffer[readIndex], buf, size);
  221. buf += bytes;
  222. size -= bytes;
  223. ringbuf_add_index_s(&readIndex, self->capacity, bytes);
  224. }
  225. self->size += rc;
  226. return rc;
  227. }
  228. RING_BUFFER_RC_TYPE ringbuf_front(const ringbuf_t * self)
  229. {
  230. RINGBUF_ASSERT(self);
  231. if(!self->size)
  232. {
  233. return RINGBUF_RC_NO_DATA;
  234. }
  235. return self->buffer[self->readIndex];
  236. }
  237. RING_BUFFER_RC_TYPE ringbuf_back(const ringbuf_t * self)
  238. {
  239. RINGBUF_ASSERT(self);
  240. if(!self->size)
  241. {
  242. return RINGBUF_RC_NO_DATA;
  243. }
  244. RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
  245. ringbuf_add_index_s(&readIndex, self->capacity, self->size);
  246. return self->buffer[readIndex];
  247. }
  248. RING_BUFFER_RC_TYPE ringbuf_push(ringbuf_t * self,
  249. RING_BUFFER_ELEMENT_TYPE element)
  250. {
  251. RINGBUF_ASSERT(self);
  252. if(!ringbuf_free_space(self))
  253. {
  254. return RINGBUF_RC_OVERFLOW;
  255. }
  256. self->buffer[self->writeIndex] = element;
  257. ringbuf_add_write_index_s(self, 1);
  258. ++self->size;
  259. return 1;
  260. }
  261. RING_BUFFER_RC_TYPE ringbuf_pop(ringbuf_t * self)
  262. {
  263. RINGBUF_ASSERT(self);
  264. if(!self->size)
  265. {
  266. return RINGBUF_RC_NO_DATA;
  267. }
  268. RING_BUFFER_RC_TYPE rc = self->buffer[self->readIndex];
  269. ringbuf_add_read_index_s(self, 1);
  270. --self->size;
  271. return rc;
  272. }
  273. //RING_BUFFER_RC_TYPE ringbuf_push_front(ringbuf_t * self,
  274. // RING_BUFFER_ELEMENT_TYPE element);
  275. //RING_BUFFER_RC_TYPE ringbuf_pop_front(ringbuf_t * self);
  276. //RING_BUFFER_RC_TYPE ringbuf_push_back(ringbuf_t * self,
  277. // RING_BUFFER_ELEMENT_TYPE element);
  278. //RING_BUFFER_RC_TYPE ringbuf_pop_back(ringbuf_t * self);
  279. RING_BUFFER_RC_TYPE ringbuf_at(const ringbuf_t * self, RING_BUFFER_SIZE_TYPE index)
  280. {
  281. RINGBUF_ASSERT(self);
  282. if(index >= self->size)
  283. {
  284. return RINGBUF_RC_BAD_PARAM;
  285. }
  286. RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
  287. ringbuf_add_index_s(&readIndex, self->capacity, index);
  288. return self->buffer[readIndex];
  289. }
  290. void ringbuf_clear(ringbuf_t * self)
  291. {
  292. RINGBUF_ASSERT(self);
  293. self->size = 0;
  294. self->writeIndex = 0;
  295. self->readIndex = 0;
  296. }
  297. RING_BUFFER_RC_TYPE ringbuf_erase(ringbuf_t * self, RING_BUFFER_SIZE_TYPE count)
  298. {
  299. RINGBUF_ASSERT(self);
  300. RING_BUFFER_RC_TYPE rc = self->size;
  301. if(rc > count)
  302. {
  303. rc = count;
  304. }
  305. else
  306. {
  307. count = rc;
  308. }
  309. ringbuf_add_read_index_s(self, rc);
  310. self->size -= rc;
  311. return rc;
  312. }
  313. RING_BUFFER_RC_TYPE ringbuf_copy(ringbuf_t * lhs, ringbuf_t * rhs)
  314. {
  315. if(NULL == lhs || NULL == rhs)
  316. {
  317. return RINGBUF_RC_BAD_PARAM;
  318. }
  319. if(ringbuf_free_space(lhs) < rhs->size)
  320. {
  321. return RINGBUF_RC_OVERFLOW;
  322. }
  323. RING_BUFFER_SIZE_TYPE size = rhs->size;
  324. RING_BUFFER_SIZE_TYPE readIndex = rhs->readIndex;
  325. while(size)
  326. {
  327. RING_BUFFER_SIZE_TYPE bytes = rhs->capacity - readIndex;
  328. if(bytes > size)
  329. {
  330. bytes = size;
  331. }
  332. size -= ringbuf_write_s(lhs, &rhs->buffer[readIndex], bytes);
  333. ringbuf_add_index_s(&readIndex, rhs->capacity, bytes);
  334. }
  335. return rhs->size;
  336. }
  337. RING_BUFFER_RC_TYPE ringbuf_move(ringbuf_t * lhs, ringbuf_t * rhs)
  338. {
  339. if(NULL == lhs || NULL == rhs)
  340. {
  341. return RINGBUF_RC_BAD_PARAM;
  342. }
  343. memcpy(lhs, rhs, sizeof(*lhs));
  344. ringbuf_reset_s(rhs);
  345. return RINGBUF_RC_NO_ERROR;
  346. }
  347. RING_BUFFER_RC_TYPE ringbuf_find(ringbuf_t * self,
  348. void * context,
  349. pfRingbuf_predicate_t predicate)
  350. {
  351. RINGBUF_ASSERT(self);
  352. if(NULL == predicate)
  353. {
  354. return RINGBUF_RC_BAD_PARAM;
  355. }
  356. RING_BUFFER_SIZE_TYPE index = 0;
  357. RING_BUFFER_SIZE_TYPE size = self->size;
  358. RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
  359. while(size--)
  360. {
  361. if(predicate(context, self->buffer[readIndex]))
  362. {
  363. goto FEND;
  364. }
  365. ringbuf_add_index_s(&readIndex, self->capacity, 1);
  366. ++index;
  367. }
  368. index = RINGBUF_RC_NO_DATA;
  369. FEND:
  370. return index;
  371. }
  372. RING_BUFFER_RC_TYPE ringbuf_visit(ringbuf_t * self,
  373. void * context,
  374. pfRingbuf_visitor_t visitor)
  375. {
  376. RINGBUF_ASSERT(self);
  377. if(NULL == visitor)
  378. {
  379. return RINGBUF_RC_BAD_PARAM;
  380. }
  381. RING_BUFFER_SIZE_TYPE size = self->size;
  382. RING_BUFFER_SIZE_TYPE readIndex = self->readIndex;
  383. while(size--)
  384. {
  385. visitor(context, self->buffer[readIndex]);
  386. ringbuf_add_index_s(&readIndex, self->capacity, 1);
  387. }
  388. return self->size;
  389. }
  390. RING_BUFFER_RC_TYPE ringbuf_write_s(ringbuf_t * self,
  391. const RING_BUFFER_ELEMENT_TYPE * buffer,
  392. RING_BUFFER_SIZE_TYPE size)
  393. {
  394. RINGBUF_ASSERT(self && buffer && size >= 0);
  395. RING_BUFFER_RC_TYPE rc = size;
  396. while(size)
  397. {
  398. RING_BUFFER_SIZE_TYPE bytes = ringbuf_wr_index_to_tail_s(self);
  399. if(bytes > size)
  400. {
  401. bytes = size;
  402. }
  403. memcpy(&self->buffer[self->writeIndex], buffer, bytes);
  404. buffer += bytes;
  405. size -= bytes;
  406. ringbuf_add_write_index_s(self, bytes);
  407. }
  408. self->size += rc;
  409. return rc;
  410. }
  411. static inline RING_BUFFER_SIZE_TYPE ringbuf_wr_index_to_tail_s(const ringbuf_t * self)
  412. {
  413. RINGBUF_ASSERT(self);
  414. return self->capacity - self->writeIndex;
  415. }
  416. static inline RING_BUFFER_SIZE_TYPE ringbuf_rd_index_to_tail_s(const ringbuf_t * self)
  417. {
  418. RINGBUF_ASSERT(self);
  419. return self->capacity - self->readIndex;
  420. }
  421. static inline void ringbuf_add_index_s(RING_BUFFER_SIZE_TYPE * index,
  422. RING_BUFFER_SIZE_TYPE capacity,
  423. RING_BUFFER_SIZE_TYPE add)
  424. {
  425. RINGBUF_ASSERT(index && capacity > 0 && add >= 0);
  426. *index += add;
  427. if(*index >= capacity)
  428. {
  429. *index -= capacity;
  430. }
  431. }
  432. static inline void ringbuf_add_write_index_s(ringbuf_t * self,
  433. RING_BUFFER_SIZE_TYPE add)
  434. {
  435. RINGBUF_ASSERT(self);
  436. ringbuf_add_index_s(&self->writeIndex, self->capacity, add);
  437. }
  438. static inline void ringbuf_add_read_index_s(ringbuf_t * self,
  439. RING_BUFFER_SIZE_TYPE add)
  440. {
  441. RINGBUF_ASSERT(self);
  442. ringbuf_add_index_s(&self->readIndex, self->capacity, add);
  443. }
  444. static inline void ringbuf_reset_s(ringbuf_t * self)
  445. {
  446. RINGBUF_ASSERT(self);
  447. memset(self, 0x00, sizeof(*self));
  448. }