6#ifndef aida_pva_types_helper_h
7#define aida_pva_types_helper_h
17#define MIN_FLOAT_ALLOCATIONS 100
22#define FORMAT_INTEGER 'd'
26#define FORMAT_UNSIGNED_INTEGER 'u'
30#define FORMAT_FLOAT 'f'
34#define FORMAT_STRING 's'
38#define FORMAT_BYTE 'c'
42#define FORMAT_BOOLEAN 'b'
47#define FORMAT_OPTIONAL_FLAG 'o'
52#define FORMAT_PREFIX_SHORT 'h'
56#define FORMAT_PREFIX_LONG 'l'
61#define FORMAT_SUFFIX_ARRAY 'a'
66#define MAX_FORMAT_SPECIFIERS 20
74#define ARRAY_TARGET(_cType) &((_cType *)(*arrayPtr))[i]
78#define ASCANF_SET_SCALAR(_format, _cType, _jsonType, _typeName, _target) \
80 _cType* ptr = (_cType*)(_target); \
81 if (!valueShouldBeJson) { \
82 if ( sscanf(stringValue, _format, ptr) == 0 ) { \
83 SPRINTF_ERROR_FREE_MEMORY_AND_RETURN_(AIDA_INTERNAL_EXCEPTION, "can't convert argument \"%s\" to " _typeName, stringValue, EXIT_FAILURE) \
86 if (jsonRoot->type == json_integer) { \
87 *ptr = (_cType)jsonRoot->u.integer; \
88 } else if (jsonRoot->type == json_double) { \
89 *ptr = (_cType)(jsonRoot->u.dbl); \
90 } else if (jsonRoot->type == json_string) { \
91 if ( sscanf(jsonRoot->u.string.ptr, _format, ptr) == 0 ) { \
92 SPRINTF_ERROR_FREE_MEMORY_AND_RETURN_(AIDA_INTERNAL_EXCEPTION, "can't convert argument \"%s\" to " _typeName, jsonRoot->u.string.ptr, EXIT_FAILURE) \
94 } else if (isRequired) { \
95 PRINT_ERROR_FREE_MEMORY_AND_RETURN_(AIDA_INTERNAL_EXCEPTION, "can't convert argument to " _typeName ": <json>", EXIT_FAILURE) \
103#define ASCANF_SET_BOOLEAN(_targetBoolean) \
105 unsigned char* ptr = (unsigned char*)(_targetBoolean); \
106 if (!valueShouldBeJson) { \
107 if (isdigit(*stringValue)) {\
109 sscanf(stringValue, "%lg", &number); \
110 *ptr = (unsigned char)((number == 0.0) ? 0 : 1); \
112 int _val = getBooleanValue(stringValue); \
113 if ( _val == -1 ) { \
114 SPRINTF_ERROR_FREE_MEMORY_AND_RETURN_(AIDA_INTERNAL_EXCEPTION, "can't convert argument to boolean: %s", stringValue, EXIT_FAILURE) \
120 if (jsonRoot->type == json_integer) { \
121 *ptr = (unsigned char)(jsonRoot->u.integer != 0); \
122 } else if (jsonRoot->type == json_double) { \
123 *ptr = (unsigned char)(jsonRoot->u.dbl != 0.0); \
124 } else if (jsonRoot->type == json_boolean) { \
125 *ptr = (unsigned char)jsonRoot->u.boolean; \
126 } else if (jsonRoot->type == json_string) { \
127 int _val = getBooleanValue(jsonRoot->u.string.ptr); \
128 if ( _val == -1 ) { \
129 SPRINTF_ERROR_FREE_MEMORY_AND_RETURN_(AIDA_INTERNAL_EXCEPTION, "can't convert argument to boolean: %s", jsonRoot->u.string.ptr, EXIT_FAILURE) \
134 PRINT_ERROR_FREE_MEMORY_AND_RETURN_(AIDA_INTERNAL_EXCEPTION, "can't convert argument to boolean: <json>", EXIT_FAILURE) \
142#define ASCANF_SET_BYTE(_targetByte) \
144 unsigned char* ptr = (unsigned char*)(_targetByte); \
145 if (!valueShouldBeJson) { \
146 *ptr = *stringValue; \
148 if (jsonRoot->type == json_integer) { \
149 *ptr = (int)(jsonRoot->u.integer & 0XFF) ; \
150 } else if (jsonRoot->type == json_string && jsonRoot->u.string.length == 1) { \
151 *ptr = *jsonRoot->u.string.ptr; \
153 PRINT_ERROR_FREE_MEMORY_AND_RETURN_(AIDA_INTERNAL_EXCEPTION, "can't convert argument to byte: <json>", EXIT_FAILURE) \
161#define ASCANF_SET_STRING(_targetString) \
163 char** ptr = (char**)(_targetString); \
164 if (!valueShouldBeJson) { \
165 *ptr = stringValue; \
167 if (aidaType == AIDA_STRING_TYPE) { \
168 ALLOCATE_AND_TRACK_MEMORY_AND_ON_ERROR_RETURN_(env, nextStringPosition, jsonRoot->u.string.length+1, "string arguments", EXIT_FAILURE) \
170 if (jsonRoot->type == json_string) { \
171 strcpy(nextStringPosition, jsonRoot->u.string.ptr); \
172 } else if (jsonRoot->type == json_integer) { \
173 sprintf(nextStringPosition, "%ld", jsonRoot->u.integer); \
174 } else if (jsonRoot->type == json_double) { \
175 sprintf(nextStringPosition, "%g", jsonRoot->u.dbl); \
177 PRINT_ERROR_FREE_MEMORY_AND_RETURN_(AIDA_INTERNAL_EXCEPTION, "can't convert argument to string: <json>", EXIT_FAILURE) \
179 *ptr = nextStringPosition; \
180 nextStringPosition+=strlen(nextStringPosition)+1; \
187#define ASCANF_SET_ARRAY(_format, _cType, _jsonType, _typeName) \
189 ALLOCATE_AND_TRACK_MEMORY_AND_ON_ERROR_RETURN_(env, *arrayPtr, arrayCount * sizeof(_cType), "array arguments", EXIT_FAILURE) \
190 for (int i = 0; i < arrayCount; i++) { \
191 jsonRoot = arrayRoot->u.array.values[i]; \
192 ASCANF_SET_SCALAR(_format, _cType, _jsonType, _typeName, ARRAY_TARGET(_cType)) \
199#define ASCANF_SET_BOOLEAN_OR_BYTE_ARRAY(_cType, _setMacro) \
201 ALLOCATE_AND_TRACK_MEMORY_AND_ON_ERROR_RETURN_(env, *arrayPtr, arrayCount * sizeof(_cType), "array arguments", EXIT_FAILURE) \
202 for (int i = 0; i < arrayCount; i++) { \
203 jsonRoot = arrayRoot->u.array.values[i]; \
204 _setMacro(ARRAY_TARGET(_cType)) \
211#define ASCANF_SET_BOOLEAN_ARRAY ASCANF_SET_BOOLEAN_OR_BYTE_ARRAY(unsigned char, ASCANF_SET_BOOLEAN)
216#define ASCANF_SET_BYTE_ARRAY ASCANF_SET_BOOLEAN_OR_BYTE_ARRAY(unsigned char, ASCANF_SET_BYTE)
223#define ASCANF_SET_STRING_ARRAY \
225 size_t pointerSpace = arrayCount * sizeof(char*); \
226 ALLOCATE_AND_TRACK_MEMORY_AND_ON_ERROR_RETURN_(env, *arrayPtr, pointerSpace + totalStingLengthOf(arrayRoot) + arrayCount + 1, "string array arguments", EXIT_FAILURE) \
227 nextStringPosition = ((char*)*arrayPtr) + pointerSpace; \
228 for (int i = 0; i < arrayCount; i++) { \
229 jsonRoot = arrayRoot->u.array.values[i]; \
230 ASCANF_SET_STRING(ARRAY_TARGET(char *)) \
The Header File for the AIDA-PVA Module functions.