A small memory footprint AMQP implimentation
Dependents: iothub_client_sample_amqp remote_monitoring simplesample_amqp
Diff: amqpvalue.c
- Revision:
- 23:1111ee8bcba4
- Parent:
- 21:f9c433d8e6ca
- Child:
- 25:1101516ee67d
--- a/amqpvalue.c Thu Apr 06 14:11:27 2017 -0700 +++ b/amqpvalue.c Fri Apr 21 14:50:32 2017 -0700 @@ -172,6 +172,8 @@ DECODER_STATE_ERROR } DECODER_STATE; +typedef struct INTERNAL_DECODER_DATA_TAG* INTERNAL_DECODER_HANDLE; + typedef struct INTERNAL_DECODER_DATA_TAG { ON_VALUE_DECODED on_value_decoded; @@ -180,7 +182,7 @@ DECODER_STATE decoder_state; uint8_t constructor_byte; AMQP_VALUE_DATA* decode_to_value; - void* inner_decoder; + INTERNAL_DECODER_HANDLE inner_decoder; DECODE_VALUE_STATE_UNION decode_value_state; } INTERNAL_DECODER_DATA; @@ -193,22 +195,31 @@ /* Codes_SRS_AMQPVALUE_01_003: [1.6.1 null Indicates an empty value.] */ AMQP_VALUE amqpvalue_create_null(void) { - /* Codes_SRS_AMQPVALUE_01_002: [If allocating the AMQP_VALUE fails then amqpvalue_create_null shall return NULL.] */ AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_002: [If allocating the AMQP_VALUE fails then amqpvalue_create_null shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_001: [amqpvalue_create_null shall return a handle to an AMQP_VALUE that stores a null value.] */ result->type = AMQP_TYPE_NULL; } + return result; } /* Codes_SRS_AMQPVALUE_01_004: [1.6.2 boolean Represents a true or false value.] */ AMQP_VALUE amqpvalue_create_boolean(bool value) { - /* Codes_SRS_AMQPVALUE_01_007: [If allocating the AMQP_VALUE fails then amqpvalue_create_boolean shall return NULL.] */ AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - if (result != NULL) + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_007: [If allocating the AMQP_VALUE fails then amqpvalue_create_boolean shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else { /* Codes_SRS_AMQPVALUE_01_006: [amqpvalue_create_boolean shall return a handle to an AMQP_VALUE that stores a boolean value.] */ result->type = AMQP_TYPE_BOOL; @@ -226,7 +237,9 @@ if ((value == NULL) || (bool_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, bool_value = %p", + value, bool_value); + result = __FAILURE__; } else { @@ -234,7 +247,8 @@ /* Codes_SRS_AMQPVALUE_01_011: [If the type of the value is not Boolean, then amqpvalue_get_boolean shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_BOOL) { - result = __FAILURE__; + LogError("Value is not of type bool"); + result = __FAILURE__; } else { @@ -271,7 +285,9 @@ if ((value == NULL) || (ubyte_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, ubyte_value = %p", + value, ubyte_value); + result = __FAILURE__; } else { @@ -279,7 +295,8 @@ /* Codes_SRS_AMQPVALUE_01_037: [If the type of the value is not ubyte (was not created with amqpvalue_create_ubyte), then amqpvalue_get_ubyte shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_UBYTE) { - result = __FAILURE__; + LogError("Value is not of type UBYTE"); + result = __FAILURE__; } else { @@ -298,13 +315,18 @@ AMQP_VALUE amqpvalue_create_ushort(uint16_t value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_039: [If allocating the AMQP_VALUE fails then amqpvalue_create_ushort shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_039: [If allocating the AMQP_VALUE fails then amqpvalue_create_ushort shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_038: [amqpvalue_create_ushort shall return a handle to an AMQP_VALUE that stores an uint16_t value.] */ result->type = AMQP_TYPE_USHORT; result->value.ushort_value = value; } + return result; } @@ -316,7 +338,9 @@ if ((value == NULL) || (ushort_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, ushort_value = %p", + value, ushort_value); + result = __FAILURE__; } else { @@ -324,7 +348,8 @@ /* Codes_SRS_AMQPVALUE_01_043: [If the type of the value is not ushort (was not created with amqpvalue_create_ushort), then amqpvalue_get_ushort shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_USHORT) { - result = __FAILURE__; + LogError("Value is not of type USHORT"); + result = __FAILURE__; } else { @@ -343,13 +368,18 @@ AMQP_VALUE amqpvalue_create_uint(uint32_t value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_045: [If allocating the AMQP_VALUE fails then amqpvalue_create_uint shall return NULL.] */ - if (result != NULL) + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_045: [If allocating the AMQP_VALUE fails then amqpvalue_create_uint shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else { /* Codes_SRS_AMQPVALUE_01_044: [amqpvalue_create_uint shall return a handle to an AMQP_VALUE that stores an uint32_t value.] */ result->type = AMQP_TYPE_UINT; result->value.uint_value = value; } + return result; } @@ -361,7 +391,9 @@ if ((value == NULL) || (uint_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, uint_value = %p", + value, uint_value); + result = __FAILURE__; } else { @@ -369,7 +401,8 @@ /* Codes_SRS_AMQPVALUE_01_048: [If the type of the value is not uint (was not created with amqpvalue_create_uint), then amqpvalue_get_uint shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_UINT) { - result = __FAILURE__; + LogError("Value is not of type UINT"); + result = __FAILURE__; } else { @@ -388,13 +421,18 @@ AMQP_VALUE amqpvalue_create_ulong(uint64_t value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_050: [If allocating the AMQP_VALUE fails then amqpvalue_create_ulong shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_050: [If allocating the AMQP_VALUE fails then amqpvalue_create_ulong shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_049: [amqpvalue_create_ulong shall return a handle to an AMQP_VALUE that stores an uint64_t value.] */ result->type = AMQP_TYPE_ULONG; result->value.ulong_value = value; } + return result; } @@ -406,7 +444,9 @@ if ((value == NULL) || (ulong_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, ulong_value = %p", + value, ulong_value); + result = __FAILURE__; } else { @@ -414,7 +454,8 @@ /* Codes_SRS_AMQPVALUE_01_054: [If the type of the value is not ulong (was not created with amqpvalue_create_ulong), then amqpvalue_get_ulong shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_ULONG) { - result = __FAILURE__; + LogError("Value is not of type ULONG"); + result = __FAILURE__; } else { @@ -433,13 +474,18 @@ AMQP_VALUE amqpvalue_create_byte(char value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_056: [If allocating the AMQP_VALUE fails then amqpvalue_create_byte shall return NULL.] */ - if (result != NULL) + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_056: [If allocating the AMQP_VALUE fails then amqpvalue_create_byte shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else { /* Codes_SRS_AMQPVALUE_01_055: [amqpvalue_create_byte shall return a handle to an AMQP_VALUE that stores a char value.] */ result->type = AMQP_TYPE_BYTE; result->value.byte_value = value; } + return result; } @@ -451,7 +497,9 @@ if ((value == NULL) || (byte_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, byte_value = %p", + value, byte_value); + result = __FAILURE__; } else { @@ -459,7 +507,8 @@ /* Codes_SRS_AMQPVALUE_01_060: [If the type of the value is not byte (was not created with amqpvalue_create_byte), then amqpvalue_get_byte shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_BYTE) { - result = __FAILURE__; + LogError("Value is not of type BYTE"); + result = __FAILURE__; } else { @@ -478,9 +527,13 @@ AMQP_VALUE amqpvalue_create_short(int16_t value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_062: [If allocating the AMQP_VALUE fails then amqpvalue_create_short shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_062: [If allocating the AMQP_VALUE fails then amqpvalue_create_short shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_061: [amqpvalue_create_short shall return a handle to an AMQP_VALUE that stores an int16_t value.] */ result->type = AMQP_TYPE_SHORT; result->value.short_value = value; @@ -496,7 +549,9 @@ if ((value == NULL) || (short_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, short_value = %p", + value, short_value); + result = __FAILURE__; } else { @@ -504,7 +559,8 @@ /* Codes_SRS_AMQPVALUE_01_066: [If the type of the value is not short (was not created with amqpvalue_create_short), then amqpvalue_get_short shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_SHORT) { - result = __FAILURE__; + LogError("Value is not of type SHORT"); + result = __FAILURE__; } else { @@ -523,13 +579,18 @@ AMQP_VALUE amqpvalue_create_int(int32_t value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_068: [If allocating the AMQP_VALUE fails then amqpvalue_create_int shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_068: [If allocating the AMQP_VALUE fails then amqpvalue_create_int shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_067: [amqpvalue_create_int shall return a handle to an AMQP_VALUE that stores an int32_t value.] */ result->type = AMQP_TYPE_INT; result->value.int_value = value; } + return result; } @@ -541,7 +602,9 @@ if ((value == NULL) || (int_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, int_value = %p", + value, int_value); + result = __FAILURE__; } else { @@ -549,7 +612,8 @@ /* Codes_SRS_AMQPVALUE_01_072: [If the type of the value is not int (was not created with amqpvalue_create_int), then amqpvalue_get_int shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_INT) { - result = __FAILURE__; + LogError("Value is not of type INT"); + result = __FAILURE__; } else { @@ -568,13 +632,18 @@ AMQP_VALUE amqpvalue_create_long(int64_t value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_074: [If allocating the AMQP_VALUE fails then amqpvalue_create_long shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_074: [If allocating the AMQP_VALUE fails then amqpvalue_create_long shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_073: [amqpvalue_create_long shall return a handle to an AMQP_VALUE that stores an int64_t value.] */ result->type = AMQP_TYPE_LONG; result->value.long_value = value; } + return result; } @@ -586,7 +655,9 @@ if ((value == NULL) || (long_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, long_value = %p", + value, long_value); + result = __FAILURE__; } else { @@ -594,7 +665,8 @@ /* Codes_SRS_AMQPVALUE_01_078: [If the type of the value is not long (was not created with amqpvalue_create_long), then amqpvalue_get_long shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_LONG) { - result = __FAILURE__; + LogError("Value is not of type LONG"); + result = __FAILURE__; } else { @@ -613,13 +685,18 @@ AMQP_VALUE amqpvalue_create_float(float value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_081: [If allocating the AMQP_VALUE fails then amqpvalue_create_float shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_081: [If allocating the AMQP_VALUE fails then amqpvalue_create_float shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_080: [amqpvalue_create_float shall return a handle to an AMQP_VALUE that stores a float value.] */ result->type = AMQP_TYPE_FLOAT; result->value.float_value = value; } + return result; } @@ -631,7 +708,9 @@ if ((value == NULL) || (float_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, float_value = %p", + value, float_value); + result = __FAILURE__; } else { @@ -639,7 +718,8 @@ /* Codes_SRS_AMQPVALUE_01_085: [If the type of the value is not float (was not created with amqpvalue_create_float), then amqpvalue_get_float shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_FLOAT) { - result = __FAILURE__; + LogError("Value is not of type FLOAT"); + result = __FAILURE__; } else { @@ -658,13 +738,18 @@ AMQP_VALUE amqpvalue_create_double(double value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_087: [If allocating the AMQP_VALUE fails then amqpvalue_create_double shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_087: [If allocating the AMQP_VALUE fails then amqpvalue_create_double shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_086: [amqpvalue_create_double shall return a handle to an AMQP_VALUE that stores a double value.] */ result->type = AMQP_TYPE_DOUBLE; result->value.double_value = value; } + return result; } @@ -676,7 +761,9 @@ if ((value == NULL) || (double_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, double_value = %p", + value, double_value); + result = __FAILURE__; } else { @@ -684,7 +771,8 @@ /* Codes_SRS_AMQPVALUE_01_091: [If the type of the value is not double (was not created with amqpvalue_create_double), then amqpvalue_get_double shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_DOUBLE) { - result = __FAILURE__; + LogError("Value is not of type DOUBLE"); + result = __FAILURE__; } else { @@ -707,14 +795,19 @@ /* Codes_SRS_AMQPVALUE_01_098: [If the code point value is outside of the allowed range [0, 0x10FFFF] then amqpvalue_create_char shall return NULL.] */ if (value > 0x10FFFF) { + LogError("Invalid value for a Unicode char"); result = NULL; } else { result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_093: [If allocating the AMQP_VALUE fails then amqpvalue_create_char shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_093: [If allocating the AMQP_VALUE fails then amqpvalue_create_char shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_092: [amqpvalue_create_char shall return a handle to an AMQP_VALUE that stores a single UTF-32 character value.] */ result->type = AMQP_TYPE_CHAR; result->value.char_value = value; @@ -732,7 +825,9 @@ if ((value == NULL) || (char_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, double_value = %p", + value, char_value); + result = __FAILURE__; } else { @@ -740,7 +835,8 @@ /* Codes_SRS_AMQPVALUE_01_097: [If the type of the value is not char (was not created with amqpvalue_create_char), then amqpvalue_get_char shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_CHAR) { - result = __FAILURE__; + LogError("Value is not of type CHAR"); + result = __FAILURE__; } else { @@ -759,13 +855,18 @@ AMQP_VALUE amqpvalue_create_timestamp(int64_t value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_108: [If allocating the AMQP_VALUE fails then amqpvalue_create_timestamp shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_108: [If allocating the AMQP_VALUE fails then amqpvalue_create_timestamp shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_107: [amqpvalue_create_timestamp shall return a handle to an AMQP_VALUE that stores an uint64_t value that represents a millisecond precision Unix time.] */ result->type = AMQP_TYPE_TIMESTAMP; result->value.timestamp_value = value; } + return result; } @@ -777,7 +878,9 @@ if ((value == NULL) || (timestamp_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, timestamp_value = %p", + value, timestamp_value); + result = __FAILURE__; } else { @@ -785,7 +888,8 @@ /* Codes_SRS_AMQPVALUE_01_112: [If the type of the value is not timestamp (was not created with amqpvalue_create_timestamp), then amqpvalue_get_timestamp shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_TIMESTAMP) { - result = __FAILURE__; + LogError("Value is not of type TIMESTAMP"); + result = __FAILURE__; } else { @@ -804,13 +908,18 @@ AMQP_VALUE amqpvalue_create_uuid(uuid value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_114: [If allocating the AMQP_VALUE fails then amqpvalue_create_uuid shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_114: [If allocating the AMQP_VALUE fails then amqpvalue_create_uuid shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_113: [amqpvalue_create_uuid shall return a handle to an AMQP_VALUE that stores an uuid value that represents a unique identifier per RFC-4122 section 4.1.2.] */ result->type = AMQP_TYPE_UUID; (void)memcpy(&result->value.uuid_value, value, 16); } + return result; } @@ -822,7 +931,9 @@ if ((value == NULL) || (uuid_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, uuid_value = %p", + value, uuid_value); + result = __FAILURE__; } else { @@ -830,7 +941,8 @@ /* Codes_SRS_AMQPVALUE_01_118: [If the type of the value is not uuid (was not created with amqpvalue_create_uuid), then amqpvalue_get_uuid shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_UUID) { - result = __FAILURE__; + LogError("Value is not of type UUID"); + result = __FAILURE__; } else { @@ -853,14 +965,19 @@ (value.length > 0)) { /* Codes_SRS_AMQPVALUE_01_129: [If value.data is NULL and value.length is positive then amqpvalue_create_binary shall return NULL.] */ + LogError("NULL bytes with non-zero length"); result = NULL; } else { - /* Codes_SRS_AMQPVALUE_01_128: [If allocating the AMQP_VALUE fails then amqpvalue_create_binary shall return NULL.] */ result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_128: [If allocating the AMQP_VALUE fails then amqpvalue_create_binary shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_127: [amqpvalue_create_binary shall return a handle to an AMQP_VALUE that stores a sequence of bytes.] */ result->type = AMQP_TYPE_BINARY; if (value.length > 0) @@ -877,7 +994,8 @@ if ((result->value.binary_value.bytes == NULL) && (value.length > 0)) { /* Codes_SRS_AMQPVALUE_01_128: [If allocating the AMQP_VALUE fails then amqpvalue_create_binary shall return NULL.] */ - free(result); + LogError("Could not allocate memory for binary payload of AMQP value"); + free(result); result = NULL; } else @@ -889,6 +1007,7 @@ } } } + return result; } @@ -900,7 +1019,9 @@ if ((value == NULL) || (binary_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, binary_value = %p", + value, binary_value); + result = __FAILURE__; } else { @@ -908,7 +1029,8 @@ /* Codes_SRS_AMQPVALUE_01_133: [If the type of the value is not binary (was not created with amqpvalue_create_binary), then amqpvalue_get_binary shall return NULL.] */ if (value_data->type != AMQP_TYPE_BINARY) { - result = __FAILURE__; + LogError("Value is not of type BINARY"); + result = __FAILURE__; } else { @@ -930,30 +1052,33 @@ AMQP_VALUE_DATA* result; if (value == NULL) { - result = NULL; + LogError("NULL argument value"); + result = NULL; } else { size_t length = strlen(value); - /* Codes_SRS_AMQPVALUE_01_136: [If allocating the AMQP_VALUE fails then amqpvalue_create_string shall return NULL.] */ result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_136: [If allocating the AMQP_VALUE fails then amqpvalue_create_string shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { result->type = AMQP_TYPE_STRING; - result->value.string_value.chars = malloc(length + 1); + result->value.string_value.chars = (char*)malloc(length + 1); if (result->value.string_value.chars == NULL) { /* Codes_SRS_AMQPVALUE_01_136: [If allocating the AMQP_VALUE fails then amqpvalue_create_string shall return NULL.] */ - free(result); + LogError("Could not allocate memory for string AMQP value"); + free(result); result = NULL; } else { -#if _MSC_VER -#pragma warning(suppress: 6324) /* we use strcpy intentionally */ -#endif - (void)strcpy(result->value.string_value.chars, value); + (void)memcpy(result->value.string_value.chars, value, length + 1); } } } @@ -969,7 +1094,9 @@ if ((value == NULL) || (string_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, string_value = %p", + value, string_value); + result = __FAILURE__; } else { @@ -978,7 +1105,8 @@ /* Codes_SRS_AMQPVALUE_01_140: [If the type of the value is not string (was not created with amqpvalue_create_string), then amqpvalue_get_string shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_STRING) { - result = __FAILURE__; + LogError("Value is not of type STRING"); + result = __FAILURE__; } else { @@ -1051,7 +1179,9 @@ if ((value == NULL) || (symbol_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, symbol_value = %p", + value, symbol_value); + result = __FAILURE__; } else { @@ -1060,7 +1190,8 @@ /* Codes_SRS_AMQPVALUE_01_148: [If the type of the value is not symbol (was not created with amqpvalue_create_symbol), then amqpvalue_get_symbol shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_SYMBOL) { - result = __FAILURE__; + LogError("Value is not of type SYMBOL"); + result = __FAILURE__; } else { @@ -1078,10 +1209,14 @@ /* Codes_SRS_AMQPVALUE_01_030: [1.6.22 list A sequence of polymorphic values.] */ AMQP_VALUE amqpvalue_create_list(void) { - /* Codes_SRS_AMQPVALUE_01_150: [If allocating the AMQP_VALUE fails then amqpvalue_create_list shall return NULL.] */ AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_150: [If allocating the AMQP_VALUE fails then amqpvalue_create_list shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_149: [amqpvalue_create_list shall return a handle to an AMQP_VALUE that stores a list.] */ result->type = AMQP_TYPE_LIST; @@ -1100,16 +1235,17 @@ /* Codes_SRS_AMQPVALUE_01_155: [If the value argument is NULL, amqpvalue_set_list_item_count shall return a non-zero value.] */ if (value == NULL) { - result = __FAILURE__; + LogError("NULL list value"); + result = __FAILURE__; } else { AMQP_VALUE_DATA* value_data = (AMQP_VALUE_DATA*)value; - if (value_data->type != AMQP_TYPE_LIST) { /* Codes_SRS_AMQPVALUE_01_156: [If the value is not of type list, then amqpvalue_set_list_item_count shall return a non-zero value.] */ - result = __FAILURE__; + LogError("Value is not of type LIST"); + result = __FAILURE__; } else { @@ -1122,7 +1258,8 @@ if (new_list == NULL) { /* Codes_SRS_AMQPVALUE_01_154: [If allocating memory for the list according to the new size fails, then amqpvalue_set_list_item_count shall return a non-zero value, while preserving the existing list contents.] */ - result = __FAILURE__; + LogError("Could not reallocate list memory"); + result = __FAILURE__; } else { @@ -1137,7 +1274,8 @@ new_list[i] = amqpvalue_create_null(); if (new_list[i] == NULL) { - break; + LogError("Could not create NULL AMQP value to be inserted in list"); + break; } } @@ -1195,7 +1333,9 @@ if ((value == NULL) || (size == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, size = %p", + value, size); + result = __FAILURE__; } else { @@ -1204,7 +1344,8 @@ /* Codes_SRS_AMQPVALUE_01_160: [If the AMQP_VALUE is not a list then amqpvalue_get_list_item_count shall return a non-zero value.] */ if (value_data->type != AMQP_TYPE_LIST) { - result = __FAILURE__; + LogError("Value is not of type LIST"); + result = __FAILURE__; } else { @@ -1226,25 +1367,27 @@ /* Codes_SRS_AMQPVALUE_01_165: [If value or list_item_value is NULL, amqpvalue_set_list_item shall fail and return a non-zero value.] */ if (value == NULL) { - result = __FAILURE__; + LogError("NULL list value"); + result = __FAILURE__; } else { AMQP_VALUE_DATA* value_data = (AMQP_VALUE_DATA*)value; if (value_data->type != AMQP_TYPE_LIST) { - result = __FAILURE__; + LogError("Value is not of type LIST"); + result = __FAILURE__; } else { /* Codes_SRS_AMQPVALUE_01_168: [The item stored at the index-th position in the list shall be a clone of list_item_value.] */ AMQP_VALUE cloned_item = amqpvalue_clone(list_item_value); - if (cloned_item == NULL) { /* Codes_SRS_AMQPVALUE_01_170: [When amqpvalue_set_list_item fails due to not being able to clone the item or grow the list, the list shall not be altered.] */ /* Codes_SRS_AMQPVALUE_01_169: [If cloning the item fails, amqpvalue_set_list_item shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Could not clone list item"); + result = __FAILURE__; } else { @@ -1254,7 +1397,8 @@ if (new_list == NULL) { /* Codes_SRS_AMQPVALUE_01_170: [When amqpvalue_set_list_item fails due to not being able to clone the item or grow the list, the list shall not be altered.] */ - amqpvalue_destroy(cloned_item); + LogError("Could not reallocate list storage"); + amqpvalue_destroy(cloned_item); result = __FAILURE__; } else @@ -1268,7 +1412,8 @@ new_list[i] = amqpvalue_create_null(); if (new_list[i] == NULL) { - break; + LogError("Could not allocate NULL value for list entries"); + break; } } @@ -1322,18 +1467,24 @@ if (value == NULL) { /* Codes_SRS_AMQPVALUE_01_174: [If the value argument is NULL, amqpvalue_get_list_item shall fail and return NULL.] */ - result = NULL; + LogError("NULL list value"); + result = NULL; } else { AMQP_VALUE_DATA* value_data = (AMQP_VALUE_DATA*)value; /* Codes_SRS_AMQPVALUE_01_177: [If value is not a list then amqpvalue_get_list_item shall fail and return NULL.] */ - if ((value_data->type != AMQP_TYPE_LIST) || - /* Codes_SRS_AMQPVALUE_01_175: [If index is greater or equal to the number of items in the list then amqpvalue_get_list_item shall fail and return NULL.] */ - (value_data->value.list_value.count <= index)) + if (value_data->type != AMQP_TYPE_LIST) + { + LogError("Value is not of type LIST"); + result = NULL; + } + /* Codes_SRS_AMQPVALUE_01_175: [If index is greater or equal to the number of items in the list then amqpvalue_get_list_item shall fail and return NULL.] */ + else if (value_data->value.list_value.count <= index) { - result = NULL; + LogError("Bad index value %u", (unsigned int)index); + result = NULL; } else { @@ -1352,9 +1503,13 @@ { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - /* Codes_SRS_AMQPVALUE_01_179: [If allocating memory for the map fails, then amqpvalue_create_map shall return NULL.] */ - if (result != NULL) - { + if (result == NULL) + { + /* Codes_SRS_AMQPVALUE_01_179: [If allocating memory for the map fails, then amqpvalue_create_map shall return NULL.] */ + LogError("Could not allocate memory for AMQP value"); + } + else + { result->type = AMQP_TYPE_MAP; /* Codes_SRS_AMQPVALUE_01_180: [The number of key/value pairs in the newly created map shall be zero.] */ @@ -1374,7 +1529,9 @@ (key == NULL) || (value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: map = %p, key = %p, value = %p", + map, key, value); + result = __FAILURE__; } else { @@ -1383,7 +1540,8 @@ /* Codes_SRS_AMQPVALUE_01_196: [If the map argument is not an AMQP value created with the amqpvalue_create_map function than amqpvalue_set_map_value shall fail and return a non-zero value.] */ if (value_data->type != AMQP_TYPE_MAP) { - result = __FAILURE__; + LogError("Value is not of type MAP"); + result = __FAILURE__; } else { @@ -1394,7 +1552,8 @@ if (cloned_value == NULL) { /* Codes_SRS_AMQPVALUE_01_188: [If cloning the value fails, amqpvalue_set_map_value shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Could not clone value to set in the map"); + result = __FAILURE__; } else { @@ -1405,7 +1564,8 @@ { if (amqpvalue_are_equal(value_data->value.map_value.pairs[i].key, key)) { - break; + LogError("Could not allocate NULL value for map entries"); + break; } } @@ -1427,7 +1587,8 @@ { /* Codes_SRS_AMQPVALUE_01_187: [If cloning the key fails, amqpvalue_set_map_value shall fail and return a non-zero value.] */ amqpvalue_destroy(cloned_value); - result = __FAILURE__; + LogError("Could not clone key for map"); + result = __FAILURE__; } else { @@ -1437,7 +1598,8 @@ /* Codes_SRS_AMQPVALUE_01_186: [If allocating memory to hold a new key/value pair fails, amqpvalue_set_map_value shall fail and return a non-zero value.] */ amqpvalue_destroy(cloned_key); amqpvalue_destroy(cloned_value); - result = __FAILURE__; + LogError("Could not reallocate memory for map"); + result = __FAILURE__; } else { @@ -1468,7 +1630,9 @@ if ((map == NULL) || (key == NULL)) { - result = NULL; + LogError("Bad arguments: map = %p, key = %p", + map, key); + result = NULL; } else { @@ -1477,7 +1641,8 @@ /* Codes_SRS_AMQPVALUE_01_197: [If the map argument is not an AMQP value created with the amqpvalue_create_map function than amqpvalue_get_map_value shall return NULL.] */ if (value_data->type != AMQP_TYPE_MAP) { - result = NULL; + LogError("Value is not of type MAP"); + result = NULL; } else { @@ -1487,7 +1652,7 @@ { if (amqpvalue_are_equal(value_data->value.map_value.pairs[i].key, key)) { - break; + break; } } @@ -1516,7 +1681,9 @@ if ((map == NULL) || (pair_count == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: map = %p, pair_count = %p", + map, pair_count); + result = __FAILURE__; } else { @@ -1525,7 +1692,8 @@ if (value_data->type != AMQP_TYPE_MAP) { /* Codes_SRS_AMQPVALUE_01_198: [If the map argument is not an AMQP value created with the amqpvalue_create_map function then amqpvalue_get_map_pair_count shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Value is not of type MAP"); + result = __FAILURE__; } else { @@ -1549,7 +1717,9 @@ (key == NULL) || (value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: map = %p, key = %p, value = %p", + map, key, value); + result = __FAILURE__; } else { @@ -1558,12 +1728,14 @@ if (value_data->type != AMQP_TYPE_MAP) { /* Codes_SRS_AMQPVALUE_01_205: [If the map argument is not an AMQP value created with the amqpvalue_create_map function then amqpvalue_get_map_key_value_pair shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Value is not of type MAP"); + result = __FAILURE__; } else if (value_data->value.map_value.pair_count <= index) { /* Codes_SRS_AMQPVALUE_01_204: [If the index argument is greater or equal to the number of key/value pairs in the map then amqpvalue_get_map_key_value_pair shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Index out of range: %u", (unsigned int)index); + result = __FAILURE__; } else { @@ -1572,7 +1744,8 @@ if (*key == NULL) { /* Codes_SRS_AMQPVALUE_01_202: [If cloning the key fails, amqpvalue_get_map_key_value_pair shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Could not clone index %u key", (unsigned int)index); + result = __FAILURE__; } else { @@ -1581,7 +1754,8 @@ { /* Codes_SRS_AMQPVALUE_01_203: [If cloning the value fails, amqpvalue_get_map_key_value_pair shall fail and return a non-zero value.] */ amqpvalue_destroy(*key); - result = __FAILURE__; + LogError("Could not clone index %u value", (unsigned int)index); + result = __FAILURE__; } else { @@ -1602,26 +1776,22 @@ if ((value == NULL) || (map_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, map_value = %p", + value, map_value); + result = __FAILURE__; } else { AMQP_VALUE_DATA* value_data = (AMQP_VALUE_DATA*)value; if (value_data->type != AMQP_TYPE_MAP) { - result = __FAILURE__; + LogError("Value is not of type MAP"); + result = __FAILURE__; } else { - if (map_value == NULL) - { - result = __FAILURE__; - } - else - { - *map_value = value; - result = 0; - } + *map_value = value; + result = 0; } } @@ -1631,10 +1801,15 @@ AMQP_VALUE amqpvalue_create_array(void) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - if (result != NULL) - { + if (result == NULL) + { + LogError("Could not allocate memory for AMQP value"); + } + else + { result->type = AMQP_TYPE_ARRAY; } + return result; } @@ -1645,7 +1820,9 @@ if ((value == NULL) || (size == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, size = %p", + value, size); + result = __FAILURE__; } else { @@ -1653,7 +1830,8 @@ if (value_data->type != AMQP_TYPE_ARRAY) { - result = __FAILURE__; + LogError("Value is not of type ARRAY"); + result = __FAILURE__; } else { @@ -1671,31 +1849,33 @@ if (value == NULL) { - result = __FAILURE__; + LogError("NULL value"); + result = __FAILURE__; } else { AMQP_VALUE_DATA* value_data = (AMQP_VALUE_DATA*)value; if (value_data->type != AMQP_TYPE_ARRAY) { - result = __FAILURE__; + LogError("Value is not of type ARRAY"); + result = __FAILURE__; } else { AMQP_VALUE_DATA* array_item_value_data = (AMQP_VALUE_DATA*)array_item_value; - if ((value_data->value.array_value.count > 0) && (array_item_value_data->type != value_data->value.array_value.items[0]->type)) { - result = __FAILURE__; + LogError("Cannot put different types in the same array"); + result = __FAILURE__; } else { AMQP_VALUE cloned_item = amqpvalue_clone(array_item_value); - if (cloned_item == NULL) { - result = __FAILURE__; + LogError("Cannot clone value to put in the array"); + result = __FAILURE__; } else { @@ -1703,7 +1883,8 @@ if (new_array == NULL) { amqpvalue_destroy(cloned_item); - result = __FAILURE__; + LogError("Cannot resize array"); + result = __FAILURE__; } else { @@ -1728,16 +1909,22 @@ if (value == NULL) { - result = NULL; + LogError("NULL value"); + result = NULL; } else { AMQP_VALUE_DATA* value_data = (AMQP_VALUE_DATA*)value; - if ((value_data->type != AMQP_TYPE_ARRAY) || - (value_data->value.array_value.count <= index)) + if (value_data->type != AMQP_TYPE_ARRAY) + { + LogError("Value is not of type ARRAY"); + result = NULL; + } + else if (value_data->value.array_value.count <= index) { - result = NULL; + LogError("Index out of range: %u", (unsigned int)index); + result = NULL; } else { @@ -1755,26 +1942,22 @@ if ((value == NULL) || (array_value == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, array_value = %p", + value, array_value); + result = __FAILURE__; } else { AMQP_VALUE_DATA* value_data = (AMQP_VALUE_DATA*)value; if (value_data->type != AMQP_TYPE_ARRAY) { - result = __FAILURE__; + LogError("Value is not of type ARRAY"); + result = __FAILURE__; } else { - if (array_value == NULL) - { - result = __FAILURE__; - } - else - { - *array_value = value; - result = 0; - } + *array_value = value; + result = 0; } } @@ -1790,7 +1973,9 @@ if ((value1 == NULL) && (value2 == NULL)) { - result = true; + LogError("Bad arguments: value1 = %p, value2 = %p", + value1, value2); + result = true; } /* Codes_SRS_AMQPVALUE_01_208: [If one of the arguments is NULL and the other is not, amqpvalue_are_equal shall return false.] */ else if ((value1 != value2) && ((value1 == NULL) || (value2 == NULL))) @@ -1974,7 +2159,8 @@ if (value == NULL) { - result = NULL; + LogError("NULL value"); + result = NULL; } else { @@ -1982,7 +2168,8 @@ switch (value_data->type) { default: - result = NULL; + LogError("Invalid data type: %d", (int)value_data->type); + result = NULL; break; case AMQP_TYPE_NULL: @@ -2079,11 +2266,12 @@ { /* Codes_SRS_AMQPVALUE_01_258: [list] */ uint32_t i; - AMQP_VALUE_DATA* result_data = malloc(sizeof(AMQP_VALUE_DATA)); + AMQP_VALUE_DATA* result_data = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); if (result_data == NULL) { /* Codes_SRS_AMQPVALUE_01_236: [If creating the cloned value fails, amqpvalue_clone shall return NULL.] */ - result = NULL; + LogError("Cannot allocate memory for cloned value"); + result = NULL; } else { @@ -2096,7 +2284,8 @@ if (result_data->value.list_value.items == NULL) { /* Codes_SRS_AMQPVALUE_01_236: [If creating the cloned value fails, amqpvalue_clone shall return NULL.] */ - free(result_data); + LogError("Cannot allocate memory for cloned list"); + free(result_data); result = NULL; } else @@ -2106,7 +2295,8 @@ result_data->value.list_value.items[i] = amqpvalue_clone(value_data->value.list_value.items[i]); if (result_data->value.list_value.items[i] == NULL) { - break; + LogError("Cannot clone list item %u", (unsigned int)i); + break; } } @@ -2144,11 +2334,12 @@ { /* Codes_SRS_AMQPVALUE_01_259: [map] */ uint32_t i; - AMQP_VALUE_DATA* result_data = malloc(sizeof(AMQP_VALUE_DATA)); + AMQP_VALUE_DATA* result_data = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); if (result_data == NULL) { /* Codes_SRS_AMQPVALUE_01_236: [If creating the cloned value fails, amqpvalue_clone shall return NULL.] */ - result = NULL; + LogError("Cannot allocate memory for cloned map"); + result = NULL; } else { @@ -2161,6 +2352,7 @@ if (result_data->value.map_value.pairs == NULL) { /* Codes_SRS_AMQPVALUE_01_236: [If creating the cloned value fails, amqpvalue_clone shall return NULL.] */ + LogError("Cannot allocate memory for cloned map storage"); free(result_data); result = NULL; } @@ -2171,13 +2363,15 @@ result_data->value.map_value.pairs[i].key = amqpvalue_clone(value_data->value.map_value.pairs[i].key); if (result_data->value.map_value.pairs[i].key == NULL) { - break; + LogError("Cannot clone map key index %u", (unsigned int)i); + break; } result_data->value.map_value.pairs[i].value = amqpvalue_clone(value_data->value.map_value.pairs[i].value); if (result_data->value.map_value.pairs[i].value == NULL) { - amqpvalue_destroy(result_data->value.map_value.pairs[i].key); + LogError("Cannot clone map value index %u", (unsigned int)i); + amqpvalue_destroy(result_data->value.map_value.pairs[i].key); break; } } @@ -2215,10 +2409,11 @@ case AMQP_TYPE_ARRAY: { uint32_t i; - AMQP_VALUE_DATA* result_data = malloc(sizeof(AMQP_VALUE_DATA)); + AMQP_VALUE_DATA* result_data = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); if (result_data == NULL) { - result = NULL; + LogError("Cannot allocate memory for cloned array"); + result = NULL; } else { @@ -2230,7 +2425,8 @@ result_data->value.array_value.items = (AMQP_VALUE*)malloc(value_data->value.array_value.count * sizeof(AMQP_VALUE)); if (result_data->value.array_value.items == NULL) { - free(result_data); + LogError("Cannot allocate memory for cloned array storage"); + free(result_data); result = NULL; } else @@ -2240,7 +2436,8 @@ result_data->value.array_value.items[i] = amqpvalue_clone(value_data->value.array_value.items[i]); if (result_data->value.array_value.items[i] == NULL) { - break; + LogError("Cannot allocate memory for cloned array item %u", (unsigned int)i); + break; } } @@ -2284,16 +2481,19 @@ if (result_data == NULL) { - result = NULL; + LogError("Cannot allocate memory for cloned composite value"); + result = NULL; } else if ((cloned_descriptor = amqpvalue_clone(value_data->value.described_value.descriptor)) == NULL) { - free(result_data); + LogError("Cannot clone descriptor"); + free(result_data); result = NULL; } else if ((cloned_list = amqpvalue_clone(value_data->value.described_value.value)) == NULL) { - amqpvalue_destroy(cloned_descriptor); + LogError("Cannot clone described value"); + amqpvalue_destroy(cloned_descriptor); free(result_data); result = NULL; } @@ -2346,7 +2546,7 @@ { /* Codes_SRS_AMQPVALUE_01_267: [amqpvalue_encode shall pass the encoded bytes to the encoder_output function.] */ /* Codes_SRS_AMQPVALUE_01_268: [On each call to the encoder_output function, amqpvalue_encode shall also pass the context argument.] */ - result = encoder_output(context, bytes, length); + result = encoder_output(context, (const unsigned char*)bytes, length); } else { @@ -2366,7 +2566,8 @@ if (output_byte(encoder_output, context, 0x42) != 0) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding boolean"); + result = __FAILURE__; } else { @@ -2379,7 +2580,8 @@ if (output_byte(encoder_output, context, 0x41) != 0) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding boolean"); + result = __FAILURE__; } else { @@ -2399,7 +2601,8 @@ (output_byte(encoder_output, context, value) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding ubyte"); + result = __FAILURE__; } else { @@ -2420,7 +2623,8 @@ (output_byte(encoder_output, context, (value & 0xFF)) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding ushort"); + result = __FAILURE__; } else { @@ -2441,7 +2645,8 @@ /* Codes_SRS_AMQPVALUE_01_279: [<encoding name="uint0" code="0x43" category="fixed" width="0" label="the uint value 0"/>] */ if (output_byte(encoder_output, context, 0x43) != 0) { - result = __FAILURE__; + LogError("Failed encoding uint"); + result = __FAILURE__; } else { @@ -2457,7 +2662,8 @@ (output_byte(encoder_output, context, value & 0xFF) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding uint"); + result = __FAILURE__; } else { @@ -2475,7 +2681,8 @@ (output_byte(encoder_output, context, value & 0xFF) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding uint"); + result = __FAILURE__; } else { @@ -2497,7 +2704,8 @@ if (output_byte(encoder_output, context, 0x44) != 0) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding ulong"); + result = __FAILURE__; } else { @@ -2513,7 +2721,8 @@ (output_byte(encoder_output, context, value & 0xFF) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding ulong"); + result = __FAILURE__; } else { @@ -2535,7 +2744,8 @@ (output_byte(encoder_output, context, value & 0xFF) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding ulong"); + result = __FAILURE__; } else { @@ -2556,7 +2766,8 @@ (output_byte(encoder_output, context, value) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding byte"); + result = __FAILURE__; } else { @@ -2577,7 +2788,8 @@ (output_byte(encoder_output, context, (value & 0xFF)) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding short"); + result = __FAILURE__; } else { @@ -2599,7 +2811,8 @@ (output_byte(encoder_output, context, value & 0xFF) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding int"); + result = __FAILURE__; } else { @@ -2617,7 +2830,8 @@ (output_byte(encoder_output, context, value & 0xFF) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding int"); + result = __FAILURE__; } else { @@ -2640,7 +2854,8 @@ (output_byte(encoder_output, context, value & 0xFF) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding long"); + result = __FAILURE__; } else { @@ -2662,7 +2877,8 @@ (output_byte(encoder_output, context, value & 0xFF) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding long"); + result = __FAILURE__; } else { @@ -2674,6 +2890,60 @@ return result; } +static int encode_float(AMQPVALUE_ENCODER_OUTPUT encoder_output, void* context, float value) +{ + int result; + + uint32_t value_as_uint32 = *((uint32_t*)(void*)&value); + /* Codes_SRS_AMQPVALUE_01_289: [\<encoding name="ieee-754" code="0x72" category="fixed" width="4" label="IEEE 754-2008 binary32"/>] */ + if ((output_byte(encoder_output, context, 0x72) != 0) || + (output_byte(encoder_output, context, (value_as_uint32 >> 24) & 0xFF) != 0) || + (output_byte(encoder_output, context, (value_as_uint32 >> 16) & 0xFF) != 0) || + (output_byte(encoder_output, context, (value_as_uint32 >> 8) & 0xFF) != 0) || + (output_byte(encoder_output, context, (value_as_uint32) & 0xFF) != 0)) + { + /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ + LogError("Failure encoding bytes for float"); + result = __FAILURE__; + } + else + { + /* Codes_SRS_AMQPVALUE_01_266: [On success amqpvalue_encode shall return 0.] */ + result = 0; + } + + return result; +} + +static int encode_double(AMQPVALUE_ENCODER_OUTPUT encoder_output, void* context, double value) +{ + int result; + + uint64_t value_as_uint64 = *((uint64_t*)(void*)&value); + /* Codes_SRS_AMQPVALUE_01_290: [\<encoding name="ieee-754" code="0x82" category="fixed" width="8" label="IEEE 754-2008 binary64"/>] */ + if ((output_byte(encoder_output, context, 0x82) != 0) || + (output_byte(encoder_output, context, (value_as_uint64 >> 56) & 0xFF) != 0) || + (output_byte(encoder_output, context, (value_as_uint64 >> 48) & 0xFF) != 0) || + (output_byte(encoder_output, context, (value_as_uint64 >> 40) & 0xFF) != 0) || + (output_byte(encoder_output, context, (value_as_uint64 >> 32) & 0xFF) != 0) || + (output_byte(encoder_output, context, (value_as_uint64 >> 24) & 0xFF) != 0) || + (output_byte(encoder_output, context, (value_as_uint64 >> 16) & 0xFF) != 0) || + (output_byte(encoder_output, context, (value_as_uint64 >> 8) & 0xFF) != 0) || + (output_byte(encoder_output, context, (value_as_uint64) & 0xFF) != 0)) + { + /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ + LogError("Failure encoding bytes for double"); + result = __FAILURE__; + } + else + { + /* Codes_SRS_AMQPVALUE_01_266: [On success amqpvalue_encode shall return 0.] */ + result = 0; + } + + return result; +} + static int encode_timestamp(AMQPVALUE_ENCODER_OUTPUT encoder_output, void* context, int64_t value) { int result; @@ -2690,7 +2960,8 @@ (output_byte(encoder_output, context, value & 0xFF) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding timestamp"); + result = __FAILURE__; } else { @@ -2710,7 +2981,8 @@ (output_bytes(encoder_output, context, uuid, 16) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding uuid"); + result = __FAILURE__; } else { @@ -2732,7 +3004,8 @@ ((length > 0) && (output_bytes(encoder_output, context, value, length) != 0))) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding binary"); + result = __FAILURE__; } else { @@ -2751,7 +3024,8 @@ (output_bytes(encoder_output, context, value, length) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding binary"); + result = __FAILURE__; } else { @@ -2776,7 +3050,8 @@ (output_bytes(encoder_output, context, value, length) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding string"); + result = __FAILURE__; } else { @@ -2795,7 +3070,8 @@ (output_bytes(encoder_output, context, value, length) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding string"); + result = __FAILURE__; } else { @@ -2820,7 +3096,8 @@ (output_bytes(encoder_output, context, value, length) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding symbol"); + result = __FAILURE__; } else { @@ -2840,7 +3117,8 @@ (output_bytes(encoder_output, context, value, length) != 0)) { /* Codes_SRS_AMQPVALUE_01_274: [When the encoder output function fails, amqpvalue_encode shall fail and return a non-zero value.] */ - result = __FAILURE__; + LogError("Failed encoding symbol"); + result = __FAILURE__; } else { @@ -2882,7 +3160,7 @@ size_t item_size; if (amqpvalue_get_encoded_size(items[i], &item_size) != 0) { - LogError("Could not get encoded size for element %zu of the list", i); + LogError("Could not get encoded size for element %u of the list", (unsigned int)i); break; } @@ -2958,13 +3236,13 @@ { if (amqpvalue_encode(items[i], encoder_output, context) != 0) { - break; + break; } } if (i < count) { - LogError("Failed encoding element %zu of the list", i); + LogError("Failed encoding element %u of the list", (unsigned int)i); result = __FAILURE__; } else @@ -2994,7 +3272,7 @@ size_t item_size; if (amqpvalue_get_encoded_size(pairs[i].key, &item_size) != 0) { - LogError("Could not get encoded size for key element %zu of the map", i); + LogError("Could not get encoded size for key element %u of the map", (unsigned int)i); break; } @@ -3009,7 +3287,7 @@ if (amqpvalue_get_encoded_size(pairs[i].value, &item_size) != 0) { - LogError("Could not get encoded size for value element %zu of the map", i); + LogError("Could not get encoded size for value element %u of the map", (unsigned int)i); break; } @@ -3087,7 +3365,8 @@ if ((amqpvalue_encode(pairs[i].key, encoder_output, context) != 0) || (amqpvalue_encode(pairs[i].value, encoder_output, context) != 0)) { - break; + LogError("Failed encoding map element %u", (unsigned int)i); + break; } } @@ -3110,8 +3389,15 @@ { int result; - output_byte(encoder_output, context, 0x00); - result = 0; + if (output_byte(encoder_output, context, 0x00) != 0) + { + LogError("Failed encoding descriptor header"); + result = __FAILURE__; + } + else + { + result = 0; + } return result; } @@ -3125,7 +3411,9 @@ if ((value == NULL) || (encoder_output == NULL)) { - result = __FAILURE__; + LogError("Bad arguments: value = %p, encoder_output = %p", + value, encoder_output); + result = __FAILURE__; } else { @@ -3135,7 +3423,8 @@ { default: /* Codes_SRS_AMQPVALUE_01_271: [If encoding fails due to any error not specifically mentioned here, it shall return a non-zero value.] */ - result = __FAILURE__; + LogError("Invalid type: %d", (int)value_data->type); + result = __FAILURE__; break; case AMQP_TYPE_NULL: @@ -3180,6 +3469,14 @@ result = encode_long(encoder_output, context, value_data->value.long_value); break; + case AMQP_TYPE_FLOAT: + result = encode_float(encoder_output, context, value_data->value.float_value); + break; + + case AMQP_TYPE_DOUBLE: + result = encode_double(encoder_output, context, value_data->value.double_value); + break; + case AMQP_TYPE_TIMESTAMP: result = encode_timestamp(encoder_output, context, value_data->value.timestamp_value); break; @@ -3189,7 +3486,7 @@ break; case AMQP_TYPE_BINARY: - result = encode_binary(encoder_output, context, value_data->value.binary_value.bytes, value_data->value.binary_value.length); + result = encode_binary(encoder_output, context, (const unsigned char*)value_data->value.binary_value.bytes, value_data->value.binary_value.length); break; case AMQP_TYPE_STRING: @@ -3215,12 +3512,14 @@ (amqpvalue_encode(value_data->value.described_value.descriptor, encoder_output, context) != 0) || (amqpvalue_encode(value_data->value.described_value.value, encoder_output, context) != 0)) { - result = __FAILURE__; + LogError("Failed encoding described or composite type"); + result = __FAILURE__; } else { result = 0; } + break; } } @@ -3247,6 +3546,8 @@ if ((value == NULL) || (encoded_size == NULL)) { + LogError("Bad arguments: value = %p, encoded_size = %p", + value, encoded_size); result = __FAILURE__; } else @@ -3263,7 +3564,8 @@ switch (value_data->type) { default: - break; + break; + case AMQP_TYPE_BINARY: if (value_data->value.binary_value.bytes != NULL) { @@ -3332,8 +3634,12 @@ void amqpvalue_destroy(AMQP_VALUE value) { /* Codes_SRS_AMQPVALUE_01_315: [If the value argument is NULL, amqpvalue_destroy shall do nothing.] */ - if (value != NULL) - { + if (value == NULL) + { + LogError("NULL value"); + } + else + { /* Codes_SRS_AMQPVALUE_01_314: [amqpvalue_destroy shall free all resources allocated by any of the amqpvalue_create_xxx functions or amqpvalue_clone.] */ AMQP_VALUE_DATA* value_data = (AMQP_VALUE_DATA*)value; amqpvalue_clear(value_data); @@ -3344,8 +3650,12 @@ static INTERNAL_DECODER_DATA* internal_decoder_create(ON_VALUE_DECODED on_value_decoded, void* callback_context, AMQP_VALUE_DATA* value_data) { INTERNAL_DECODER_DATA* internal_decoder_data = (INTERNAL_DECODER_DATA*)malloc(sizeof(INTERNAL_DECODER_DATA)); - if (internal_decoder_data != NULL) - { + if (internal_decoder_data == NULL) + { + LogError("Cannot allocate memory for internal decoder structure"); + } + else + { internal_decoder_data->on_value_decoded = on_value_decoded; internal_decoder_data->on_value_decoded_context = callback_context; internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; @@ -3368,21 +3678,23 @@ static void inner_decoder_callback(void* context, AMQP_VALUE decoded_value) { /* API issue: the decoded_value should be removed completely: - Filed: uAMQP: inner_decoder_callback in amqpvalue.c could probably do without the decoded_value ... */ + TODO: uAMQP: inner_decoder_callback in amqpvalue.c could probably do without the decoded_value ... */ (void)decoded_value; INTERNAL_DECODER_DATA* internal_decoder_data = (INTERNAL_DECODER_DATA*)context; INTERNAL_DECODER_DATA* inner_decoder = (INTERNAL_DECODER_DATA*)internal_decoder_data->inner_decoder; inner_decoder->decoder_state = DECODER_STATE_DONE; } -int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder_data, const unsigned char* buffer, size_t size, size_t* used_bytes) +static int internal_decoder_decode_bytes(INTERNAL_DECODER_DATA* internal_decoder_data, const unsigned char* buffer, size_t size, size_t* used_bytes) { int result; size_t initial_size = size; if (internal_decoder_data == NULL) { - result = __FAILURE__; + /* TODO: investigate if this check is even needed */ + LogError("NULL internal_decoder_data"); + result = __FAILURE__; } else { @@ -3393,8 +3705,10 @@ switch (internal_decoder_data->decoder_state) { default: + LogError("Invalid decoder state: %d", (int)internal_decoder_data->decoder_state); result = __FAILURE__; break; + case DECODER_STATE_CONSTRUCTOR: { amqpvalue_clear(internal_decoder_data->decode_to_value); @@ -3406,35 +3720,41 @@ { default: internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Invalid constructor byte: 0x%02x", internal_decoder_data->constructor_byte); + result = __FAILURE__; break; + case 0x00: /* descriptor */ - internal_decoder_data->decode_to_value->type = AMQP_TYPE_DESCRIBED; - AMQP_VALUE_DATA* descriptor = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - if (descriptor == NULL) - { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; - } - else - { - descriptor->type = AMQP_TYPE_UNKNOWN; - internal_decoder_data->decode_to_value->value.described_value.descriptor = descriptor; - internal_decoder_data->inner_decoder = internal_decoder_create(inner_decoder_callback, internal_decoder_data, descriptor); - if (internal_decoder_data->inner_decoder == NULL) - { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; - } - else - { - internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA; - internal_decoder_data->decode_value_state.described_value_state.described_value_state = DECODE_DESCRIBED_VALUE_STEP_DESCRIPTOR; - result = 0; - } - } - - break; + { + internal_decoder_data->decode_to_value->type = AMQP_TYPE_DESCRIBED; + AMQP_VALUE_DATA* descriptor = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); + if (descriptor == NULL) + { + internal_decoder_data->decoder_state = DECODER_STATE_ERROR; + LogError("Could not allocate memory for descriptor"); + result = __FAILURE__; + } + else + { + descriptor->type = AMQP_TYPE_UNKNOWN; + internal_decoder_data->decode_to_value->value.described_value.descriptor = descriptor; + internal_decoder_data->inner_decoder = internal_decoder_create(inner_decoder_callback, internal_decoder_data, descriptor); + if (internal_decoder_data->inner_decoder == NULL) + { + internal_decoder_data->decoder_state = DECODER_STATE_ERROR; + LogError("Could not create inner decoder for descriptor"); + result = __FAILURE__; + } + else + { + internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA; + internal_decoder_data->decode_value_state.described_value_state.described_value_state = DECODE_DESCRIBED_VALUE_STEP_DESCRIPTOR; + result = 0; + } + } + + break; + } /* Codes_SRS_AMQPVALUE_01_329: [<encoding code="0x40" category="fixed" width="0" label="the null value"/>] */ case 0x40: @@ -3664,7 +3984,33 @@ result = 0; break; } - /* Codes_SRS_AMQPVALUE_01_369: [<encoding name="ms64" code="0x83" category="fixed" width="8" label="64-bit two's-complement integer representing milliseconds since the unix epoch"/>] */ + /* Codes_SRS_AMQPVALUE_01_289: [\<encoding name="ieee-754" code="0x72" category="fixed" width="4" label="IEEE 754-2008 binary32"/>] */ + case 0x72: + { + /* Codes_SRS_AMQPVALUE_01_019: [1.6.11 float 32-bit floating point number (IEEE 754-2008 binary32).] */ + internal_decoder_data->decode_to_value->type = AMQP_TYPE_FLOAT; + internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA; + internal_decoder_data->bytes_decoded = 0; + *((uint32_t*)&internal_decoder_data->decode_to_value->value.float_value) = 0; + + /* Codes_SRS_AMQPVALUE_01_327: [If not enough bytes have accumulated to decode a value, the on_value_decoded shall not be called.] */ + result = 0; + break; + } + /* Codes_SRS_AMQPVALUE_01_290: [\<encoding name="ieee-754" code="0x82" category="fixed" width="8" label="IEEE 754-2008 binary64"/>] */ + case 0x82: + { + /* Codes_SRS_AMQPVALUE_01_020: [1.6.12 double 64-bit floating point number (IEEE 754-2008 binary64).] */ + internal_decoder_data->decode_to_value->type = AMQP_TYPE_DOUBLE; + internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA; + internal_decoder_data->bytes_decoded = 0; + *((uint64_t*)&internal_decoder_data->decode_to_value->value.double_value) = 0; + + /* Codes_SRS_AMQPVALUE_01_327: [If not enough bytes have accumulated to decode a value, the on_value_decoded shall not be called.] */ + result = 0; + break; + } + /* Codes_SRS_AMQPVALUE_01_369: [<encoding name="ms64" code="0x83" category="fixed" width="8" label="64-bit two's-complement integer representing milliseconds since the unix epoch"/>] */ case 0x83: { /* Codes_SRS_AMQPVALUE_01_368: [1.6.17 timestamp An absolute point in time.] */ @@ -3799,8 +4145,9 @@ switch (internal_decoder_data->constructor_byte) { default: - result = __FAILURE__; - break; + LogError("Invalid constructor byte: 0x%02x", internal_decoder_data->constructor_byte); + result = __FAILURE__; + break; case 0x00: /* descriptor */ { @@ -3808,7 +4155,8 @@ switch (step) { default: - result = __FAILURE__; + LogError("Invalid described value decode step: %d", step); + result = __FAILURE__; break; case DECODE_DESCRIBED_VALUE_STEP_DESCRIPTOR: @@ -3816,7 +4164,8 @@ size_t inner_used_bytes; if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, buffer, size, &inner_used_bytes) != 0) { - result = __FAILURE__; + LogError("Decoding bytes for described value failed"); + result = __FAILURE__; } else { @@ -3832,7 +4181,8 @@ if (described_value == NULL) { internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Could not allocate memory for AMQP value"); + result = __FAILURE__; } else { @@ -3842,7 +4192,8 @@ if (internal_decoder_data->inner_decoder == NULL) { internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Could not create inner decoder"); + result = __FAILURE__; } else { @@ -3863,7 +4214,8 @@ size_t inner_used_bytes; if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, buffer, size, &inner_used_bytes) != 0) { - result = __FAILURE__; + LogError("Decoding bytes for described value failed"); + result = __FAILURE__; } else { @@ -3892,7 +4244,8 @@ /* Codes_SRS_AMQPVALUE_01_331: [<encoding code="0x56" category="fixed" width="1" label="boolean with the octet 0x00 being false and octet 0x01 being true"/>] */ if (buffer[0] >= 2) { - result = __FAILURE__; + LogError("Bad boolean value: %02X", buffer[0]); + result = __FAILURE__; } else { @@ -4131,7 +4484,51 @@ result = 0; break; } - /* Codes_SRS_AMQPVALUE_01_369: [<encoding name="ms64" code="0x83" category="fixed" width="8" label="64-bit two's-complement integer representing milliseconds since the unix epoch"/>] */ + /* Codes_SRS_AMQPVALUE_01_289: [\<encoding name="ieee-754" code="0x72" category="fixed" width="4" label="IEEE 754-2008 binary32"/>] */ + case 0x72: + { + *((uint32_t*)&internal_decoder_data->decode_to_value->value.float_value) += ((uint32_t)buffer[0]) << ((3 - internal_decoder_data->bytes_decoded) * 8); + internal_decoder_data->bytes_decoded++; + buffer++; + size--; + + /* Codes_SRS_AMQPVALUE_01_327: [If not enough bytes have accumulated to decode a value, the on_value_decoded shall not be called.] */ + if (internal_decoder_data->bytes_decoded == 4) + { + internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; + + /* Codes_SRS_AMQPVALUE_01_323: [When enough bytes have been processed for a valid amqp value, the on_value_decoded passed in amqpvalue_decoder_create shall be called.] */ + /* Codes_SRS_AMQPVALUE_01_324: [The decoded amqp value shall be passed to on_value_decoded.] */ + /* Codes_SRS_AMQPVALUE_01_325: [Also the context stored in amqpvalue_decoder_create shall be passed to the on_value_decoded callback.] */ + internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); + } + + result = 0; + break; + } + /* Codes_SRS_AMQPVALUE_01_290: [\<encoding name="ieee-754" code="0x82" category="fixed" width="8" label="IEEE 754-2008 binary64"/>]*/ + case 0x82: + { + *((uint64_t*)&internal_decoder_data->decode_to_value->value.double_value) += ((uint64_t)buffer[0]) << ((7 - internal_decoder_data->bytes_decoded) * 8); + internal_decoder_data->bytes_decoded++; + buffer++; + size--; + + /* Codes_SRS_AMQPVALUE_01_327: [If not enough bytes have accumulated to decode a value, the on_value_decoded shall not be called.] */ + if (internal_decoder_data->bytes_decoded == 8) + { + internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; + + /* Codes_SRS_AMQPVALUE_01_323: [When enough bytes have been processed for a valid amqp value, the on_value_decoded passed in amqpvalue_decoder_create shall be called.] */ + /* Codes_SRS_AMQPVALUE_01_324: [The decoded amqp value shall be passed to on_value_decoded.] */ + /* Codes_SRS_AMQPVALUE_01_325: [Also the context stored in amqpvalue_decoder_create shall be passed to the on_value_decoded callback.] */ + internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); + } + + result = 0; + break; + } + /* Codes_SRS_AMQPVALUE_01_369: [<encoding name="ms64" code="0x83" category="fixed" width="8" label="64-bit two's-complement integer representing milliseconds since the unix epoch"/>] */ case 0x83: { internal_decoder_data->decode_to_value->value.timestamp_value = (int64_t)((uint64_t)internal_decoder_data->decode_to_value->value.timestamp_value + (((uint64_t)buffer[0]) << ((7 - internal_decoder_data->bytes_decoded) * 8))); @@ -4206,8 +4603,9 @@ internal_decoder_data->decode_to_value->value.binary_value.bytes = (unsigned char*)malloc(internal_decoder_data->decode_to_value->value.binary_value.length); if (internal_decoder_data->decode_to_value->value.binary_value.bytes == NULL) { - /* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */ - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; + /* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */ + LogError("Cannot allocate memory for decoded binary value"); + internal_decoder_data->decoder_state = DECODER_STATE_ERROR; result = __FAILURE__; } else @@ -4274,7 +4672,8 @@ { /* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */ internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Cannot allocate memory for decoded binary value"); + result = __FAILURE__; } else { @@ -4295,25 +4694,18 @@ to_copy = size; } - if (memcpy((unsigned char*)(internal_decoder_data->decode_to_value->value.binary_value.bytes) + (internal_decoder_data->bytes_decoded - 4), buffer, to_copy) == NULL) - { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; - } - else + (void)memcpy((unsigned char*)(internal_decoder_data->decode_to_value->value.binary_value.bytes) + (internal_decoder_data->bytes_decoded - 4), buffer, to_copy); + buffer += to_copy; + size -= to_copy; + internal_decoder_data->bytes_decoded += to_copy; + + if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_to_value->value.binary_value.length + 4) { - buffer += to_copy; - size -= to_copy; - internal_decoder_data->bytes_decoded += to_copy; - - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_to_value->value.binary_value.length + 4) - { - internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; - internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); - } - - result = 0; + internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; + internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); } + + result = 0; } break; @@ -4333,7 +4725,8 @@ { /* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */ internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Could not allocate memory for decoded string value"); + result = __FAILURE__; } else { @@ -4358,30 +4751,23 @@ to_copy = size; } - if (memcpy(internal_decoder_data->decode_to_value->value.string_value.chars + (internal_decoder_data->bytes_decoded - 1), buffer, to_copy) == NULL) - { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; - } - else + (void)memcpy(internal_decoder_data->decode_to_value->value.string_value.chars + (internal_decoder_data->bytes_decoded - 1), buffer, to_copy); + buffer += to_copy; + size -= to_copy; + internal_decoder_data->bytes_decoded += to_copy; + + if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.string_value_state.length + 1) { - buffer += to_copy; - size -= to_copy; - internal_decoder_data->bytes_decoded += to_copy; - - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.string_value_state.length + 1) - { - internal_decoder_data->decode_to_value->value.string_value.chars[internal_decoder_data->decode_value_state.string_value_state.length] = 0; - internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; - - /* Codes_SRS_AMQPVALUE_01_323: [When enough bytes have been processed for a valid amqp value, the on_value_decoded passed in amqpvalue_decoder_create shall be called.] */ - /* Codes_SRS_AMQPVALUE_01_324: [The decoded amqp value shall be passed to on_value_decoded.] */ - /* Codes_SRS_AMQPVALUE_01_325: [Also the context stored in amqpvalue_decoder_create shall be passed to the on_value_decoded callback.] */ - internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); - } - - result = 0; + internal_decoder_data->decode_to_value->value.string_value.chars[internal_decoder_data->decode_value_state.string_value_state.length] = 0; + internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; + + /* Codes_SRS_AMQPVALUE_01_323: [When enough bytes have been processed for a valid amqp value, the on_value_decoded passed in amqpvalue_decoder_create shall be called.] */ + /* Codes_SRS_AMQPVALUE_01_324: [The decoded amqp value shall be passed to on_value_decoded.] */ + /* Codes_SRS_AMQPVALUE_01_325: [Also the context stored in amqpvalue_decoder_create shall be passed to the on_value_decoded callback.] */ + internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); } + + result = 0; } break; } @@ -4402,7 +4788,8 @@ { /* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */ internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Could not allocate memory for decoded string value"); + result = __FAILURE__; } else { @@ -4432,30 +4819,23 @@ to_copy = size; } - if (memcpy(internal_decoder_data->decode_to_value->value.string_value.chars + (internal_decoder_data->bytes_decoded - 4), buffer, to_copy) == NULL) - { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; - } - else + (void)memcpy(internal_decoder_data->decode_to_value->value.string_value.chars + (internal_decoder_data->bytes_decoded - 4), buffer, to_copy); + buffer += to_copy; + size -= to_copy; + internal_decoder_data->bytes_decoded += to_copy; + + if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.string_value_state.length + 4) { - buffer += to_copy; - size -= to_copy; - internal_decoder_data->bytes_decoded += to_copy; - - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.string_value_state.length + 4) - { - internal_decoder_data->decode_to_value->value.string_value.chars[internal_decoder_data->decode_value_state.string_value_state.length] = '\0'; - internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; - - /* Codes_SRS_AMQPVALUE_01_323: [When enough bytes have been processed for a valid amqp value, the on_value_decoded passed in amqpvalue_decoder_create shall be called.] */ - /* Codes_SRS_AMQPVALUE_01_324: [The decoded amqp value shall be passed to on_value_decoded.] */ - /* Codes_SRS_AMQPVALUE_01_325: [Also the context stored in amqpvalue_decoder_create shall be passed to the on_value_decoded callback.] */ - internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); - } - - result = 0; + internal_decoder_data->decode_to_value->value.string_value.chars[internal_decoder_data->decode_value_state.string_value_state.length] = '\0'; + internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; + + /* Codes_SRS_AMQPVALUE_01_323: [When enough bytes have been processed for a valid amqp value, the on_value_decoded passed in amqpvalue_decoder_create shall be called.] */ + /* Codes_SRS_AMQPVALUE_01_324: [The decoded amqp value shall be passed to on_value_decoded.] */ + /* Codes_SRS_AMQPVALUE_01_325: [Also the context stored in amqpvalue_decoder_create shall be passed to the on_value_decoded callback.] */ + internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); } + + result = 0; } break; } @@ -4474,7 +4854,8 @@ { /* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */ internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Could not allocate memory for decoded symbol value"); + result = __FAILURE__; } else { @@ -4499,30 +4880,23 @@ to_copy = size; } - if (memcpy(internal_decoder_data->decode_to_value->value.symbol_value.chars + (internal_decoder_data->bytes_decoded - 1), buffer, to_copy) == NULL) - { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; - } - else + (void)memcpy(internal_decoder_data->decode_to_value->value.symbol_value.chars + (internal_decoder_data->bytes_decoded - 1), buffer, to_copy); + buffer += to_copy; + size -= to_copy; + internal_decoder_data->bytes_decoded += to_copy; + + if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.symbol_value_state.length + 1) { - buffer += to_copy; - size -= to_copy; - internal_decoder_data->bytes_decoded += to_copy; - - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.symbol_value_state.length + 1) - { - internal_decoder_data->decode_to_value->value.symbol_value.chars[internal_decoder_data->decode_value_state.symbol_value_state.length] = 0; - internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; - - /* Codes_SRS_AMQPVALUE_01_323: [When enough bytes have been processed for a valid amqp value, the on_value_decoded passed in amqpvalue_decoder_create shall be called.] */ - /* Codes_SRS_AMQPVALUE_01_324: [The decoded amqp value shall be passed to on_value_decoded.] */ - /* Codes_SRS_AMQPVALUE_01_325: [Also the context stored in amqpvalue_decoder_create shall be passed to the on_value_decoded callback.] */ - internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); - } - - result = 0; + internal_decoder_data->decode_to_value->value.symbol_value.chars[internal_decoder_data->decode_value_state.symbol_value_state.length] = 0; + internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; + + /* Codes_SRS_AMQPVALUE_01_323: [When enough bytes have been processed for a valid amqp value, the on_value_decoded passed in amqpvalue_decoder_create shall be called.] */ + /* Codes_SRS_AMQPVALUE_01_324: [The decoded amqp value shall be passed to on_value_decoded.] */ + /* Codes_SRS_AMQPVALUE_01_325: [Also the context stored in amqpvalue_decoder_create shall be passed to the on_value_decoded callback.] */ + internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); } + + result = 0; } break; } @@ -4543,7 +4917,8 @@ { /* Codes_SRS_AMQPVALUE_01_326: [If any allocation failure occurs during decoding, amqpvalue_decode_bytes shall fail and return a non-zero value.] */ internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Could not allocate memory for decoded symbol value"); + result = __FAILURE__; } else { @@ -4573,30 +4948,23 @@ to_copy = size; } - if (memcpy(internal_decoder_data->decode_to_value->value.symbol_value.chars + (internal_decoder_data->bytes_decoded - 4), buffer, to_copy) == NULL) - { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; - } - else + (void)memcpy(internal_decoder_data->decode_to_value->value.symbol_value.chars + (internal_decoder_data->bytes_decoded - 4), buffer, to_copy); + buffer += to_copy; + size -= to_copy; + internal_decoder_data->bytes_decoded += to_copy; + + if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.symbol_value_state.length + 4) { - buffer += to_copy; - size -= to_copy; - internal_decoder_data->bytes_decoded += to_copy; - - if (internal_decoder_data->bytes_decoded == internal_decoder_data->decode_value_state.symbol_value_state.length + 4) - { - internal_decoder_data->decode_to_value->value.symbol_value.chars[internal_decoder_data->decode_value_state.symbol_value_state.length] = '\0'; - internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; - - /* Codes_SRS_AMQPVALUE_01_323: [When enough bytes have been processed for a valid amqp value, the on_value_decoded passed in amqpvalue_decoder_create shall be called.] */ - /* Codes_SRS_AMQPVALUE_01_324: [The decoded amqp value shall be passed to on_value_decoded.] */ - /* Codes_SRS_AMQPVALUE_01_325: [Also the context stored in amqpvalue_decoder_create shall be passed to the on_value_decoded callback.] */ - internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); - } - - result = 0; + internal_decoder_data->decode_to_value->value.symbol_value.chars[internal_decoder_data->decode_value_state.symbol_value_state.length] = '\0'; + internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR; + + /* Codes_SRS_AMQPVALUE_01_323: [When enough bytes have been processed for a valid amqp value, the on_value_decoded passed in amqpvalue_decoder_create shall be called.] */ + /* Codes_SRS_AMQPVALUE_01_324: [The decoded amqp value shall be passed to on_value_decoded.] */ + /* Codes_SRS_AMQPVALUE_01_325: [Also the context stored in amqpvalue_decoder_create shall be passed to the on_value_decoded callback.] */ + internal_decoder_data->on_value_decoded(internal_decoder_data->on_value_decoded_context, internal_decoder_data->decode_to_value); } + + result = 0; } break; } @@ -4610,7 +4978,8 @@ switch (step) { default: - result = __FAILURE__; + LogError("Invalid step in decoding list value: %d", step); + result = __FAILURE__; break; case DECODE_LIST_STEP_SIZE: @@ -4633,6 +5002,7 @@ internal_decoder_data->bytes_decoded = 0; internal_decoder_data->decode_to_value->value.list_value.count = 0; } + result = 0; } @@ -4647,6 +5017,7 @@ { internal_decoder_data->decode_to_value->value.list_value.count += buffer[0] << ((3 - internal_decoder_data->bytes_decoded) * 8); } + internal_decoder_data->bytes_decoded++; buffer++; size--; @@ -4669,7 +5040,8 @@ internal_decoder_data->decode_to_value->value.list_value.items = (AMQP_VALUE*)malloc(sizeof(AMQP_VALUE) * internal_decoder_data->decode_to_value->value.list_value.count); if (internal_decoder_data->decode_to_value->value.list_value.items == NULL) { - result = __FAILURE__; + LogError("Could not allocate memory for decoded list value"); + result = __FAILURE__; } else { @@ -4703,10 +5075,12 @@ else { uint32_t i; + internal_decoder_data->decode_to_value->value.list_value.items = (AMQP_VALUE*)malloc(sizeof(AMQP_VALUE) * internal_decoder_data->decode_to_value->value.list_value.count); if (internal_decoder_data->decode_to_value->value.list_value.items == NULL) { - result = __FAILURE__; + LogError("Could not allocate memory for decoded list value"); + result = __FAILURE__; } else { @@ -4714,6 +5088,7 @@ { internal_decoder_data->decode_to_value->value.list_value.items[i] = NULL; } + internal_decoder_data->decode_value_state.list_value_state.list_value_state = DECODE_LIST_STEP_ITEMS; internal_decoder_data->bytes_decoded = 0; internal_decoder_data->inner_decoder = NULL; @@ -4748,8 +5123,9 @@ internal_decoder_data->inner_decoder = internal_decoder_create(inner_decoder_callback, internal_decoder_data, list_item); if (internal_decoder_data->inner_decoder == NULL) { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Could not create inner decoder for list items"); + internal_decoder_data->decoder_state = DECODER_STATE_ERROR; + result = __FAILURE__; } else { @@ -4760,11 +5136,13 @@ if (internal_decoder_data->inner_decoder == NULL) { - result = __FAILURE__; + LogError("NULL inner decoder. This should not happen under normal circumstances"); + result = __FAILURE__; } else if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, buffer, size, &inner_used_bytes) != 0) { - result = __FAILURE__; + LogError("Decoding list items failed"); + result = __FAILURE__; } else { @@ -4809,7 +5187,8 @@ switch (step) { default: - result = __FAILURE__; + LogError("Invalid step in decoding map value: %d", step); + result = __FAILURE__; break; case DECODE_MAP_STEP_SIZE: @@ -4868,7 +5247,8 @@ internal_decoder_data->decode_to_value->value.map_value.pairs = (AMQP_MAP_KEY_VALUE_PAIR*)malloc(sizeof(AMQP_MAP_KEY_VALUE_PAIR) * (internal_decoder_data->decode_to_value->value.map_value.pair_count * 2)); if (internal_decoder_data->decode_to_value->value.map_value.pairs == NULL) { - result = __FAILURE__; + LogError("Could not allocate memory for map value items"); + result = __FAILURE__; } else { @@ -4906,7 +5286,8 @@ internal_decoder_data->decode_to_value->value.map_value.pairs = (AMQP_MAP_KEY_VALUE_PAIR*)malloc(sizeof(AMQP_MAP_KEY_VALUE_PAIR) * (internal_decoder_data->decode_to_value->value.map_value.pair_count * 2)); if (internal_decoder_data->decode_to_value->value.map_value.pairs == NULL) { - result = __FAILURE__; + LogError("Could not allocate memory for map value items"); + result = __FAILURE__; } else { @@ -4915,6 +5296,7 @@ internal_decoder_data->decode_to_value->value.map_value.pairs[i].key = NULL; internal_decoder_data->decode_to_value->value.map_value.pairs[i].value = NULL; } + internal_decoder_data->decode_value_state.map_value_state.map_value_state = DECODE_MAP_STEP_PAIRS; internal_decoder_data->bytes_decoded = 0; internal_decoder_data->inner_decoder = NULL; @@ -4939,7 +5321,8 @@ AMQP_VALUE_DATA* map_item = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); if (map_item == NULL) { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; + LogError("Could not allocate memory for map item"); + internal_decoder_data->decoder_state = DECODER_STATE_ERROR; result = __FAILURE__; } else @@ -4956,7 +5339,8 @@ internal_decoder_data->inner_decoder = internal_decoder_create(inner_decoder_callback, internal_decoder_data, map_item); if (internal_decoder_data->inner_decoder == NULL) { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; + LogError("Could not create inner decoder for map item"); + internal_decoder_data->decoder_state = DECODER_STATE_ERROR; result = __FAILURE__; } else @@ -4968,11 +5352,13 @@ if (internal_decoder_data->inner_decoder == NULL) { - result = __FAILURE__; + LogError("NULL inner decoder. This should not happen under normal circumstances"); + result = __FAILURE__; } else if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, buffer, size, &inner_used_bytes) != 0) { - result = __FAILURE__; + LogError("Could not decode map item"); + result = __FAILURE__; } else { @@ -5016,7 +5402,8 @@ switch (step) { default: - result = __FAILURE__; + LogError("Invalid step in decoding array value: %d", step); + result = __FAILURE__; break; case DECODE_ARRAY_STEP_SIZE: @@ -5053,6 +5440,7 @@ { internal_decoder_data->decode_to_value->value.array_value.count += buffer[0] << ((3 - internal_decoder_data->bytes_decoded) * 8); } + internal_decoder_data->bytes_decoded++; buffer++; size--; @@ -5072,7 +5460,8 @@ internal_decoder_data->decode_to_value->value.array_value.items = (AMQP_VALUE*)malloc(sizeof(AMQP_VALUE) * internal_decoder_data->decode_to_value->value.array_value.count); if (internal_decoder_data->decode_to_value->value.array_value.items == NULL) { - result = __FAILURE__; + LogError("Could not allocate memory for array items"); + result = __FAILURE__; } else { @@ -5105,7 +5494,8 @@ internal_decoder_data->decode_to_value->value.array_value.items = (AMQP_VALUE*)malloc(sizeof(AMQP_VALUE) * internal_decoder_data->decode_to_value->value.array_value.count); if (internal_decoder_data->decode_to_value->value.array_value.items == NULL) { - result = __FAILURE__; + LogError("Could not allocate memory for array items"); + result = __FAILURE__; } else { @@ -5139,8 +5529,9 @@ AMQP_VALUE_DATA* array_item = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); if (array_item == NULL) { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Could not allocate memory for array item to be decoded"); + internal_decoder_data->decoder_state = DECODER_STATE_ERROR; + result = __FAILURE__; } else { @@ -5150,7 +5541,8 @@ if (internal_decoder_data->inner_decoder == NULL) { internal_decoder_data->decoder_state = DECODER_STATE_ERROR; - result = __FAILURE__; + LogError("Could not create inner decoder for array items"); + result = __FAILURE__; } else { @@ -5161,11 +5553,13 @@ if (internal_decoder_data->inner_decoder == NULL) { - result = __FAILURE__; + LogError("NULL inner decoder. This should not happen under normal circumstances"); + result = __FAILURE__; } else if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, buffer, size, &inner_used_bytes) != 0) { - result = __FAILURE__; + LogError("Could not decode array item"); + result = __FAILURE__; } else { @@ -5192,7 +5586,8 @@ AMQP_VALUE_DATA* array_item = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); if (array_item == NULL) { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; + LogError("Could not allocate memory for array item"); + internal_decoder_data->decoder_state = DECODER_STATE_ERROR; result = __FAILURE__; } else @@ -5202,14 +5597,16 @@ internal_decoder_data->inner_decoder = internal_decoder_create(inner_decoder_callback, internal_decoder_data, array_item); if (internal_decoder_data->inner_decoder == NULL) { - internal_decoder_data->decoder_state = DECODER_STATE_ERROR; + LogError("Could not create inner decoder for array item"); + internal_decoder_data->decoder_state = DECODER_STATE_ERROR; result = __FAILURE__; } else { if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, &internal_decoder_data->decode_value_state.array_value_state.constructor_byte, 1, NULL) != 0) { - result = __FAILURE__; + LogError("Could not decode array item data"); + result = __FAILURE__; } else { @@ -5258,19 +5655,25 @@ /* Codes_SRS_AMQPVALUE_01_312: [If the on_value_decoded argument is NULL, amqpvalue_decoder_create shall return NULL.] */ if (on_value_decoded == NULL) { - decoder_instance = NULL; + LogError("NULL on_value_decoded"); + decoder_instance = NULL; } else { decoder_instance = (AMQPVALUE_DECODER_HANDLE_DATA*)malloc(sizeof(AMQPVALUE_DECODER_HANDLE_DATA)); /* Codes_SRS_AMQPVALUE_01_313: [If creating the decoder fails, amqpvalue_decoder_create shall return NULL.] */ - if (decoder_instance != NULL) - { + if (decoder_instance == NULL) + { + LogError("Could not allocate memory for AMQP value decoder"); + } + else + { decoder_instance->decode_to_value = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); if (decoder_instance->decode_to_value == NULL) { /* Codes_SRS_AMQPVALUE_01_313: [If creating the decoder fails, amqpvalue_decoder_create shall return NULL.] */ - free(decoder_instance); + LogError("Could not allocate memory for decoded AMQP value"); + free(decoder_instance); decoder_instance = NULL; } else @@ -5280,7 +5683,8 @@ if (decoder_instance->internal_decoder == NULL) { /* Codes_SRS_AMQPVALUE_01_313: [If creating the decoder fails, amqpvalue_decoder_create shall return NULL.] */ - free(decoder_instance->decode_to_value); + LogError("Could not create the internal decoder"); + free(decoder_instance->decode_to_value); free(decoder_instance); decoder_instance = NULL; } @@ -5294,11 +5698,14 @@ void amqpvalue_decoder_destroy(AMQPVALUE_DECODER_HANDLE handle) { - AMQPVALUE_DECODER_HANDLE_DATA* decoder_instance = (AMQPVALUE_DECODER_HANDLE_DATA*)handle; - - /* Codes_SRS_AMQPVALUE_01_317: [If handle is NULL, amqpvalue_decoder_destroy shall do nothing.] */ - if (decoder_instance != NULL) - { + if (handle == NULL) + { + /* Codes_SRS_AMQPVALUE_01_317: [If handle is NULL, amqpvalue_decoder_destroy shall do nothing.] */ + LogError("NULL handle"); + } + else + { + AMQPVALUE_DECODER_HANDLE_DATA* decoder_instance = (AMQPVALUE_DECODER_HANDLE_DATA*)handle; /* Codes_SRS_AMQPVALUE_01_316: [amqpvalue_decoder_destroy shall free all resources associated with the amqpvalue_decoder.] */ amqpvalue_destroy(decoder_instance->decode_to_value); internal_decoder_destroy(decoder_instance->internal_decoder); @@ -5318,7 +5725,9 @@ /* Codes_SRS_AMQPVALUE_01_321: [If size is 0, amqpvalue_decode_bytes shall return a non-zero value.] */ (size == 0)) { - result = __FAILURE__; + LogError("Bad arguments: decoder_instance = %p, buffer = %p, size = %u", + decoder_instance, buffer, size); + result = __FAILURE__; } else { @@ -5327,7 +5736,8 @@ /* Codes_SRS_AMQPVALUE_01_318: [amqpvalue_decode_bytes shall decode size bytes that are passed in the buffer argument.] */ if (internal_decoder_decode_bytes(decoder_instance->internal_decoder, buffer, size, &used_bytes) != 0) { - result = __FAILURE__; + LogError("Failed decoding bytes"); + result = __FAILURE__; } else { @@ -5345,7 +5755,8 @@ if (value == NULL) { - result = NULL; + LogError("NULL value"); + result = NULL; } else { @@ -5353,7 +5764,8 @@ if ((value_data->type != AMQP_TYPE_DESCRIBED) && (value_data->type != AMQP_TYPE_COMPOSITE)) { - result = NULL; + LogError("Type is not described or composite"); + result = NULL; } else { @@ -5370,7 +5782,8 @@ if (value == NULL) { - result = NULL; + LogError("NULL value"); + result = NULL; } else { @@ -5378,7 +5791,8 @@ if ((value_data->type != AMQP_TYPE_DESCRIBED) && (value_data->type != AMQP_TYPE_COMPOSITE)) { - result = NULL; + LogError("Type is not described or composite"); + result = NULL; } else { @@ -5392,25 +5806,35 @@ AMQP_VALUE amqpvalue_create_described(AMQP_VALUE descriptor, AMQP_VALUE value) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - if (result != NULL) - { + if (result == NULL) + { + LogError("Cannot allocate memory for described type"); + } + else + { result->type = AMQP_TYPE_DESCRIBED; result->value.described_value.descriptor = descriptor; result->value.described_value.value = value; } + return result; } AMQP_VALUE amqpvalue_create_composite(AMQP_VALUE descriptor, uint32_t list_size) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - if (result != NULL) - { + if (result == NULL) + { + LogError("Cannot allocate memory for composite type"); + } + else + { result->type = AMQP_TYPE_COMPOSITE; result->value.described_value.descriptor = amqpvalue_clone(descriptor); if (result->value.described_value.descriptor == NULL) { - free(result); + LogError("Cannot clone descriptor for composite type"); + free(result); result = NULL; } else @@ -5418,7 +5842,8 @@ result->value.described_value.value = amqpvalue_create_list(); if (result->value.described_value.value == NULL) { - amqpvalue_destroy(result->value.described_value.descriptor); + LogError("Cannot create list for composite type"); + amqpvalue_destroy(result->value.described_value.descriptor); free(result); result = NULL; } @@ -5426,7 +5851,8 @@ { if (amqpvalue_set_list_item_count(result->value.described_value.value, list_size) != 0) { - amqpvalue_destroy(result->value.described_value.descriptor); + LogError("Cannot set list item count for composite type"); + amqpvalue_destroy(result->value.described_value.descriptor); amqpvalue_destroy(result->value.described_value.value); free(result); result = NULL; @@ -5441,33 +5867,31 @@ AMQP_VALUE amqpvalue_create_composite_with_ulong_descriptor(uint64_t descriptor) { AMQP_VALUE_DATA* result = (AMQP_VALUE_DATA*)malloc(sizeof(AMQP_VALUE_DATA)); - if (result != NULL) - { + if (result == NULL) + { + LogError("Cannot allocate memory for composite type"); + } + else + { AMQP_VALUE descriptor_ulong_value = amqpvalue_create_ulong(descriptor); if (descriptor_ulong_value == NULL) { - free(result); + LogError("Cannot create ulong descriptor for composite type"); + free(result); result = NULL; } else { result->type = AMQP_TYPE_COMPOSITE; result->value.described_value.descriptor = descriptor_ulong_value; - if (result->value.described_value.descriptor == NULL) + result->value.described_value.value = amqpvalue_create_list(); + if (result->value.described_value.value == NULL) { - free(descriptor_ulong_value); + LogError("Cannot create list for composite type"); + amqpvalue_destroy(descriptor_ulong_value); free(result); result = NULL; } - else - { - result->value.described_value.value = amqpvalue_create_list(); - if (result->value.described_value.value == NULL) - { - free(result); - result = NULL; - } - } } } @@ -5480,20 +5904,23 @@ if (value == NULL) { - result = __FAILURE__; + LogError("NULL value"); + result = __FAILURE__; } else { AMQP_VALUE_DATA* value_data = (AMQP_VALUE_DATA*)value; if (value_data->type != AMQP_TYPE_COMPOSITE) { - result = __FAILURE__; + LogError("Attempt to set composite item on a non-composite type"); + result = __FAILURE__; } else { if (amqpvalue_set_list_item(value_data->value.described_value.value, index, item_value) != 0) { - result = __FAILURE__; + LogError("amqpvalue_set_list_item failed for composite item"); + result = __FAILURE__; } else { @@ -5511,7 +5938,8 @@ if (value == NULL) { - result = NULL; + LogError("NULL value"); + result = NULL; } else { @@ -5519,11 +5947,16 @@ if ((value_data->type != AMQP_TYPE_COMPOSITE) && (value_data->type != AMQP_TYPE_DESCRIBED)) { - result = NULL; + LogError("Attempt to get composite item on a non-composite type"); + result = NULL; } else { result = amqpvalue_get_list_item(value_data->value.described_value.value, index); + if (result == NULL) + { + LogError("amqpvalue_get_list_item failed for composite item"); + } } } @@ -5536,7 +5969,8 @@ if (value == NULL) { - result = NULL; + LogError("NULL value"); + result = NULL; } else { @@ -5544,24 +5978,65 @@ if ((value_data->type != AMQP_TYPE_COMPOSITE) && (value_data->type != AMQP_TYPE_DESCRIBED)) { - result = NULL; + LogError("Attempt to get composite item in place on a non-composite type"); + result = NULL; } else { result = amqpvalue_get_list_item_in_place(value_data->value.described_value.value, index); + if (result == NULL) + { + LogError("amqpvalue_get_list_item_in_place failed for composite item"); + } } } return result; } +int amqpvalue_get_composite_item_count(AMQP_VALUE value, uint32_t* item_count) +{ + int result; + + if (value == NULL) + { + LogError("NULL value"); + result = __FAILURE__; + } + else + { + AMQP_VALUE_DATA* value_data = (AMQP_VALUE_DATA*)value; + if ((value_data->type != AMQP_TYPE_COMPOSITE) && + (value_data->type != AMQP_TYPE_DESCRIBED)) + { + LogError("Attempt to get composite item in place on a non-composite type"); + result = __FAILURE__; + } + else + { + if (amqpvalue_get_list_item_count(value_data->value.described_value.value, item_count) != 0) + { + LogError("amqpvalue_get_list_item_in_place failed for composite item"); + result = __FAILURE__; + } + else + { + result = 0; + } + } + } + + return result; +} + AMQP_VALUE amqpvalue_get_list_item_in_place(AMQP_VALUE value, size_t index) { AMQP_VALUE result; if (value == NULL) { - result = NULL; + LogError("NULL value"); + result = NULL; } else { @@ -5570,7 +6045,8 @@ if ((value_data->type != AMQP_TYPE_LIST) || (value_data->value.list_value.count <= index)) { - result = NULL; + LogError("Attempt to get list item in place on a non-list type"); + result = NULL; } else {