Finish impl of Deque, testing required

This commit is contained in:
Stephen Seo 2019-01-26 20:44:31 +09:00
parent b76df86a4f
commit dd984b85a6
3 changed files with 184 additions and 11 deletions

View file

@ -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")

View file

@ -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;
}

View file

@ -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