--- libaitio/src/Attic/vars.c 2011/12/13 10:40:05 1.3.2.1 +++ libaitio/src/Attic/vars.c 2012/05/14 12:49:21 1.6 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: vars.c,v 1.3.2.1 2011/12/13 10:40:05 misho Exp $ +* $Id: vars.c,v 1.6 2012/05/14 12:49:21 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 +Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -47,7 +47,8 @@ SUCH DAMAGE. /* - * io_vars2buffer() Marshaling data from array with variables to buffer + * io_vars2buffer() - Marshaling data from array with variables to buffer + * * @buf = Buffer * @buflen = Size of buffer * @vars = Variable array @@ -59,7 +60,7 @@ io_vars2buffer(u_char *buf, int buflen, array_t *vars) int Limit = 0; register int i; ait_val_t *v, *val; - u_char *data; + u_char *dat; assert(buf); assert(vars); @@ -70,14 +71,14 @@ io_vars2buffer(u_char *buf, int buflen, array_t *vars) Limit = sizeof(ait_val_t) * io_arraySize(vars); if (Limit > buflen) { - io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n", + io_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", buflen, Limit); return -1; } else { memset(buf, 0, buflen); v = (ait_val_t*) buf; - data = buf + Limit; + dat = buf + Limit; } /* marshaling */ @@ -85,6 +86,7 @@ io_vars2buffer(u_char *buf, int buflen, array_t *vars) val = io_array(vars, i, ait_val_t*); v[i].val_type = val->val_type; + AIT_KEY(&v[i]) = htobe16(AIT_KEY(val)); AIT_LEN(&v[i]) = htobe32(AIT_LEN(val)); switch (AIT_TYPE(val)) { @@ -101,22 +103,35 @@ io_vars2buffer(u_char *buf, int buflen, array_t *vars) case u64: v[i].val.net = htobe64(val->val.net); break; + case data: + if (AIT_LEN(val) > buflen - Limit) { + io_SetErr(EMSGSIZE, "Short buffer buflen=%d " + "needed min %d", buflen, Limit + AIT_LEN(val)); + return -1; + } else + Limit += AIT_LEN(val); + + memcpy(dat, val->val_data, AIT_LEN(val)); + /* Debug:: data offset in packet, not matter for anything! */ + v[i].val.net = dat - buf; + dat += AIT_LEN(val); + break; case buffer: case string: if (AIT_LEN(val) > buflen - Limit) { - io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d " - "needed min %d ...\n", buflen, Limit + AIT_LEN(val)); + io_SetErr(EMSGSIZE, "Short buffer buflen=%d " + "needed min %d", buflen, Limit + AIT_LEN(val)); return -1; } else Limit += AIT_LEN(val); - memcpy(data, val->val.buffer, AIT_LEN(val)); + memcpy(dat, val->val.buffer, AIT_LEN(val)); /* Debug:: data offset in packet, not matter for anything! */ - v[i].val.net = data - buf; - data += AIT_LEN(val); + v[i].val.net = dat - buf; + dat += AIT_LEN(val); break; default: - io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n", + io_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", AIT_TYPE(val), i); return -1; } @@ -126,7 +141,8 @@ io_vars2buffer(u_char *buf, int buflen, array_t *vars) } /* - * io_buffer2vars() De-marshaling data from buffer to array with variables + * io_buffer2vars() - De-marshaling data from buffer to array with variables + * * @buf = Buffer * @buflen = Size of buffer * @vnum = Number of variables into buffer @@ -141,7 +157,7 @@ io_buffer2vars(u_char *buf, int buflen, int vnum, int int Limit = 0; register int i; ait_val_t *v, *val; - u_char *data; + u_char *dat; assert(buf); if (!buf || !buflen || !vnum) @@ -149,7 +165,7 @@ io_buffer2vars(u_char *buf, int buflen, int vnum, int Limit = sizeof(ait_val_t) * vnum; if (Limit > buflen) { - io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n", + io_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", buflen, Limit); return NULL; } else { @@ -157,7 +173,7 @@ io_buffer2vars(u_char *buf, int buflen, int vnum, int return NULL; v = (ait_val_t*) buf; - data = buf + Limit; + dat = buf + Limit; } /* de-marshaling */ @@ -177,8 +193,10 @@ io_buffer2vars(u_char *buf, int buflen, int vnum, int val->val_type = v[i].val_type; #if defined(__OpenBSD__) AIT_LEN(val) = betoh32(AIT_LEN(&v[i])); + AIT_KEY(val) = betoh16(AIT_KEY(&v[i])); #else AIT_LEN(val) = be32toh(AIT_LEN(&v[i])); + AIT_KEY(val) = be16toh(AIT_KEY(&v[i])); #endif switch (AIT_TYPE(val)) { @@ -199,11 +217,14 @@ io_buffer2vars(u_char *buf, int buflen, int vnum, int val->val.net = be64toh(v[i].val.net); #endif break; + case data: + /* WARNING:: remap data type to buffer */ + val->val_type = buffer; case buffer: case string: if (AIT_LEN(val) > buflen - Limit) { - io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d " - "needed min %d ...\n", buflen, Limit + AIT_LEN(val)); + io_SetErr(EMSGSIZE, "Short buffer buflen=%d " + "needed min %d", buflen, Limit + AIT_LEN(val)); if (!zcpy) io_arrayFree(vars); io_arrayDestroy(&vars); @@ -219,13 +240,13 @@ io_buffer2vars(u_char *buf, int buflen, int vnum, int io_arrayDestroy(&vars); return NULL; } else - memcpy(val->val.buffer, data, AIT_LEN(val)); + memcpy(val->val.buffer, dat, AIT_LEN(val)); } else - val->val.buffer = data; - data += AIT_LEN(val); + val->val.buffer = dat; + dat += AIT_LEN(val); break; default: - io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n", + io_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", AIT_TYPE(val), i); if (!zcpy) io_arrayFree(vars); @@ -240,7 +261,8 @@ io_buffer2vars(u_char *buf, int buflen, int vnum, int /* buffer marshaling without swapping bytes to network order */ /* - * io_vars2map() Marshaling data from array with variables to memory map + * io_vars2map() - Marshaling data from array with variables to memory map + * * @buf = Buffer * @buflen = Size of buffer * @vars = Variable array @@ -252,7 +274,7 @@ io_vars2map(u_char *buf, int buflen, array_t *vars) int Limit = 0; register int i; ait_val_t *v, *val; - u_char *data; + u_char *dat; assert(buf); assert(vars); @@ -263,14 +285,14 @@ io_vars2map(u_char *buf, int buflen, array_t *vars) Limit = sizeof(ait_val_t) * io_arraySize(vars); if (Limit > buflen) { - io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n", + io_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", buflen, Limit); return -1; } else { memset(buf, 0, buflen); v = (ait_val_t*) buf; - data = buf + Limit; + dat = buf + Limit; } /* marshaling */ @@ -278,6 +300,7 @@ io_vars2map(u_char *buf, int buflen, array_t *vars) val = io_array(vars, i, ait_val_t*); v[i].val_type = val->val_type; + AIT_KEY(&v[i]) = AIT_KEY(val); AIT_LEN(&v[i]) = AIT_LEN(val); switch (AIT_TYPE(val)) { @@ -294,22 +317,35 @@ io_vars2map(u_char *buf, int buflen, array_t *vars) case u64: v[i].val.net = val->val.net; break; + case data: + if (AIT_LEN(val) > buflen - Limit) { + io_SetErr(EMSGSIZE, "Short buffer buflen=%d " + "needed min %d", buflen, Limit + AIT_LEN(val)); + return -1; + } else + Limit += AIT_LEN(val); + + memcpy(dat, val->val_data, AIT_LEN(val)); + /* Debug:: data offset in packet, not matter for anything! */ + v[i].val.net = dat - buf; + dat += AIT_LEN(val); + break; case buffer: case string: if (AIT_LEN(val) > buflen - Limit) { - io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d " - "needed min %d ...\n", buflen, Limit + AIT_LEN(val)); + io_SetErr(EMSGSIZE, "Short buffer buflen=%d " + "needed min %d", buflen, Limit + AIT_LEN(val)); return -1; } else Limit += AIT_LEN(val); - memcpy(data, val->val.buffer, AIT_LEN(val)); + memcpy(dat, val->val.buffer, AIT_LEN(val)); /* Debug:: data offset in packet, not matter for anything! */ - v[i].val.net = data - buf; - data += AIT_LEN(val); + v[i].val.net = dat - buf; + dat += AIT_LEN(val); break; default: - io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n", + io_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", AIT_TYPE(val), i); return -1; } @@ -319,7 +355,8 @@ io_vars2map(u_char *buf, int buflen, array_t *vars) } /* - * io_map2vars() De-marshaling data from memory map to array with variables + * io_map2vars() - De-marshaling data from memory map to array with variables + * * @buf = Buffer * @buflen = Size of buffer * @vnum = Number of variables into buffer @@ -334,7 +371,7 @@ io_map2vars(u_char *buf, int buflen, int vnum, int zcp int Limit = 0; register int i; ait_val_t *v, *val; - u_char *data; + u_char *dat; assert(buf); if (!buf || !buflen || !vnum) @@ -342,7 +379,7 @@ io_map2vars(u_char *buf, int buflen, int vnum, int zcp Limit = sizeof(ait_val_t) * vnum; if (Limit > buflen) { - io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n", + io_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", buflen, Limit); return NULL; } else { @@ -350,7 +387,7 @@ io_map2vars(u_char *buf, int buflen, int vnum, int zcp return NULL; v = (ait_val_t*) buf; - data = buf + Limit; + dat = buf + Limit; } /* de-marshaling */ @@ -368,6 +405,7 @@ io_map2vars(u_char *buf, int buflen, int vnum, int zcp io_arraySet(vars, i, val); val->val_type = v[i].val_type; + AIT_KEY(val) = AIT_KEY(&v[i]); AIT_LEN(val) = AIT_LEN(&v[i]); switch (AIT_TYPE(val)) { @@ -384,11 +422,14 @@ io_map2vars(u_char *buf, int buflen, int vnum, int zcp case u64: val->val.net = v[i].val.net; break; + case data: + /* WARNING:: remap data type to buffer */ + val->val_type = buffer; case buffer: case string: if (AIT_LEN(val) > buflen - Limit) { - io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d " - "needed min %d ...\n", buflen, Limit + AIT_LEN(val)); + io_SetErr(EMSGSIZE, "short buffer buflen=%d " + "needed min %d", buflen, Limit + AIT_LEN(val)); if (!zcpy) io_arrayFree(vars); io_arrayDestroy(&vars); @@ -404,13 +445,13 @@ io_map2vars(u_char *buf, int buflen, int vnum, int zcp io_arrayDestroy(&vars); return NULL; } else - memcpy(val->val.buffer, data, AIT_LEN(val)); + memcpy(val->val.buffer, dat, AIT_LEN(val)); } else - val->val.buffer = data; - data += AIT_LEN(val); + val->val.buffer = dat; + dat += AIT_LEN(val); break; default: - io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n", + io_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", AIT_TYPE(val), i); if (!zcpy) io_arrayFree(vars); @@ -424,7 +465,8 @@ io_map2vars(u_char *buf, int buflen, int vnum, int zcp /* - * io_allocVars() Allocate ait_val_t array + * io_allocVars() - Allocate ait_val_t array + * * @varnum = Number of variables * return: =NULL error or !=NULL allocated array */ @@ -439,22 +481,19 @@ io_allocVars(int varnum) return NULL; for (i = 0; i < io_arraySize(arr); i++) { - v = malloc(sizeof(ait_val_t)); - if (!v) { - LOGERR; + if (!(v = io_allocVar())) { io_freeVars(&arr); return NULL; - } else { - memset(v, 0, sizeof(ait_val_t)); + } else io_arraySet(arr, i, v); - } } return arr; } /* - * io_clrVars() Clear ait_val_t elements from array + * io_clrVars() - Clear ait_val_t elements from array + * * @vars = Variable array * return: -1 error or size of array */ @@ -467,14 +506,14 @@ io_clrVars(array_t * __restrict vars) return -1; for (i = 0; i < io_arraySize(vars); i++) - if (io_arrayGet(vars, i)) - AIT_FREE_VAL(io_array(vars, i, ait_val_t*)); + io_freeVar((ait_val_t**) io_arrayGet2(vars, i)); return io_arraySize(vars); } /* - * io_freeVars() Free ait_val_t array + * io_freeVars() - Free ait_val_t array + * * @vars = Variable array * return: none */ @@ -485,12 +524,12 @@ io_freeVars(array_t ** __restrict vars) return; io_clrVars(*vars); - io_arrayFree(*vars); io_arrayDestroy(vars); } /* - * io_allocVar() Allocate memory for variable + * io_allocVar() - Allocate memory for variable + * * return: NULL error or new variable, after use free variable with io_freeVar() */ inline ait_val_t * @@ -510,7 +549,8 @@ io_allocVar(void) } /* - * io_freeVar() Free allocated memory for variable + * io_freeVar() - Free allocated memory for variable + * * @val = Variable * return: none */ @@ -522,4 +562,78 @@ io_freeVar(ait_val_t ** __restrict val) free(*val); *val = NULL; } +} + +static int +_cmp_arr_key_asc(const void *a, const void *b) +{ + return AIT_KEY(*(ait_val_t**) a) - AIT_KEY(*(ait_val_t**) b); +} + +static int +_cmp_arr_key_desc(const void *a, const void *b) +{ + return AIT_KEY(*(ait_val_t**) b) - AIT_KEY(*(ait_val_t**) a); +} + +/* + * io_sortVars() - Sorting array with variables + * + * @vars = Variable array + * @order = Sort order. If =0 ascend or !=0 descend + * @cmp = Compare function for sorting. If =NULL compare by key + * return: none + */ +inline void +io_sortVars(array_t * __restrict vars, int order, int (*cmp)(const void*, const void*)) +{ + if (!vars) + return; + + if (cmp) + qsort(vars->arr_data, vars->arr_num, sizeof(void*), cmp); + else if (order) + qsort(vars->arr_data, vars->arr_num, sizeof(void*), _cmp_arr_key_desc); + else + qsort(vars->arr_data, vars->arr_num, sizeof(void*), _cmp_arr_key_asc); +} + +/* + * io_findKeyVars() - Find variable by key from array + * + * @vars = Variables + * @key = Search key + * return: NULL error or not found, !=NULL valid element + */ +ait_val_t * +io_findKeyVars(array_t * __restrict vars, u_short key) +{ + array_t *tmp; + ait_val_t **vv, *v = NULL; + register int i; + const u_char *p; + + if (!vars) + return NULL; + + if (io_arrayCopy(&tmp, vars) == -1) + return NULL; + else + qsort(tmp->arr_data, tmp->arr_num, sizeof(void*), _cmp_arr_key_asc); + + /* binary search */ + for (p = (const u_char*) tmp->arr_data, i = io_arraySize(tmp); i; i >>= 1) { + vv = (ait_val_t**) (p + (i >> 1) * sizeof(void*)); + if (!(key - AIT_KEY(*vv))) { /* found! */ + v = *vv; + break; + } + if ((key - AIT_KEY(*vv)) > 0) { /* move right key > current */ + p = (const u_char*) vv + sizeof(void*); + i--; + } /* else move left */ + } + + io_arrayDestroy(&tmp); + return v; }