chan_socketcan_ringbuffer.c 5.0 KB

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