--- libelwix/inc/elwix/avar.h 2013/01/17 10:05:35 1.1 +++ libelwix/inc/elwix/avar.h 2022/01/24 17:08:21 1.13 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: avar.h,v 1.1 2013/01/17 10:05:35 misho Exp $ +* $Id: avar.h,v 1.13 2022/01/24 17:08: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, 2012, 2013 +Copyright 2004 - 2022 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -57,14 +57,18 @@ typedef enum { i8, i16, i32, i64, /* integers ... */ } ait_type_t; -typedef struct { +typedef struct __packed { uint8_t val_type; union { struct { uint8_t val_in:1; uint8_t val_be:1; uint8_t val_le:1; - uint8_t val_pad:5; + uint8_t val_const:1; + uint8_t val_f0:1; + uint8_t val_f1:1; + uint8_t val_f2:1; + uint8_t val_f3:1; }; uint8_t val_opt; }; @@ -89,7 +93,7 @@ typedef struct { int64_t i64; } val; uint8_t val_data[0]; -} __packed ait_val_t; /* sizeof 16 bytes */ +} /*__packed*/ ait_val_t; /* sizeof 16 bytes */ #define AIT_TYPE(_vl) ((ait_type_t) (_vl)->val_type) #define AIT_LEN(_vl) (_vl)->val_len @@ -99,6 +103,11 @@ typedef struct { #define AIT_IN(_vl) (_vl)->val_in #define AIT_BE(_vl) (_vl)->val_be #define AIT_LE(_vl) (_vl)->val_le +#define AIT_CONST(_vl) (_vl)->val_const +#define AIT_FLAG0(_vl) (_vl)->val_f0 +#define AIT_FLAG1(_vl) (_vl)->val_f1 +#define AIT_FLAG2(_vl) (_vl)->val_f2 +#define AIT_FLAG3(_vl) (_vl)->val_f3 #define AIT_BLOB_CHUNKS(_vl, _n) (AIT_LEN((_vl)) / _n + (AIT_LEN((_vl)) % _n) ? 1 : 0) #define AIT_ISEMPTY(_vl) (AIT_TYPE((_vl)) == empty) @@ -123,7 +132,9 @@ typedef struct { #define AIT_GET_F32(_vl) (assert(AIT_TYPE((_vl)) == f32), (_vl)->val.f32) #define AIT_GET_F64(_vl) (assert(AIT_TYPE((_vl)) == f64), (_vl)->val.f64) -#define AIT_SET_DATA(_vl, _p, _len) do { ait_val_t *__val = e_realloc((_vl), (sizeof(ait_val_t) + _len)); \ +#define AIT_SET_DATA(_vl, _p, _len) do { assert(!(_vl) || ((_vl) && !AIT_CONST((_vl)))); \ + ait_val_t *__val = e_realloc((_vl), \ + (sizeof(ait_val_t) + _len)); \ if (__val) { \ void *__p = (_p); \ if (__p) \ @@ -133,22 +144,26 @@ typedef struct { (_vl) = __val; \ } \ } while (0); -#define AIT_SET_PTR(_vl, _p, _len) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_PTR(_vl, _p, _len) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = ptr; __val->val.ptr = _p; \ AIT_LEN(__val) = _len; } while (0) -#define AIT_RE_BUF(_vl, _len) do { ait_val_t *__val = (_vl); assert(__val && !__val->val_in); \ +#define AIT_RE_BUF(_vl, _len) do { ait_val_t *__val = (_vl); \ + assert(__val && !__val->val_in && !AIT_CONST(__val)); \ void *__ptr = e_realloc(AIT_GET_BUF(__val), _len); \ if (__ptr) { \ __val->val.buffer = __ptr; AIT_LEN(__val) = _len; \ } } while (0) -#define AIT_SET_BUFSIZ(_vl, _c, _len) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_BUFSIZ(_vl, _c, _len) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val.buffer = e_malloc(_len); \ if (__val->val.buffer) { \ __val->val_in ^= __val->val_in; \ __val->val_type = buffer; AIT_LEN(__val) = _len; \ memset(__val->val.buffer, _c, _len); \ } } while (0) -#define AIT_SET_BUF(_vl, _v, _len) do { ait_val_t *__val = (_vl); void *__p = (_v); assert(__val); \ +#define AIT_SET_BUF(_vl, _v, _len) do { ait_val_t *__val = (_vl); void *__p = (_v); \ + assert(__val && !AIT_CONST(__val)); \ __val->val.buffer = e_malloc(_len); \ if (__val->val.buffer) { \ __val->val_in ^= __val->val_in; \ @@ -158,7 +173,8 @@ typedef struct { else \ memset(__val->val.buffer, 0, _len); \ } } while (0) -#define AIT_SET_STR(_vl, _v) do { ait_val_t *__val = (_vl); const char *__s = (_v); assert(__val); \ +#define AIT_SET_STR(_vl, _v) do { ait_val_t *__val = (_vl); const char *__s = (_v); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = string; \ __val->val_in ^= __val->val_in; \ if (__s) { \ @@ -170,7 +186,8 @@ typedef struct { AIT_LEN(__val) = 0; \ } \ } while (0) -#define AIT_SET_STRSIZ(_vl, _len) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_STRSIZ(_vl, _len) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val.string = (int8_t*) e_malloc(_len + 1); \ if (__val->val.string) { \ __val->val_in ^= __val->val_in; \ @@ -179,7 +196,7 @@ typedef struct { } \ } while (0) #define AIT_SET_STRCAT(_vl, _v) do { ait_val_t *__val = (_vl); const char *__s = (_v); int __l; \ - assert(__val && !__val->val_in); \ + assert(__val && !__val->val_in && !AIT_CONST(__val)); \ assert(AIT_TYPE(__val) == string); \ if (!__s || !*__s) \ break; \ @@ -198,7 +215,7 @@ typedef struct { } \ } while (0) #define AIT_SET_STRCPY(_vl, _v) do { ait_val_t *__val = (_vl); const char *__s = (_v); int __l; \ - assert(__val && !__val->val_in); \ + assert(__val && !__val->val_in && !AIT_CONST(__val)); \ assert(AIT_TYPE(__val) == string); \ if (!__s || !*__s) \ break; \ @@ -212,7 +229,7 @@ typedef struct { AIT_LEN(__val)); \ } } while (0) #define AIT_SET_STRLCPY(_vl, _v, _len) do { ait_val_t *__val = (_vl); const char *__s = (_v); \ - assert(__val && !__val->val_in); \ + assert(__val && !__val->val_in && !AIT_CONST(__val)); \ assert(AIT_TYPE(__val) == string); \ if (!__s || !*__s) \ break; \ @@ -223,47 +240,59 @@ typedef struct { strlcpy((char*) __val->val.string, __s, \ AIT_LEN(__val)); \ } } while (0) -#define AIT_SET_BLOB(_vl, _n, _len) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_BLOB(_vl, _n, _len) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = blob; __val->val.blob = _n; \ AIT_LEN(__val) = _len; } while (0) -#define AIT_SET_BLOB2(_vl, _bv) do { ait_val_t *__val = (_vl); assert(__val); assert((_bv)); \ +#define AIT_SET_BLOB2(_vl, _bv) do { ait_val_t *__val = (_vl); assert((_bv)); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = blob; AIT_LEN(__val) = \ (_bv)->blob_len; \ __val->val.blob = (_bv)->blob_var; } while (0) #define AIT_NEW_BLOB(_vl, _len) AIT_SET_BLOB((_vl), 0, _len) -#define AIT_SET_U8(_vl, _n) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_U8(_vl, _n) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = u8; __val->val.u8 = _n; \ AIT_LEN(__val) = sizeof(uint8_t); } while (0) -#define AIT_SET_U16(_vl, _n) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_U16(_vl, _n) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = u16; __val->val.u16 = _n; \ AIT_LEN(__val) = sizeof(uint16_t); } while (0) -#define AIT_SET_U32(_vl, _n) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_U32(_vl, _n) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = u32; __val->val.u32 = _n; \ AIT_LEN(__val) = sizeof(uint32_t); } while (0) -#define AIT_SET_U64(_vl, _n) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_U64(_vl, _n) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = u64; __val->val.u64 = _n; \ AIT_LEN(__val) = sizeof(uint64_t); } while (0) -#define AIT_SET_I8(_vl, _n) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_I8(_vl, _n) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = i8; __val->val.i8 = _n; \ AIT_LEN(__val) = sizeof(int8_t); } while (0) -#define AIT_SET_I16(_vl, _n) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_I16(_vl, _n) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = i16; __val->val.i16 = _n; \ AIT_LEN(__val) = sizeof(int16_t); } while (0) -#define AIT_SET_I32(_vl, _n) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_I32(_vl, _n) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = i32; __val->val.i32 = _n; \ AIT_LEN(__val) = sizeof(int32_t); } while (0) -#define AIT_SET_I64(_vl, _n) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_I64(_vl, _n) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = i64; __val->val.i64 = _n; \ AIT_LEN(__val) = sizeof(int64_t); } while (0) -#define AIT_SET_F32(_vl, _n) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_F32(_vl, _n) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = f32; __val->val.f32 = _n; \ AIT_LEN(__val) = sizeof(float); } while (0) -#define AIT_SET_F64(_vl, _n) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_SET_F64(_vl, _n) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ __val->val_type = f64; __val->val.f64 = _n; \ AIT_LEN(__val) = sizeof(double); } while (0) -#define AIT_COPY_VAL(_vl, _v) do { assert((_vl)); assert((_v)); \ +#define AIT_COPY_VAL(_vl, _v) do { assert((_vl) && (_v) && !AIT_CONST((_vl))); \ memcpy((_vl), (_v), sizeof(ait_val_t)); \ switch (AIT_TYPE((_vl))) { \ case buffer: \ @@ -279,12 +308,18 @@ typedef struct { break; \ } \ } while (0) +/* Additional helper macro, which can help about copy data variables */ #define AIT_COPY_DATA(_vl, _v) do { AIT_COPY_VAL((_vl), (_v)); \ if (AIT_TYPE((_vl)) == data) \ AIT_SET_DATA((_vl), AIT_GET_DATA((_v)), \ AIT_LEN((_v))); \ } while (0) +#define AIT_VAL_INITIALIZER(_vl) { .val_type = empty, { .val_opt = 0 }, \ + .val_key = 0, .val_len = 0, \ + .val.net = 0LL \ + } +#define AIT_VAL_INIT AIT_VAL_INITIALIZER() #define AIT_INIT_VAL(_vl) (memset((_vl), 0, sizeof(ait_val_t))) #define AIT_INIT_VAL2(_vl, _t) do { \ AIT_INIT_VAL((_vl)); \ @@ -313,10 +348,12 @@ typedef struct { AIT_LEN(__val) = 0; \ AIT_KEY(__val) = 0; \ } while (0) -#define AIT_ZERO_VAL(_vl) do { ait_val_t *__val = (_vl); assert(__val); \ +#define AIT_ZERO_VAL(_vl) do { ait_val_t *__val = (_vl); \ + assert(__val && !AIT_CONST(__val)); \ switch (AIT_TYPE(__val)) { \ case buffer: \ case string: \ + assert(!__val->val_in); \ if (__val->val.buffer) \ memset(__val->val.buffer, 0, \ AIT_LEN(__val)); \ @@ -340,8 +377,7 @@ typedef struct { * @vars = Variable array * return: -1 error, 0 nothing done or >0 size of marshaled data */ -inline int ait_vars2buffer(unsigned char * __restrict buf, int buflen, - array_t * __restrict vars); +int ait_vars2buffer(unsigned char * __restrict buf, int buflen, array_t * __restrict vars); /* * ait_buffer2vars() - De-marshaling data from buffer to array with variables * @@ -352,8 +388,25 @@ inline int ait_vars2buffer(unsigned char * __restrict *DON'T MODIFY OR DESTROY BUFFER*. =0 call array_Free() before array_Destroy() * return: =NULL error, !=NULL allocated variable array, after use must free with array_Destroy() */ -inline array_t *ait_buffer2vars(unsigned char * __restrict buf, int buflen, int vnum, int zcpy); +array_t *ait_buffer2vars(unsigned char * __restrict buf, int buflen, int vnum, int zcpy); /* + * ait_vars2tlv() - Marshaling data from array with variables to TLV buffer + * + * @buf = Buffer, If =NULL then we return only needed buffer size + * @buflen = Size of buffer + * @vars = Variable array + * return: -1 error, 0 nothing done or >0 size of marshaled data + */ +int ait_vars2tlv(u_char * __restrict buf, int buflen, array_t * __restrict vars); +/* + * ait_tlv2vars() - De-marshaling data from TLV buffer to array with variables + * + * @buf = Buffer + * @buflen = Size of buffer + * return: =NULL error, !=NULL allocated variable array, after use must free with ait_freeVars() + */ +array_t *ait_tlv2vars(u_char * __restrict buf, int buflen); +/* * ait_vars2map() - Marshaling data from array with variables to memory map * * @buf = Buffer @@ -361,7 +414,7 @@ inline array_t *ait_buffer2vars(unsigned char * __rest * @vars = Variable array * return: -1 error, 0 nothing done or >0 size of marshaled data */ -inline int ait_vars2map(unsigned char * __restrict buf, int buflen, array_t * __restrict vars); +int ait_vars2map(unsigned char * __restrict buf, int buflen, array_t * __restrict vars); /* * ait_map2vars() - De-marshaling data from memory map to array with variables * @@ -372,22 +425,30 @@ inline int ait_vars2map(unsigned char * __restrict buf *DON'T MODIFY OR DESTROY BUFFER*. =0 call array_Free() before array_Destroy() * return: =NULL error, !=NULL allocated variable array, after use must free with array_Destroy() */ -inline array_t *ait_map2vars(unsigned char * __restrict buf, int buflen, int vnum, int zcpy); +array_t *ait_map2vars(unsigned char * __restrict buf, int buflen, int vnum, int zcpy); +/* + * ait_array2vars() - Build array with variables from Null Terminated String Array + * + * @args = Null-terminated array with strings + * @dn = Convert numbers from strings to numbers into variables + * return: =NULL error, !=NULL allocated variable array, after use must free with ait_freeVars() + */ +array_t *ait_array2vars(const char **args, int dn); /* * ait_allocVar() - Allocate memory for variable * * return: NULL error or new variable, after use free variable with ait_freeVar() */ -inline ait_val_t *ait_allocVar(void); +ait_val_t *ait_allocVar(void); /* * ait_freeVar() - Free allocated memory for variable * * @val = Variable * return: none */ -inline void ait_freeVar(ait_val_t ** __restrict val); +void ait_freeVar(ait_val_t ** __restrict val); /* * ait_makeVar() - Allocate memory and fill variable * @@ -403,7 +464,7 @@ ait_val_t *ait_makeVar(ait_type_t type, ...); * @v = variable * return: return raw data */ -inline uint64_t ait_getlikeVar(ait_val_t * __restrict v); +uint64_t ait_getlikeVar(ait_val_t * __restrict v); /* * ait_setlikeVar() - Set variable like ... * @@ -413,7 +474,7 @@ inline uint64_t ait_getlikeVar(ait_val_t * __restrict * @... = data * return: -1 error or 0 ok */ -inline int ait_setlikeVar(ait_val_t * __restrict v, ait_type_t t, unsigned int l, ...); +int ait_setlikeVar(ait_val_t * __restrict v, ait_type_t t, unsigned int l, ...); /* * ait_sprintfVar() - Builtin string variable from formatted input * @@ -430,7 +491,7 @@ int ait_sprintfVar(ait_val_t * __restrict v, const cha * @b = 2nd variable * return: 0 is equal or !=0 is different */ -inline int ait_cmpVar(ait_val_t * __restrict a, ait_val_t * __restrict b); +int ait_cmpVar(ait_val_t * __restrict a, ait_val_t * __restrict b); /* * ait_hashVar() - Generate hash key for variable from string or value * @@ -447,21 +508,21 @@ unsigned short ait_hashVar(ait_val_t * __restrict v, c * @varnum = Number of variables * return: =NULL error or !=NULL allocated array */ -inline array_t *ait_allocVars(int varnum); +array_t *ait_allocVars(int varnum); /* * ait_clrVars() - Clear ait_val_t elements from array * * @vars = Variable array * return: -1 error or size of array */ -inline int ait_clrVars(array_t * __restrict vars); +int ait_clrVars(array_t * __restrict vars); /* * ait_freeVars() - Free ait_val_t array * * @vars = Variable array * return: none */ -inline void ait_freeVars(array_t ** __restrict vars); +void ait_freeVars(array_t ** __restrict vars); /* * ait_getVars() - Get ait_val_t element from array and if not exists allocate it * @@ -469,15 +530,22 @@ inline void ait_freeVars(array_t ** __restrict vars); * @n = index of variable into array * return: NULL error or !=NULL ait_val_t element */ -inline ait_val_t *ait_getVars(array_t ** __restrict vars, int n); +ait_val_t *ait_getVars(array_t ** __restrict vars, int n); /* + * ait_resideVars() - Calculate footprint of resided variables into array + * + * @vars = Variable array + * return: bytes for whole array + */ +size_t ait_resideVars(array_t * __restrict vars); +/* * ait_sortVarsByKey() - Sorting array with variables by key * * @vars = Variable array * @order = Sort order. If =0 ascend or !=0 descend * return: none */ -inline void ait_sortVarsByKey(array_t * __restrict vars, int order); +void ait_sortVarsByKey(array_t * __restrict vars, int order); /* * ait_sortVarsByVal() - Sorting array with variables by value * @@ -486,7 +554,7 @@ inline void ait_sortVarsByKey(array_t * __restrict var * @cmp = Custom compare function for sorting. If =NULL compare by value * return: none */ -inline void ait_sortVarsByVal(array_t * __restrict vars, int order, +void ait_sortVarsByVal(array_t * __restrict vars, int order, int (*cmp)(const void*, const void*)); /* * ait_findKeyVars() - Find variable by key from array @@ -503,14 +571,14 @@ ait_val_t *ait_findKeyVars(array_t * __restrict vars, * @key = Search string * return: NULL error or not found, !=NULL valid element */ -inline ait_val_t *ait_findKeyHash(array_t * __restrict vars, const char * __restrict key); +ait_val_t *ait_findKeyHash(array_t * __restrict vars, const char * __restrict key); /* * ait_hashKeyVars() - Generate hash keys for variables * * @vars = Variables * return -1 error or 0 ok */ -inline int ait_hashKeyVars(array_t * __restrict vars); +int ait_hashKeyVars(array_t * __restrict vars); #endif