Finish impl of Deque, testing required
This commit is contained in:
parent
b76df86a4f
commit
dd984b85a6
3 changed files with 184 additions and 11 deletions
|
@ -3,6 +3,7 @@ project(UDPConnection)
|
|||
|
||||
set(UDPConnection_SOURCES
|
||||
src/UDPConnection.c
|
||||
src/Deque.c
|
||||
)
|
||||
|
||||
set(CMAKE_C_FLAGS "-Wall -Wno-missing-braces")
|
||||
|
|
145
src/Deque.c
145
src/Deque.c
|
@ -3,13 +3,60 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void UDPC_Deque_init(UDPC_Deque *deque, uint32_t alloc_size)
|
||||
int UDPC_Deque_init(UDPC_Deque *deque, uint32_t alloc_size)
|
||||
{
|
||||
deque->head = 0;
|
||||
deque->tail = 0;
|
||||
deque->size = 0;
|
||||
UDPC_Deque_clear(deque);
|
||||
deque->alloc_size = alloc_size;
|
||||
deque->buf = malloc(alloc_size);
|
||||
if(deque->buf)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void UDPC_Deque_destroy(UDPC_Deque *deque)
|
||||
{
|
||||
free(deque->buf);
|
||||
deque->buf = NULL;
|
||||
}
|
||||
|
||||
int UDPC_Deque_realloc(UDPC_Deque *deque, uint32_t new_size)
|
||||
{
|
||||
if(new_size < deque->size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(deque->size != 0 && deque->tail <= deque->head)
|
||||
{
|
||||
char *buf = malloc(new_size);
|
||||
memcpy(buf, &deque->buf[deque->head], deque->alloc_size - deque->head);
|
||||
if(deque->tail != 0)
|
||||
{
|
||||
memcpy(&buf[deque->alloc_size - deque->head], deque->buf, deque->tail);
|
||||
}
|
||||
free(deque->buf);
|
||||
deque->buf = buf;
|
||||
deque->alloc_size = new_size;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
void *buf = realloc(deque->buf, new_size);
|
||||
if(buf)
|
||||
{
|
||||
deque->buf = buf;
|
||||
deque->alloc_size = new_size;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int UDPC_Deque_push_back(UDPC_Deque *deque, const char *data, uint32_t size)
|
||||
|
@ -86,12 +133,18 @@ uint32_t UDPC_Deque_get_available(UDPC_Deque *deque)
|
|||
return deque->alloc_size - deque->size;
|
||||
}
|
||||
|
||||
uint32_t UDPC_Deque_get_used(UDPC_Deque *deque)
|
||||
{
|
||||
return deque->size;
|
||||
}
|
||||
|
||||
int UDPC_Deque_get_back(UDPC_Deque *deque, char **data, uint32_t *size)
|
||||
{
|
||||
int returnValue = 1;
|
||||
if(deque->size == 0)
|
||||
{
|
||||
*size = 0;
|
||||
*data = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if(*size > deque->size)
|
||||
|
@ -122,6 +175,7 @@ int UDPC_Deque_get_front(UDPC_Deque *deque, char **data, uint32_t *size)
|
|||
if(deque->size == 0)
|
||||
{
|
||||
*size = 0;
|
||||
*data = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if(*size > deque->size)
|
||||
|
@ -154,9 +208,7 @@ void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size)
|
|||
}
|
||||
else if(deque->size <= size)
|
||||
{
|
||||
deque->head = 0;
|
||||
deque->tail = 0;
|
||||
deque->size = 0;
|
||||
UDPC_Deque_clear(deque);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -180,9 +232,7 @@ void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size)
|
|||
}
|
||||
else if(deque->size <= size)
|
||||
{
|
||||
deque->head = 0;
|
||||
deque->tail = 0;
|
||||
deque->size = 0;
|
||||
UDPC_Deque_clear(deque);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -201,3 +251,78 @@ void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, char **out)
|
||||
{
|
||||
uint32_t pos = unitSize * index;
|
||||
uint32_t abspos;
|
||||
if(pos >= deque->alloc_size)
|
||||
{
|
||||
*out = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out = malloc(unitSize);
|
||||
|
||||
if(pos + deque->head >= deque->alloc_size)
|
||||
{
|
||||
abspos = pos + deque->head - deque->alloc_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
abspos = pos + deque->head;
|
||||
}
|
||||
|
||||
if(abspos + unitSize >= deque->alloc_size)
|
||||
{
|
||||
memcpy(*out, &deque->buf[abspos], deque->alloc_size - abspos);
|
||||
memcpy(*out, deque->buf, unitSize - (deque->alloc_size - abspos));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(*out, &deque->buf[abspos], unitSize);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, char **out)
|
||||
{
|
||||
uint32_t pos = unitSize * (index + 1);
|
||||
uint32_t abspos;
|
||||
if(pos >= deque->alloc_size)
|
||||
{
|
||||
*out = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out = malloc(unitSize);
|
||||
|
||||
if(pos > deque->tail)
|
||||
{
|
||||
abspos = deque->alloc_size - (pos - deque->tail);
|
||||
}
|
||||
else
|
||||
{
|
||||
abspos = deque->tail - pos;
|
||||
}
|
||||
|
||||
if(abspos + unitSize >= deque->alloc_size)
|
||||
{
|
||||
memcpy(*out, &deque->buf[abspos], deque->alloc_size - abspos);
|
||||
memcpy(*out, deque->buf, unitSize - (deque->alloc_size - abspos));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(*out, &deque->buf[abspos], unitSize);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void UDPC_Deque_clear(UDPC_Deque *deque)
|
||||
{
|
||||
deque->head = 0;
|
||||
deque->tail = 0;
|
||||
deque->size = 0;
|
||||
}
|
||||
|
|
49
src/Deque.h
49
src/Deque.h
|
@ -12,7 +12,22 @@ typedef struct
|
|||
char *buf;
|
||||
} UDPC_Deque;
|
||||
|
||||
void UDPC_Deque_init(UDPC_Deque *deque, uint32_t alloc_size);
|
||||
/*!
|
||||
* \return non-zero on success
|
||||
*/
|
||||
int UDPC_Deque_init(UDPC_Deque *deque, uint32_t alloc_size);
|
||||
|
||||
/*!
|
||||
* Frees resources used by a UDPC_Deque
|
||||
*/
|
||||
void UDPC_Deque_destroy(UDPC_Deque *deque);
|
||||
|
||||
/*!
|
||||
* 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);
|
||||
|
||||
/*!
|
||||
* If there was not enough space in the Deque, then no data is inserted at all.
|
||||
|
@ -26,8 +41,16 @@ int UDPC_Deque_push_back(UDPC_Deque *deque, const char *data, uint32_t size);
|
|||
*/
|
||||
int UDPC_Deque_push_front(UDPC_Deque *deque, const char *data, uint32_t size);
|
||||
|
||||
/*!
|
||||
* \return size in bytes of available data
|
||||
*/
|
||||
uint32_t UDPC_Deque_get_available(UDPC_Deque *deque);
|
||||
|
||||
/*!
|
||||
* \return size in bytes of used data
|
||||
*/
|
||||
uint32_t UDPC_Deque_get_used(UDPC_Deque *deque);
|
||||
|
||||
/*!
|
||||
* \brief Get data from back of deque
|
||||
* Data must be free'd after use as it was allocated with malloc.
|
||||
|
@ -64,4 +87,28 @@ void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size);
|
|||
*/
|
||||
void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size);
|
||||
|
||||
/*!
|
||||
* \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.
|
||||
* Note that the out data must be free'd, but nothing will be malloc'd on fail
|
||||
* and *out will be set to NULL.
|
||||
* \return non-zero if unitSize * index < allocated_size_of_Deque
|
||||
*/
|
||||
int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, char **out);
|
||||
|
||||
/*!
|
||||
* \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
|
||||
* the data at the specified unitSize * (index + 1) relative to tail in reverse
|
||||
* direction.
|
||||
* Note that the out data must be free'd, but nothing will be malloc'd on fail
|
||||
* and *out will be set to NULL.
|
||||
* \return non-zero if unitSize * (index + 1) < allocated_size_of_Deque
|
||||
*/
|
||||
int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, char **out);
|
||||
|
||||
void UDPC_Deque_clear(UDPC_Deque *deque);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue