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
|
set(UDPConnection_SOURCES
|
||||||
src/UDPConnection.c
|
src/UDPConnection.c
|
||||||
|
src/Deque.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "-Wall -Wno-missing-braces")
|
set(CMAKE_C_FLAGS "-Wall -Wno-missing-braces")
|
||||||
|
|
145
src/Deque.c
145
src/Deque.c
|
@ -3,13 +3,60 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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;
|
UDPC_Deque_clear(deque);
|
||||||
deque->tail = 0;
|
|
||||||
deque->size = 0;
|
|
||||||
deque->alloc_size = alloc_size;
|
deque->alloc_size = alloc_size;
|
||||||
deque->buf = malloc(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)
|
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;
|
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 UDPC_Deque_get_back(UDPC_Deque *deque, char **data, uint32_t *size)
|
||||||
{
|
{
|
||||||
int returnValue = 1;
|
int returnValue = 1;
|
||||||
if(deque->size == 0)
|
if(deque->size == 0)
|
||||||
{
|
{
|
||||||
*size = 0;
|
*size = 0;
|
||||||
|
*data = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if(*size > deque->size)
|
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)
|
if(deque->size == 0)
|
||||||
{
|
{
|
||||||
*size = 0;
|
*size = 0;
|
||||||
|
*data = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if(*size > deque->size)
|
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)
|
else if(deque->size <= size)
|
||||||
{
|
{
|
||||||
deque->head = 0;
|
UDPC_Deque_clear(deque);
|
||||||
deque->tail = 0;
|
|
||||||
deque->size = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,9 +232,7 @@ void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size)
|
||||||
}
|
}
|
||||||
else if(deque->size <= size)
|
else if(deque->size <= size)
|
||||||
{
|
{
|
||||||
deque->head = 0;
|
UDPC_Deque_clear(deque);
|
||||||
deque->tail = 0;
|
|
||||||
deque->size = 0;
|
|
||||||
return;
|
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;
|
char *buf;
|
||||||
} UDPC_Deque;
|
} 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.
|
* 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);
|
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);
|
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
|
* \brief Get data from back of deque
|
||||||
* Data must be free'd after use as it was allocated with malloc.
|
* 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);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue