#include "clist.h"
void CList_init(CList* self, int size)
{
self->data = malloc(size);
self->size = size;
self->len = 0;
self->locked = false;
self->next = NULL;
}
void CList_free(CList* self)
{
CList* current = self;
CList* next;
while (current != NULL) {
next = current->next;
free(current->data);
free(current);
current = next;
}
}
void* CList_get(CList* self, int index)
{
if (index < 0 || index >= self->len) {
return NULL;
}
CList* current = self;
for (int i = 0; i < index; i++) {
current = current->next;
}
return current->data;
}
void CList_append(CList* self, void* data)
{
if (self->locked) {
return;
}
CList* new_node = (CList*)malloc(sizeof(CList));
new_node->data = malloc(self->size);
memcpy(new_node->data, data, self->size);
new_node->size = self->size;
new_node->len = 1;
new_node->locked = false;
new_node->next = NULL;
CList* current = self;
while (current->next != NULL) {
current = current->next;
}
current->next = new_node;
self->len++;
}
void CList_extend(CList* self, CList* list)
{
if (self->locked) {
return;
}
CList* current = list;
while (current != NULL) {
CList_append(self, current->data);
current = current->next;
}
}
void CList_push(CList* self, void* array)
{
if (self->locked) {
return;
}
int array_len = sizeof(array) / self->size;
for (int i = 0; i < array_len; i++) {
void* data = (char*)array + i * self->size;
CList_append(self, data);
}
}
void CList_remove(CList* self, void* data)
{
if (self->locked) {
return;
}
CList* current = self;
CList* prev = NULL;
while (current != NULL) {
if (memcmp(current->data, data, self->size) == 0) {
if (prev != NULL) {
prev->next = current->next;
} else {
if (current->next != NULL) {
self->data = current->next->data;
self->next = current->next->next;
free(current);
current = self;
continue;
} else {
free(current->data);
free(current);
self->data = NULL;
self->next = NULL;
self->len = 0;
return;
}
}
free(current->data);
free(current);
self->len--;
return;
}
prev = current;
current = current->next;
}
}
void CList_pop(CList* self, int index)
{
if (self->locked) {
return;
}
if (index < 0 || index >= self->len) {
return;
}
CList* current = self;
CList* prev = NULL;
for (int i = 0; i < index; i++) {
prev = current;
current = current->next;
}
if (prev != NULL) {
prev->next = current->next;
} else {
if (current->next != NULL) {
self->data = current->next->data;
self->next = current->next->next;
free(current);
current = self;
} else {
free(current->data);
free(current);
self->data = NULL;
self->next = NULL;
self->len = 0;
return;
}
}
free(current->data);
free(current);
self->len--;
}
void* CList_to_array(CList* self, void** array)
{
*array = malloc(self->len * self->size);
CList* current = self;
int index = 0;
while (current != NULL) {
memcpy((char*)(*array) + index * self->size, current->data, self->size);
current = current->next;
index++;
}
return *array;
}
void* CList_to_array_new(CList* self)
{
void* array = malloc(self->len * self->size);
CList* current = self;
int index = 0;
while (current != NULL) {
memcpy((char*)array + index * self->size, current->data, self->size);
current = current->next;
index++;
}
return array;
}
int CList_size(CList* self)
{
return self->size;
}
int CList_len(CList* self)
{
return self->len;
}
void CList_lock(CList* self)
{
self->locked = true;
}
void CList_unlock(CList* self)
{
self->locked = false;
}
bool CList_is_locked(CList* self)
{
return self->locked;
}