A modelling and serializer library for Microsoft Azure IoTHub client applications
Dependents: sht15_remote_monitoring f767zi_mqtt remote_monitoring simplesample_amqp ... more
This library implements a serializer library to be used in projects involving Microsoft Azure IoT Hub connectivity. The code is replicated from https://github.com/Azure/azure-iot-sdks
Diff: agenttypesystem.c
- Revision:
- 8:380e6e830589
- Parent:
- 7:5176a13270bb
- Child:
- 9:747680124ff7
diff -r 5176a13270bb -r 380e6e830589 agenttypesystem.c --- a/agenttypesystem.c Thu Feb 04 11:29:40 2016 -0800 +++ b/agenttypesystem.c Tue Feb 16 14:25:09 2016 -0800 @@ -42,7 +42,25 @@ #define NAN ((float)(INFINITY * 0.0F)) #endif /* NAN */ -#define GUID_STRING_LENGHT 38 +#define GUID_STRING_LENGTH 38 + +// This is an artificial upper limit on floating point string length +// (e.g. the size of the string when printing %f). It is set to twice the +// maximum decimal precision plus 2. 1 for the decimal point and 1 for a +// sign (+/-) +// Unfortunately it is quite possible to print a float larger than this. +// An example of this would be printf("%.*f", MAX_FLOATING_POINT_STRING_LENGTH, 1.3); +// But currently no explicit requests for this exist in the file nor are +// any expected to reasonably occur when being used (numbers that hit +// this limit would be experiencing significant precision loss in storage anyway. +#define MAX_FLOATING_POINT_STRING_LENGTH (DECIMAL_DIG *2 + 2) + +// This maximum length is 11 for 32 bit integers (including the sign) +// optionally increase to 21 if longs are 64 bit +#define MAX_LONG_STRING_LENGTH ( 11 + (10 * (sizeof(long)/ 8))) + +// This is the maximum length for the largest 64 bit number (signed) +#define MAX_ULONG_LONG_STRING_LENGTH 20 DEFINE_ENUM_STRINGS(AGENT_DATA_TYPES_RESULT, AGENT_DATA_TYPES_RESULT_VALUES); @@ -1235,9 +1253,6 @@ } } -#define tempBufferSize 10240 -static char tempBuffer[tempBufferSize]; - static char hexDigitToChar(uint8_t hexDigit) { if (hexDigit < 10) return '0' + hexDigit; @@ -1394,53 +1409,115 @@ { if (value->value.edmDateTimeOffset.hasFractionalSecond) { - if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.12llu%+.2d:%.2d\"", /*+ in printf forces the sign to appear*/ - value->value.edmDateTimeOffset.dateTime.tm_year+1900, - value->value.edmDateTimeOffset.dateTime.tm_mon+1, - value->value.edmDateTimeOffset.dateTime.tm_mday, - value->value.edmDateTimeOffset.dateTime.tm_hour, - value->value.edmDateTimeOffset.dateTime.tm_min, - value->value.edmDateTimeOffset.dateTime.tm_sec, - value->value.edmDateTimeOffset.fractionalSecond, - value->value.edmDateTimeOffset.timeZoneHour, - value->value.edmDateTimeOffset.timeZoneMinute) < 0) - { - result = AGENT_DATA_TYPES_ERROR; - LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); - } - else if (STRING_concat(destination, tempBuffer) != 0) + size_t tempBufferSize = 1 + // \" + MAX_LONG_STRING_LENGTH + // %.4d + 1 + // - + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // - + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // T + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // : + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // : + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // . + MAX_ULONG_LONG_STRING_LENGTH + // %.12llu + 1 + MAX_LONG_STRING_LENGTH + // %+.2d + 1 + // : + MAX_LONG_STRING_LENGTH + // %.2d + 1 + //\" + 1; // " (terminating NULL); + + char* tempBuffer = (char*)malloc(tempBufferSize); + if (tempBuffer == NULL) { result = AGENT_DATA_TYPES_ERROR; LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); } else { - result = AGENT_DATA_TYPES_OK; + if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.12llu%+.2d:%.2d\"", /*+ in printf forces the sign to appear*/ + value->value.edmDateTimeOffset.dateTime.tm_year+1900, + value->value.edmDateTimeOffset.dateTime.tm_mon+1, + value->value.edmDateTimeOffset.dateTime.tm_mday, + value->value.edmDateTimeOffset.dateTime.tm_hour, + value->value.edmDateTimeOffset.dateTime.tm_min, + value->value.edmDateTimeOffset.dateTime.tm_sec, + value->value.edmDateTimeOffset.fractionalSecond, + value->value.edmDateTimeOffset.timeZoneHour, + value->value.edmDateTimeOffset.timeZoneMinute) < 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else if (STRING_concat(destination, tempBuffer) != 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else + { + result = AGENT_DATA_TYPES_OK; + } + + // Clean up temp buffer if allocated + free(tempBuffer); } } else { - if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d%+.2d:%.2d\"", /*+ in printf forces the sign to appear*/ - value->value.edmDateTimeOffset.dateTime.tm_year + 1900, - value->value.edmDateTimeOffset.dateTime.tm_mon+1, - value->value.edmDateTimeOffset.dateTime.tm_mday, - value->value.edmDateTimeOffset.dateTime.tm_hour, - value->value.edmDateTimeOffset.dateTime.tm_min, - value->value.edmDateTimeOffset.dateTime.tm_sec, - value->value.edmDateTimeOffset.timeZoneHour, - value->value.edmDateTimeOffset.timeZoneMinute) < 0) - { - result = AGENT_DATA_TYPES_ERROR; - LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); - } - else if (STRING_concat(destination, tempBuffer) != 0) + size_t tempBufferSize = 1 + // \" + MAX_LONG_STRING_LENGTH + // %.4d + 1 + // - + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // - + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // T + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // : + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // : + MAX_LONG_STRING_LENGTH + // %.2d + 1 + MAX_LONG_STRING_LENGTH + // %+.2d + 1 + // : + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // \" + 1; // " terminating NULL + char* tempBuffer = (char*)malloc(tempBufferSize); + + if (tempBuffer == NULL) { result = AGENT_DATA_TYPES_ERROR; LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); } else { - result = AGENT_DATA_TYPES_OK; + if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d%+.2d:%.2d\"", /*+ in printf forces the sign to appear*/ + value->value.edmDateTimeOffset.dateTime.tm_year + 1900, + value->value.edmDateTimeOffset.dateTime.tm_mon+1, + value->value.edmDateTimeOffset.dateTime.tm_mday, + value->value.edmDateTimeOffset.dateTime.tm_hour, + value->value.edmDateTimeOffset.dateTime.tm_min, + value->value.edmDateTimeOffset.dateTime.tm_sec, + value->value.edmDateTimeOffset.timeZoneHour, + value->value.edmDateTimeOffset.timeZoneMinute) < 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else if (STRING_concat(destination, tempBuffer) != 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else + { + result = AGENT_DATA_TYPES_OK; + } + + // Clean up temp buffer if allocated + free(tempBuffer); } } } @@ -1448,53 +1525,108 @@ { if (value->value.edmDateTimeOffset.hasFractionalSecond) { - if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.12lluZ\"", /*+ in printf forces the sign to appear*/ - value->value.edmDateTimeOffset.dateTime.tm_year + 1900, - value->value.edmDateTimeOffset.dateTime.tm_mon+1, - value->value.edmDateTimeOffset.dateTime.tm_mday, - value->value.edmDateTimeOffset.dateTime.tm_hour, - value->value.edmDateTimeOffset.dateTime.tm_min, - value->value.edmDateTimeOffset.dateTime.tm_sec, - value->value.edmDateTimeOffset.fractionalSecond) < 0) - { - result = AGENT_DATA_TYPES_ERROR; - LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); - } - else if (STRING_concat(destination, tempBuffer) != 0) + size_t tempBufferSize = 1 + //\" + MAX_LONG_STRING_LENGTH + // %.4d + 1 + // - + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // - + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // T + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // : + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // : + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // . + MAX_ULONG_LONG_STRING_LENGTH + // %.12llu + 1 + // Z + 1 + // \" + 1; // " (terminating NULL) + char* tempBuffer = (char*)malloc(tempBufferSize); + + if (tempBuffer == NULL) { result = AGENT_DATA_TYPES_ERROR; LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); } else { - result = AGENT_DATA_TYPES_OK; + if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.12lluZ\"", /*+ in printf forces the sign to appear*/ + value->value.edmDateTimeOffset.dateTime.tm_year + 1900, + value->value.edmDateTimeOffset.dateTime.tm_mon+1, + value->value.edmDateTimeOffset.dateTime.tm_mday, + value->value.edmDateTimeOffset.dateTime.tm_hour, + value->value.edmDateTimeOffset.dateTime.tm_min, + value->value.edmDateTimeOffset.dateTime.tm_sec, + value->value.edmDateTimeOffset.fractionalSecond) < 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else if (STRING_concat(destination, tempBuffer) != 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else + { + result = AGENT_DATA_TYPES_OK; + } + + free(tempBuffer); } } else { - if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ\"", - value->value.edmDateTimeOffset.dateTime.tm_year + 1900, - value->value.edmDateTimeOffset.dateTime.tm_mon+1, - value->value.edmDateTimeOffset.dateTime.tm_mday, - value->value.edmDateTimeOffset.dateTime.tm_hour, - value->value.edmDateTimeOffset.dateTime.tm_min, - value->value.edmDateTimeOffset.dateTime.tm_sec) < 0) - { - result = AGENT_DATA_TYPES_ERROR; - LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); - } - else if (STRING_concat(destination, tempBuffer) != 0) + size_t tempBufferSize = 1 + // \" + MAX_LONG_STRING_LENGTH + // %.4d + 1 + // - + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // - + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // T + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // : + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // : + MAX_LONG_STRING_LENGTH + // %.2d + 1 + // Z + 1 + // \" + 1; // " (terminating null); + + char* tempBuffer = (char*)malloc(tempBufferSize); + + if (tempBuffer == NULL) { result = AGENT_DATA_TYPES_ERROR; LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); } else { - result = AGENT_DATA_TYPES_OK; + if (sprintf_s(tempBuffer, tempBufferSize, "\"%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ\"", + value->value.edmDateTimeOffset.dateTime.tm_year + 1900, + value->value.edmDateTimeOffset.dateTime.tm_mon+1, + value->value.edmDateTimeOffset.dateTime.tm_mday, + value->value.edmDateTimeOffset.dateTime.tm_hour, + value->value.edmDateTimeOffset.dateTime.tm_min, + value->value.edmDateTimeOffset.dateTime.tm_sec) < 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else if (STRING_concat(destination, tempBuffer) != 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else + { + result = AGENT_DATA_TYPES_OK; + } + + free(tempBuffer); } } - - } break; } @@ -1708,7 +1840,9 @@ else { /*forward parse the string to scan for " and for \ that in JSON are \" respectively \\*/ - if (tempBufferSize < vlen + 5 * nControlCharacters + nEscapeCharacters + 3) + size_t tempBufferSize = vlen + 5 * nControlCharacters + nEscapeCharacters + 3 + 1; + char* tempBuffer = (char*)malloc(tempBufferSize); + if (tempBuffer == NULL) { result = AGENT_DATA_TYPES_ERROR; LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); @@ -1765,6 +1899,8 @@ { result = AGENT_DATA_TYPES_OK; } + + free(tempBuffer); } } @@ -1833,19 +1969,34 @@ result = AGENT_DATA_TYPES_OK; } } - else if(sprintf_s(tempBuffer, tempBufferSize, "%.*f", FLT_DIG, (double)(value->value.edmSingle.value))<0) - { - result = AGENT_DATA_TYPES_ERROR; - LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); - } - else if (STRING_concat(destination, tempBuffer) != 0) - { - result = AGENT_DATA_TYPES_ERROR; - LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); - } else { - result = AGENT_DATA_TYPES_OK; + size_t tempBufferSize = MAX_FLOATING_POINT_STRING_LENGTH; + char* tempBuffer = (char*)malloc(tempBufferSize); + if (tempBuffer == NULL) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else + { + if (sprintf_s(tempBuffer, tempBufferSize, "%.*f", FLT_DIG, (double)(value->value.edmSingle.value)) < 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else if (STRING_concat(destination, tempBuffer) != 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else + { + result = AGENT_DATA_TYPES_OK; + } + + free(tempBuffer); + } } break; } @@ -1896,19 +2047,34 @@ } } /*Codes_SRS_AGENT_TYPE_SYSTEM_99_022:[ EDM_DOUBLE: doubleValue = decimalValue [ "e" [SIGN] 1*DIGIT ] / nanInfinity ; IEEE 754 binary64 floating-point number (15-17 decimal digits). The representation shall use DBL_DIG C #define*/ - else if(sprintf_s(tempBuffer, tempBufferSize, "%.*f", DBL_DIG, value->value.edmDouble.value)<0) - { - result = AGENT_DATA_TYPES_ERROR; - LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); - } - else if (STRING_concat(destination, tempBuffer) != 0) - { - result = AGENT_DATA_TYPES_ERROR; - LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); - } else { - result = AGENT_DATA_TYPES_OK; + size_t tempBufferSize = DECIMAL_DIG * 2; + char* tempBuffer = (char*)malloc(tempBufferSize); + if (tempBuffer == NULL) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else + { + if (sprintf_s(tempBuffer, tempBufferSize, "%.*f", DBL_DIG, value->value.edmDouble.value) < 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else if (STRING_concat(destination, tempBuffer) != 0) + { + result = AGENT_DATA_TYPES_ERROR; + LogError("(result = %s)\r\n", ENUM_TO_STRING(AGENT_DATA_TYPES_RESULT, result)); + } + else + { + result = AGENT_DATA_TYPES_OK; + } + + free(tempBuffer); + } } break; } @@ -2922,10 +3088,29 @@ /* Codes_SRS_AGENT_TYPE_SYSTEM_99_082:[ EDM_INT32] */ case EDM_INT32_TYPE: { - long long int32Value; - if ((sscanf(source, "%lld", &int32Value) != 1) || - (int32Value < -2147483648LL) || - (int32Value > 2147483647)) + int32_t int32Value; + unsigned char isNegative; + uint32_t uint32Value; + const char* pos; + size_t strLength; + + if (source[0] == '-') + { + isNegative = 1; + pos = &source[1]; + } + else + { + isNegative = 0; + pos = &source[0]; + } + + strLength = strlen(source); + + if ((sscanf(pos, "%lu", &uint32Value) != 1) || + (strLength > 11) || + ((uint32Value > 2147483648UL) && isNegative) || + ((uint32Value > 2147483647UL) && (!isNegative))) { /* Codes_SRS_AGENT_TYPE_SYSTEM_99_087:[ CreateAgentDataType_From_String shall return AGENT_DATA_TYPES_INVALID_ARG if source is not a valid string for a value of type type.] */ result = AGENT_DATA_TYPES_INVALID_ARG; @@ -2933,6 +3118,22 @@ } else { + if (isNegative) + { + if (uint32Value == 2147483648UL) + { + int32Value = -2147483647L - 1L; + } + else + { + int32Value = -(int32_t)uint32Value; + } + } + else + { + int32Value = uint32Value; + } + agentData->type = EDM_INT32_TYPE; agentData->value.edmInt32.value = (int32_t)int32Value; result = AGENT_DATA_TYPES_OK; @@ -3380,7 +3581,7 @@ /*Codes_SRS_AGENT_TYPE_SYSTEM_99_097:[ EDM_GUID]*/ case EDM_GUID_TYPE: { - if (strlen(source) != GUID_STRING_LENGHT) + if (strlen(source) != GUID_STRING_LENGTH) { result = AGENT_DATA_TYPES_INVALID_ARG; }