aboutsummaryrefslogtreecommitdiff
path: root/lib/container/container.c
blob: 4a45d0ec4e19211f37561aa0d1dd84c2be5e17e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "container.h"

#include "../malloc/malloc.h"

#define DEFAULT_SIZE 128

container_t *new_container(u64 element_size)
{
	container_t *container = malloc(sizeof(container_t));

	container->data = malloc(element_size * DEFAULT_SIZE);
	container->element_size = element_size;
	container->size = 0;
	container->data_size = DEFAULT_SIZE;

	return container;
}


void free_container(container_t *container)
{
	free(container->data);
	free(container);
}

void container_push(container_t *container, u64 value)
{
	++container->size;


	if (container->size > container->data_size)
		container_resize(container, container->data_size + DEFAULT_SIZE);


	container_set(container, container->size - 1, value);
}


void container_erase(container_t *container, u64 start, u64 end)
{
	u64 data_end = container->size;
	container->size -= end - start;

	for (int i = 0; i < data_end - end; ++i)
		container_set(container, start + i, container_get(container, end + i));
}

void container_resize(container_t *container, u64 new_size)
{
	container->data_size = new_size;
	container->data = realloc(container->data, new_size * container->element_size);
}


u64 container_get(container_t *container, u64 index)
{
	switch (container->element_size) {
		case sizeof(u8):  return ((u8*)container->data)[index];
		case sizeof(u16): return ((u16*)container->data)[index];
		case sizeof(u32): return ((u32*)container->data)[index];
		case sizeof(u64): return ((u64*)container->data)[index];
	}

	return 0;
}


void container_set(container_t *container, u64 index, u64 data)
{
	switch (container->element_size) {
		case sizeof(u8):  ((u8*)container->data)[index]  = (u8)data;  break;
		case sizeof(u16): ((u16*)container->data)[index] = (u16)data; break;
		case sizeof(u32): ((u32*)container->data)[index] = (u32)data; break;
		case sizeof(u64): ((u64*)container->data)[index] = (u64)data; break;
	}
}


void container_merge(container_t *dest, container_t *src)
{
	container_append(dest, src->data, src->size);
}


void container_append(container_t *container, void *src, u64 size)
{
	for (int i = 0; i < size; ++i) {
		switch (container->element_size) {
			case sizeof(u8):  container_push(container, (u64)((u8*)src)[i]);  break;
			case sizeof(u16): container_push(container, (u64)((u16*)src)[i]); break;
			case sizeof(u32): container_push(container, (u64)((u32*)src)[i]); break;
			case sizeof(u64): container_push(container, (u64)((u64*)src)[i]); break;
		}
	}
}