File:  [ELWIX - Embedded LightWeight unIX -] / libaitio / src / Attic / vars.c
Revision 1.4: download - view: text, annotated - select for diffs - revision graph
Thu Feb 2 21:32:42 2012 UTC (12 years, 5 months ago) by misho
Branches: MAIN
CVS tags: io2_5, io2_4, IO2_4, IO2_3, HEAD
version 2.3
added feature for bufio

    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.4 2012/02/02 21:32:42 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_vars2buffer() 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_vars2buffer(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_buffer2vars() 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_buffer2vars(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_vars2map() 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_vars2map(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_map2vars() 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_map2vars(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: }
  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: }
  491: 
  492: /*
  493:  * io_allocVar() Allocate memory for variable
  494:  * return: NULL error or new variable, after use free variable with io_freeVar()
  495:  */
  496: inline ait_val_t *
  497: io_allocVar(void)
  498: {
  499: 	ait_val_t *v = NULL;
  500: 
  501: 	v = malloc(sizeof(ait_val_t));
  502: 	if (!v) {
  503: 		LOGERR;
  504: 		return NULL;
  505: 	} else
  506: 		memset(v, 0, sizeof(ait_val_t));
  507: 	v->val_type = empty;
  508: 
  509: 	return v;
  510: }
  511: 
  512: /*
  513:  * io_freeVar() Free allocated memory for variable
  514:  * @val = Variable
  515:  * return: none
  516:  */
  517: inline void
  518: io_freeVar(ait_val_t * __restrict val)
  519: {
  520: 	if (val) {
  521: 		AIT_FREE_VAL(val);
  522: 		free(val);
  523: 		val = NULL;
  524: 	}
  525: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>