Annotation of libaitio/src/vars.c, revision 1.2
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 $
! 6: * $Id: vars.c,v 1.1.2.6 2011/09/07 13:49:28 misho Exp $
! 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: /*
! 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
! 57: io_vals2buffer(u_char *buf, int buflen, array_t *vars)
! 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: /*
! 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;
! 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: /*
! 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>