Annotation of libelwix/src/vars.c, revision 1.4.20.1
1.1 misho 1: /*************************************************************************
2: * (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
3: * by Michael Pounov <misho@elwix.org>
4: *
5: * $Author: misho $
1.4.20.1! misho 6: * $Id: vars.c,v 1.4 2013/05/30 09:07:34 misho Exp $
1.1 misho 7: *
8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
46: #include "global.h"
47:
48:
1.4 misho 49: static inline int
1.1 misho 50: vars2buffer(u_char * __restrict buf, int buflen, int be, array_t * __restrict vars)
51: {
52: int Limit = 0;
53: register int i;
54: ait_val_t *v, *val;
55: u_char *dat;
56:
57: assert(buf);
58: assert(vars);
59: if (!buf || !vars)
60: return -1;
61: if (!buflen || !array_Size(vars))
62: return 0;
63: be = !!be;
64:
65: Limit = sizeof(ait_val_t) * array_Size(vars);
66: if (Limit > buflen) {
67: elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d",
68: buflen, Limit);
69: return -1;
70: } else {
71: memset(buf, 0, buflen);
72:
73: v = (ait_val_t*) buf;
74: dat = buf + Limit;
75: }
76:
77: /* marshaling */
78: for (i = 0; i < array_Size(vars); i++) {
79: val = array(vars, i, ait_val_t*);
80:
81: v[i].val_type = val->val_type;
82: AIT_IN(&v[i]) = 1;
83: AIT_BE(&v[i]) = be;
84: AIT_LE(&v[i]) = !be;
85: if (AIT_BE(&v[i])) {
86: AIT_KEY(&v[i]) = htobe16(AIT_KEY(val));
87: AIT_LEN(&v[i]) = htobe32(AIT_LEN(val));
88: }
89: if (AIT_LE(&v[i])) {
90: AIT_KEY(&v[i]) = htole16(AIT_KEY(val));
91: AIT_LEN(&v[i]) = htole32(AIT_LEN(val));
92: }
93:
94: switch (AIT_TYPE(val)) {
95: case blob:
96: case f32:
97: case f64:
98: case i8:
99: case i16:
100: case i32:
101: case i64:
102: case u8:
103: case u16:
104: case u32:
105: case u64:
106: if (AIT_BE(&v[i]))
107: v[i].val.net = htobe64(val->val.net);
108: if (AIT_LE(&v[i]))
109: v[i].val.net = htole64(val->val.net);
110: break;
111: case data:
112: if (AIT_LEN(val) > buflen - Limit) {
113: elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d "
114: "needed min %d", buflen, Limit + AIT_LEN(val));
115: return -1;
116: } else
117: Limit += AIT_LEN(val);
118:
119: memcpy(dat, val->val_data, AIT_LEN(val));
120: /* Debug:: data offset in packet, not matter for anything! */
121: v[i].val.net = dat - buf;
122: dat += AIT_LEN(val);
123: break;
124: case buffer:
125: case string:
126: if (AIT_LEN(val) > buflen - Limit) {
127: elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d "
128: "needed min %d", buflen, Limit + AIT_LEN(val));
129: return -1;
130: } else
131: Limit += AIT_LEN(val);
132:
133: memcpy(dat, val->val.buffer, AIT_LEN(val));
134: /* Debug:: data offset in packet, not matter for anything! */
135: v[i].val.net = dat - buf;
136: dat += AIT_LEN(val);
137: break;
138: default:
139: elwix_SetErr(EINVAL, "Unsupported variable type=%d at element #%d",
140: AIT_TYPE(val), i);
141: return -1;
142: }
143: }
144:
145: return Limit;
146: }
147:
1.4 misho 148: static inline array_t *
1.1 misho 149: buffer2vars(u_char * __restrict buf, int buflen, int vnum, int zcpy)
150: {
151: array_t *vars;
152: int Limit = 0;
153: register int i;
154: ait_val_t *v, *val;
155: u_char *dat;
156:
157: assert(buf);
158: if (!buf || !buflen || !vnum)
159: return NULL;
160:
161: Limit = sizeof(ait_val_t) * vnum;
162: if (Limit > buflen) {
163: elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d",
164: buflen, Limit);
165: return NULL;
166: } else {
167: if (!(vars = array_Init(vnum)))
168: return NULL;
169:
170: v = (ait_val_t*) buf;
171: dat = buf + Limit;
172: }
173:
174: /* de-marshaling */
175: for (i = 0; i < array_Size(vars); i++) {
176: if (!zcpy) {
177: val = e_malloc(sizeof(ait_val_t));
178: if (!val) {
179: if (!zcpy)
180: array_Free(vars);
181: array_Destroy(&vars);
182: return NULL;
183: }
184: AIT_IN(val) = 0;
185: } else {
186: val = v + i;
187: AIT_IN(val) = 1;
188: }
189: array_Set(vars, i, val);
190:
191: val->val_type = v[i].val_type;
192: AIT_BE(val) = AIT_BE(&v[i]);
193: AIT_LE(val) = AIT_LE(&v[i]);
194: if (AIT_BE(val)) {
195: AIT_LEN(val) = be32toh(AIT_LEN(&v[i]));
196: AIT_KEY(val) = be16toh(AIT_KEY(&v[i]));
197: }
198: if (AIT_LE(val)) {
199: AIT_LEN(val) = le32toh(AIT_LEN(&v[i]));
200: AIT_KEY(val) = le16toh(AIT_KEY(&v[i]));
201: }
202:
203: switch (AIT_TYPE(val)) {
204: case blob:
205: case f32:
206: case f64:
207: case i8:
208: case i16:
209: case i32:
210: case i64:
211: case u8:
212: case u16:
213: case u32:
214: case u64:
215: if (AIT_BE(val))
216: val->val.net = be64toh(v[i].val.net);
217: if (AIT_LE(val))
218: val->val.net = le64toh(v[i].val.net);
219: break;
220: case data:
221: /* WARNING:: remap data type to buffer */
222: val->val_type = buffer;
223: case buffer:
224: case string:
225: if (!zcpy) {
226: val->val.buffer = e_malloc(AIT_LEN(val));
227: if (!val->val.buffer) {
228: array_Free(vars);
229: array_Destroy(&vars);
230: return NULL;
231: } else
232: memcpy(val->val.buffer, dat, AIT_LEN(val));
233: } else
234: val->val.buffer = dat;
235: dat += AIT_LEN(val);
236: break;
237: default:
238: elwix_SetErr(EINVAL, "Unsupported variable type=%d at element #%d",
239: AIT_TYPE(val), i);
240: if (!zcpy)
241: array_Free(vars);
242: array_Destroy(&vars);
243: return NULL;
244: }
245: }
246:
247: return vars;
248: }
249:
250:
251: /* buffer marshaling with swapping bytes to network order */
252:
253: /*
254: * ait_vars2buffer() - Marshaling data from array with variables to buffer
255: *
256: * @buf = Buffer
257: * @buflen = Size of buffer
258: * @vars = Variable array
259: * return: -1 error, 0 nothing done or >0 size of marshaled data
260: */
1.4 misho 261: int
1.1 misho 262: ait_vars2buffer(u_char * __restrict buf, int buflen, array_t * __restrict vars)
263: {
264: return vars2buffer(buf, buflen, 42, vars);
265: }
266:
267: /*
268: * ait_buffer2vars() - De-marshaling data from buffer to array with variables
269: *
270: * @buf = Buffer
271: * @buflen = Size of buffer
272: * @vnum = Number of variables into buffer
273: * @zcpy = Zero-copy for variables, if !=0 don't use array_Free() for free variables and
274: *DON'T MODIFY OR DESTROY BUFFER*. =0 call array_Free() before array_Destroy()
275: * return: =NULL error, !=NULL allocated variable array, after use must free with array_Destroy()
276: */
1.4 misho 277: array_t *
1.1 misho 278: ait_buffer2vars(u_char * __restrict buf, int buflen, int vnum, int zcpy)
279: {
280: return buffer2vars(buf, buflen, vnum, zcpy);
281: }
282:
283: /* buffer marshaling without swapping bytes to network order */
284:
285: /*
286: * ait_vars2map() - Marshaling data from array with variables to memory map
287: *
288: * @buf = Buffer
289: * @buflen = Size of buffer
290: * @vars = Variable array
291: * return: -1 error, 0 nothing done or >0 size of marshaled data
292: */
1.4 misho 293: int
1.1 misho 294: ait_vars2map(u_char *buf, int buflen, array_t *vars)
295: {
296: return vars2buffer(buf, buflen, 0, vars);
297: }
298:
299: /*
300: * ait_map2vars() - De-marshaling data from memory map to array with variables
301: *
302: * @buf = Buffer
303: * @buflen = Size of buffer
304: * @vnum = Number of variables into buffer
305: * @zcpy = Zero-copy for variables, if !=0 don't use array_Free() for free variables and
306: *DON'T MODIFY OR DESTROY BUFFER*. =0 call array_Free() before array_Destroy()
307: * return: =NULL error, !=NULL allocated variable array, after use must free with array_Destroy()
308: */
1.4 misho 309: array_t *
1.1 misho 310: ait_map2vars(u_char *buf, int buflen, int vnum, int zcpy)
311: {
312: return buffer2vars(buf, buflen, vnum, zcpy);
313: }
314:
315:
316: /* variables array */
317:
318: /*
319: * ait_allocVars() - Allocate ait_val_t array
320: *
321: * @varnum = Number of variables
322: * return: =NULL error or !=NULL allocated array
323: */
1.4 misho 324: array_t *
1.1 misho 325: ait_allocVars(int varnum)
326: {
327: array_t *arr;
328: register int i;
329: ait_val_t *v;
330:
331: if (!(arr = array_Init(varnum)))
332: return NULL;
333:
334: for (i = 0; i < array_Size(arr); i++) {
335: if (!(v = ait_allocVar())) {
336: ait_freeVars(&arr);
337: return NULL;
338: } else
339: array_Set(arr, i, v);
340: }
341:
342: return arr;
343: }
344:
345: /*
346: * ait_getVars() - Get ait_val_t element from array and if not exists allocate it
347: *
348: * @vars = Variable array
349: * @n = index of variable into array
350: * return: NULL error or !=NULL ait_val_t element
351: */
1.4 misho 352: ait_val_t *
1.1 misho 353: ait_getVars(array_t ** __restrict vars, int n)
354: {
355: register int i;
356: ait_val_t *v;
357:
358: if (!vars)
359: return NULL;
360:
361: if (!*vars) {
362: if (!(*vars = ait_allocVars(n + 1)))
363: return NULL;
364: } else if (n >= (i = array_Size(*vars))) {
365: if (array_Grow(*vars, n + 1, 0))
366: return NULL;
367: for (; i < array_Size(*vars); i++)
368: if (!array_Get(*vars, i)) {
369: if (!(v = ait_allocVar()))
370: return NULL;
371: else
372: array_Set(*vars, i, v);
373: }
374: }
375:
376: return array(*vars, n, ait_val_t*);
377: }
378:
379: /*
380: * ait_clrVars() - Clear ait_val_t elements from array
381: *
382: * @vars = Variable array
383: * return: -1 error or size of array
384: */
1.4 misho 385: int
1.1 misho 386: ait_clrVars(array_t * __restrict vars)
387: {
388: register int i;
389: ait_val_t *v;
390:
391: if (!vars)
392: return -1;
393:
394: for (i = 0; i < array_Size(vars); i++)
395: if ((v = array(vars, i, ait_val_t*)))
396: AIT_FREE_VAL(v);
397:
398: return array_Size(vars);
399: }
400:
401: /*
402: * ait_freeVars() - Free ait_val_t array
403: *
404: * @vars = Variable array
405: * return: none
406: */
1.4 misho 407: void
1.1 misho 408: ait_freeVars(array_t ** __restrict vars)
409: {
410: if (!vars || !*vars)
411: return;
412:
413: ait_clrVars(*vars);
414: array_Free(*vars);
415: array_Destroy(vars);
416: }
417:
1.4.20.1! misho 418: /*
! 419: * ait_resideVars() - Calculate footprint of resided variables into array
! 420: *
! 421: * @vars = Variable array
! 422: * return: -1 error or !=-1 bytes for whole array
! 423: */
! 424: ssize_t
! 425: ait_resideVars(array_t * __restrict vars)
! 426: {
! 427: ssize_t ret = 0;
! 428: register int i;
! 429:
! 430: if (!vars)
! 431: return -1;
! 432:
! 433: ret = array_Size(vars) * sizeof(ait_val_t);
! 434: for (i = 0; i < array_Size(vars); i++)
! 435: switch (AIT_TYPE(array(vars, i, ait_val_t*))) {
! 436: case buffer:
! 437: case string:
! 438: case data:
! 439: case ptr:
! 440: ret += AIT_LEN(array(vars, i, ait_val_t*));
! 441: break;
! 442: default:
! 443: break;
! 444: }
! 445:
! 446: return ret;
! 447: }
! 448:
1.1 misho 449:
450: /*
451: * ait_allocVar() - Allocate memory for variable
452: *
453: * return: NULL error or new variable, after use free variable with ait_freeVar()
454: */
1.4 misho 455: ait_val_t *
1.1 misho 456: ait_allocVar(void)
457: {
458: ait_val_t *v = NULL;
459:
460: v = e_malloc(sizeof(ait_val_t));
461: if (!v)
462: return NULL;
463: else
464: memset(v, 0, sizeof(ait_val_t));
465: v->val_type = empty;
466:
467: return v;
468: }
469:
470: /*
471: * ait_freeVar() - Free allocated memory for variable
472: *
473: * @val = Variable
474: * return: none
475: */
1.4 misho 476: void
1.1 misho 477: ait_freeVar(ait_val_t ** __restrict val)
478: {
479: if (val && *val) {
480: AIT_FREE_VAL(*val);
481: e_free(*val);
482: *val = NULL;
483: }
484: }
485:
486: /*
487: * ait_makeVar() - Allocate memory and fill variable
488: *
489: * @type = type of variable
490: * @... = arg1 is value of variable
491: * @... = arg2 is length of variabla. Not required for numbers and strings!
492: * return: NULL error or new variable, after use free variable with io_freeVar()
493: */
494: ait_val_t *
495: ait_makeVar(ait_type_t type, ...)
496: {
497: ait_val_t *v = NULL;
498: va_list lst;
499: void *p = NULL;
500: uint32_t len = 0;
501: uint64_t n = 0LL;
502:
503: v = ait_allocVar();
504: if (!v)
505: return NULL;
506:
507: va_start(lst, type);
508: switch (type) {
509: case empty:
510: v->val_type = (uint8_t) empty;
511: break;
512: case ptr:
513: p = va_arg(lst, void*);
514: len = va_arg(lst, uint32_t);
515: AIT_SET_PTR(v, p, len);
516: break;
517: case data:
518: p = va_arg(lst, void*);
519: len = va_arg(lst, uint32_t);
520: AIT_SET_DATA(v, p, len);
521: break;
522: case buffer:
523: p = va_arg(lst, void*);
524: len = va_arg(lst, uint32_t);
525: AIT_SET_BUF(v, p, len);
526: break;
527: case string:
528: p = va_arg(lst, char*);
529: AIT_SET_STR(v, (char*) p);
530: break;
531: case blob:
532: n = va_arg(lst, uint32_t);
533: len = va_arg(lst, uint32_t);
534: AIT_SET_BLOB(v, n, len);
535: break;
536: case f32:
537: AIT_SET_F32(v, (float) va_arg(lst, double));
538: break;
539: case f64:
540: AIT_SET_F64(v, va_arg(lst, double));
541: break;
542: case u8:
543: AIT_SET_U8(v, (uint8_t) va_arg(lst, int));
544: break;
545: case u16:
546: AIT_SET_U16(v, (uint16_t) va_arg(lst, int));
547: break;
548: case u32:
549: AIT_SET_U32(v, va_arg(lst, uint32_t));
550: break;
551: case u64:
552: AIT_SET_U64(v, va_arg(lst, uint64_t));
553: break;
554: case i8:
555: AIT_SET_I8(v, (int8_t) va_arg(lst, int));
556: break;
557: case i16:
558: AIT_SET_I16(v, (int16_t) va_arg(lst, int));
559: break;
560: case i32:
561: AIT_SET_I32(v, va_arg(lst, int32_t));
562: break;
563: case i64:
564: AIT_SET_I64(v, va_arg(lst, int64_t));
565: break;
566: }
567: va_end(lst);
568:
569: return v;
570: }
571:
572: static int
573: _cmp_arr_key_asc(const void *a, const void *b)
574: {
575: return AIT_KEY(*(ait_val_t**) a) - AIT_KEY(*(ait_val_t**) b);
576: }
577:
578: static int
579: _cmp_arr_key_desc(const void *a, const void *b)
580: {
581: return AIT_KEY(*(ait_val_t**) b) - AIT_KEY(*(ait_val_t**) a);
582: }
583:
584: static int
585: _cmp_arr_val_asc(const void *a, const void *b)
586: {
587: return AIT_RAW(*(ait_val_t**) a) - AIT_RAW(*(ait_val_t**) b);
588: }
589:
590: static int
591: _cmp_arr_val_desc(const void *a, const void *b)
592: {
593: return AIT_RAW(*(ait_val_t**) b) - AIT_RAW(*(ait_val_t**) a);
594: }
595:
596: /*
597: * ait_sortVarsByVal() - Sorting array with variables by value
598: *
599: * @vars = Variable array
600: * @order = Sort order. If =0 ascend or !=0 descend
601: * @cmp = Custom compare function for sorting. If =NULL compare by value
602: * return: none
603: */
1.4 misho 604: void
1.1 misho 605: ait_sortVarsByVal(array_t * __restrict vars, int order, int (*cmp)(const void*, const void*))
606: {
607: if (!vars)
608: return;
609:
610: if (cmp)
1.2 misho 611: qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), cmp);
1.1 misho 612: else if (order)
1.2 misho 613: qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_val_desc);
1.1 misho 614: else
1.2 misho 615: qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_val_asc);
1.1 misho 616: }
617:
618: /*
619: * ait_sortVarsByKey() - Sorting array with variables by key
620: *
621: * @vars = Variable array
622: * @order = Sort order. If =0 ascend or !=0 descend
623: * return: none
624: */
1.4 misho 625: void
1.1 misho 626: ait_sortVarsByKey(array_t * __restrict vars, int order)
627: {
628: if (!vars)
629: return;
630:
631: if (order)
1.2 misho 632: qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_key_desc);
1.1 misho 633: else
1.2 misho 634: qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_key_asc);
1.1 misho 635: }
636:
637: /*
638: * ait_findKeyVars() - Find variable by key from array
639: *
640: * @vars = Variables
641: * @key = Search key
642: * return: NULL error or not found, !=NULL valid element
643: */
644: ait_val_t *
645: ait_findKeyVars(array_t * __restrict vars, u_short key)
646: {
647: array_t *tmp;
648: ait_val_t **vv, *v = NULL;
649: register int i;
650: const u_char *p;
651:
652: if (!vars)
653: return NULL;
654:
655: if (array_Copy(&tmp, vars) == -1)
656: return NULL;
657: else
1.2 misho 658: qsort(tmp->arr_data, tmp->arr_num, sizeof(uintptr_t), _cmp_arr_key_asc);
1.1 misho 659:
660: /* binary search */
661: for (p = (const u_char*) tmp->arr_data, i = array_Size(tmp); i; i >>= 1) {
1.2 misho 662: vv = (ait_val_t**) (p + (i >> 1) * sizeof(uintptr_t));
1.1 misho 663: if (!(key - AIT_KEY(*vv))) { /* found! */
664: v = *vv;
665: break;
666: }
667: if ((key - AIT_KEY(*vv)) > 0) { /* move right key > current */
1.2 misho 668: p = (const u_char*) vv + sizeof(uintptr_t);
1.1 misho 669: i--;
670: } /* else move left */
671: }
672:
673: array_Destroy(&tmp);
674: return v;
675: }
676:
677: /*
678: * ait_hashVar() - Generate hash key for variable from string or value
679: *
680: * @v = variable
681: * @key = key string for hash, if =NULL hash will built from variable
682: * return: hash key
683: */
684: u_short
685: ait_hashVar(ait_val_t * __restrict v, const char * __restrict key)
686: {
687: void *p;
688: u_short cksum;
689: int l;
690:
691: if (!v)
692: return 0;
693:
694: if (key) {
695: p = (void*) key;
696: l = (strlen(key) + 1) / 2;
697: } else {
698: switch (AIT_TYPE(v)) {
699: case empty:
700: AIT_KEY(v) = 0;
701: return 0;
702: case string:
703: case buffer:
704: p = AIT_ADDR(v);
705: l = AIT_LEN(v) / 2;
706: break;
707: case data:
708: p = v->val_data;
709: l = AIT_LEN(v) / 2;
710: break;
711: default:
712: p = &AIT_RAW(v);
713: l = sizeof AIT_RAW(v) / 2;
714: break;
715: }
716: }
717:
718: cksum = crcFletcher16((u_short*) p, l);
719:
720: if (AIT_BE(v))
721: AIT_KEY(v) = htobe16(cksum);
722: else if (AIT_LE(v))
723: AIT_KEY(v) = htole16(cksum);
724: else
725: AIT_KEY(v) = cksum;
726:
727: return AIT_KEY(v);
728: }
729:
730: /*
731: * ait_hashKeyVars() - Generate hash keys for variables
732: *
733: * @vars = Variables
734: * return -1 error or 0 ok
735: */
1.4 misho 736: int
1.1 misho 737: ait_hashKeyVars(array_t * __restrict vars)
738: {
739: register int i;
740:
741: if (!vars)
742: return -1;
743:
744: for (i = 0; i < array_Size(vars); i++)
745: ait_hashVar(array(vars, i, ait_val_t*), NULL);
746:
747: return 0;
748: }
749:
750: /*
751: * ait_findKeyHash() - Find variable by hash string from array
752: *
753: * @vars = Variables
754: * @key = Search string
755: * return: NULL error or not found, !=NULL valid element
756: */
1.4 misho 757: ait_val_t *
1.1 misho 758: ait_findKeyHash(array_t * __restrict vars, const char * __restrict key)
759: {
760: u_short k = 0;
761:
762: if (!vars || !key)
763: return NULL;
764:
765: k = crcFletcher16((u_short*) key, (strlen(key) + 1) / 2);
766: return ait_findKeyVars(vars, k);
767: }
768:
769: /*
770: * ait_sprintfVar() - Builtin string variable from formatted input
771: *
772: * @v = variable
773: * @fmt = format string
774: * @... = argument(s)
775: * return: -1 error or >0 copied bytes to variable
776: */
777: int
1.2 misho 778: ait_sprintfVar(ait_val_t * __restrict v, const char *fmt, ...)
1.1 misho 779: {
780: int ret = 0;
781: va_list lst;
782: char *str = NULL;
783:
784: if (!v || !fmt)
785: return -1;
786:
787: va_start(lst, fmt);
788: ret = vasprintf(&str, fmt, lst);
789: va_end(lst);
790:
791: if (str && ret > -1) {
792: AIT_FREE_VAL(v);
793: AIT_SET_STR(v, str);
794: } else
795: LOGERR;
796:
797: if (str)
798: free(str);
799: return ret;
800: }
801:
802: /*
803: * ait_setlikeVar() - Set variable like ...
804: *
805: * @v = variable
806: * @t = type of data
807: * @l = length of data
808: * @... = data
809: * return: -1 error or 0 ok
810: */
1.4 misho 811: int
1.1 misho 812: ait_setlikeVar(ait_val_t * __restrict v, ait_type_t t, u_int l, ...)
813: {
814: va_list lst;
815:
816: if (!v)
817: return -1;
818:
819: AIT_FREE_VAL(v);
820: AIT_INIT_VAL2(v, t);
821: AIT_LEN(v) = l;
822: AIT_IN(v) = 1;
823:
824: va_start(lst, l);
825: switch (AIT_TYPE(v)) {
826: case ptr:
827: case buffer:
828: case string:
829: AIT_ADDR(v) = va_arg(lst, void*);
830: break;
831: default:
832: AIT_RAW(v) = va_arg(lst, uint64_t);
833: break;
834: }
835: va_end(lst);
836:
837: return 0;
838: }
839:
840: /*
841: * ait_getlikeVar() - Get variable like ...
842: *
843: * @v = variable
844: * return: return raw data
845: */
1.4 misho 846: uint64_t
1.1 misho 847: ait_getlikeVar(ait_val_t * __restrict v)
848: {
849: if (!v)
850: return (uintptr_t) -1;
851:
852: return AIT_RAW(v);
853: }
854:
855: /*
856: * ait_cmpVar() - Compare two variables
857: *
858: * @a = 1st variable
859: * @b = 2nd variable
860: * return: 0 is equal or !=0 is different
861: */
1.4 misho 862: int
1.1 misho 863: ait_cmpVar(ait_val_t * __restrict a, ait_val_t * __restrict b)
864: {
865: intptr_t ret;
866:
867: if (!(ret = (a - b)))
868: return ret;
869: if ((ret = AIT_TYPE(a) - AIT_TYPE(b)))
870: return ret;
871: if ((ret = AIT_LEN(a) - AIT_LEN(b)))
872: return ret;
873:
874: switch (AIT_TYPE(a)) {
875: case buffer:
876: ret = memcmp(AIT_GET_BUF(a), AIT_GET_BUF(b), AIT_LEN(a));
877: break;
878: case string:
879: ret = strncmp(AIT_GET_STR(a), AIT_GET_STR(b), AIT_LEN(a));
880: break;
881: case data:
882: ret = memcmp(AIT_GET_DATA(a), AIT_GET_DATA(b), AIT_LEN(a));
883: break;
884: case ptr:
885: ret = AIT_ADDR(a) - AIT_ADDR(b);
886: break;
887: default:
888: ret = AIT_RAW(a) - AIT_RAW(b);
889: break;
890: }
891:
892: return (int) ret;
893: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>