2019-01-26 10:11:12 +00:00
|
|
|
#ifndef UDPC_DEQUE_H
|
|
|
|
#define UDPC_DEQUE_H
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
2019-02-04 08:21:49 +00:00
|
|
|
typedef struct {
|
2019-01-26 10:11:12 +00:00
|
|
|
uint32_t head;
|
|
|
|
uint32_t tail;
|
|
|
|
uint32_t size;
|
|
|
|
uint32_t alloc_size;
|
|
|
|
char *buf;
|
|
|
|
} UDPC_Deque;
|
|
|
|
|
2019-01-26 11:44:31 +00:00
|
|
|
/*!
|
2019-01-27 09:30:35 +00:00
|
|
|
* \return non-null on success
|
2019-01-26 11:44:31 +00:00
|
|
|
*/
|
2019-01-27 09:30:35 +00:00
|
|
|
UDPC_Deque* UDPC_Deque_init(uint32_t alloc_size);
|
2019-01-26 11:44:31 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* Frees resources used by a UDPC_Deque
|
|
|
|
*/
|
2019-01-28 06:10:04 +00:00
|
|
|
void UDPC_Deque_destroy(UDPC_Deque *deque);
|
2019-01-26 11:44:31 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* Fails if new_size is smaller than current size of Deque.
|
|
|
|
* On failure, deque remains unchanged.
|
|
|
|
* \return non-zero on success
|
|
|
|
*/
|
|
|
|
int UDPC_Deque_realloc(UDPC_Deque *deque, uint32_t new_size);
|
2019-01-26 10:11:12 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* If there was not enough space in the Deque, then no data is inserted at all.
|
|
|
|
* \return non-zero on success (there was enough size to insert data)
|
|
|
|
*/
|
2019-01-27 06:09:38 +00:00
|
|
|
int UDPC_Deque_push_back(UDPC_Deque *deque, const void *data, uint32_t size);
|
2019-01-26 10:11:12 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* If there was not enough space in the Deque, then no data is inserted at all.
|
|
|
|
* \return non-zero on success (there was enough size to insert data)
|
|
|
|
*/
|
2019-01-27 06:09:38 +00:00
|
|
|
int UDPC_Deque_push_front(UDPC_Deque *deque, const void *data, uint32_t size);
|
2019-01-26 10:11:12 +00:00
|
|
|
|
2019-02-21 03:34:35 +00:00
|
|
|
/*!
|
|
|
|
* \brief Same as push_back, but realloc if not enough free space
|
|
|
|
* Note when realloc occurs, the allocated space is doubled.
|
|
|
|
* \return non-zero on data pushed into Deque success
|
|
|
|
*/
|
|
|
|
int UDPC_Deque_push_back_realloc(UDPC_Deque *deque, const void *data, uint32_t size);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Same as push_front, but realloc if not enough free space
|
|
|
|
* Note when realloc occurs, the allocated space is doubled.
|
|
|
|
* \return non-zero on data pushed into Deque success
|
|
|
|
*/
|
|
|
|
int UDPC_Deque_push_front_realloc(UDPC_Deque *deque, const void *data, uint32_t size);
|
2019-02-20 06:13:57 +00:00
|
|
|
|
2019-01-26 11:44:31 +00:00
|
|
|
/*!
|
|
|
|
* \return size in bytes of available data
|
|
|
|
*/
|
2019-01-26 10:11:12 +00:00
|
|
|
uint32_t UDPC_Deque_get_available(UDPC_Deque *deque);
|
|
|
|
|
2019-01-26 11:44:31 +00:00
|
|
|
/*!
|
|
|
|
* \return size in bytes of used data
|
|
|
|
*/
|
|
|
|
uint32_t UDPC_Deque_get_used(UDPC_Deque *deque);
|
|
|
|
|
2019-01-26 10:11:12 +00:00
|
|
|
/*!
|
|
|
|
* \brief Get data from back of deque
|
|
|
|
* Data must be free'd after use as it was allocated with malloc.
|
|
|
|
* When size is greater than deque size, partial data is allocated, size is
|
|
|
|
* updated to allocated amount. If deque is empty, no data is allocated.
|
|
|
|
* \return non-zero if full requested size was returned
|
|
|
|
*/
|
2019-01-27 06:09:38 +00:00
|
|
|
int UDPC_Deque_get_back(UDPC_Deque *deque, void **data, uint32_t *size);
|
2019-01-26 10:11:12 +00:00
|
|
|
|
2019-01-31 03:16:01 +00:00
|
|
|
/*!
|
|
|
|
* \brief Get data ptr from back of deque
|
|
|
|
* The returned ptr is part of the Deque's internal buffer and must not be
|
|
|
|
* manually free'd; it will be free'd when the Deque itself is destroyed.
|
|
|
|
* \return non-null if tail of deque has contiguous data of size unitSize
|
|
|
|
*/
|
|
|
|
void* UDPC_Deque_get_back_ptr(UDPC_Deque *deque, uint32_t unitSize);
|
|
|
|
|
2019-01-26 10:11:12 +00:00
|
|
|
/*!
|
|
|
|
* \brief Get data from front of deque
|
|
|
|
* Data must be free'd after use as it was allocated with malloc.
|
|
|
|
* When size is greater than deque size, partial data is allocated, size is
|
|
|
|
* updated to allocated amount. If deque is empty, no data is allocated.
|
|
|
|
* \return non-zero if full requested size was returned
|
|
|
|
*/
|
2019-01-27 06:09:38 +00:00
|
|
|
int UDPC_Deque_get_front(UDPC_Deque *deque, void **data, uint32_t *size);
|
2019-01-26 10:11:12 +00:00
|
|
|
|
2019-01-31 03:16:01 +00:00
|
|
|
/*!
|
|
|
|
* \brief Get data ptr from front of deque
|
|
|
|
* The returned ptr is part of the Deque's internal buffer and must not be
|
|
|
|
* manually free'd; it will be free'd when the Deque itself is destroyed.
|
|
|
|
* \return non-null if head of deque has contiguous data of size unitSize
|
|
|
|
*/
|
|
|
|
void* UDPC_Deque_get_front_ptr(UDPC_Deque *deque, uint32_t unitSize);
|
|
|
|
|
2019-01-26 10:11:12 +00:00
|
|
|
/*!
|
|
|
|
* \brief "free" data from the back of the deque
|
|
|
|
* If size is greater than data used, then all data will be "free"d.
|
|
|
|
* Note that this doesn't actually deallocate data, but changes internal values
|
|
|
|
* that keep track of data positions in the internal buffer. The data will only
|
|
|
|
* actually be removed when it is overwritten or the Deque is free'd.
|
|
|
|
*/
|
|
|
|
void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief "free" data from the front of the deque
|
|
|
|
* If size is greater than data used, then all data will be "free"d.
|
|
|
|
* Note that this doesn't actually deallocate data, but changes internal values
|
|
|
|
* that keep track of data positions in the internal buffer. The data will only
|
|
|
|
* actually be removed when it is overwritten or the Deque is free'd.
|
|
|
|
*/
|
|
|
|
void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size);
|
|
|
|
|
2019-01-26 11:44:31 +00:00
|
|
|
/*!
|
|
|
|
* \brief Get a unitSize sized chunk of data at position unitSize * index
|
|
|
|
* The data will be indexed relative to the head of the Deque.
|
|
|
|
* The out pointer will be malloc'd with size unitSize and will have a copy of
|
|
|
|
* the data at the specified unitSize * index.
|
2019-01-27 06:09:38 +00:00
|
|
|
* Note that the out data must be free'd, but on fail nothing will be malloc'd
|
2019-01-26 11:44:31 +00:00
|
|
|
* and *out will be set to NULL.
|
2019-01-27 06:09:38 +00:00
|
|
|
* \return non-zero if unitSize * index < size
|
2019-01-26 11:44:31 +00:00
|
|
|
*/
|
2019-01-27 06:09:38 +00:00
|
|
|
int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out);
|
2019-01-26 11:44:31 +00:00
|
|
|
|
2019-01-31 03:16:01 +00:00
|
|
|
/*!
|
|
|
|
* \brief Get a ptr to the indexed data at position unitSize * index
|
|
|
|
* The ptr will be indexed relative to the head of the Deque.
|
|
|
|
* The returned ptr is part of the Deque's internal buffer and will be free'd
|
|
|
|
* when the Deque is destroyed, so it should not be free'd directly.
|
|
|
|
* \return non-null if indexed data is a valid contiguous part of the buffer
|
|
|
|
*/
|
|
|
|
void* UDPC_Deque_index_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index);
|
|
|
|
|
2019-01-26 11:44:31 +00:00
|
|
|
/*!
|
|
|
|
* \brief Get a unitSize sized chunk of data at position relative to tail
|
|
|
|
* The out pointer will be malloc'd with size unitSize and will have a copy of
|
2019-01-27 06:09:38 +00:00
|
|
|
* the data at the specified unitSize * index relative to tail in reverse
|
2019-01-26 11:44:31 +00:00
|
|
|
* direction.
|
2019-01-27 06:09:38 +00:00
|
|
|
* Note that the out data must be free'd, but on fail nothing will be malloc'd
|
2019-01-26 11:44:31 +00:00
|
|
|
* and *out will be set to NULL.
|
2019-01-27 06:09:38 +00:00
|
|
|
* \return non-zero if unitSize * index < size
|
2019-01-26 11:44:31 +00:00
|
|
|
*/
|
2019-01-27 06:09:38 +00:00
|
|
|
int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out);
|
2019-01-26 11:44:31 +00:00
|
|
|
|
2019-01-31 03:16:01 +00:00
|
|
|
/*!
|
|
|
|
* \brief Get a ptr to the indexed data at position unitSize * index
|
|
|
|
* The ptr will be indexed relative to the tail of the Deque.
|
|
|
|
* The returned ptr is part of the Deque's internal buffer and will be free'd
|
|
|
|
* when the Deque is destroyed, so it should not be free'd directly.
|
|
|
|
* \return non-null if indexed data is a valid contiguous part of the buffer
|
|
|
|
*/
|
|
|
|
void* UDPC_Deque_index_rev_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index);
|
|
|
|
|
2019-01-30 07:40:13 +00:00
|
|
|
/*!
|
|
|
|
* \brief Replaces the data at index with data at the end (if exists)
|
|
|
|
* Note this will reduce the size of the Deque by unitSize amount.
|
|
|
|
* \return non-zero if data was removed
|
|
|
|
*/
|
|
|
|
int UDPC_Deque_remove(UDPC_Deque *deque, uint32_t unitSize, uint32_t index);
|
|
|
|
|
2019-01-26 11:44:31 +00:00
|
|
|
void UDPC_Deque_clear(UDPC_Deque *deque);
|
|
|
|
|
2019-01-26 10:11:12 +00:00
|
|
|
#endif
|