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