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