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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-28 06:10:04 +00:00
|
|
|
void UDPC_Deque_destroy(UDPC_Deque *deque)
|
2019-01-26 11:44:31 +00:00
|
|
|
{
|
2019-01-28 06:10:04 +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;
|
|
|
|
}
|
|
|
|
|
2019-02-21 03:34:35 +00:00
|
|
|
int UDPC_Deque_push_back_realloc(UDPC_Deque *deque, const void *data, uint32_t size)
|
|
|
|
{
|
|
|
|
if(UDPC_Deque_push_back(deque, data, size) == 0)
|
|
|
|
{
|
|
|
|
if(UDPC_Deque_realloc(deque, deque->alloc_size * 2) != 0)
|
|
|
|
{
|
|
|
|
return UDPC_Deque_push_back(deque, data, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int UDPC_Deque_push_front_realloc(UDPC_Deque *deque, const void *data, uint32_t size)
|
|
|
|
{
|
|
|
|
if(UDPC_Deque_push_front(deque, data, size) == 0)
|
|
|
|
{
|
|
|
|
if(UDPC_Deque_realloc(deque, deque->alloc_size * 2) != 0)
|
|
|
|
{
|
|
|
|
return UDPC_Deque_push_front(deque, data, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-01-26 10:11:12 +00:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
2019-01-30 07:40:13 +00:00
|
|
|
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;
|
|
|
|
}
|