chan_tcpservcan_ringbuffer.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "chan_tcpservcan_ringbuffer.h"
  2. /** * Returns whether a ring buffer is empty.
  3. * @param buffer The buffer for which it should be returned whether it is empty.
  4. * @return 1 if empty; 0 otherwise.
  5. */
  6. inline chan_tcpservcan_ringbuffer_size_t chan_tcpservcan_ringbuffer_is_empty(chan_tcpservcan_ringbuffer_t *buffer)
  7. {
  8. return (buffer->head_index == buffer->tail_index);
  9. }
  10. /** * Returns whether a ring buffer is full.
  11. * @param buffer The buffer for which it should be returned whether it is full.
  12. * @return 1 if full; 0 otherwise.
  13. */
  14. inline chan_tcpservcan_ringbuffer_size_t chan_tcpservcan_ringbuffer_is_full(chan_tcpservcan_ringbuffer_t *buffer)
  15. {
  16. return ((buffer->head_index - buffer->tail_index) & CHAN_TCPSERVCAN_RINGBUFFER_MASK) == CHAN_TCPSERVCAN_RINGBUFFER_MASK;
  17. }
  18. /** * Initializes the ring buffer pointed to by <em>buffer</em>.
  19. * This function can also be used to empty/reset the buffer.
  20. * @param buffer The ring buffer to initialize.
  21. */
  22. void chan_tcpservcan_ringbuffer_init(chan_tcpservcan_ringbuffer_t *buffer)
  23. {
  24. buffer->tail_index = 0;
  25. buffer->head_index = 0;
  26. }
  27. /** * Adds a byte to a ring buffer.
  28. * @param buffer The buffer in which the data should be placed.
  29. * @param data The byte to place.
  30. */
  31. void chan_tcpservcan_ringbuffer_queue(chan_tcpservcan_ringbuffer_t *buffer, chan_tcpservcan_ringbuffer_element_t data)
  32. {
  33. /* Is buffer full? */
  34. if(chan_tcpservcan_ringbuffer_is_full(buffer)) {
  35. /* Is going to overwrite the oldest byte */
  36. /* Increase tail index */
  37. buffer->tail_index = ((buffer->tail_index + 1) & CHAN_TCPSERVCAN_RINGBUFFER_MASK);
  38. }
  39. /* Place data in buffer */
  40. buffer->buffer[buffer->head_index] = data;
  41. buffer->head_index = ((buffer->head_index + 1) & CHAN_TCPSERVCAN_RINGBUFFER_MASK);
  42. }
  43. /** * Adds an array of bytes to a ring buffer.
  44. * @param buffer The buffer in which the data should be placed.
  45. * @param data A pointer to the array of bytes to place in the queue.
  46. * @param size The size of the array.
  47. */
  48. void chan_tcpservcan_ringbuffer_queue_arr(chan_tcpservcan_ringbuffer_t *buffer, const chan_tcpservcan_ringbuffer_element_t*data, chan_tcpservcan_ringbuffer_size_t size)
  49. {
  50. /* Add bytes; one by one */
  51. chan_tcpservcan_ringbuffer_size_t i;
  52. for(i = 0; i < size; i++) {
  53. chan_tcpservcan_ringbuffer_queue(buffer, data[i]);
  54. }
  55. }
  56. /** * Returns the oldest byte in a ring buffer.
  57. * @param buffer The buffer from which the data should be returned.
  58. * @param data A pointer to the location at which the data should be placed.
  59. * @return 1 if data was returned; 0 otherwise.
  60. */
  61. chan_tcpservcan_ringbuffer_size_t chan_tcpservcan_ringbuffer_dequeue(chan_tcpservcan_ringbuffer_t *buffer, chan_tcpservcan_ringbuffer_element_t* data)
  62. {
  63. if(chan_tcpservcan_ringbuffer_is_empty(buffer)) {
  64. /* No items */
  65. return 0;
  66. }
  67. *data = buffer->buffer[buffer->tail_index];
  68. buffer->tail_index = ((buffer->tail_index + 1) & CHAN_TCPSERVCAN_RINGBUFFER_MASK);
  69. return 1;
  70. }
  71. /** * Returns the <em>len</em> oldest bytes in a ring buffer.
  72. * @param buffer The buffer from which the data should be returned.
  73. * @param data A pointer to the array at which the data should be placed.
  74. * @param len The maximum number of bytes to return.
  75. * @return The number of bytes returned.
  76. */
  77. chan_tcpservcan_ringbuffer_size_t chan_tcpservcan_ringbuffer_dequeue_arr(chan_tcpservcan_ringbuffer_t *buffer, chan_tcpservcan_ringbuffer_element_t* data, chan_tcpservcan_ringbuffer_size_t len)
  78. {
  79. if(chan_tcpservcan_ringbuffer_is_empty(buffer)) {
  80. /* No items */
  81. return 0;
  82. }
  83. chan_tcpservcan_ringbuffer_element_t* data_ptr = data;
  84. chan_tcpservcan_ringbuffer_size_t cnt = 0;
  85. while((cnt < len) && chan_tcpservcan_ringbuffer_dequeue(buffer, data_ptr)) {
  86. cnt++;
  87. data_ptr++;
  88. }
  89. return cnt;
  90. }
  91. /** * Peeks a ring buffer, i.e. returns an element without removing it.
  92. * @param buffer The buffer from which the data should be returned.
  93. * @param data A pointer to the location at which the data should be placed.
  94. * @param index The index to peek. * @return 1 if data was returned; 0 otherwise.
  95. */
  96. chan_tcpservcan_ringbuffer_size_t chan_tcpservcan_ringbuffer_peek(chan_tcpservcan_ringbuffer_t *buffer, chan_tcpservcan_ringbuffer_element_t* data, chan_tcpservcan_ringbuffer_size_t index)
  97. {
  98. if(index >= chan_tcpservcan_ringbuffer_num_items(buffer)) {
  99. /* No items at index */
  100. return 0;
  101. }
  102. /* Add index to pointer */
  103. chan_tcpservcan_ringbuffer_size_t data_index = ((buffer->tail_index + index) & CHAN_TCPSERVCAN_RINGBUFFER_MASK);
  104. *data = buffer->buffer[data_index];
  105. return 1;
  106. }
  107. /** * Returns the number of items in a ring buffer.
  108. * @param buffer The buffer for which the number of items should be returned.
  109. * @return The number of items in the ring buffer.
  110. */
  111. chan_tcpservcan_ringbuffer_size_t chan_tcpservcan_ringbuffer_num_items(chan_tcpservcan_ringbuffer_t *buffer)
  112. {
  113. return ((buffer->head_index - buffer->tail_index) & CHAN_TCPSERVCAN_RINGBUFFER_MASK);
  114. }