|
version 1.6, 2013/11/14 21:31:28
|
version 1.12.6.1, 2022/10/24 00:09:07
|
|
Line 12 terms:
|
Line 12 terms:
|
| All of the documentation and software included in the ELWIX and AITNET |
All of the documentation and software included in the ELWIX and AITNET |
| Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> |
Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> |
| |
|
| Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 | Copyright 2004 - 2022 |
| by Michael Pounov <misho@elwix.org>. All rights reserved. |
by Michael Pounov <misho@elwix.org>. All rights reserved. |
| |
|
| Redistribution and use in source and binary forms, with or without |
Redistribution and use in source and binary forms, with or without |
|
Line 249 buffer2vars(u_char * __restrict buf, int buflen, int v
|
Line 249 buffer2vars(u_char * __restrict buf, int buflen, int v
|
| return vars; |
return vars; |
| } |
} |
| |
|
| |
/* |
| |
* ait_var2tlv() - Marshaling data from variable to TLV buffer |
| |
* |
| |
* @buf = Buffer, If =NULL then we return only needed buffer size |
| |
* @buflen = Size of buffer |
| |
* @var = Variable |
| |
* return: -1 error, 0 nothing done or >0 size of marshaled data |
| |
*/ |
| |
int |
| |
ait_var2tlv(u_char * __restrict buf, int buflen, ait_val_t * __restrict v) |
| |
{ |
| |
int Limit = 0; |
| |
u_char *dat; |
| |
|
| |
assert(v); |
| |
if (!v) |
| |
return -1; |
| |
if (AIT_TYPE(v) == empty) |
| |
return 0; |
| |
|
| |
/* calculate amount of data into buffer */ |
| |
Limit = 5 + AIT_LEN(v); |
| |
/* check only needed buffer size */ |
| |
if (!buf) |
| |
return Limit; |
| |
else |
| |
dat = buf; |
| |
|
| |
if (Limit > buflen) { |
| |
elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", |
| |
buflen, Limit); |
| |
return -1; |
| |
} else |
| |
memset(buf, 0, buflen); |
| |
|
| |
/* marshaling */ |
| |
*dat++ = AIT_TYPE(v); |
| |
|
| |
*((uint32_t*) dat) = htonl(AIT_LEN(v)); |
| |
dat += sizeof(uint32_t); |
| |
|
| |
switch (AIT_TYPE(v)) { |
| |
case i8: |
| |
*((int8_t*) dat) = AIT_GET_I8(v); |
| |
break; |
| |
case u8: |
| |
*((uint8_t*) dat) = AIT_GET_U8(v); |
| |
break; |
| |
case i16: |
| |
*((int16_t*) dat) = AIT_GET_I16(v); |
| |
break; |
| |
case u16: |
| |
*((uint16_t*) dat) = AIT_GET_U16(v); |
| |
break; |
| |
case i32: |
| |
*((int32_t*) dat) = AIT_GET_I32(v); |
| |
break; |
| |
case blob: |
| |
case u32: |
| |
*((uint32_t*) dat) = AIT_GET_U32(v); |
| |
break; |
| |
case i64: |
| |
*((int64_t*) dat) = AIT_GET_I64(v); |
| |
break; |
| |
case u64: |
| |
*((uint64_t*) dat) = AIT_GET_U64(v); |
| |
break; |
| |
case f32: |
| |
*((float*) dat) = AIT_GET_F32(v); |
| |
break; |
| |
case f64: |
| |
*((double*) dat) = AIT_GET_F64(v); |
| |
break; |
| |
case data: |
| |
memcpy(dat, AIT_GET_DATA(v), AIT_LEN(v)); |
| |
break; |
| |
case buffer: |
| |
memcpy(dat, AIT_GET_BUF(v), AIT_LEN(v)); |
| |
break; |
| |
case string: |
| |
memcpy(dat, AIT_GET_STR(v), AIT_LEN(v)); |
| |
break; |
| |
case ptr: |
| |
memcpy(dat, AIT_GET_PTR(v), AIT_LEN(v)); |
| |
break; |
| |
default: |
| |
elwix_SetErr(EINVAL, "Unsupported variable type=%d", AIT_TYPE(v)); |
| |
return -1; |
| |
} |
| |
|
| |
return Limit; |
| |
} |
| |
|
| |
/* |
| |
* 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) |
| |
{ |
| |
int Limit = 0; |
| |
register int i; |
| |
ait_val_t *val; |
| |
u_char *dat; |
| |
|
| |
assert(vars); |
| |
if (!vars) |
| |
return -1; |
| |
if (!array_Size(vars)) |
| |
return 0; |
| |
|
| |
/* calculate amount of data into buffer */ |
| |
for (i = 0, Limit = 0; i < array_Size(vars); |
| |
Limit += 5 + AIT_LEN(array(vars, i, ait_val_t*)), i++); |
| |
/* check only needed buffer size */ |
| |
if (!buf) |
| |
return Limit; |
| |
|
| |
if (Limit > buflen) { |
| |
elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", |
| |
buflen, Limit); |
| |
return -1; |
| |
} else |
| |
memset(buf, 0, buflen); |
| |
|
| |
/* marshaling */ |
| |
for (i = 0, dat = buf; i < array_Size(vars) && dat < (buf + Limit); i++) { |
| |
val = array(vars, i, ait_val_t*); |
| |
|
| |
*dat++ = AIT_TYPE(val); |
| |
|
| |
*((uint32_t*) dat) = htonl(AIT_LEN(val)); |
| |
dat += sizeof(uint32_t); |
| |
|
| |
switch (AIT_TYPE(val)) { |
| |
case i8: |
| |
*((int8_t*) dat) = AIT_GET_I8(val); |
| |
break; |
| |
case u8: |
| |
*((uint8_t*) dat) = AIT_GET_U8(val); |
| |
break; |
| |
case i16: |
| |
*((int16_t*) dat) = AIT_GET_I16(val); |
| |
break; |
| |
case u16: |
| |
*((uint16_t*) dat) = AIT_GET_U16(val); |
| |
break; |
| |
case i32: |
| |
*((int32_t*) dat) = AIT_GET_I32(val); |
| |
break; |
| |
case blob: |
| |
case u32: |
| |
*((uint32_t*) dat) = AIT_GET_U32(val); |
| |
break; |
| |
case i64: |
| |
*((int64_t*) dat) = AIT_GET_I64(val); |
| |
break; |
| |
case u64: |
| |
*((uint64_t*) dat) = AIT_GET_U64(val); |
| |
break; |
| |
case f32: |
| |
*((float*) dat) = AIT_GET_F32(val); |
| |
break; |
| |
case f64: |
| |
*((double*) dat) = AIT_GET_F64(val); |
| |
break; |
| |
case data: |
| |
memcpy(dat, AIT_GET_DATA(val), AIT_LEN(val)); |
| |
break; |
| |
case buffer: |
| |
memcpy(dat, AIT_GET_BUF(val), AIT_LEN(val)); |
| |
break; |
| |
case string: |
| |
memcpy(dat, AIT_GET_STR(val), AIT_LEN(val)); |
| |
break; |
| |
case ptr: |
| |
memcpy(dat, AIT_GET_PTR(val), AIT_LEN(val)); |
| |
break; |
| |
default: |
| |
elwix_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", |
| |
AIT_TYPE(val), i); |
| |
return -1; |
| |
} |
| |
dat += AIT_LEN(val); |
| |
} |
| |
|
| |
return Limit; |
| |
} |
| |
|
| |
/* |
| |
* ait_tlv2var() - De-marshaling data from TLV buffer to variable |
| |
* |
| |
* @buf = Buffer |
| |
* @buflen = Size of buffer |
| |
* @next_tlv = Next TLV position, if it is !=NULL |
| |
* return: =NULL error, !=NULL allocated variable array, after use must free with ait_freeVar() |
| |
*/ |
| |
ait_val_t * |
| |
ait_tlv2var(u_char * __restrict buf, int buflen, off_t *next_tlv) |
| |
{ |
| |
ait_val_t *val; |
| |
u_char *dat; |
| |
|
| |
assert(buf); |
| |
if (!buf || !buflen) |
| |
return NULL; |
| |
|
| |
if (!(val = ait_allocVar())) |
| |
return NULL; |
| |
else |
| |
dat = buf; |
| |
|
| |
/* de-marshaling */ |
| |
if (*dat != empty) { |
| |
val->val_type = *dat++; |
| |
AIT_LEN(val) = ntohl(*((uint32_t*) dat)); |
| |
dat += sizeof(uint32_t); |
| |
|
| |
switch (AIT_TYPE(val)) { |
| |
case f32: |
| |
AIT_SET_F32(val, *((float*) dat)); |
| |
break; |
| |
case f64: |
| |
AIT_SET_F64(val, *((double*) dat)); |
| |
break; |
| |
case i8: |
| |
AIT_SET_I8(val, *((int8_t*) dat)); |
| |
break; |
| |
case i16: |
| |
AIT_SET_I16(val, *((int16_t*) dat)); |
| |
break; |
| |
case i32: |
| |
AIT_SET_I32(val, *((int32_t*) dat)); |
| |
break; |
| |
case i64: |
| |
AIT_SET_I64(val, *((int64_t*) dat)); |
| |
break; |
| |
case u8: |
| |
AIT_SET_U8(val, *((uint8_t*) dat)); |
| |
break; |
| |
case u16: |
| |
AIT_SET_U16(val, *((uint16_t*) dat)); |
| |
break; |
| |
case blob: |
| |
case u32: |
| |
AIT_SET_U32(val, *((uint32_t*) dat)); |
| |
break; |
| |
case u64: |
| |
AIT_SET_U64(val, *((uint64_t*) dat)); |
| |
break; |
| |
case data: |
| |
AIT_SET_DATA(val, dat, AIT_LEN(val)); |
| |
break; |
| |
case ptr: |
| |
case buffer: |
| |
AIT_SET_BUF(val, dat, AIT_LEN(val)); |
| |
break; |
| |
case string: |
| |
AIT_SET_STR(val, (char*) dat); |
| |
break; |
| |
default: |
| |
elwix_SetErr(EINVAL, "Unsupported variable type=%d", AIT_TYPE(val)); |
| |
ait_freeVar(&val); |
| |
return NULL; |
| |
} |
| |
dat += AIT_LEN(val); |
| |
} |
| |
|
| |
if (next_tlv) |
| |
*next_tlv = dat - buf; |
| |
|
| |
return val; |
| |
} |
| |
|
| |
/* |
| |
* 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) |
| |
{ |
| |
array_t *vars; |
| |
register int i; |
| |
ait_val_t *val; |
| |
u_char *dat; |
| |
|
| |
assert(buf); |
| |
if (!buf || !buflen) |
| |
return NULL; |
| |
|
| |
if (!(vars = ait_allocVars(1))) |
| |
return NULL; |
| |
|
| |
/* de-marshaling */ |
| |
for (i = 0, dat = buf; *dat != empty && dat < (buf + buflen); i++) { |
| |
val = ait_getVars(&vars, i); |
| |
if (!val) { |
| |
ait_freeVars(&vars); |
| |
return NULL; |
| |
} |
| |
|
| |
val->val_type = *dat++; |
| |
AIT_LEN(val) = ntohl(*((uint32_t*) dat)); |
| |
dat += sizeof(uint32_t); |
| |
|
| |
switch (AIT_TYPE(val)) { |
| |
case f32: |
| |
AIT_SET_F32(val, *((float*) dat)); |
| |
break; |
| |
case f64: |
| |
AIT_SET_F64(val, *((double*) dat)); |
| |
break; |
| |
case i8: |
| |
AIT_SET_I8(val, *((int8_t*) dat)); |
| |
break; |
| |
case i16: |
| |
AIT_SET_I16(val, *((int16_t*) dat)); |
| |
break; |
| |
case i32: |
| |
AIT_SET_I32(val, *((int32_t*) dat)); |
| |
break; |
| |
case i64: |
| |
AIT_SET_I64(val, *((int64_t*) dat)); |
| |
break; |
| |
case u8: |
| |
AIT_SET_U8(val, *((uint8_t*) dat)); |
| |
break; |
| |
case u16: |
| |
AIT_SET_U16(val, *((uint16_t*) dat)); |
| |
break; |
| |
case blob: |
| |
case u32: |
| |
AIT_SET_U32(val, *((uint32_t*) dat)); |
| |
break; |
| |
case u64: |
| |
AIT_SET_U64(val, *((uint64_t*) dat)); |
| |
break; |
| |
case data: |
| |
AIT_SET_DATA(val, dat, AIT_LEN(val)); |
| |
break; |
| |
case ptr: |
| |
case buffer: |
| |
AIT_SET_BUF(val, dat, AIT_LEN(val)); |
| |
break; |
| |
case string: |
| |
AIT_SET_STR(val, (char*) dat); |
| |
break; |
| |
default: |
| |
elwix_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", |
| |
AIT_TYPE(val), i); |
| |
ait_freeVars(&vars); |
| |
return NULL; |
| |
} |
| |
dat += AIT_LEN(val); |
| |
} |
| |
|
| |
return vars; |
| |
} |
| |
|
| /* buffer marshaling with swapping bytes to network order */ |
/* buffer marshaling with swapping bytes to network order */ |
| |
|
| /* |
/* |
|
Line 314 ait_map2vars(u_char *buf, int buflen, int vnum, int zc
|
Line 679 ait_map2vars(u_char *buf, int buflen, int vnum, int zc
|
| return buffer2vars(buf, buflen, vnum, zcpy); |
return buffer2vars(buf, buflen, vnum, 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) |
| |
{ |
| |
array_t *vars; |
| |
ait_val_t *val; |
| |
register int i; |
| |
long n; |
| |
double d; |
| |
char *str; |
| |
|
| |
if (!args) |
| |
return NULL; |
| |
|
| |
vars = ait_allocVars(0); |
| |
if (!vars) |
| |
return NULL; |
| |
|
| |
for (i = 0; *args; i++, args++) { |
| |
val = ait_getVars(&vars, i); |
| |
if (!val) { |
| |
ait_freeVars(&vars); |
| |
return NULL; |
| |
} |
| |
|
| |
if (dn) { |
| |
n = strtol(*args, &str, 0); |
| |
if (!str || !*str) { |
| |
AIT_SET_I64(val, (int64_t) n); |
| |
continue; |
| |
} |
| |
d = strtod(*args, &str); |
| |
if (!str || !*str) { |
| |
AIT_SET_F64(val, d); |
| |
continue; |
| |
} |
| |
AIT_SET_STR(val, *args); |
| |
} else |
| |
AIT_SET_STR(val, *args); |
| |
} |
| |
|
| |
return vars; |
| |
} |
| |
|
| /* variables array */ |
/* variables array */ |
| |
|
| /* |
/* |
|
Line 794 ait_sprintfVar(ait_val_t * __restrict v, const char *f
|
Line 1208 ait_sprintfVar(ait_val_t * __restrict v, const char *f
|
| { |
{ |
| int ret = 0; |
int ret = 0; |
| va_list lst; |
va_list lst; |
| char *str = NULL; | char str[65536] = { [0 ... 65535] = 0 }; |
| |
|
| if (!v || !fmt) |
if (!v || !fmt) |
| return -1; |
return -1; |
| |
|
| va_start(lst, fmt); |
va_start(lst, fmt); |
| ret = vasprintf(&str, fmt, lst); | ret = vsnprintf(str, sizeof str - 1, fmt, lst); |
| va_end(lst); |
va_end(lst); |
| |
|
| if (str && ret > -1) { | if (ret > -1) { |
| AIT_FREE_VAL(v); |
AIT_FREE_VAL(v); |
| AIT_SET_STR(v, str); |
AIT_SET_STR(v, str); |
| } else |
} else |
| LOGERR; |
LOGERR; |
| |
|
| if (str) |
|
| free(str); |
|
| return ret; |
return ret; |
| } |
} |
| |
|