UDPConnection/src/UDPC_Deque.c

488 lines
9.9 KiB
C
Raw Normal View History

2019-01-27 06:09:38 +00:00
#include "UDPC_Deque.h"
2019-01-26 10:11:12 +00:00
#include <stdlib.h>
#include <string.h>
2019-01-27 09:30:35 +00:00
UDPC_Deque* UDPC_Deque_init(uint32_t alloc_size)
2019-01-26 10:11:12 +00:00
{
2019-01-27 09:30:35 +00:00
UDPC_Deque *deque = malloc(sizeof(UDPC_Deque));
2019-01-31 03:16:01 +00:00
if(!deque)
{
return NULL;
}
2019-01-26 11:44:31 +00:00
UDPC_Deque_clear(deque);
2019-01-26 10:11:12 +00:00
deque->alloc_size = alloc_size;
deque->buf = malloc(alloc_size);
2019-01-26 11:44:31 +00:00
if(deque->buf)
{
2019-01-27 09:30:35 +00:00
return deque;
2019-01-26 11:44:31 +00:00
}
else
{
2019-01-27 09:30:35 +00:00
free(deque);
return NULL;
2019-01-26 11:44:31 +00:00
}
}
void UDPC_Deque_destroy(UDPC_Deque *deque)
2019-01-26 11:44:31 +00:00
{
free(deque->buf);
free(deque);
2019-01-26 11:44:31 +00:00
}
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;
2019-01-27 06:09:38 +00:00
deque->head = 0;
deque->tail = deque->size;
if(deque->tail == deque->alloc_size)
{
deque->tail = 0;
}
2019-01-26 11:44:31 +00:00
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;
}
}
2019-01-26 10:11:12 +00:00
}
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(deque->size + size > deque->alloc_size)
{
return 0;
}
else if(deque->tail + size <= deque->alloc_size)
{
memcpy(&deque->buf[deque->tail], data, size);
deque->tail += size;
if(deque->tail == deque->alloc_size)
{
deque->tail = 0;
}
deque->size += size;
return 1;
}
uint32_t temp;
if(deque->tail < deque->alloc_size)
{
memcpy(&deque->buf[deque->tail], data, deque->alloc_size - deque->tail);
temp = deque->alloc_size - deque->tail;
deque->size += temp;
size -= temp;
deque->tail = 0;
}
if(size > 0)
{
2019-01-27 06:09:38 +00:00
memcpy(&deque->buf[deque->tail], &((const char*)data)[temp], size);
2019-01-26 10:11:12 +00:00
deque->tail += size;
deque->size += size;
}
return 1;
}
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
{
if(deque->size + size > deque->alloc_size)
{
return 0;
}
else if(size <= deque->head)
{
memcpy(&deque->buf[deque->head - size], data, size);
deque->head -= size;
deque->size += size;
return 1;
}
if(deque->head > 0)
{
2019-01-27 06:09:38 +00:00
memcpy(deque->buf, &((const char*)data)[size - deque->head], deque->head);
2019-01-26 10:11:12 +00:00
deque->size += deque->head;
size -= deque->head;
deque->head = 0;
}
if(size > 0)
{
memcpy(&deque->buf[deque->alloc_size - size], data, size);
deque->head = deque->alloc_size - size;
deque->size += size;
}
return 1;
}
uint32_t UDPC_Deque_get_available(UDPC_Deque *deque)
{
return deque->alloc_size - deque->size;
}
2019-01-26 11:44:31 +00:00
uint32_t UDPC_Deque_get_used(UDPC_Deque *deque)
{
return deque->size;
}
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
{
int returnValue = 1;
if(deque->size == 0)
{
*size = 0;
2019-01-26 11:44:31 +00:00
*data = NULL;
2019-01-26 10:11:12 +00:00
return 0;
}
else if(*size > deque->size)
{
*size = deque->size;
returnValue = 0;
}
*data = malloc(*size);
2019-01-31 03:16:01 +00:00
if(deque->tail == 0)
{
memcpy(*data, &deque->buf[deque->alloc_size - *size], *size);
return returnValue;
}
else if(deque->tail < *size)
2019-01-26 10:11:12 +00:00
{
memcpy(data[*size - deque->tail], deque->buf, deque->tail);
memcpy(
*data,
&deque->buf[deque->alloc_size - (*size - deque->tail)],
*size - deque->tail);
return returnValue;
}
2019-01-31 03:16:01 +00:00
else
{
memcpy(*data, &deque->buf[deque->tail - *size], *size);
return returnValue;
}
}
void* UDPC_Deque_get_back_ptr(UDPC_Deque *deque, uint32_t unitSize)
{
if(deque->size < unitSize)
{
return NULL;
}
2019-01-26 10:11:12 +00:00
2019-01-31 03:16:01 +00:00
if(deque->tail == 0 && deque->size >= unitSize)
{
return &deque->buf[deque->alloc_size - unitSize];
}
else if(deque->tail < unitSize)
{
return NULL;
}
else
{
return &deque->buf[deque->tail - unitSize];
}
2019-01-26 10:11:12 +00:00
}
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
{
int returnValue = 1;
if(deque->size == 0)
{
*size = 0;
2019-01-26 11:44:31 +00:00
*data = NULL;
2019-01-26 10:11:12 +00:00
return 0;
}
else if(*size > deque->size)
{
*size = deque->size;
returnValue = 0;
}
*data = malloc(*size);
if(deque->head + *size > deque->alloc_size)
{
memcpy(*data, &deque->buf[deque->head], deque->alloc_size - deque->head);
memcpy(
data[deque->alloc_size - deque->head],
deque->buf,
*size - (deque->alloc_size - deque->head));
return returnValue;
}
2019-01-31 03:16:01 +00:00
else
{
memcpy(*data, &deque->buf[deque->head], *size);
return returnValue;
}
}
void* UDPC_Deque_get_front_ptr(UDPC_Deque *deque, uint32_t unitSize)
{
if(deque->size < unitSize || deque->head + unitSize > deque->alloc_size)
{
return NULL;
}
2019-01-26 10:11:12 +00:00
2019-01-31 03:16:01 +00:00
return &deque->buf[deque->head];
2019-01-26 10:11:12 +00:00
}
void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size)
{
if(deque->size == 0)
{
return;
}
else if(deque->size <= size)
{
2019-01-26 11:44:31 +00:00
UDPC_Deque_clear(deque);
2019-01-26 10:11:12 +00:00
return;
}
deque->size -= size;
if(deque->tail < size)
{
deque->tail = deque->alloc_size - (size - deque->tail);
}
else
{
deque->tail -= size;
}
}
void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size)
{
if(deque->size == 0)
{
return;
}
else if(deque->size <= size)
{
2019-01-26 11:44:31 +00:00
UDPC_Deque_clear(deque);
2019-01-26 10:11:12 +00:00
return;
}
deque->size -= size;
if(deque->head + size > deque->alloc_size)
{
deque->head = deque->head + size - deque->alloc_size;
}
else
{
deque->head += size;
if(deque->head == deque->alloc_size)
{
deque->head = 0;
}
}
}
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
{
uint32_t pos = unitSize * index;
uint32_t abspos;
2019-01-27 06:09:38 +00:00
if(pos >= deque->size)
2019-01-26 11:44:31 +00:00
{
*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;
}
2019-01-31 03:16:01 +00:00
void* UDPC_Deque_index_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index)
{
uint32_t pos = unitSize * index;
uint32_t abspos;
if(pos >= deque->size)
{
return NULL;
}
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)
{
return NULL;
}
return &deque->buf[abspos];
}
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
{
uint32_t pos = unitSize * (index + 1);
uint32_t abspos;
2019-01-27 06:09:38 +00:00
if(pos >= deque->size + unitSize)
2019-01-26 11:44:31 +00:00
{
*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;
}
2019-01-31 03:16:01 +00:00
void* UDPC_Deque_index_rev_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index)
{
uint32_t pos = unitSize * (index + 1);
uint32_t abspos;
if(pos >= deque->size + unitSize)
{
return NULL;
}
if(pos > deque->tail)
{
abspos = deque->alloc_size - (pos - deque->tail);
}
else
{
abspos = deque->tail - pos;
}
if(abspos + unitSize > deque->alloc_size)
{
return NULL;
}
return &deque->buf[abspos];
}
int UDPC_Deque_remove(UDPC_Deque *deque, uint32_t unitSize, uint32_t index)
{
uint32_t pos = unitSize * index;
uint32_t abspos;
uint32_t lastpos;
if(deque->size == 0 || pos >= deque->size)
{
return 0;
}
else if(deque->size <= unitSize)
{
UDPC_Deque_clear(deque);
return 1;
}
if(pos + deque->head >= deque->alloc_size)
{
abspos = pos + deque->head - deque->alloc_size;
}
else
{
abspos = pos + deque->head;
}
if(deque->tail == 0)
{
lastpos = deque->alloc_size - unitSize;
}
else
{
lastpos = deque->tail - unitSize;
}
if(abspos != lastpos)
{
if(deque->tail == 0)
{
memcpy(&deque->buf[abspos], &deque->buf[deque->alloc_size - unitSize], unitSize);
deque->tail = deque->alloc_size - unitSize;
}
else
{
memcpy(&deque->buf[abspos], &deque->buf[deque->tail - unitSize], unitSize);
deque->tail -= unitSize;
}
deque->size -= unitSize;
}
else
{
UDPC_Deque_pop_back(deque, unitSize);
}
return 1;
}
2019-01-26 11:44:31 +00:00
void UDPC_Deque_clear(UDPC_Deque *deque)
{
deque->head = 0;
deque->tail = 0;
deque->size = 0;
}