Annotation of libaitio/src/array.c, revision 1.1.2.2
1.1.2.1 misho 1: /*************************************************************************
2: * (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
3: * by Michael Pounov <misho@openbsd-bg.org>
4: *
5: * $Author: misho $
1.1.2.2 ! misho 6: * $Id: array.c,v 1.1.2.1 2011/04/19 21:07:32 misho Exp $
1.1.2.1 misho 7: *
8: *************************************************************************/
9: #include "global.h"
10:
11:
12: /*
13: * io_arrayInit() - Create and initialize dynamic array
14: * @numItems = Number of Items
15: * return: NULL error, != NULL allocated memory for array
16: */
17: inline array_t *
18: io_arrayInit(int numItems)
19: {
20: array_t *arr = NULL;
21:
22: arr = malloc(sizeof(array_t));
23: if (!arr) {
24: LOGERR;
25: return NULL;
26: }
27:
28: arr->arr_num = numItems;
29: arr->arr_data = calloc(arr->arr_num, sizeof(void*));
30: if (!arr->arr_data) {
31: LOGERR;
32: free(arr);
33: return NULL;
34: } else
35: memset(arr->arr_data, 0, arr->arr_num * sizeof(void*));
36:
37: return arr;
38: }
39:
40: /*
41: * io_arrayFree() - Free all data in dynamic array
42: * (WARNING! If assign static array dont use this!!!)
43: * @arr = Array
44: * return: none
45: */
46: inline void
47: io_arrayFree(array_t * __restrict arr)
48: {
49: register int i;
50:
51: assert(arr);
52: if (!arr)
53: return;
54:
55: for (i = 0; i < arr->arr_num; i++)
56: if (arr->arr_data[i]) {
57: free(arr->arr_data[i]);
58: arr->arr_data[i] = NULL;
59: }
60: }
61:
62: /*
63: * io_arrayDestroy() - Free all data in dynamic array and Destroy dynamic array
64: * @parr = Array
65: * return: none
66: */
67: inline void
68: io_arrayDestroy(array_t ** __restrict parr)
69: {
70: assert(parr);
71: if (!parr)
72: return;
73:
74: if ((*parr)->arr_data)
75: free((*parr)->arr_data);
76: free(*parr);
77: *parr = NULL;
78: }
79:
80: /*
81: * io_arrayLen() - Get last used element in dynamic array (array Length)
82: * @arr = Array
83: * return: -1 error, 0 empty or >0 position of last used element
84: */
85: inline int
86: io_arrayLen(array_t * __restrict arr)
87: {
88: register int i;
89:
90: assert(arr);
91: if (!arr)
92: return -1;
93:
94: for (i = arr->arr_num; i && !arr->arr_data[i - 1]; i--);
95:
96: return i;
97: }
98:
99: /*
100: * io_arrayGrow() - Grow/Shrink dynamic array, Use with care when it shrink!!!
101: * @arr = Array
102: * @newNumItems = Number of Items
103: * return: -1 error, 0 ok
104: */
105: int
106: io_arrayGrow(array_t * __restrict arr, int newNumItems)
107: {
108: void **data;
109: int n = 0;
110: /* register int i; */
111:
112: assert(arr);
113: if (!arr)
114: return -1;
115:
116: if (arr->arr_num == newNumItems)
117: return 0;
118: if (arr->arr_num < newNumItems) {
119: n = newNumItems - arr->arr_num;
120: } /* else
121: for (i = newNumItems; i < arr->arr_num; i++)
122: if (arr->arr_data[i])
123: free(arr->arr_data[i]);
124: */
125:
1.1.2.2 ! misho 126: arr->arr_num = newNumItems;
1.1.2.1 misho 127: data = realloc(arr->arr_data, arr->arr_num * sizeof(void*));
128: if (!data) {
129: LOGERR;
130: return -1;
131: } else
132: arr->arr_data = data;
1.1.2.2 ! misho 133: memset(arr->arr_data + (arr->arr_num - n), 0, n * sizeof(void*));
1.1.2.1 misho 134:
135: return 0;
136: }
137:
138: /*
139: * io_arrayVacuum() - Vacuum dynamic array, empty elements will be deleted
140: * @arr = Array
141: * @fromWhere = 1 begin, 2 ALL empty elements
142: * return: -1 error, 0 ok
143: */
144: int
145: io_arrayVacuum(array_t * __restrict arr, int fromWhere)
146: {
147: register int i, j, num;
148: int cx = 0;
149:
150: assert(arr);
151: if (!arr)
152: return -1;
153: else
154: fromWhere &= 0x7;
155:
156: num = arr->arr_num;
157: /*
158: if (fromWhere & VACUUM_RIGHT) {
159: for (cx = 0, i = num - 1; i && !arr->arr_data[i]; i--, cx++);
160: num -= cx;
161: }
162: */
163: if (fromWhere & VACUUM_LEFT) {
164: for (i = 0; i < num && !arr->arr_data[i]; i++);
165:
166: memmove(arr->arr_data, arr->arr_data + i, (num - i) * sizeof(void*));
167: memset(arr->arr_data + (num - i), 0, i * sizeof(void*));
168:
169: num -= i;
170: cx += i;
171: }
172: if (fromWhere & VACUUM_BETWEEN) {
173: for (i = 0; i < num; i++) {
174: if (arr->arr_data[i])
175: continue;
176:
177: for (j = i; j < num && !arr->arr_data[j]; j++);
178:
179: memmove(arr->arr_data + i, arr->arr_data + j, (num - j) * sizeof(void*));
180: memset(arr->arr_data + i + (num - j), 0, (j - i) * sizeof(void*));
181:
182: num -= j - i;
183: cx += j - i;
184: }
185: }
186:
187: return cx;
188: }
189:
190: /*
191: * io_argsNum() Parse and calculate number of arguments
192: * @csArgs = Input arguments line
193: * @csDelim = Delimiter(s) for separate
194: * return: 0 error format; -1 error:: can`t read; >0 ok, number of items
195: */
196: inline int
197: io_argsNum(const char *csArgs, const char *csDelim)
198: {
199: register int res;
200: char *pos;
201:
202: assert(csArgs);
203: assert(csDelim);
204: if (!csArgs || !csDelim)
205: return -1;
206:
207: for (res = 1, pos = (char*) csArgs; (pos = strpbrk(pos, csDelim)); res++, pos++);
208: return res;
209: }
210:
211: /*
212: * io_arrayMake() Parse and make array from arguments ... (input string will be modified!!!
213: * and output array must be free with io_arrayDestroy() after use!)
214: * @psArgs = Input arguments line, after execute string is modified!!!
215: * @nargs = Maximum requested count of arguments from input string psArgs, if 0 all psArgs
216: * @csDelim = Delimiter(s) for separate
217: * @parr = Output array of arguments ... (must be free with io_arrayDestroy() after use!)
218: * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
219: */
220: int
221: io_arrayMake(char * __restrict psArgs, int nargs, const char *csDelim, array_t ** __restrict parr)
222: {
223: char **app;
224: register int i;
225:
226: assert(psArgs);
227: assert(csDelim);
228: assert(parr);
229: if (!psArgs || !csDelim || !parr)
230: return -1;
231:
232: if (nargs)
233: i = nargs;
234: else
235: i = io_argsNum(psArgs, csDelim);
236: *parr = io_arrayInit(i);
237: if (!*parr)
238: return -1;
239:
240: for (i = 0, app = (char**) (*parr)->arr_data;
241: app < (char**) (*parr)->arr_data + (*parr)->arr_num &&
242: (*app = strsep((char **) &psArgs, csDelim));
243: **app ? i++ : i, **app ? app++ : app);
244: return i;
245: }
246:
247: /*
248: * io_MakeAV() Parse and make attribute/value pair
249: * @csArgs = Input argument line
250: * @csDelim = Delimiter for separate
251: * @psAttr = Output Attribute
252: * @attrLen = Size of attribute array
253: * @psValue = Output Value, if ==NULL this element not present value or not wanted for return
254: * @valLen = Size of value array
255: * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items
256: */
257: int
258: io_MakeAV(const char * __restrict csArgs, const char *csDelim,
259: char * __restrict psAttr, int attrLen, char * __restrict psValue, int valLen)
260: {
261: register int ret = 0;
262: char *pos, *psBuf;
263:
264: if (!csArgs || !csDelim || !psAttr || !attrLen)
265: return -1;
266: if (psValue && !valLen)
267: return -1;
268: else
269: memset(psValue, 0, valLen);
270: psBuf = strdup(csArgs);
271: if (!psBuf) {
272: LOGERR;
273: return -1;
274: }
275:
276: pos = strpbrk(psBuf, csDelim);
277: if (pos)
278: *pos++ = 0;
279: ret++;
280: strlcpy(psAttr, psBuf, attrLen);
281:
282: if (pos && *pos) {
283: ret++;
284: if (psValue)
285: strlcpy(psValue, pos, valLen);
286: }
287:
288: free(psBuf);
289: return ret;
290: }
291:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>