/*************************************************************************
* (C) 2013 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
* by Michael Pounov <misho@elwix.org>
*
* $Author: misho $
* $Id: avar.h,v 1.2.14.1 2013/07/08 12:35:13 misho Exp $
*
**************************************************************************
The ELWIX and AITNET software is distributed under the following
terms:
All of the documentation and software included in the ELWIX and AITNET
Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
by Michael Pounov <misho@elwix.org>. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by Michael Pounov <misho@elwix.org>
ELWIX - Embedded LightWeight unIX and its contributors.
4. Neither the name of AITNET nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#ifndef __AVAR_H
#define __AVAR_H
/* AIT RPC variables and managment */
typedef enum {
empty, ptr, data, /* empty -> variable is not set; ptr -> void*; data -> data after struct */
buffer, string, blob, /* buffer -> uint8_t*; string -> int8_t*; blob -> uint32_t blobID(+socket); */
f32, f64, /* float -> f32; double -> f64 */
u8, u16, u32, u64, /* unsigned integers ... */
i8, i16, i32, i64, /* integers ... */
} ait_type_t;
typedef struct {
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_opt;
};
uint16_t val_key;
uint32_t val_len;
union {
uint64_t net;
void *ptr;
uint8_t *buffer;
int8_t *string;
uint32_t blob;
float f32;
double f64;
uint8_t u8;
uint16_t u16;
uint32_t u32;
uint64_t u64;
int8_t i8;
int16_t i16;
int32_t i32;
int64_t i64;
} val;
uint8_t val_data[0];
} __packed ait_val_t; /* sizeof 16 bytes */
#define AIT_TYPE(_vl) ((ait_type_t) (_vl)->val_type)
#define AIT_LEN(_vl) (_vl)->val_len
#define AIT_KEY(_vl) (_vl)->val_key
#define AIT_RAW(_vl) (_vl)->val.net
#define AIT_ADDR(_vl) (_vl)->val.buffer
#define AIT_IN(_vl) (_vl)->val_in
#define AIT_BE(_vl) (_vl)->val_be
#define AIT_LE(_vl) (_vl)->val_le
#define AIT_BLOB_CHUNKS(_vl, _n) (AIT_LEN((_vl)) / _n + (AIT_LEN((_vl)) % _n) ? 1 : 0)
#define AIT_ISEMPTY(_vl) (AIT_TYPE((_vl)) == empty)
#define AIT_GET_LIKE(_vl, _type) ((_type) AIT_ADDR((_vl)))
#define AIT_SET_LIKE(_vl, _t, _l, _v) (assert((_vl)), ait_setlikeVar((_vl), _t, _l, _v))
#define AIT_GET_PTR(_vl) (assert(AIT_TYPE((_vl)) == ptr), (_vl)->val.ptr)
#define AIT_GET_DATA(_vl) (assert(AIT_TYPE((_vl)) == data), (_vl)->val_data)
#define AIT_GET_BUF(_vl) (assert(AIT_TYPE((_vl)) == buffer), (_vl)->val.buffer)
#define AIT_GET_STR(_vl) (assert(AIT_TYPE((_vl)) == string), (char*) (_vl)->val.string)
#define AIT_GET_STRZ(_vl) (assert(AIT_TYPE((_vl)) == string), (_vl)->val.string ? \
(char*) (_vl)->val.string : "")
#define AIT_GET_BLOB(_vl) (assert(AIT_TYPE((_vl)) == blob), (_vl)->val.blob)
#define AIT_GET_U8(_vl) (assert(AIT_TYPE((_vl)) == u8), (_vl)->val.u8)
#define AIT_GET_U16(_vl) (assert(AIT_TYPE((_vl)) == u16), (_vl)->val.u16)
#define AIT_GET_U32(_vl) (assert(AIT_TYPE((_vl)) == u32), (_vl)->val.u32)
#define AIT_GET_U64(_vl) (assert(AIT_TYPE((_vl)) == u64), (_vl)->val.u64)
#define AIT_GET_I8(_vl) (assert(AIT_TYPE((_vl)) == i8), (_vl)->val.i8)
#define AIT_GET_I16(_vl) (assert(AIT_TYPE((_vl)) == i16), (_vl)->val.i16)
#define AIT_GET_I32(_vl) (assert(AIT_TYPE((_vl)) == i32), (_vl)->val.i32)
#define AIT_GET_I64(_vl) (assert(AIT_TYPE((_vl)) == i64), (_vl)->val.i64)
#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)); \
if (__val) { \
void *__p = (_p); \
if (__p) \
memcpy(__val->val_data, __p, _len); \
__val->val_in ^= __val->val_in; \
__val->val_type = data; AIT_LEN(__val) = _len; \
(_vl) = __val; \
} \
} while (0);
#define AIT_SET_PTR(_vl, _p, _len) do { ait_val_t *__val = (_vl); assert(__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); \
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); \
__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); \
__val->val.buffer = e_malloc(_len); \
if (__val->val.buffer) { \
__val->val_in ^= __val->val_in; \
__val->val_type = buffer; AIT_LEN(__val) = _len; \
if (__p) \
memcpy(__val->val.buffer, __p, _len); \
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); \
__val->val_type = string; \
__val->val_in ^= __val->val_in; \
if (__s) { \
__val->val.string = (int8_t*) e_strdup(__s); \
AIT_LEN(__val) = strlen((const char*) \
__val->val.string) + 1; \
} else { \
__val->val.string = NULL; \
AIT_LEN(__val) = 0; \
} \
} while (0)
#define AIT_SET_STRSIZ(_vl, _len) do { ait_val_t *__val = (_vl); assert(__val); \
__val->val.string = (int8_t*) e_malloc(_len + 1); \
if (__val->val.string) { \
__val->val_in ^= __val->val_in; \
__val->val_type = string; AIT_LEN(__val) = _len + 1; \
memset(__val->val.string, 0, AIT_LEN(__val)); \
} \
} 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(AIT_TYPE(__val) == string); \
if (!__s || !*__s) \
break; \
else \
__l = strlen(__s); \
if (!__val->val.string) \
__l++; \
void *__p = e_realloc(__val->val.string, AIT_LEN(__val) + __l); \
if (__p) { \
AIT_LEN(__val) += __l; \
if (!__val->val.string) \
memset(__p, 0, AIT_LEN(__val)); \
__val->val.string = __p; \
strlcat((char*) __val->val.string, __s, \
AIT_LEN(__val)); \
} \
} 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(AIT_TYPE(__val) == string); \
if (!__s || !*__s) \
break; \
else \
__l = strlen(__s) + 1; \
void *__p = e_realloc(__val->val.string, __l); \
if (__p) { \
AIT_LEN(__val) = __l; \
__val->val.string = __p; \
strlcpy((char*) __val->val.string, __s, \
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(AIT_TYPE(__val) == string); \
if (!__s || !*__s) \
break; \
void *__p = e_realloc(__val->val.string, _len); \
if (__p) { \
AIT_LEN(__val) = _len; \
__val->val.string = __p; \
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); \
__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)); \
__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); \
__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); \
__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); \
__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); \
__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); \
__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); \
__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); \
__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); \
__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); \
__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); \
__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)); \
memcpy((_vl), (_v), sizeof(ait_val_t)); \
switch (AIT_TYPE((_vl))) { \
case buffer: \
AIT_SET_BUF((_vl), \
AIT_GET_BUF((_v)), \
AIT_LEN((_v))); \
break; \
case string: \
AIT_SET_STR((_vl), \
AIT_GET_STR((_v))); \
break; \
default: \
break; \
} \
} while (0)
#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_INIT_VAL(_vl) (memset((_vl), 0, sizeof(ait_val_t)))
#define AIT_INIT_VAL2(_vl, _t) do { \
AIT_INIT_VAL((_vl)); \
(_vl)->val_type = _t; \
} while (0)
/* if attribute zeroCopy is set not execute e_free() */
#define AIT_FREE_VAL(_vl) do { ait_val_t *__val = (_vl); assert(__val); \
switch (AIT_TYPE(__val)) { \
case buffer: \
if (!__val->val_in && \
__val->val.buffer) \
e_free(__val->val.buffer); \
__val->val.buffer = NULL; \
break; \
case string: \
if (!__val->val_in && \
__val->val.string) \
e_free(__val->val.string); \
__val->val.string = NULL; \
break; \
default: \
break; \
} \
__val->val_type = empty; \
__val->val_opt ^= __val->val_opt; \
AIT_LEN(__val) = 0; \
AIT_KEY(__val) = 0; \
} while (0)
#define AIT_ZERO_VAL(_vl) do { ait_val_t *__val = (_vl); assert(__val); \
switch (AIT_TYPE(__val)) { \
case buffer: \
case string: \
if (__val->val.buffer) \
memset(__val->val.buffer, 0, \
AIT_LEN(__val)); \
break; \
case data: \
memset(__val->val_data, 0, AIT_LEN(__val)); \
break; \
default: \
__val->val.net = 0LL; \
break; \
} \
AIT_KEY(__val) = 0; \
} while (0)
/*
* ait_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 ait_vars2buffer(unsigned char * __restrict buf, int buflen,
array_t * __restrict vars);
/*
* ait_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 array_Free() for free variables and
*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()
*/
array_t *ait_buffer2vars(unsigned char * __restrict buf, int buflen, int vnum, int zcpy);
/*
* ait_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
*/
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
*
* @buf = Buffer
* @buflen = Size of buffer
* @vnum = Number of variables into buffer
* @zcpy = Zero-copy for variables, if !=0 don't use array_Free() for free variables and
*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()
*/
array_t *ait_map2vars(unsigned char * __restrict buf, int buflen, int vnum, int zcpy);
/*
* ait_allocVar() - Allocate memory for variable
*
* return: NULL error or new variable, after use free variable with ait_freeVar()
*/
ait_val_t *ait_allocVar(void);
/*
* ait_freeVar() - Free allocated memory for variable
*
* @val = Variable
* return: none
*/
void ait_freeVar(ait_val_t ** __restrict val);
/*
* ait_makeVar() - Allocate memory and fill variable
*
* @type = type of variable
* @... = arg1 is value of variable
* @... = arg2 is length of variabla. Not required for numbers and strings!
* return: NULL error or new variable, after use free variable with ait_freeVar()
*/
ait_val_t *ait_makeVar(ait_type_t type, ...);
/*
* ait_getlikeVar() - Get variable like ...
*
* @v = variable
* return: return raw data
*/
uint64_t ait_getlikeVar(ait_val_t * __restrict v);
/*
* ait_setlikeVar() - Set variable like ...
*
* @v = variable
* @t = type of data
* @l = length of data
* @... = data
* return: -1 error or 0 ok
*/
int ait_setlikeVar(ait_val_t * __restrict v, ait_type_t t, unsigned int l, ...);
/*
* ait_sprintfVar() - Builtin string variable from formatted input
*
* @v = variable
* @fmt = format string
* @... = argument(s)
* return: -1 error or >0 copied bytes to variable
*/
int ait_sprintfVar(ait_val_t * __restrict v, const char *fmt, ...);
/*
* ait_cmpVar() - Compare two variables
*
* @a = 1st variable
* @b = 2nd variable
* return: 0 is equal or !=0 is different
*/
int ait_cmpVar(ait_val_t * __restrict a, ait_val_t * __restrict b);
/*
* ait_hashVar() - Generate hash key for variable from string or value
*
* @v = variable
* @key = key string for hash, if =NULL hash will built from variable
* return: hash key
*/
unsigned short ait_hashVar(ait_val_t * __restrict v, const char * __restrict key);
/*
* ait_allocVars() - Allocate ait_val_t array
*
* @varnum = Number of variables
* return: =NULL error or !=NULL allocated array
*/
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
*/
int ait_clrVars(array_t * __restrict vars);
/*
* ait_freeVars() - Free ait_val_t array
*
* @vars = Variable array
* return: none
*/
void ait_freeVars(array_t ** __restrict vars);
/*
* ait_getVars() - Get ait_val_t element from array and if not exists allocate it
*
* @vars = Variable array
* @n = index of variable into array
* return: NULL error or !=NULL ait_val_t element
*/
ait_val_t *ait_getVars(array_t ** __restrict vars, int n);
/*
* ait_sortVarsByKey() - Sorting array with variables by key
*
* @vars = Variable array
* @order = Sort order. If =0 ascend or !=0 descend
* return: none
*/
void ait_sortVarsByKey(array_t * __restrict vars, int order);
/*
* ait_sortVarsByVal() - Sorting array with variables by value
*
* @vars = Variable array
* @order = Sort order. If =0 ascend or !=0 descend
* @cmp = Custom compare function for sorting. If =NULL compare by value
* return: none
*/
void ait_sortVarsByVal(array_t * __restrict vars, int order,
int (*cmp)(const void*, const void*));
/*
* ait_findKeyVars() - Find variable by key from array
*
* @vars = Variables
* @key = Search key
* return: NULL error or not found, !=NULL valid element
*/
ait_val_t *ait_findKeyVars(array_t * __restrict vars, unsigned short key);
/*
* ait_findKeyHash() - Find variable by hash string from array
*
* @vars = Variables
* @key = Search string
* return: NULL error or not found, !=NULL valid element
*/
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
*/
int ait_hashKeyVars(array_t * __restrict vars);
#endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>