Annotation of libaitio/src/vars.c, revision 1.4.4.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.4.4.3 ! misho 6: * $Id: vars.c,v 1.4.4.2 2012/03/27 21:37: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.4.4.1 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:
49: /*
1.3 misho 50: * io_vars2buffer() Marshaling data from array with variables to buffer
1.4.4.2 misho 51: *
1.2 misho 52: * @buf = Buffer
53: * @buflen = Size of buffer
54: * @vars = Variable array
55: * return: -1 error, 0 nothing done or >0 size of marshaled data
56: */
57: int
1.3 misho 58: io_vars2buffer(u_char *buf, int buflen, array_t *vars)
1.2 misho 59: {
60: int Limit = 0;
61: register int i;
62: ait_val_t *v, *val;
63: u_char *data;
64:
65: assert(buf);
66: assert(vars);
67: if (!buf || !vars)
68: return -1;
69: if (!buflen || !io_arraySize(vars))
70: return 0;
71:
72: Limit = sizeof(ait_val_t) * io_arraySize(vars);
73: if (Limit > buflen) {
74: io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n",
75: buflen, Limit);
76: return -1;
77: } else {
78: memset(buf, 0, buflen);
79:
80: v = (ait_val_t*) buf;
81: data = buf + Limit;
82: }
83:
84: /* marshaling */
85: for (i = 0; i < io_arraySize(vars); i++) {
86: val = io_array(vars, i, ait_val_t*);
87:
88: v[i].val_type = val->val_type;
1.4.4.2 misho 89: AIT_HASH(&v[i]) = htobe16(AIT_HASH(val));
1.2 misho 90: AIT_LEN(&v[i]) = htobe32(AIT_LEN(val));
91:
92: switch (AIT_TYPE(val)) {
93: case blob:
94: case f32:
95: case f64:
96: case i8:
97: case i16:
98: case i32:
99: case i64:
100: case u8:
101: case u16:
102: case u32:
103: case u64:
104: v[i].val.net = htobe64(val->val.net);
105: break;
106: case buffer:
107: case string:
108: if (AIT_LEN(val) > buflen - Limit) {
109: io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d "
110: "needed min %d ...\n", buflen, Limit + AIT_LEN(val));
111: return -1;
112: } else
113: Limit += AIT_LEN(val);
114:
115: memcpy(data, val->val.buffer, AIT_LEN(val));
116: /* Debug:: data offset in packet, not matter for anything! */
117: v[i].val.net = data - buf;
118: data += AIT_LEN(val);
119: break;
120: default:
121: io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n",
122: AIT_TYPE(val), i);
123: return -1;
124: }
125: }
126:
127: return Limit;
128: }
129:
130: /*
1.3 misho 131: * io_buffer2vars() De-marshaling data from buffer to array with variables
1.4.4.2 misho 132: *
1.2 misho 133: * @buf = Buffer
134: * @buflen = Size of buffer
135: * @vnum = Number of variables into buffer
136: * @zcpy = Zero-copy for variables, if !=0 don't use io_arrayFree() for free variables and
137: *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy()
138: * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy()
139: */
140: array_t *
1.3 misho 141: io_buffer2vars(u_char *buf, int buflen, int vnum, int zcpy)
1.2 misho 142: {
143: array_t *vars;
144: int Limit = 0;
145: register int i;
146: ait_val_t *v, *val;
147: u_char *data;
148:
149: assert(buf);
150: if (!buf || !buflen || !vnum)
151: return NULL;
152:
153: Limit = sizeof(ait_val_t) * vnum;
154: if (Limit > buflen) {
155: io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n",
156: buflen, Limit);
157: return NULL;
158: } else {
159: if (!(vars = io_arrayInit(vnum)))
160: return NULL;
161:
162: v = (ait_val_t*) buf;
163: data = buf + Limit;
164: }
165:
166: /* de-marshaling */
167: for (i = 0; i < io_arraySize(vars); i++) {
168: if (!zcpy) {
169: val = malloc(sizeof(ait_val_t));
170: if (!val) {
171: LOGERR;
172: io_arrayFree(vars);
173: io_arrayDestroy(&vars);
174: return NULL;
175: }
176: } else
177: val = v + i;
178: io_arraySet(vars, i, val);
179:
180: val->val_type = v[i].val_type;
181: #if defined(__OpenBSD__)
182: AIT_LEN(val) = betoh32(AIT_LEN(&v[i]));
1.4.4.2 misho 183: AIT_HASH(val) = betoh16(AIT_HASH(&v[i]));
1.2 misho 184: #else
185: AIT_LEN(val) = be32toh(AIT_LEN(&v[i]));
1.4.4.2 misho 186: AIT_HASH(val) = be16toh(AIT_HASH(&v[i]));
1.2 misho 187: #endif
188:
189: switch (AIT_TYPE(val)) {
190: case blob:
191: case f32:
192: case f64:
193: case i8:
194: case i16:
195: case i32:
196: case i64:
197: case u8:
198: case u16:
199: case u32:
200: case u64:
201: #if defined(__OpenBSD__)
202: val->val.net = betoh64(v[i].val.net);
203: #else
204: val->val.net = be64toh(v[i].val.net);
205: #endif
206: break;
207: case buffer:
208: case string:
209: if (AIT_LEN(val) > buflen - Limit) {
210: io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d "
211: "needed min %d ...\n", buflen, Limit + AIT_LEN(val));
212: if (!zcpy)
213: io_arrayFree(vars);
214: io_arrayDestroy(&vars);
215: return NULL;
216: } else
217: Limit += AIT_LEN(val);
218:
219: if (!zcpy) {
220: val->val.buffer = malloc(AIT_LEN(val));
221: if (!val->val.buffer) {
222: LOGERR;
223: io_arrayFree(vars);
224: io_arrayDestroy(&vars);
225: return NULL;
226: } else
227: memcpy(val->val.buffer, data, AIT_LEN(val));
228: } else
229: val->val.buffer = data;
230: data += AIT_LEN(val);
231: break;
232: default:
233: io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n",
234: AIT_TYPE(val), i);
235: if (!zcpy)
236: io_arrayFree(vars);
237: io_arrayDestroy(&vars);
238: return NULL;
239: }
240: }
241:
242: return vars;
243: }
244:
245: /* buffer marshaling without swapping bytes to network order */
246:
247: /*
1.3 misho 248: * io_vars2map() Marshaling data from array with variables to memory map
1.4.4.2 misho 249: *
1.2 misho 250: * @buf = Buffer
251: * @buflen = Size of buffer
252: * @vars = Variable array
253: * return: -1 error, 0 nothing done or >0 size of marshaled data
254: */
255: int
1.3 misho 256: io_vars2map(u_char *buf, int buflen, array_t *vars)
1.2 misho 257: {
258: int Limit = 0;
259: register int i;
260: ait_val_t *v, *val;
261: u_char *data;
262:
263: assert(buf);
264: assert(vars);
265: if (!buf || !vars)
266: return -1;
267: if (!buflen || !io_arraySize(vars))
268: return 0;
269:
270: Limit = sizeof(ait_val_t) * io_arraySize(vars);
271: if (Limit > buflen) {
272: io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n",
273: buflen, Limit);
274: return -1;
275: } else {
276: memset(buf, 0, buflen);
277:
278: v = (ait_val_t*) buf;
279: data = buf + Limit;
280: }
281:
282: /* marshaling */
283: for (i = 0; i < io_arraySize(vars); i++) {
284: val = io_array(vars, i, ait_val_t*);
285:
286: v[i].val_type = val->val_type;
1.4.4.2 misho 287: AIT_HASH(&v[i]) = AIT_HASH(val);
1.2 misho 288: AIT_LEN(&v[i]) = AIT_LEN(val);
289:
290: switch (AIT_TYPE(val)) {
291: case blob:
292: case f32:
293: case f64:
294: case i8:
295: case i16:
296: case i32:
297: case i64:
298: case u8:
299: case u16:
300: case u32:
301: case u64:
302: v[i].val.net = val->val.net;
303: break;
304: case buffer:
305: case string:
306: if (AIT_LEN(val) > buflen - Limit) {
307: io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d "
308: "needed min %d ...\n", buflen, Limit + AIT_LEN(val));
309: return -1;
310: } else
311: Limit += AIT_LEN(val);
312:
313: memcpy(data, val->val.buffer, AIT_LEN(val));
314: /* Debug:: data offset in packet, not matter for anything! */
315: v[i].val.net = data - buf;
316: data += AIT_LEN(val);
317: break;
318: default:
319: io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n",
320: AIT_TYPE(val), i);
321: return -1;
322: }
323: }
324:
325: return Limit;
326: }
327:
328: /*
1.3 misho 329: * io_map2vars() De-marshaling data from memory map to array with variables
1.4.4.2 misho 330: *
1.2 misho 331: * @buf = Buffer
332: * @buflen = Size of buffer
333: * @vnum = Number of variables into buffer
334: * @zcpy = Zero-copy for variables, if !=0 don't use io_arrayFree() for free variables and
335: *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy()
336: * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy()
337: */
338: array_t *
1.3 misho 339: io_map2vars(u_char *buf, int buflen, int vnum, int zcpy)
1.2 misho 340: {
341: array_t *vars;
342: int Limit = 0;
343: register int i;
344: ait_val_t *v, *val;
345: u_char *data;
346:
347: assert(buf);
348: if (!buf || !buflen || !vnum)
349: return NULL;
350:
351: Limit = sizeof(ait_val_t) * vnum;
352: if (Limit > buflen) {
353: io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n",
354: buflen, Limit);
355: return NULL;
356: } else {
357: if (!(vars = io_arrayInit(vnum)))
358: return NULL;
359:
360: v = (ait_val_t*) buf;
361: data = buf + Limit;
362: }
363:
364: /* de-marshaling */
365: for (i = 0; i < io_arraySize(vars); i++) {
366: if (!zcpy) {
367: val = malloc(sizeof(ait_val_t));
368: if (!val) {
369: LOGERR;
370: io_arrayFree(vars);
371: io_arrayDestroy(&vars);
372: return NULL;
373: }
374: } else
375: val = v + i;
376: io_arraySet(vars, i, val);
377:
378: val->val_type = v[i].val_type;
1.4.4.2 misho 379: AIT_HASH(val) = AIT_HASH(&v[i]);
1.2 misho 380: AIT_LEN(val) = AIT_LEN(&v[i]);
381:
382: switch (AIT_TYPE(val)) {
383: case blob:
384: case f32:
385: case f64:
386: case i8:
387: case i16:
388: case i32:
389: case i64:
390: case u8:
391: case u16:
392: case u32:
393: case u64:
394: val->val.net = v[i].val.net;
395: break;
396: case buffer:
397: case string:
398: if (AIT_LEN(val) > buflen - Limit) {
399: io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d "
400: "needed min %d ...\n", buflen, Limit + AIT_LEN(val));
401: if (!zcpy)
402: io_arrayFree(vars);
403: io_arrayDestroy(&vars);
404: return NULL;
405: } else
406: Limit += AIT_LEN(val);
407:
408: if (!zcpy) {
409: val->val.buffer = malloc(AIT_LEN(val));
410: if (!val->val.buffer) {
411: LOGERR;
412: io_arrayFree(vars);
413: io_arrayDestroy(&vars);
414: return NULL;
415: } else
416: memcpy(val->val.buffer, data, AIT_LEN(val));
417: } else
418: val->val.buffer = data;
419: data += AIT_LEN(val);
420: break;
421: default:
422: io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n",
423: AIT_TYPE(val), i);
424: if (!zcpy)
425: io_arrayFree(vars);
426: io_arrayDestroy(&vars);
427: return NULL;
428: }
429: }
430:
431: return vars;
432: }
1.3 misho 433:
434:
435: /*
436: * io_allocVars() Allocate ait_val_t array
1.4.4.2 misho 437: *
1.3 misho 438: * @varnum = Number of variables
439: * return: =NULL error or !=NULL allocated array
440: */
441: inline array_t *
442: io_allocVars(int varnum)
443: {
444: array_t *arr;
445: register int i;
446: ait_val_t *v;
447:
448: if (!varnum || !(arr = io_arrayInit(varnum)))
449: return NULL;
450:
451: for (i = 0; i < io_arraySize(arr); i++) {
452: v = malloc(sizeof(ait_val_t));
453: if (!v) {
454: LOGERR;
455: io_freeVars(&arr);
456: return NULL;
457: } else {
458: memset(v, 0, sizeof(ait_val_t));
459: io_arraySet(arr, i, v);
460: }
461: }
462:
463: return arr;
464: }
465:
466: /*
467: * io_clrVars() Clear ait_val_t elements from array
1.4.4.2 misho 468: *
1.3 misho 469: * @vars = Variable array
470: * return: -1 error or size of array
471: */
472: inline int
473: io_clrVars(array_t * __restrict vars)
474: {
475: register int i;
1.4.4.3 ! misho 476: ait_val_t *v;
1.3 misho 477:
478: if (!vars)
479: return -1;
480:
481: for (i = 0; i < io_arraySize(vars); i++)
1.4.4.3 ! misho 482: if ((v = io_array(vars, i, ait_val_t*)))
! 483: AIT_FREE_VAL(v);
1.3 misho 484:
485: return io_arraySize(vars);
486: }
487:
488: /*
489: * io_freeVars() Free ait_val_t array
1.4.4.2 misho 490: *
1.3 misho 491: * @vars = Variable array
492: * return: none
493: */
494: inline void
495: io_freeVars(array_t ** __restrict vars)
496: {
497: if (!vars || !*vars)
498: return;
499:
500: io_clrVars(*vars);
501: io_arrayFree(*vars);
502: io_arrayDestroy(vars);
503: }
1.4 misho 504:
505: /*
506: * io_allocVar() Allocate memory for variable
1.4.4.2 misho 507: *
1.4 misho 508: * return: NULL error or new variable, after use free variable with io_freeVar()
509: */
510: inline ait_val_t *
511: io_allocVar(void)
512: {
513: ait_val_t *v = NULL;
514:
515: v = malloc(sizeof(ait_val_t));
516: if (!v) {
517: LOGERR;
518: return NULL;
519: } else
520: memset(v, 0, sizeof(ait_val_t));
521: v->val_type = empty;
522:
523: return v;
524: }
525:
526: /*
527: * io_freeVar() Free allocated memory for variable
1.4.4.2 misho 528: *
1.4 misho 529: * @val = Variable
530: * return: none
531: */
532: inline void
533: io_freeVar(ait_val_t * __restrict val)
534: {
535: if (val) {
536: AIT_FREE_VAL(val);
537: free(val);
538: val = NULL;
539: }
540: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>