--- libaitio/inc/aitio.h 2012/05/14 12:49:21 1.17 +++ libaitio/inc/aitio.h 2012/07/03 08:51:05 1.20 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitio.h,v 1.17 2012/05/14 12:49:21 misho Exp $ +* $Id: aitio.h,v 1.20 2012/07/03 08:51:05 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -58,8 +58,13 @@ SUCH DAMAGE. #include #include #include +#include +#include +#define IO_SYSM 0 +#define IO_MPOOL 1 + #define VACUUM_LEFT 1 #define VACUUM_BETWEEN 2 @@ -123,7 +128,7 @@ typedef struct { #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_GET_LIKE(_vl, _type) ((_type) AIT_ADDR((_vl))) #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) @@ -142,7 +147,7 @@ typedef struct { #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 = (_vl); \ - __val = realloc(__val, sizeof(ait_val_t) + _len); \ + __val = io_realloc(__val, sizeof(ait_val_t) + _len); \ if (__val) { \ __val->val_type = data; AIT_LEN(__val) = _len; \ if ((_p)) \ @@ -151,23 +156,37 @@ typedef struct { (_vl) = __val; \ } while (0); #define AIT_SET_PTR(_vl, _p, _len) do { ait_val_t *__val = (_vl); assert(__val); \ - __val->val_type = ptr; AIT_LEN(__val) = _len; \ - __val->val.ptr = _p; } while (0) + __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); \ + void *__ptr = io_realloc(AIT_GET_BUF(__val), _len); \ + if (__ptr) { \ + __val->val.buffer = __ptr; AIT_LEN(__val) = _len; \ + } } while (0) +#define AIT_SET_BUF2(_vl, _c, _len) do { ait_val_t *__val = (_vl); assert(__val); \ + __val->val.buffer = io_malloc(_len); \ + if (__val->val.buffer) { \ + __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); assert(__val); \ - __val->val.buffer = malloc(_len); \ + __val->val.buffer = io_malloc(_len); \ if (__val->val.buffer) { \ __val->val_type = buffer; AIT_LEN(__val) = _len; \ - memcpy(__val->val.buffer, (_v), _len); \ + if ((_v)) \ + memcpy(__val->val.buffer, (_v), _len); \ + else \ + memset(__val->val.buffer, 0, _len); \ } } while (0) #define AIT_SET_STR(_vl, _v) do { ait_val_t *__val = (_vl); assert(__val); \ - __val->val.string = (int8_t*) strdup((_v)); \ + __val->val.string = (int8_t*) io_strdup((_v)); \ if (__val->val.string) { \ __val->val_type = string; \ AIT_LEN(__val) = strlen((_v)) + 1; \ } } while (0) #define AIT_SET_STRCAT(_vl, _v) do { ait_val_t *__val = (_vl); assert(__val); \ assert(AIT_TYPE(__val) == string); \ - void *__p = realloc(__val->val.string, \ + void *__p = io_realloc(__val->val.string, \ AIT_LEN(__val) + strlen((_v))); \ if (__p) { \ __val->val.string = __p; \ @@ -176,8 +195,8 @@ typedef struct { AIT_LEN(__val)); \ } } while (0) #define AIT_SET_BLOB(_vl, _n, _len) do { ait_val_t *__val = (_vl); assert(__val); \ - __val->val_type = blob; AIT_LEN(__val) = _len; \ - __val->val.blob = _n; } while (0) + __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) @@ -214,19 +233,36 @@ typedef struct { __val->val_type = f64; __val->val.f64 = _n; \ AIT_LEN(__val) = sizeof(double); } while (0) +#define AIT_COPY_VAL(_vl, _v) do { 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_VAL2(_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_INIT_VAL(_vl) (memset((_vl), 0, sizeof(ait_val_t))) - /* if attribute zeroCopy is set not execute free() */ + /* if attribute zeroCopy is set not execute io_free() */ #define AIT_FREE_VAL(_vl) do { ait_val_t *__val = (_vl); assert(__val); \ switch (AIT_TYPE(__val)) { \ case buffer: \ if (__val->val.buffer) { \ - free(__val->val.buffer); \ + io_free(__val->val.buffer); \ __val->val.buffer = NULL; \ } \ break; \ case string: \ if (__val->val.string) { \ - free(__val->val.string); \ + io_free(__val->val.string); \ __val->val.string = NULL; \ } \ break; \ @@ -261,7 +297,33 @@ inline int io_GetErrno(); inline const char *io_GetError(); +// io_mm_inuse() Check for memory management model +inline int io_mm_inuse(); + /* + * ioLibInit() - Init libaitio library memory management + * + * @mm = memory management (IO_SYSM or IO_MPOOL) + * @maxmem = memory limit + * return: -1 error or !=-1 used memory management model + */ +inline int ioLibInit(int mm, unsigned long maxmem); +/* + * ioLibFini() - Finish libaitio library memory management + * + * return: none + */ +inline void ioLibFini(); + +/* memory management hooks */ +extern void *(*io_malloc)(size_t); +extern void *(*io_calloc)(size_t, size_t); +extern void *(*io_realloc)(void*, size_t); +extern char *(*io_strdup)(const char*); +extern void (*io_free)(void*); + + +/* * io_ether_ntoa() - Convert ethernet address to string * * @n = ethernet address structure, like struct ether_addr @@ -380,6 +442,14 @@ inline int io_clrVars(array_t * __restrict vars); */ inline void io_freeVars(array_t ** __restrict vars); /* + * io_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 + */ +inline ait_val_t *io_getVars(array_t ** __restrict vars, int n); +/* * io_sortVars() - Sorting array with variables * * @vars = Variable array @@ -447,7 +517,7 @@ int ioRegexGet(const char *csRegex, const char *csData * @csRegex = Regulare expression pattern * @csData = Source data * @csNew = Data for replace - * return: NULL not match or error; !=NULL allocated new string, must be free after use! + * return: NULL not match or error; !=NULL allocated new string, must be io_free after use! */ char *ioRegexReplace(const char *csRegex, const char *csData, const char *csNew); @@ -455,7 +525,7 @@ char *ioRegexReplace(const char *csRegex, const char * * ioStrAst() - Function for evaluate string like asterisk variable "{text[:[-]#[:#]]}" * * @csString = Input string - * return: NULL error, !=NULL Allocated new string evaluated from input string, must be free() + * return: NULL error, !=NULL Allocated new string evaluated from input string, must be io_free() */ char *ioStrAst(const char *csString); @@ -492,7 +562,7 @@ inline int io_TrimStr(char * __restrict psLine); * * @psLine = Text string * @lineLen = Length of Text string - * return: NULL nothing to do or error; !=0 Allocated new converted data without term\0 (must be free) + * return: NULL nothing to do or error; !=0 Allocated new converted data without term\0 (must be io_free) */ inline unsigned char *io_Ch2Hex(unsigned char *psLine, int lineLen); /* @@ -500,7 +570,7 @@ inline unsigned char *io_Ch2Hex(unsigned char *psLine, * * @psLine = Text string * @lineLen = Length of Text string - * return: NULL nothing to do or error; !=0 Allocated new converted string(must be free) + * return: NULL nothing to do or error; !=0 Allocated new converted string(must be io_free) */ inline char *io_Hex2Ch(unsigned char *psLine, int lineLen); @@ -602,25 +672,21 @@ int io_arrayVacuum(array_t * __restrict arr, int fromW io_arraySize((_arr)) * sizeof(void*))) #define io_arrayGet2(_arr, _d) (assert((_arr) && (_arr)->arr_num > _d), ((_arr)->arr_data + _d)) -#define io_arrayGet(_arr, _d) (assert((_arr) && (_arr)->arr_num > _d), *((_arr)->arr_data + _d)) +#define io_arrayGet(_arr, _d) (assert((_arr) && (_arr)->arr_num > _d), (_arr)->arr_data[_d]) #define io_array(_arr, _d, _type) (assert((_arr) && (_arr)->arr_num > _d), \ - ((_type) *((_arr)->arr_data + _d))) + ((_type) (_arr)->arr_data[_d])) #define io_arraySet(_arr, _d, _ptr) do { \ assert((_arr) && (_arr)->arr_num > _d); \ if ((_arr)->arr_last < _d) \ (_arr)->arr_last = _d; \ - *((_arr)->arr_data + _d) = (void*) (_ptr); \ + (_arr)->arr_data[_d] = (void*) (_ptr); \ } while (0) #define io_arrayDel(_arr, _d, _fri) do { \ assert((_arr) && (_arr)->arr_num > _d); \ - if (_fri) \ - free(*((_arr)->arr_data + _d)); \ - *((_arr)->arr_data + _d) = NULL; \ + if (_fri && (_arr)->arr_data[_d]) \ + free((_arr)->arr_data[_d]); \ + (_arr)->arr_data[_d] = NULL; \ } while (0) -#define io_arraySyncLast(_arr) do { \ - assert((_arr)); \ - (_arr)->arr_last = io_arrayLen((_arr)); \ - } while (0) /* * io_arrayElem() - Always GET/PUT element into dynamic array, if not enough elements grow array @@ -666,7 +732,7 @@ inline int io_argsNum(const char *csArgs, const char * * @psArgs = Input arguments line, after execute string is modified!!! * @nargs = Maximum requested count of arguments from input string psArgs, if 0 all psArgs * @csDelim = Delimiter(s) for separate - * @parr = Output array of arguments ... (must be free with io_arrayDestroy() after use!) + * @parr = Output array of arguments ... (must be io_free with io_arrayDestroy() after use!) * return: 0 error format; -1 error:: can`t read; >0 ok, number of readed items */ int io_arrayMake(char * __restrict psArgs, int nargs, const char *csDelim, @@ -776,7 +842,7 @@ sarr_t *io_array2sarr(array_t ** __restrict a, int seg * io_CopyEnv() - Copy environment to new environment array; * * @oldenv = Environment array - * return: NULL error; !=NULL Allocated new environment array(must be free) + * return: NULL error; !=NULL Allocated new environment array(must be io_free) */ char **io_CopyEnv(const char **oldenv); /* @@ -784,7 +850,7 @@ char **io_CopyEnv(const char **oldenv); * * @psProg = Program name for execute * @oldarg = Arguments array - * return: NULL error; !=NULL Allocated execution array(must be free) + * return: NULL error; !=NULL Allocated execution array(must be io_free) */ char **io_ExecArgs(const char *psProg, const char **oldarg); /* @@ -901,7 +967,7 @@ extern int io_Debug; * * @pInput = input buffer * @inLen = input buffer len - * @ppOutput = output allocated buffe, must be free after use + * @ppOutput = output allocated buffe, must be io_free after use * @Cipher = cipher engine, like EVP_bf_cbc() or etc... * @pKey = key * @pIV = IV, salt (8 bytes) @@ -916,7 +982,7 @@ int ioCipher(unsigned char *pInput, int inLen, unsigne * * @pInput = input buffer * @inLen = input buffer len - * @ppOutput = output allocated buffe, must be free after use + * @ppOutput = output allocated buffe, must be io_free after use * @pKey = key * @pIV = IV, salt (8 bytes) * @nMode = Mode 0 - decrypting or 1 - encrypting @@ -929,7 +995,7 @@ int io_Blowfish(unsigned char *pInput, int inLen, unsi * * @pInput = Input buffer with ASCII * @inLen = Input buffer data length - * @ppOutput = Output buffer with cipher data, must be free after use + * @ppOutput = Output buffer with cipher data, must be io_free after use * @pKey = Key * @IV = IVector/Nonce/Counter, Warning: IV must be variable, because we write there!!! * return: -1 error or >-1 how many cipher blocks proceeded