Annotation of libaitio/src/vars.c, revision 1.1.2.6
1.1.2.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.1.2.6 ! misho 6: * $Id: vars.c,v 1.1.2.5 2011/09/07 01:26:08 misho Exp $
1.1.2.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
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.1.2.2 misho 49: /*
50: * io_vals2buffer() Marshaling data from array with variables to buffer
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.1.2.3 misho 57: io_vals2buffer(u_char *buf, int buflen, array_t *vars)
1.1.2.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);
1.1.2.3 misho 66: if (!buf || !vars)
1.1.2.2 misho 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 {
1.1.2.3 misho 77: memset(buf, 0, buflen);
1.1.2.2 misho 78:
1.1.2.3 misho 79: v = (ait_val_t*) buf;
80: data = buf + Limit;
1.1.2.2 misho 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! */
1.1.2.3 misho 115: v[i].val.net = data - buf;
1.1.2.2 misho 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: /*
129: * io_buffer2vals() De-marshaling data from buffer to array with variables
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 *
138: io_buffer2vals(u_char *buf, int buflen, int vnum, int zcpy)
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;
1.1.2.5 misho 178: #if defined(__OpenBSD__)
1.1.2.2 misho 179: AIT_LEN(val) = betoh32(AIT_LEN(&v[i]));
1.1.2.5 misho 180: #else
181: AIT_LEN(val) = be32toh(AIT_LEN(&v[i]));
182: #endif
1.1.2.2 misho 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:
1.1.2.5 misho 196: #if defined(__OpenBSD__)
1.1.2.2 misho 197: val->val.net = betoh64(v[i].val.net);
1.1.2.5 misho 198: #else
199: val->val.net = be64toh(v[i].val.net);
200: #endif
1.1.2.2 misho 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:
1.1.2.4 misho 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
1.1.2.2 misho 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: }
1.1.2.6 ! misho 239:
! 240: /* buffer marshaling without swapping bytes to network order */
! 241:
! 242: /*
! 243: * io_vals2map() Marshaling data from array with variables to memory map
! 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
! 250: io_vals2map(u_char *buf, int buflen, array_t *vars)
! 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: /*
! 322: * io_map2vals() De-marshaling data from memory map to array with variables
! 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 *
! 331: io_map2vals(u_char *buf, int buflen, int vnum, int zcpy)
! 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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>