Annotation of libelwix/src/vars.c, revision 1.8.4.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.8.4.1 ! misho 6: * $Id: vars.c,v 1.8 2015/06/25 17:53:50 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:
1.8 misho 15: Copyright 2004 - 2015
1.1 misho 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:
1.5 misho 126: case ptr:
1.1 misho 127: if (AIT_LEN(val) > buflen - Limit) {
128: elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d "
129: "needed min %d", buflen, Limit + AIT_LEN(val));
130: return -1;
131: } else
132: Limit += AIT_LEN(val);
133:
134: memcpy(dat, val->val.buffer, AIT_LEN(val));
135: /* Debug:: data offset in packet, not matter for anything! */
136: v[i].val.net = dat - buf;
137: dat += AIT_LEN(val);
138: break;
139: default:
140: elwix_SetErr(EINVAL, "Unsupported variable type=%d at element #%d",
141: AIT_TYPE(val), i);
142: return -1;
143: }
144: }
145:
146: return Limit;
147: }
148:
1.4 misho 149: static inline array_t *
1.1 misho 150: buffer2vars(u_char * __restrict buf, int buflen, int vnum, int zcpy)
151: {
152: array_t *vars;
153: int Limit = 0;
154: register int i;
155: ait_val_t *v, *val;
156: u_char *dat;
157:
158: assert(buf);
159: if (!buf || !buflen || !vnum)
160: return NULL;
161:
162: Limit = sizeof(ait_val_t) * vnum;
163: if (Limit > buflen) {
164: elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d",
165: buflen, Limit);
166: return NULL;
167: } else {
168: if (!(vars = array_Init(vnum)))
169: return NULL;
170:
171: v = (ait_val_t*) buf;
172: dat = buf + Limit;
173: }
174:
175: /* de-marshaling */
176: for (i = 0; i < array_Size(vars); i++) {
177: if (!zcpy) {
178: val = e_malloc(sizeof(ait_val_t));
179: if (!val) {
180: if (!zcpy)
181: array_Free(vars);
182: array_Destroy(&vars);
183: return NULL;
184: }
185: AIT_IN(val) = 0;
186: } else {
187: val = v + i;
188: AIT_IN(val) = 1;
189: }
190: array_Set(vars, i, val);
191:
192: val->val_type = v[i].val_type;
193: AIT_BE(val) = AIT_BE(&v[i]);
194: AIT_LE(val) = AIT_LE(&v[i]);
195: if (AIT_BE(val)) {
196: AIT_LEN(val) = be32toh(AIT_LEN(&v[i]));
197: AIT_KEY(val) = be16toh(AIT_KEY(&v[i]));
198: }
199: if (AIT_LE(val)) {
200: AIT_LEN(val) = le32toh(AIT_LEN(&v[i]));
201: AIT_KEY(val) = le16toh(AIT_KEY(&v[i]));
202: }
203:
204: switch (AIT_TYPE(val)) {
205: case blob:
206: case f32:
207: case f64:
208: case i8:
209: case i16:
210: case i32:
211: case i64:
212: case u8:
213: case u16:
214: case u32:
215: case u64:
216: if (AIT_BE(val))
217: val->val.net = be64toh(v[i].val.net);
218: if (AIT_LE(val))
219: val->val.net = le64toh(v[i].val.net);
220: break;
221: case data:
1.5 misho 222: case ptr:
223: /* WARNING:: remap data and ptr type to buffer! */
1.1 misho 224: val->val_type = buffer;
225: case buffer:
226: case string:
227: if (!zcpy) {
228: val->val.buffer = e_malloc(AIT_LEN(val));
229: if (!val->val.buffer) {
230: array_Free(vars);
231: array_Destroy(&vars);
232: return NULL;
233: } else
234: memcpy(val->val.buffer, dat, AIT_LEN(val));
235: } else
236: val->val.buffer = dat;
237: dat += AIT_LEN(val);
238: break;
239: default:
240: elwix_SetErr(EINVAL, "Unsupported variable type=%d at element #%d",
241: AIT_TYPE(val), i);
242: if (!zcpy)
243: array_Free(vars);
244: array_Destroy(&vars);
245: return NULL;
246: }
247: }
248:
249: return vars;
250: }
251:
252:
253: /* buffer marshaling with swapping bytes to network order */
254:
255: /*
256: * ait_vars2buffer() - Marshaling data from array with variables to buffer
257: *
258: * @buf = Buffer
259: * @buflen = Size of buffer
260: * @vars = Variable array
261: * return: -1 error, 0 nothing done or >0 size of marshaled data
262: */
1.4 misho 263: int
1.1 misho 264: ait_vars2buffer(u_char * __restrict buf, int buflen, array_t * __restrict vars)
265: {
266: return vars2buffer(buf, buflen, 42, vars);
267: }
268:
269: /*
270: * ait_buffer2vars() - De-marshaling data from buffer to array with variables
271: *
272: * @buf = Buffer
273: * @buflen = Size of buffer
274: * @vnum = Number of variables into buffer
275: * @zcpy = Zero-copy for variables, if !=0 don't use array_Free() for free variables and
276: *DON'T MODIFY OR DESTROY BUFFER*. =0 call array_Free() before array_Destroy()
277: * return: =NULL error, !=NULL allocated variable array, after use must free with array_Destroy()
278: */
1.4 misho 279: array_t *
1.1 misho 280: ait_buffer2vars(u_char * __restrict buf, int buflen, int vnum, int zcpy)
281: {
282: return buffer2vars(buf, buflen, vnum, zcpy);
283: }
284:
285: /* buffer marshaling without swapping bytes to network order */
286:
287: /*
288: * ait_vars2map() - Marshaling data from array with variables to memory map
289: *
290: * @buf = Buffer
291: * @buflen = Size of buffer
292: * @vars = Variable array
293: * return: -1 error, 0 nothing done or >0 size of marshaled data
294: */
1.4 misho 295: int
1.1 misho 296: ait_vars2map(u_char *buf, int buflen, array_t *vars)
297: {
298: return vars2buffer(buf, buflen, 0, vars);
299: }
300:
301: /*
302: * ait_map2vars() - De-marshaling data from memory map to array with variables
303: *
304: * @buf = Buffer
305: * @buflen = Size of buffer
306: * @vnum = Number of variables into buffer
307: * @zcpy = Zero-copy for variables, if !=0 don't use array_Free() for free variables and
308: *DON'T MODIFY OR DESTROY BUFFER*. =0 call array_Free() before array_Destroy()
309: * return: =NULL error, !=NULL allocated variable array, after use must free with array_Destroy()
310: */
1.4 misho 311: array_t *
1.1 misho 312: ait_map2vars(u_char *buf, int buflen, int vnum, int zcpy)
313: {
314: return buffer2vars(buf, buflen, vnum, zcpy);
315: }
316:
317:
318: /* variables array */
319:
320: /*
321: * ait_allocVars() - Allocate ait_val_t array
322: *
323: * @varnum = Number of variables
324: * return: =NULL error or !=NULL allocated array
325: */
1.4 misho 326: array_t *
1.1 misho 327: ait_allocVars(int varnum)
328: {
329: array_t *arr;
330: register int i;
331: ait_val_t *v;
332:
333: if (!(arr = array_Init(varnum)))
334: return NULL;
335:
336: for (i = 0; i < array_Size(arr); i++) {
337: if (!(v = ait_allocVar())) {
338: ait_freeVars(&arr);
339: return NULL;
340: } else
341: array_Set(arr, i, v);
342: }
343:
344: return arr;
345: }
346:
347: /*
348: * ait_getVars() - Get ait_val_t element from array and if not exists allocate it
349: *
350: * @vars = Variable array
351: * @n = index of variable into array
352: * return: NULL error or !=NULL ait_val_t element
353: */
1.4 misho 354: ait_val_t *
1.1 misho 355: ait_getVars(array_t ** __restrict vars, int n)
356: {
357: register int i;
358: ait_val_t *v;
359:
360: if (!vars)
361: return NULL;
362:
363: if (!*vars) {
364: if (!(*vars = ait_allocVars(n + 1)))
365: return NULL;
366: } else if (n >= (i = array_Size(*vars))) {
367: if (array_Grow(*vars, n + 1, 0))
368: return NULL;
369: for (; i < array_Size(*vars); i++)
370: if (!array_Get(*vars, i)) {
371: if (!(v = ait_allocVar()))
372: return NULL;
373: else
374: array_Set(*vars, i, v);
375: }
376: }
377:
378: return array(*vars, n, ait_val_t*);
379: }
380:
381: /*
382: * ait_clrVars() - Clear ait_val_t elements from array
383: *
384: * @vars = Variable array
385: * return: -1 error or size of array
386: */
1.4 misho 387: int
1.1 misho 388: ait_clrVars(array_t * __restrict vars)
389: {
390: register int i;
391: ait_val_t *v;
392:
393: if (!vars)
394: return -1;
395:
396: for (i = 0; i < array_Size(vars); i++)
397: if ((v = array(vars, i, ait_val_t*)))
398: AIT_FREE_VAL(v);
399:
400: return array_Size(vars);
401: }
402:
403: /*
404: * ait_freeVars() - Free ait_val_t array
405: *
406: * @vars = Variable array
407: * return: none
408: */
1.4 misho 409: void
1.1 misho 410: ait_freeVars(array_t ** __restrict vars)
411: {
1.6 misho 412: register int i;
413: ait_val_t *v;
414:
1.1 misho 415: if (!vars || !*vars)
416: return;
417:
1.6 misho 418: for (i = 0; i < array_Size(*vars); i++)
419: if ((v = array(*vars, i, ait_val_t*))) {
420: /* free memory if isn't zero copy */
421: if (!AIT_IN(v)) {
422: AIT_FREE_VAL(v);
423: if ((*vars)->arr_data[i])
424: e_free((*vars)->arr_data[i]);
425: } else
426: AIT_FREE_VAL(v);
427: (*vars)->arr_data[i] = NULL;
428: }
429: (*vars)->arr_last = -1;
430:
1.1 misho 431: array_Destroy(vars);
432: }
433:
1.5 misho 434: /*
435: * ait_resideVars() - Calculate footprint of resided variables into array
436: *
437: * @vars = Variable array
438: * return: bytes for whole array
439: */
440: size_t
441: ait_resideVars(array_t * __restrict vars)
442: {
443: size_t ret = 0;
444: register int i;
445:
446: if (vars) {
447: ret = array_Size(vars) * sizeof(ait_val_t);
448: for (i = 0; i < array_Size(vars); i++)
449: switch (AIT_TYPE(array(vars, i, ait_val_t*))) {
450: case buffer:
451: case string:
452: case data:
453: case ptr:
454: ret += AIT_LEN(array(vars, i, ait_val_t*));
455: break;
456: default:
457: break;
458: }
459: }
460:
461: return ret;
462: }
463:
1.1 misho 464:
465: /*
466: * ait_allocVar() - Allocate memory for variable
467: *
468: * return: NULL error or new variable, after use free variable with ait_freeVar()
469: */
1.4 misho 470: ait_val_t *
1.1 misho 471: ait_allocVar(void)
472: {
473: ait_val_t *v = NULL;
474:
475: v = e_malloc(sizeof(ait_val_t));
476: if (!v)
477: return NULL;
478: else
479: memset(v, 0, sizeof(ait_val_t));
480: v->val_type = empty;
481:
482: return v;
483: }
484:
485: /*
486: * ait_freeVar() - Free allocated memory for variable
487: *
488: * @val = Variable
489: * return: none
490: */
1.4 misho 491: void
1.1 misho 492: ait_freeVar(ait_val_t ** __restrict val)
493: {
494: if (val && *val) {
495: AIT_FREE_VAL(*val);
496: e_free(*val);
497: *val = NULL;
498: }
499: }
500:
501: /*
502: * ait_makeVar() - Allocate memory and fill variable
503: *
504: * @type = type of variable
505: * @... = arg1 is value of variable
506: * @... = arg2 is length of variabla. Not required for numbers and strings!
507: * return: NULL error or new variable, after use free variable with io_freeVar()
508: */
509: ait_val_t *
510: ait_makeVar(ait_type_t type, ...)
511: {
512: ait_val_t *v = NULL;
513: va_list lst;
514: void *p = NULL;
515: uint32_t len = 0;
516: uint64_t n = 0LL;
517:
518: v = ait_allocVar();
519: if (!v)
520: return NULL;
521:
522: va_start(lst, type);
523: switch (type) {
524: case empty:
525: v->val_type = (uint8_t) empty;
526: break;
527: case ptr:
528: p = va_arg(lst, void*);
529: len = va_arg(lst, uint32_t);
530: AIT_SET_PTR(v, p, len);
531: break;
532: case data:
533: p = va_arg(lst, void*);
534: len = va_arg(lst, uint32_t);
535: AIT_SET_DATA(v, p, len);
536: break;
537: case buffer:
538: p = va_arg(lst, void*);
539: len = va_arg(lst, uint32_t);
540: AIT_SET_BUF(v, p, len);
541: break;
542: case string:
543: p = va_arg(lst, char*);
544: AIT_SET_STR(v, (char*) p);
545: break;
546: case blob:
547: n = va_arg(lst, uint32_t);
548: len = va_arg(lst, uint32_t);
549: AIT_SET_BLOB(v, n, len);
550: break;
551: case f32:
552: AIT_SET_F32(v, (float) va_arg(lst, double));
553: break;
554: case f64:
555: AIT_SET_F64(v, va_arg(lst, double));
556: break;
557: case u8:
558: AIT_SET_U8(v, (uint8_t) va_arg(lst, int));
559: break;
560: case u16:
561: AIT_SET_U16(v, (uint16_t) va_arg(lst, int));
562: break;
563: case u32:
564: AIT_SET_U32(v, va_arg(lst, uint32_t));
565: break;
566: case u64:
567: AIT_SET_U64(v, va_arg(lst, uint64_t));
568: break;
569: case i8:
570: AIT_SET_I8(v, (int8_t) va_arg(lst, int));
571: break;
572: case i16:
573: AIT_SET_I16(v, (int16_t) va_arg(lst, int));
574: break;
575: case i32:
576: AIT_SET_I32(v, va_arg(lst, int32_t));
577: break;
578: case i64:
579: AIT_SET_I64(v, va_arg(lst, int64_t));
580: break;
581: }
582: va_end(lst);
583:
584: return v;
585: }
586:
587: static int
588: _cmp_arr_key_asc(const void *a, const void *b)
589: {
590: return AIT_KEY(*(ait_val_t**) a) - AIT_KEY(*(ait_val_t**) b);
591: }
592:
593: static int
594: _cmp_arr_key_desc(const void *a, const void *b)
595: {
596: return AIT_KEY(*(ait_val_t**) b) - AIT_KEY(*(ait_val_t**) a);
597: }
598:
599: static int
600: _cmp_arr_val_asc(const void *a, const void *b)
601: {
602: return AIT_RAW(*(ait_val_t**) a) - AIT_RAW(*(ait_val_t**) b);
603: }
604:
605: static int
606: _cmp_arr_val_desc(const void *a, const void *b)
607: {
608: return AIT_RAW(*(ait_val_t**) b) - AIT_RAW(*(ait_val_t**) a);
609: }
610:
611: /*
612: * ait_sortVarsByVal() - Sorting array with variables by value
613: *
614: * @vars = Variable array
615: * @order = Sort order. If =0 ascend or !=0 descend
616: * @cmp = Custom compare function for sorting. If =NULL compare by value
617: * return: none
618: */
1.4 misho 619: void
1.1 misho 620: ait_sortVarsByVal(array_t * __restrict vars, int order, int (*cmp)(const void*, const void*))
621: {
622: if (!vars)
623: return;
624:
625: if (cmp)
1.2 misho 626: qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), cmp);
1.1 misho 627: else if (order)
1.2 misho 628: qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_val_desc);
1.1 misho 629: else
1.2 misho 630: qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_val_asc);
1.1 misho 631: }
632:
633: /*
634: * ait_sortVarsByKey() - Sorting array with variables by key
635: *
636: * @vars = Variable array
637: * @order = Sort order. If =0 ascend or !=0 descend
638: * return: none
639: */
1.4 misho 640: void
1.1 misho 641: ait_sortVarsByKey(array_t * __restrict vars, int order)
642: {
643: if (!vars)
644: return;
645:
646: if (order)
1.2 misho 647: qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_key_desc);
1.1 misho 648: else
1.2 misho 649: qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_key_asc);
1.1 misho 650: }
651:
652: /*
653: * ait_findKeyVars() - Find variable by key from array
654: *
655: * @vars = Variables
656: * @key = Search key
657: * return: NULL error or not found, !=NULL valid element
658: */
659: ait_val_t *
660: ait_findKeyVars(array_t * __restrict vars, u_short key)
661: {
662: array_t *tmp;
663: ait_val_t **vv, *v = NULL;
664: register int i;
665: const u_char *p;
666:
667: if (!vars)
668: return NULL;
669:
670: if (array_Copy(&tmp, vars) == -1)
671: return NULL;
672: else
1.2 misho 673: qsort(tmp->arr_data, tmp->arr_num, sizeof(uintptr_t), _cmp_arr_key_asc);
1.1 misho 674:
675: /* binary search */
676: for (p = (const u_char*) tmp->arr_data, i = array_Size(tmp); i; i >>= 1) {
1.2 misho 677: vv = (ait_val_t**) (p + (i >> 1) * sizeof(uintptr_t));
1.1 misho 678: if (!(key - AIT_KEY(*vv))) { /* found! */
679: v = *vv;
680: break;
681: }
682: if ((key - AIT_KEY(*vv)) > 0) { /* move right key > current */
1.2 misho 683: p = (const u_char*) vv + sizeof(uintptr_t);
1.1 misho 684: i--;
685: } /* else move left */
686: }
687:
688: array_Destroy(&tmp);
689: return v;
690: }
691:
692: /*
693: * ait_hashVar() - Generate hash key for variable from string or value
694: *
695: * @v = variable
696: * @key = key string for hash, if =NULL hash will built from variable
697: * return: hash key
698: */
699: u_short
700: ait_hashVar(ait_val_t * __restrict v, const char * __restrict key)
701: {
702: void *p;
703: u_short cksum;
704: int l;
705:
706: if (!v)
707: return 0;
708:
709: if (key) {
710: p = (void*) key;
711: l = (strlen(key) + 1) / 2;
712: } else {
713: switch (AIT_TYPE(v)) {
714: case empty:
715: AIT_KEY(v) = 0;
716: return 0;
717: case string:
718: case buffer:
719: p = AIT_ADDR(v);
720: l = AIT_LEN(v) / 2;
721: break;
722: case data:
723: p = v->val_data;
724: l = AIT_LEN(v) / 2;
725: break;
726: default:
727: p = &AIT_RAW(v);
728: l = sizeof AIT_RAW(v) / 2;
729: break;
730: }
731: }
732:
733: cksum = crcFletcher16((u_short*) p, l);
734:
735: if (AIT_BE(v))
736: AIT_KEY(v) = htobe16(cksum);
737: else if (AIT_LE(v))
738: AIT_KEY(v) = htole16(cksum);
739: else
740: AIT_KEY(v) = cksum;
741:
742: return AIT_KEY(v);
743: }
744:
745: /*
746: * ait_hashKeyVars() - Generate hash keys for variables
747: *
748: * @vars = Variables
749: * return -1 error or 0 ok
750: */
1.4 misho 751: int
1.1 misho 752: ait_hashKeyVars(array_t * __restrict vars)
753: {
754: register int i;
755:
756: if (!vars)
757: return -1;
758:
759: for (i = 0; i < array_Size(vars); i++)
760: ait_hashVar(array(vars, i, ait_val_t*), NULL);
761:
762: return 0;
763: }
764:
765: /*
766: * ait_findKeyHash() - Find variable by hash string from array
767: *
768: * @vars = Variables
769: * @key = Search string
770: * return: NULL error or not found, !=NULL valid element
771: */
1.4 misho 772: ait_val_t *
1.1 misho 773: ait_findKeyHash(array_t * __restrict vars, const char * __restrict key)
774: {
775: u_short k = 0;
776:
777: if (!vars || !key)
778: return NULL;
779:
780: k = crcFletcher16((u_short*) key, (strlen(key) + 1) / 2);
781: return ait_findKeyVars(vars, k);
782: }
783:
784: /*
785: * ait_sprintfVar() - Builtin string variable from formatted input
786: *
787: * @v = variable
788: * @fmt = format string
789: * @... = argument(s)
790: * return: -1 error or >0 copied bytes to variable
791: */
792: int
1.2 misho 793: ait_sprintfVar(ait_val_t * __restrict v, const char *fmt, ...)
1.1 misho 794: {
795: int ret = 0;
796: va_list lst;
1.8.4.1 ! misho 797: char str[STRSIZ] = { [0 ... STRSIZ - 1] = 0 };
1.1 misho 798:
799: if (!v || !fmt)
800: return -1;
801:
802: va_start(lst, fmt);
1.8.4.1 ! misho 803: ret = vsnprintf(str, sizeof str - 1, fmt, lst);
1.1 misho 804: va_end(lst);
805:
1.8.4.1 ! misho 806: if (ret > -1) {
1.1 misho 807: AIT_FREE_VAL(v);
808: AIT_SET_STR(v, str);
809: } else
810: LOGERR;
811:
812: return ret;
813: }
814:
815: /*
816: * ait_setlikeVar() - Set variable like ...
817: *
818: * @v = variable
819: * @t = type of data
820: * @l = length of data
821: * @... = data
822: * return: -1 error or 0 ok
823: */
1.4 misho 824: int
1.1 misho 825: ait_setlikeVar(ait_val_t * __restrict v, ait_type_t t, u_int l, ...)
826: {
827: va_list lst;
828:
829: if (!v)
830: return -1;
831:
832: AIT_FREE_VAL(v);
833: AIT_INIT_VAL2(v, t);
834: AIT_LEN(v) = l;
835: AIT_IN(v) = 1;
836:
837: va_start(lst, l);
838: switch (AIT_TYPE(v)) {
839: case ptr:
840: case buffer:
841: case string:
842: AIT_ADDR(v) = va_arg(lst, void*);
843: break;
844: default:
845: AIT_RAW(v) = va_arg(lst, uint64_t);
846: break;
847: }
848: va_end(lst);
849:
850: return 0;
851: }
852:
853: /*
854: * ait_getlikeVar() - Get variable like ...
855: *
856: * @v = variable
857: * return: return raw data
858: */
1.4 misho 859: uint64_t
1.1 misho 860: ait_getlikeVar(ait_val_t * __restrict v)
861: {
862: if (!v)
863: return (uintptr_t) -1;
864:
865: return AIT_RAW(v);
866: }
867:
868: /*
869: * ait_cmpVar() - Compare two variables
870: *
871: * @a = 1st variable
872: * @b = 2nd variable
873: * return: 0 is equal or !=0 is different
874: */
1.4 misho 875: int
1.1 misho 876: ait_cmpVar(ait_val_t * __restrict a, ait_val_t * __restrict b)
877: {
878: intptr_t ret;
879:
880: if (!(ret = (a - b)))
881: return ret;
882: if ((ret = AIT_TYPE(a) - AIT_TYPE(b)))
883: return ret;
884: if ((ret = AIT_LEN(a) - AIT_LEN(b)))
885: return ret;
886:
887: switch (AIT_TYPE(a)) {
888: case buffer:
889: ret = memcmp(AIT_GET_BUF(a), AIT_GET_BUF(b), AIT_LEN(a));
890: break;
891: case string:
892: ret = strncmp(AIT_GET_STR(a), AIT_GET_STR(b), AIT_LEN(a));
893: break;
894: case data:
895: ret = memcmp(AIT_GET_DATA(a), AIT_GET_DATA(b), AIT_LEN(a));
896: break;
897: case ptr:
898: ret = AIT_ADDR(a) - AIT_ADDR(b);
899: break;
900: default:
901: ret = AIT_RAW(a) - AIT_RAW(b);
902: break;
903: }
904:
905: return (int) ret;
906: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>