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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
#include "array.h"
#include "utility.h"
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
typedef struct{
size_t size;
uint use_count;
uint mem_count;
char buf[];
} VectorHeader;
#define getHeader(X) ((VectorHeader*)(pChar(X)-offsetof(VectorHeader,buf)))
#define getTotal2(X,Y) ((Y)*(X)+sizeof(VectorHeader))
#define getTotal(X) getTotal2((X)->mem_count,(X)->size)
/********************** initalize *************************/
pvoid ctl_array_initX(ppvoid v, size_t size, uint count){
VectorHeader *tmp;
int mem = 0;
if(count >= 1)
for(mem = 1; mem < count; mem *= 2);
tmp = (VectorHeader*)ctl_malloc(getTotal2(mem, size));
tmp->size = size;
tmp->use_count = count;
tmp->mem_count = mem;
if(v != NULL){
*v = pVoid(tmp->buf);
}
return pVoid(tmp->buf);
}
/*********************** destructure **********************/
pvoid ctl_array_freeX(ppvoid v){
free(pVoid(getHeader(*v)));
*v = NULL;
return NULL;
}
/******************** methods about get??? ****************/
int ctl_array_getSizeX(ppvoid v){
return getHeader(*v)->use_count;
}
pvoid ctl_array_getEntryX(ppvoid v, uint index){
return pVoid(pChar(*v) + getHeader(*v)->size * index);
}
int ctl_array_getEntrySizeX(ppvoid v){
return getHeader(*v)->size;
}
/******************** methods about set??? ****************/
int ctl_array_setSizeX(ppvoid v, uint count){
VectorHeader *tmp = getHeader(*v);
int mem = 0;
if(count >= 1)
for(mem = 1; mem < count; mem *= 2);
tmp->use_count = count;
tmp->mem_count = mem;
tmp = (VectorHeader*)ctl_realloc(pVoid(tmp), getTotal(tmp));
*v = pVoid(tmp->buf);
return tmp->use_count;
}
pvoid ctl_array_setEntryX(ppvoid v, uint index, pcvoid data){
VectorHeader *tmp = getHeader(*v);
memcpy(pVoid(tmp->buf + index * tmp->size), data, tmp->size);
}
/************** add/del element on the back ***************/
int ctl_array_addBackX(ppvoid v, pcvoid entry){
VectorHeader *tmp = getHeader(*v);
if(tmp->use_count + 1 > tmp->mem_count){
if(tmp->mem_count == 0) tmp->mem_count = 1;
else tmp->mem_count *= 2;
tmp = (VectorHeader*)realloc(pVoid(tmp), getTotal(tmp));
*v = pVoid(tmp->buf);
}
memcpy(tmp->buf + tmp->size * tmp->use_count, entry, tmp->size);
tmp->use_count++;
return tmp->use_count;
}
int ctl_array_delBackX(ppvoid v){
VectorHeader *tmp = getHeader(*v);
if((tmp->use_count - 1) * 2 < tmp->mem_count){
tmp->mem_count /= 2;
tmp = (VectorHeader*)realloc(pVoid(tmp), getTotal(tmp));
*v = pVoid(tmp->buf);
}
tmp->use_count--;
return tmp->use_count;
}
//int ctl_array_addFrontX(ppvoid v, pcvoid entry);
//int ctl_array_delFrontX(ppvoid v);
int ctl_array_catX(ppvoid v, ppcvoid v2){
int count0 = getHeader(*v)->use_count;
int count2 = getHeader(*v2)->use_count;
ctl_array_setSize(v, count0 + count2);
int i;
for(i = 0; i < count2; i++)
ctl_array_setEntry(v, count0 + i, ctl_array_getEntry(v2, i));
return count0 + count2;
}
pvoid ctl_array_copyX(ppvoid v, ppcvoid v2){
VectorHeader* tmp = getHeader(*v2);
VectorHeader* p = (VectorHeader*)malloc(getTotal(tmp));
memcpy(pVoid(p), pVoid(tmp), getTotal(tmp));
if(v != NULL){
if(*v != NULL){
ctl_array_free(v);
}
*v = p->buf;
}
return p->buf;
}
int ctl_array_replaceX( ppvoid v , uint start1, uint length1,
ppcvoid v2, uint start2, int length2){
int end1 = (int)start1 + length1 - 1;
int end2 = (int)start2 + abs(length2) - 1, step2 = 1;
if(length2 < 0){
length2 *= -1;
step2 *= -1;
ctl_swap(int, start2, end2);
}
if (length1 < length2){ // need increase size
int sz0 = ctl_array_getSize(v);
int delta = length2 - length1;
ctl_array_setSize(v, sz0 + delta);
int i;
for(i = sz0 + delta - 1; i - delta > end1; i--){
ctl_array_setEntry(v, i, ctl_array_getEntry(v, i - delta));
}
}else if(length1 > length2){ // need decrease size
int sz0 = ctl_array_getSize(v);
int delta = length1 - length2;
int i;
for(i = end1 - delta + 1; i + delta < sz0; i++){
ctl_array_setEntry(v, i, ctl_array_getEntry(v, i + delta));
}
ctl_array_setSize(v, sz0 - delta);
}
for(end2 += step2; start2 != end2; start2 += step2, start1 += 1){
ctl_array_setEntry(v, start1, ctl_array_getEntry(v2, start2));
}
}
|