// Author: Ershov V. // Modified: Sychov. A / 12/2020 #ifndef QUEUE_H #define QUEUE_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include "app/ringbuffer/ring_buffer.h" #include "my_assert.h" typedef enum QUEUE_RC_t { QUEUE_RC_NOERROR = 0, QUEUE_RC_BAD_PARAMS = -1, QUEUE_RC_NO_MEMORY = -2, QUEUE_RC_OS_ERROR = -3, QUEUE_RC_INIT_ERROR = -4, QUEUE_RC_INTERNAL_ERROR = -5, QUEUE_RC_EMPTY = -6, QUEUE_RC_BAD_STATE = -7, QUEUE_RC_QUERY_ABORTED = -8, QUEUE_RC_TIMEOUT = -9, QUEUE_RC_CREATE_CMD_FAIL = -10, }QUEUE_RC_t; /// Forward declaration of t struct. #pragma pack(push,1) typedef struct { int16_t size; // standard record size (whole record size: header+data+payload) int16_t payload; // extended record size (payload) } queue_record_t; #pragma pack(pop) STATIC_ASSERT( sizeof(int16_t) == sizeof(RING_BUFFER_RC_TYPE), "Invalid RING_BUFFER_RC_TYPE type" ); typedef ringbuf_t queue_t; /// /// \brief Function checks if the record queue has no elements. /// \param self Pointer to the record queue. /// \return true if the queue is empty, false oserwise. /// static inline bool queue_empty( const queue_t * self ) { assert(self); RING_BUFFER_RC_TYPE rc = ringbuf_size(self); assert(0 <= rc); return (rc == 0); } /// /// \brief Placing record to the end of the queue. /// \param self Pointer to the queue. /// \param record Pointer to the record struct to place. /// \return QUEUE_RC_NOERROR if no error or error code. /// int queue_pushback(queue_t * self, queue_record_t * record); /// /// \brief Placing record to the begin of the queue. /// \param self Pointer to the queue. /// \param record Pointer to the record struct to place. /// \return QUEUE_RC_NOERROR if no error or error code. /// int queue_pushfront(queue_t * self, queue_record_t * record); /// /// \brief Getting record from the queue without extracting. /// \param self Pointer to the record queue. /// \param record Pointer to the record to store. /// \param size Size of the struct to store a record. /// \return Size of the peeked record on success, error code otherwise. /// int queue_peek(const queue_t * self, queue_record_t * record, int16_t size); /// /// \brief Extract record from the queue. /// \param self Pointer to the record queue. /// \param record Pointer to the record to store. /// \param size Size of the struct to store a record. /// \return Size of the extracted record on success, error code otherwise. /// static inline int queue_get(queue_t * self, queue_record_t * record, int16_t size) { int rc = queue_peek(self, record, size); if(0 < rc) { RING_BUFFER_RC_TYPE rc = ringbuf_erase(self, record->size); assert(record->size == rc); (void)rc; } return rc; } /// /// \brief Removes all the records from the queue. /// \param self Pointer to the record queue. /// static inline void queue_clear(queue_t * self) { ringbuf_clear(self); } /// /// \brief Extract and discard one record from the queue. /// \param self Pointer to the record queue. /// \return Size of discarded record if it exist, 0 otherwise. /// int queue_removefront(queue_t * self); #ifdef __cplusplus } #endif #endif // QUEUE_H