queue.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Author: Ershov V.
  2. // Modified: Sychov. A / 12/2020
  3. #ifndef QUEUE_H
  4. #define QUEUE_H
  5. #ifdef __cplusplus
  6. extern "C" {
  7. #endif
  8. #include <stdbool.h>
  9. #include <string.h>
  10. #include <stdint.h>
  11. #include "app/ringbuffer/ring_buffer.h"
  12. #include "my_assert.h"
  13. typedef enum QUEUE_RC_t
  14. {
  15. QUEUE_RC_NOERROR = 0,
  16. QUEUE_RC_BAD_PARAMS = -1,
  17. QUEUE_RC_NO_MEMORY = -2,
  18. QUEUE_RC_OS_ERROR = -3,
  19. QUEUE_RC_INIT_ERROR = -4,
  20. QUEUE_RC_INTERNAL_ERROR = -5,
  21. QUEUE_RC_EMPTY = -6,
  22. QUEUE_RC_BAD_STATE = -7,
  23. QUEUE_RC_QUERY_ABORTED = -8,
  24. QUEUE_RC_TIMEOUT = -9,
  25. QUEUE_RC_CREATE_CMD_FAIL = -10,
  26. }QUEUE_RC_t;
  27. /// Forward declaration of t struct.
  28. #pragma pack(push,1)
  29. typedef struct
  30. {
  31. int16_t size; // standard record size (whole record size: header+data+payload)
  32. int16_t payload; // extended record size (payload)
  33. }
  34. queue_record_t;
  35. #pragma pack(pop)
  36. STATIC_ASSERT( sizeof(int16_t) == sizeof(RING_BUFFER_RC_TYPE), "Invalid RING_BUFFER_RC_TYPE type" );
  37. typedef ringbuf_t queue_t;
  38. ///
  39. /// \brief Function checks if the record queue has no elements.
  40. /// \param self Pointer to the record queue.
  41. /// \return true if the queue is empty, false oserwise.
  42. ///
  43. static inline bool queue_empty( const queue_t * self )
  44. {
  45. assert(self);
  46. RING_BUFFER_RC_TYPE rc = ringbuf_size(self);
  47. assert(0 <= rc);
  48. return (rc == 0);
  49. }
  50. ///
  51. /// \brief Placing record to the end of the queue.
  52. /// \param self Pointer to the queue.
  53. /// \param record Pointer to the record struct to place.
  54. /// \return QUEUE_RC_NOERROR if no error or error code.
  55. ///
  56. int queue_pushback(queue_t * self, queue_record_t * record);
  57. ///
  58. /// \brief Placing record to the begin of the queue.
  59. /// \param self Pointer to the queue.
  60. /// \param record Pointer to the record struct to place.
  61. /// \return QUEUE_RC_NOERROR if no error or error code.
  62. ///
  63. int queue_pushfront(queue_t * self, queue_record_t * record);
  64. ///
  65. /// \brief Getting record from the queue without extracting.
  66. /// \param self Pointer to the record queue.
  67. /// \param record Pointer to the record to store.
  68. /// \param size Size of the struct to store a record.
  69. /// \return Size of the peeked record on success, error code otherwise.
  70. ///
  71. int queue_peek(const queue_t * self, queue_record_t * record, int16_t size);
  72. ///
  73. /// \brief Extract record from the queue.
  74. /// \param self Pointer to the record queue.
  75. /// \param record Pointer to the record to store.
  76. /// \param size Size of the struct to store a record.
  77. /// \return Size of the extracted record on success, error code otherwise.
  78. ///
  79. static inline int queue_get(queue_t * self, queue_record_t * record, int16_t size)
  80. {
  81. int rc = queue_peek(self, record, size);
  82. if(0 < rc)
  83. {
  84. RING_BUFFER_RC_TYPE rc = ringbuf_erase(self, record->size);
  85. assert(record->size == rc);
  86. (void)rc;
  87. }
  88. return rc;
  89. }
  90. ///
  91. /// \brief Removes all the records from the queue.
  92. /// \param self Pointer to the record queue.
  93. ///
  94. static inline void queue_clear(queue_t * self)
  95. {
  96. ringbuf_clear(self);
  97. }
  98. ///
  99. /// \brief Extract and discard one record from the queue.
  100. /// \param self Pointer to the record queue.
  101. /// \return Size of discarded record if it exist, 0 otherwise.
  102. ///
  103. int queue_removefront(queue_t * self);
  104. #ifdef __cplusplus
  105. }
  106. #endif
  107. #endif // QUEUE_H