--- libaitio/src/Attic/vars.c 2012/07/03 08:51:05 1.10 +++ libaitio/src/Attic/vars.c 2012/07/22 12:23:04 1.10.2.1 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: vars.c,v 1.10 2012/07/03 08:51:05 misho Exp $ +* $Id: vars.c,v 1.10.2.1 2012/07/22 12:23:04 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -46,16 +46,8 @@ SUCH DAMAGE. #include "global.h" -/* - * io_vars2buffer() - Marshaling data from array with variables to buffer - * - * @buf = Buffer - * @buflen = Size of buffer - * @vars = Variable array - * return: -1 error, 0 nothing done or >0 size of marshaled data - */ -int -io_vars2buffer(u_char *buf, int buflen, array_t *vars) +static int +vars2buffer(u_char * __restrict buf, int buflen, int be, array_t * __restrict vars) { int Limit = 0; register int i; @@ -68,6 +60,7 @@ io_vars2buffer(u_char *buf, int buflen, array_t *vars) return -1; if (!buflen || !io_arraySize(vars)) return 0; + be = !!be; Limit = sizeof(ait_val_t) * io_arraySize(vars); if (Limit > buflen) { @@ -86,8 +79,17 @@ 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)); + AIT_IN(&v[i]) = 1; + AIT_BE(&v[i]) = be; + AIT_LE(&v[i]) = !be; + if (AIT_BE(&v[i])) { + AIT_KEY(&v[i]) = htobe16(AIT_KEY(val)); + AIT_LEN(&v[i]) = htobe32(AIT_LEN(val)); + } + if (AIT_LE(&v[i])) { + AIT_KEY(&v[i]) = htole16(AIT_KEY(val)); + AIT_LEN(&v[i]) = htole32(AIT_LEN(val)); + } switch (AIT_TYPE(val)) { case blob: @@ -101,7 +103,10 @@ io_vars2buffer(u_char *buf, int buflen, array_t *vars) case u16: case u32: case u64: - v[i].val.net = htobe64(val->val.net); + if (AIT_BE(&v[i])) + v[i].val.net = htobe64(val->val.net); + if (AIT_LE(&v[i])) + v[i].val.net = htole64(val->val.net); break; case data: if (AIT_LEN(val) > buflen - Limit) { @@ -140,18 +145,8 @@ io_vars2buffer(u_char *buf, int buflen, array_t *vars) return Limit; } -/* - * io_buffer2vars() - De-marshaling data from buffer to array with variables - * - * @buf = Buffer - * @buflen = Size of buffer - * @vnum = Number of variables into buffer - * @zcpy = Zero-copy for variables, if !=0 don't use io_arrayFree() for free variables and - *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy() - * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy() - */ -array_t * -io_buffer2vars(u_char *buf, int buflen, int vnum, int zcpy) +static array_t * +buffer2vars(u_char * __restrict buf, int buflen, int vnum, int zcpy) { array_t *vars; int Limit = 0; @@ -186,18 +181,24 @@ io_buffer2vars(u_char *buf, int buflen, int vnum, int io_arrayDestroy(&vars); return NULL; } - } else + AIT_IN(val) = 0; + } else { val = v + i; + AIT_IN(val) = 1; + } io_arraySet(vars, i, val); 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 + AIT_BE(val) = AIT_BE(&v[i]); + AIT_LE(val) = AIT_LE(&v[i]); + if (AIT_BE(val)) { + AIT_LEN(val) = be32toh(AIT_LEN(&v[i])); + AIT_KEY(val) = be16toh(AIT_KEY(&v[i])); + } + if (AIT_LE(val)) { + AIT_LEN(val) = le32toh(AIT_LEN(&v[i])); + AIT_KEY(val) = le16toh(AIT_KEY(&v[i])); + } switch (AIT_TYPE(val)) { case blob: @@ -211,11 +212,10 @@ io_buffer2vars(u_char *buf, int buflen, int vnum, int case u16: case u32: case u64: -#if defined(__OpenBSD__) - val->val.net = betoh64(v[i].val.net); -#else - val->val.net = be64toh(v[i].val.net); -#endif + if (AIT_BE(val)) + val->val.net = be64toh(v[i].val.net); + if (AIT_LE(val)) + val->val.net = le64toh(v[i].val.net); break; case data: /* WARNING:: remap data type to buffer */ @@ -258,100 +258,53 @@ io_buffer2vars(u_char *buf, int buflen, int vnum, int return vars; } -/* buffer marshaling without swapping bytes to network order */ +/* buffer marshaling with swapping bytes to network order */ + /* - * io_vars2map() - Marshaling data from array with variables to memory map + * io_vars2buffer() - Marshaling data from array with variables to buffer * * @buf = Buffer * @buflen = Size of buffer * @vars = Variable array * return: -1 error, 0 nothing done or >0 size of marshaled data */ -int -io_vars2map(u_char *buf, int buflen, array_t *vars) +inline int +io_vars2buffer(u_char * __restrict buf, int buflen, array_t * __restrict vars) { - int Limit = 0; - register int i; - ait_val_t *v, *val; - u_char *dat; + return vars2buffer(buf, buflen, 42, vars); +} - assert(buf); - assert(vars); - if (!buf || !vars) - return -1; - if (!buflen || !io_arraySize(vars)) - return 0; +/* + * io_buffer2vars() - De-marshaling data from buffer to array with variables + * + * @buf = Buffer + * @buflen = Size of buffer + * @vnum = Number of variables into buffer + * @zcpy = Zero-copy for variables, if !=0 don't use io_arrayFree() for free variables and + *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy() + * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy() + */ +inline array_t * +io_buffer2vars(u_char * __restrict buf, int buflen, int vnum, int zcpy) +{ + return buffer2vars(buf, buflen, vnum, zcpy); +} - Limit = sizeof(ait_val_t) * io_arraySize(vars); - if (Limit > buflen) { - io_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", - buflen, Limit); - return -1; - } else { - memset(buf, 0, buflen); +/* buffer marshaling without swapping bytes to network order */ - v = (ait_val_t*) buf; - dat = buf + Limit; - } - - /* marshaling */ - for (i = 0; i < io_arraySize(vars); i++) { - 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)) { - case blob: - case f32: - case f64: - case i8: - case i16: - case i32: - case i64: - case u8: - case u16: - case u32: - 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, "Short buffer buflen=%d " - "needed min %d", buflen, Limit + AIT_LEN(val)); - return -1; - } else - Limit += AIT_LEN(val); - - memcpy(dat, val->val.buffer, AIT_LEN(val)); - /* Debug:: data offset in packet, not matter for anything! */ - v[i].val.net = dat - buf; - dat += AIT_LEN(val); - break; - default: - io_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", - AIT_TYPE(val), i); - return -1; - } - } - - return Limit; +/* + * io_vars2map() - Marshaling data from array with variables to memory map + * + * @buf = Buffer + * @buflen = Size of buffer + * @vars = Variable array + * return: -1 error, 0 nothing done or >0 size of marshaled data + */ +inline int +io_vars2map(u_char *buf, int buflen, array_t *vars) +{ + return vars2buffer(buf, buflen, 0, vars); } /* @@ -364,103 +317,10 @@ io_vars2map(u_char *buf, int buflen, array_t *vars) *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy() * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy() */ -array_t * +inline array_t * io_map2vars(u_char *buf, int buflen, int vnum, int zcpy) { - array_t *vars; - int Limit = 0; - register int i; - ait_val_t *v, *val; - u_char *dat; - - assert(buf); - if (!buf || !buflen || !vnum) - return NULL; - - Limit = sizeof(ait_val_t) * vnum; - if (Limit > buflen) { - io_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", - buflen, Limit); - return NULL; - } else { - if (!(vars = io_arrayInit(vnum))) - return NULL; - - v = (ait_val_t*) buf; - dat = buf + Limit; - } - - /* de-marshaling */ - for (i = 0; i < io_arraySize(vars); i++) { - if (!zcpy) { - val = io_malloc(sizeof(ait_val_t)); - if (!val) { - LOGERR; - io_arrayFree(vars); - io_arrayDestroy(&vars); - return NULL; - } - } else - val = v + i; - 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)) { - case blob: - case f32: - case f64: - case i8: - case i16: - case i32: - case i64: - case u8: - case u16: - case u32: - 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, "short buffer buflen=%d " - "needed min %d", buflen, Limit + AIT_LEN(val)); - if (!zcpy) - io_arrayFree(vars); - io_arrayDestroy(&vars); - return NULL; - } else - Limit += AIT_LEN(val); - - if (!zcpy) { - val->val.buffer = io_malloc(AIT_LEN(val)); - if (!val->val.buffer) { - LOGERR; - io_arrayFree(vars); - io_arrayDestroy(&vars); - return NULL; - } else - memcpy(val->val.buffer, dat, AIT_LEN(val)); - } else - val->val.buffer = dat; - dat += AIT_LEN(val); - break; - default: - io_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", - AIT_TYPE(val), i); - if (!zcpy) - io_arrayFree(vars); - io_arrayDestroy(&vars); - return NULL; - } - } - - return vars; + return buffer2vars(buf, buflen, vnum, zcpy); } @@ -615,16 +475,28 @@ _cmp_arr_key_desc(const void *a, const void *b) return AIT_KEY(*(ait_val_t**) b) - AIT_KEY(*(ait_val_t**) a); } +static int +_cmp_arr_val_asc(const void *a, const void *b) +{ + return AIT_RAW(*(ait_val_t**) a) - AIT_RAW(*(ait_val_t**) b); +} + +static int +_cmp_arr_val_desc(const void *a, const void *b) +{ + return AIT_RAW(*(ait_val_t**) b) - AIT_RAW(*(ait_val_t**) a); +} + /* - * io_sortVars() - Sorting array with variables + * io_sortVarsByVal() - Sorting array with variables by value * * @vars = Variable array * @order = Sort order. If =0 ascend or !=0 descend - * @cmp = Compare function for sorting. If =NULL compare by key + * @cmp = Custom compare function for sorting. If =NULL compare by value * return: none */ inline void -io_sortVars(array_t * __restrict vars, int order, int (*cmp)(const void*, const void*)) +io_sortVarsByVal(array_t * __restrict vars, int order, int (*cmp)(const void*, const void*)) { if (!vars) return; @@ -632,6 +504,25 @@ io_sortVars(array_t * __restrict vars, int order, int 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_val_desc); + else + qsort(vars->arr_data, vars->arr_num, sizeof(void*), _cmp_arr_val_asc); +} + +/* + * io_sortVarsByKey() - Sorting array with variables by key + * + * @vars = Variable array + * @order = Sort order. If =0 ascend or !=0 descend + * return: none + */ +inline void +io_sortVarsByKey(array_t * __restrict vars, int order) +{ + if (!vars) + return; + + 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);