in src/amqpvalue.c [4934:7048]
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)
{
/* TODO: investigate if this check is even needed */
LogError("NULL internal_decoder_data");
result = MU_FAILURE;
}
else
{
result = 0;
/* Codes_SRS_AMQPVALUE_01_322: [amqpvalue_decode_bytes shall process the bytes byte by byte, as a stream.] */
while ((size > 0) && (internal_decoder_data->decoder_state != DECODER_STATE_DONE))
{
switch (internal_decoder_data->decoder_state)
{
default:
LogError("Invalid decoder state: %d", (int)internal_decoder_data->decoder_state);
result = MU_FAILURE;
break;
case DECODER_STATE_CONSTRUCTOR:
{
if ((internal_decoder_data->decode_to_value != NULL) && (!internal_decoder_data->is_internal))
{
amqpvalue_destroy(internal_decoder_data->decode_to_value);
internal_decoder_data->decode_to_value = NULL;
}
if (internal_decoder_data->decode_to_value == NULL)
{
internal_decoder_data->decode_to_value = (AMQP_VALUE_DATA*)REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA);
}
if (internal_decoder_data->decode_to_value == NULL)
{
LogError("Cannot allocate decode value");
result = MU_FAILURE;
break;
}
memset(internal_decoder_data->decode_to_value, 0, sizeof(AMQP_VALUE_DATA));
internal_decoder_data->constructor_byte = buffer[0];
buffer++;
size--;
switch (internal_decoder_data->constructor_byte)
{
default:
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
LogError("Invalid constructor byte: 0x%02x", internal_decoder_data->constructor_byte);
result = MU_FAILURE;
break;
case 0x00: /* descriptor */
{
AMQP_VALUE_DATA* descriptor;
internal_decoder_data->decode_to_value->type = AMQP_TYPE_DESCRIBED;
internal_decoder_data->decode_to_value->value.described_value.value = NULL;
descriptor = REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA);
if (descriptor == NULL)
{
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
LogError("Could not allocate memory for descriptor");
result = MU_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, true);
if (internal_decoder_data->inner_decoder == NULL)
{
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
LogError("Could not create inner decoder for descriptor");
result = MU_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:
{
/* Codes_SRS_AMQPVALUE_01_328: [1.6.1 null Indicates an empty value.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_NULL;
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_331: [<encoding code="0x56" category="fixed" width="1" label="boolean with the octet 0x00 being false and octet 0x01 being true"/>] */
case 0x56:
{
/* Codes_SRS_AMQPVALUE_01_330: [1.6.2 boolean Represents a true or false value.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_BOOL;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->bytes_decoded = 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_332: [<encoding name="true" code="0x41" category="fixed" width="0" label="the boolean value true"/>] */
case 0x41:
{
/* Codes_SRS_AMQPVALUE_01_330: [1.6.2 boolean Represents a true or false value.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_BOOL;
internal_decoder_data->decode_to_value->value.bool_value = true;
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_333: [<encoding name="false" code="0x42" category="fixed" width="0" label="the boolean value false"/>] */
case 0x42:
{
/* Codes_SRS_AMQPVALUE_01_330: [1.6.2 boolean Represents a true or false value.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_BOOL;
internal_decoder_data->decode_to_value->value.bool_value = false;
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_335: [<encoding code="0x50" category="fixed" width="1" label="8-bit unsigned integer"/>] */
case 0x50:
{
/* Codes_SRS_AMQPVALUE_01_334: [1.6.3 ubyte Integer in the range 0 to 28 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_UBYTE;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.ubyte_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_337: [<encoding code="0x60" category="fixed" width="2" label="16-bit unsigned integer in network byte order"/>] */
case 0x60:
{
/* Codes_SRS_AMQPVALUE_01_336: [1.6.4 ushort Integer in the range 0 to 216 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_USHORT;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.ushort_value = 0;
internal_decoder_data->bytes_decoded = 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_339: [<encoding code="0x70" category="fixed" width="4" label="32-bit unsigned integer in network byte order"/>] */
case 0x70:
/* Codes_SRS_AMQPVALUE_01_340: [<encoding name="smalluint" code="0x52" category="fixed" width="1" label="unsigned integer value in the range 0 to 255 inclusive"/>] */
case 0x52:
{
internal_decoder_data->decode_to_value->type = AMQP_TYPE_UINT;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.uint_value = 0;
internal_decoder_data->bytes_decoded = 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_341: [<encoding name="uint0" code="0x43" category="fixed" width="0" label="the uint value 0"/>] */
case 0x43:
{
/* Codes_SRS_AMQPVALUE_01_338: [1.6.5 uint Integer in the range 0 to 232 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_UINT;
internal_decoder_data->decode_to_value->value.uint_value = 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;
}
/* Codes_SRS_AMQPVALUE_01_343: [<encoding code="0x80" category="fixed" width="8" label="64-bit unsigned integer in network byte order"/>] */
case 0x80:
{
/* Codes_SRS_AMQPVALUE_01_342: [1.6.6 ulong Integer in the range 0 to 264 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_ULONG;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.ulong_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.] */
internal_decoder_data->bytes_decoded = 0;
result = 0;
break;
}
/* Codes_SRS_AMQPVALUE_01_344: [<encoding name="smallulong" code="0x53" category="fixed" width="1" label="unsigned long value in the range 0 to 255 inclusive"/>] */
case 0x53:
{
internal_decoder_data->decode_to_value->type = AMQP_TYPE_ULONG;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.ulong_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.] */
internal_decoder_data->bytes_decoded = 0;
result = 0;
break;
}
/* Codes_SRS_AMQPVALUE_01_345: [<encoding name="ulong0" code="0x44" category="fixed" width="0" label="the ulong value 0"/>] */
case 0x44:
{
/* Codes_SRS_AMQPVALUE_01_342: [1.6.6 ulong Integer in the range 0 to 264 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_ULONG;
internal_decoder_data->decode_to_value->value.ulong_value = 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;
}
/* Codes_SRS_AMQPVALUE_01_347: [<encoding code="0x51" category="fixed" width="1" label="8-bit two's-complement integer"/>] */
case 0x51:
{
/* Codes_SRS_AMQPVALUE_01_346: [1.6.7 byte Integer in the range -(27) to 27 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_BYTE;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.byte_value = 0;
internal_decoder_data->bytes_decoded = 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_349: [<encoding code="0x61" category="fixed" width="2" label="16-bit two's-complement integer in network byte order"/>] */
case 0x61:
{
/* Codes_SRS_AMQPVALUE_01_348: [1.6.8 short Integer in the range -(215) to 215 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_SHORT;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.short_value = 0;
internal_decoder_data->bytes_decoded = 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_351: [<encoding code="0x71" category="fixed" width="4" label="32-bit two's-complement integer in network byte order"/>] */
case 0x71:
{
/* Codes_SRS_AMQPVALUE_01_350: [1.6.9 int Integer in the range -(231) to 231 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_INT;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.int_value = 0;
internal_decoder_data->bytes_decoded = 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_352: [<encoding name="smallint" code="0x54" category="fixed" width="1" label="8-bit two's-complement integer"/>] */
case 0x54:
{
/* Codes_SRS_AMQPVALUE_01_350: [1.6.9 int Integer in the range -(231) to 231 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_INT;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.int_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_354: [<encoding code="0x81" category="fixed" width="8" label="64-bit two's-complement integer in network byte order"/>] */
case 0x81:
{
/* Codes_SRS_AMQPVALUE_01_353: [1.6.10 long Integer in the range -(263) to 263 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_LONG;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.long_value = 0;
internal_decoder_data->bytes_decoded = 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_355: [<encoding name="smalllong" code="0x55" category="fixed" width="1" label="8-bit two's-complement integer"/>] */
case 0x55:
{
/* Codes_SRS_AMQPVALUE_01_353: [1.6.10 long Integer in the range -(263) to 263 - 1 inclusive.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_LONG;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.long_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_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.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_TIMESTAMP;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.timestamp_value = 0;
internal_decoder_data->bytes_decoded = 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_371: [<encoding code="0x98" category="fixed" width="16" label="UUID as defined in section 4.1.2 of RFC-4122"/>] */
case 0x98:
{
/* Codes_SRS_AMQPVALUE_01_370: [1.6.18 uuid A universally unique identifier as defined by RFC-4122 section 4.1.2 .] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_UUID;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.timestamp_value = 0;
internal_decoder_data->bytes_decoded = 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_373: [<encoding name="vbin8" code="0xa0" category="variable" width="1" label="up to 2^8 - 1 octets of binary data"/>] */
case 0xA0:
/* Codes_SRS_AMQPVALUE_01_374: [<encoding name="vbin32" code="0xb0" category="variable" width="4" label="up to 2^32 - 1 octets of binary data"/>] */
case 0xB0:
{
/* Codes_SRS_AMQPVALUE_01_372: [1.6.19 binary A sequence of octets.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_BINARY;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.binary_value.length = 0;
internal_decoder_data->decode_to_value->value.binary_value.bytes = NULL;
internal_decoder_data->bytes_decoded = 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_376: [<encoding name="str8-utf8" code="0xa1" category="variable" width="1" label="up to 2^8 - 1 octets worth of UTF-8 Unicode (with no byte order mark)"/>] */
case 0xA1:
/* Codes_SRS_AMQPVALUE_01_377: [<encoding name="str32-utf8" code="0xb1" category="variable" width="4" label="up to 2^32 - 1 octets worth of UTF-8 Unicode (with no byte order mark)"/>] */
case 0xB1:
{
/* Codes_SRS_AMQPVALUE_01_375: [1.6.20 string A sequence of Unicode characters.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_STRING;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.string_value.chars = NULL;
internal_decoder_data->decode_value_state.string_value_state.length = 0;
internal_decoder_data->bytes_decoded = 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_379: [<encoding name="sym8" code="0xa3" category="variable" width="1" label="up to 2^8 - 1 seven bit ASCII characters representing a symbolic value"/>] */
case 0xA3:
/* Codes_SRS_AMQPVALUE_01_380: [<encoding name="sym32" code="0xb3" category="variable" width="4" label="up to 2^32 - 1 seven bit ASCII characters representing a symbolic value"/>] */
case 0xB3:
{
/* Codes_SRS_AMQPVALUE_01_378: [1.6.21 symbol Symbolic values from a constrained domain.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_SYMBOL;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.symbol_value.chars = NULL;
internal_decoder_data->decode_value_state.symbol_value_state.length = 0;
internal_decoder_data->bytes_decoded = 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_384: [<encoding name="list0" code="0x45" category="fixed" width="0" label="the empty list (i.e. the list with no elements)"/>] */
case 0x45:
/* Codes_SRS_AMQPVALUE_01_383: [1.6.22 list A sequence of polymorphic values.] */
internal_decoder_data->decode_to_value->type = AMQP_TYPE_LIST;
internal_decoder_data->decoder_state = DECODER_STATE_CONSTRUCTOR;
internal_decoder_data->decode_to_value->value.list_value.count = 0;
internal_decoder_data->decode_to_value->value.list_value.items = NULL;
/* 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_385: [<encoding name="list8" code="0xc0" category="compound" width="1" label="up to 2^8 - 1 list elements with total size less than 2^8 octets"/>] */
case 0xC0:
case 0xD0:
internal_decoder_data->decode_to_value->type = AMQP_TYPE_LIST;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.list_value.count = 0;
internal_decoder_data->decode_to_value->value.list_value.items = NULL;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->decode_value_state.list_value_state.list_value_state = DECODE_LIST_STEP_SIZE;
/* 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;
case 0xC1:
case 0xD1:
internal_decoder_data->decode_to_value->type = AMQP_TYPE_MAP;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.map_value.pair_count = 0;
internal_decoder_data->decode_to_value->value.map_value.pairs = NULL;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->decode_value_state.map_value_state.map_value_state = DECODE_MAP_STEP_SIZE;
result = 0;
break;
case 0xE0:
case 0xF0:
internal_decoder_data->decode_to_value->type = AMQP_TYPE_ARRAY;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
internal_decoder_data->decode_to_value->value.array_value.count = 0;
internal_decoder_data->decode_to_value->value.array_value.items = NULL;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->decode_value_state.array_value_state.array_value_state = DECODE_ARRAY_STEP_SIZE;
result = 0;
break;
}
break;
}
case DECODER_STATE_TYPE_DATA:
{
switch (internal_decoder_data->constructor_byte)
{
default:
LogError("Invalid constructor byte: 0x%02x", internal_decoder_data->constructor_byte);
result = MU_FAILURE;
break;
case 0x00: /* descriptor */
{
DECODE_DESCRIBED_VALUE_STEP step = internal_decoder_data->decode_value_state.described_value_state.described_value_state;
switch (step)
{
default:
LogError("Invalid described value decode step: %d", step);
result = MU_FAILURE;
break;
case DECODE_DESCRIBED_VALUE_STEP_DESCRIPTOR:
{
size_t inner_used_bytes;
if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, buffer, size, &inner_used_bytes) != 0)
{
LogError("Decoding bytes for described value failed");
internal_decoder_data->decode_to_value->type = AMQP_TYPE_UNKNOWN;
result = MU_FAILURE;
}
else
{
INTERNAL_DECODER_DATA* inner_decoder = (INTERNAL_DECODER_DATA*)internal_decoder_data->inner_decoder;
buffer += inner_used_bytes;
size -= inner_used_bytes;
if (inner_decoder->decoder_state == DECODER_STATE_DONE)
{
AMQP_VALUE described_value;
internal_decoder_destroy(inner_decoder);
internal_decoder_data->inner_decoder = NULL;
described_value = REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA);
if (described_value == NULL)
{
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
LogError("Could not allocate memory for AMQP value");
result = MU_FAILURE;
}
else
{
described_value->type = AMQP_TYPE_UNKNOWN;
internal_decoder_data->decode_to_value->value.described_value.value = (AMQP_VALUE)described_value;
internal_decoder_data->inner_decoder = internal_decoder_create(inner_decoder_callback, internal_decoder_data, described_value, true);
if (internal_decoder_data->inner_decoder == NULL)
{
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
LogError("Could not create inner decoder");
result = MU_FAILURE;
}
else
{
internal_decoder_data->decode_value_state.described_value_state.described_value_state = DECODE_DESCRIBED_VALUE_STEP_VALUE;
result = 0;
}
}
}
else
{
result = 0;
}
}
break;
}
case DECODE_DESCRIBED_VALUE_STEP_VALUE:
{
size_t inner_used_bytes;
if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, buffer, size, &inner_used_bytes) != 0)
{
LogError("Decoding bytes for described value failed");
result = MU_FAILURE;
}
else
{
INTERNAL_DECODER_DATA* inner_decoder = (INTERNAL_DECODER_DATA*)internal_decoder_data->inner_decoder;
buffer += inner_used_bytes;
size -= inner_used_bytes;
if (inner_decoder->decoder_state == DECODER_STATE_DONE)
{
internal_decoder_destroy(inner_decoder);
internal_decoder_data->inner_decoder = NULL;
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;
}
}
break;
}
case 0x56:
{
/* 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)
{
LogError("Bad boolean value: %02X", buffer[0]);
result = MU_FAILURE;
}
else
{
internal_decoder_data->decode_to_value->value.bool_value = (buffer[0] == 0) ? false : true;
buffer++;
size--;
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_335: [<encoding code="0x50" category="fixed" width="1" label="8-bit unsigned integer"/>] */
case 0x50:
{
internal_decoder_data->decode_to_value->value.ubyte_value = buffer[0];
buffer++;
size--;
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_337: [<encoding code="0x60" category="fixed" width="2" label="16-bit unsigned integer in network byte order"/>] */
case 0x60:
{
internal_decoder_data->decode_to_value->value.ushort_value += ((uint16_t)buffer[0]) << ((1 - internal_decoder_data->bytes_decoded) * 8);
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
if (internal_decoder_data->bytes_decoded == 2)
{
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_339: [<encoding code="0x70" category="fixed" width="4" label="32-bit unsigned integer in network byte order"/>] */
case 0x70:
{
internal_decoder_data->decode_to_value->value.uint_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_340: [<encoding name="smalluint" code="0x52" category="fixed" width="1" label="unsigned integer value in the range 0 to 255 inclusive"/>] */
case 0x52:
{
internal_decoder_data->decode_to_value->value.uint_value = buffer[0];
buffer++;
size--;
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_343: [<encoding code="0x80" category="fixed" width="8" label="64-bit unsigned integer in network byte order"/>] */
case 0x80:
{
internal_decoder_data->decode_to_value->value.ulong_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_344: [<encoding name="smallulong" code="0x53" category="fixed" width="1" label="unsigned long value in the range 0 to 255 inclusive"/>] */
case 0x53:
{
internal_decoder_data->decode_to_value->value.ulong_value = buffer[0];
buffer++;
size--;
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_347: [<encoding code="0x51" category="fixed" width="1" label="8-bit two's-complement integer"/>] */
case 0x51:
{
internal_decoder_data->decode_to_value->value.byte_value = buffer[0];
buffer++;
size--;
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_349: [<encoding code="0x61" category="fixed" width="2" label="16-bit two's-complement integer in network byte order"/>] */
case 0x61:
{
internal_decoder_data->decode_to_value->value.short_value = (int16_t)((uint16_t)internal_decoder_data->decode_to_value->value.short_value + (((uint16_t)buffer[0]) << ((1 - 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 == 2)
{
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_351: [<encoding code="0x71" category="fixed" width="4" label="32-bit two's-complement integer in network byte order"/>] */
case 0x71:
{
internal_decoder_data->decode_to_value->value.int_value = (int32_t)((uint32_t)internal_decoder_data->decode_to_value->value.int_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_351: [<encoding code="0x71" category="fixed" width="4" label="32-bit two's-complement integer in network byte order"/>] */
case 0x54:
{
internal_decoder_data->decode_to_value->value.int_value = (int32_t)((int8_t)(buffer[0]));
buffer++;
size--;
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_354: [<encoding code="0x81" category="fixed" width="8" label="64-bit two's-complement integer in network byte order"/>] */
case 0x81:
{
internal_decoder_data->decode_to_value->value.long_value = (int64_t)((uint64_t)internal_decoder_data->decode_to_value->value.long_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_355: [<encoding name="smalllong" code="0x55" category="fixed" width="1" label="8-bit two's-complement integer"/>] */
case 0x55:
{
internal_decoder_data->decode_to_value->value.long_value = (int64_t)((int8_t)buffer[0]);
buffer++;
size--;
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_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)));
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 0x98:
{
size_t to_copy = 16 - internal_decoder_data->bytes_decoded;
if (to_copy > size)
{
to_copy = size;
}
(void)memcpy(&internal_decoder_data->decode_to_value->value.uuid_value[internal_decoder_data->bytes_decoded], buffer, to_copy);
internal_decoder_data->bytes_decoded += to_copy;
buffer += to_copy;
size -= to_copy;
/* 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 == 16)
{
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_373: [<encoding name="vbin8" code="0xa0" category="variable" width="1" label="up to 2^8 - 1 octets of binary data"/>] */
case 0xA0:
{
if (internal_decoder_data->bytes_decoded == 0)
{
internal_decoder_data->decode_to_value->value.binary_value.length = buffer[0];
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
if (internal_decoder_data->decode_to_value->value.binary_value.length == 0)
{
internal_decoder_data->decode_to_value->value.binary_value.bytes = NULL;
/* 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;
}
else
{
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.] */
LogError("Cannot allocate memory for decoded binary value");
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
result = MU_FAILURE;
}
else
{
result = 0;
}
}
}
else
{
size_t to_copy = internal_decoder_data->decode_to_value->value.binary_value.length - (internal_decoder_data->bytes_decoded - 1);
if (to_copy > size)
{
to_copy = size;
}
(void)memcpy((unsigned char*)(internal_decoder_data->decode_to_value->value.binary_value.bytes) + (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 == (size_t)internal_decoder_data->decode_to_value->value.binary_value.length + 1)
{
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_374: [<encoding name="vbin32" code="0xb0" category="variable" width="4" label="up to 2^32 - 1 octets of binary data"/>] */
case 0xB0:
{
if (internal_decoder_data->bytes_decoded < 4)
{
internal_decoder_data->decode_to_value->value.binary_value.length += buffer[0] << ((3 - internal_decoder_data->bytes_decoded) * 8);
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
if (internal_decoder_data->bytes_decoded == 4)
{
if (internal_decoder_data->decode_to_value->value.binary_value.length == 0)
{
internal_decoder_data->decode_to_value->value.binary_value.bytes = NULL;
/* 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;
}
else
{
size_t malloc_size = (size_t)internal_decoder_data->decode_to_value->value.binary_value.length + 1;
if (malloc_size == 0)
{
internal_decoder_data->decode_to_value->value.binary_value.bytes = NULL;
LogError("Invalid binary_value size exceeded max allocation");
}
else
{
internal_decoder_data->decode_to_value->value.binary_value.bytes = (unsigned char*)malloc(malloc_size);
}
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;
LogError("Cannot allocate memory for decoded binary value");
result = MU_FAILURE;
}
else
{
result = 0;
}
}
}
else
{
result = 0;
}
}
else
{
size_t to_copy = internal_decoder_data->decode_to_value->value.binary_value.length - (internal_decoder_data->bytes_decoded - 4);
if (to_copy > size)
{
to_copy = size;
}
(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 == (size_t)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;
}
break;
}
/* Codes_SRS_AMQPVALUE_01_376: [<encoding name="str8-utf8" code="0xa1" category="variable" width="1" label="up to 2^8 - 1 octets worth of UTF-8 Unicode (with no byte order mark)"/>] */
case 0xA1:
{
if (internal_decoder_data->bytes_decoded == 0)
{
internal_decoder_data->decode_value_state.string_value_state.length = buffer[0];
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
size_t malloc_size = (size_t)internal_decoder_data->decode_value_state.string_value_state.length + 1;
// If the result of malloc_size is zero it means it had a type overflow (size_t is an unsigned type).
// It is very unlikely but could happen.
if (malloc_size == 0)
{
internal_decoder_data->decode_to_value->value.string_value.chars = NULL;
LogError("Invalid string size exceeded max allocation");
}
else
{
internal_decoder_data->decode_to_value->value.string_value.chars = (char*)malloc(malloc_size);
}
if (internal_decoder_data->decode_to_value->value.string_value.chars == 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;
LogError("Could not allocate memory for decoded string value");
result = MU_FAILURE;
}
else
{
if (internal_decoder_data->decode_value_state.string_value_state.length == 0)
{
internal_decoder_data->decode_to_value->value.string_value.chars[0] = '\0';
/* 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;
}
}
else
{
size_t to_copy = internal_decoder_data->decode_value_state.string_value_state.length - (internal_decoder_data->bytes_decoded - 1);
if (to_copy > size)
{
to_copy = size;
}
(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 == (size_t)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;
}
break;
}
/* Codes_SRS_AMQPVALUE_01_377: [<encoding name="str32-utf8" code="0xb1" category="variable" width="4" label="up to 2^32 - 1 octets worth of UTF-8 Unicode (with no byte order mark)"/>] */
case 0xB1:
{
if (internal_decoder_data->bytes_decoded < 4)
{
internal_decoder_data->decode_value_state.string_value_state.length += buffer[0] << ((3 - internal_decoder_data->bytes_decoded) * 8);
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
if (internal_decoder_data->bytes_decoded == 4)
{
size_t malloc_size = (size_t)internal_decoder_data->decode_value_state.string_value_state.length + 1;
// If the result of malloc_size is zero it means it had a type overflow (size_t is an unsigned type).
// It is very unlikely but could happen.
if (malloc_size == 0)
{
internal_decoder_data->decode_to_value->value.string_value.chars = NULL;
LogError("Invalid string value size exceeded max allocation");
}
else
{
internal_decoder_data->decode_to_value->value.string_value.chars = (char*)malloc(malloc_size);
}
if (internal_decoder_data->decode_to_value->value.string_value.chars == 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;
LogError("Could not allocate memory for decoded string value");
result = MU_FAILURE;
}
else
{
if (internal_decoder_data->decode_value_state.string_value_state.length == 0)
{
internal_decoder_data->decode_to_value->value.string_value.chars[0] = '\0';
/* 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;
}
}
else
{
result = 0;
}
}
else
{
size_t to_copy = internal_decoder_data->decode_value_state.string_value_state.length - (internal_decoder_data->bytes_decoded - 4);
if (to_copy > size)
{
to_copy = size;
}
(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 == (size_t)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;
}
break;
}
/* Codes_SRS_AMQPVALUE_01_379: [<encoding name="sym8" code="0xa3" category="variable" width="1" label="up to 2^8 - 1 seven bit ASCII characters representing a symbolic value"/>] */
case 0xA3:
{
if (internal_decoder_data->bytes_decoded == 0)
{
internal_decoder_data->decode_value_state.symbol_value_state.length = buffer[0];
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
size_t malloc_size = (size_t)internal_decoder_data->decode_value_state.symbol_value_state.length + 1;
// If the result of malloc_size is zero it means it had a type overflow (size_t is an unsigned type).
// It is very unlikely but could happen.
if (malloc_size == 0)
{
internal_decoder_data->decode_to_value->value.symbol_value.chars = NULL;
LogError("Invalid symbol_value size exceeded max allocation");
}
else
{
internal_decoder_data->decode_to_value->value.symbol_value.chars = (char*)malloc(malloc_size);
}
if (internal_decoder_data->decode_to_value->value.symbol_value.chars == 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;
LogError("Could not allocate memory for decoded symbol value");
result = MU_FAILURE;
}
else
{
if (internal_decoder_data->decode_value_state.symbol_value_state.length == 0)
{
internal_decoder_data->decode_to_value->value.symbol_value.chars[0] = '\0';
/* 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;
}
}
else
{
size_t to_copy = internal_decoder_data->decode_value_state.symbol_value_state.length - (internal_decoder_data->bytes_decoded - 1);
if (to_copy > size)
{
to_copy = size;
}
(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 == (size_t)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;
}
break;
}
/* Codes_SRS_AMQPVALUE_01_380: [<encoding name="sym32" code="0xb3" category="variable" width="4" label="up to 2^32 - 1 seven bit ASCII characters representing a symbolic value"/>] */
case 0xB3:
{
if (internal_decoder_data->bytes_decoded < 4)
{
internal_decoder_data->decode_value_state.symbol_value_state.length += buffer[0] << ((3 - internal_decoder_data->bytes_decoded) * 8);
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
if (internal_decoder_data->bytes_decoded == 4)
{
size_t malloc_size = (size_t)internal_decoder_data->decode_value_state.symbol_value_state.length + 1;
// If the result of malloc_size is zero it means it had a type overflow (size_t is an unsigned type).
// It is very unlikely but could happen.
if (malloc_size == 0)
{
internal_decoder_data->decode_to_value->value.symbol_value.chars = NULL;
LogError("Invalid symbol value size exceeded max allocation");
}
else
{
internal_decoder_data->decode_to_value->value.symbol_value.chars = (char*)malloc(malloc_size);
}
if (internal_decoder_data->decode_to_value->value.symbol_value.chars == 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;
LogError("Could not allocate memory for decoded symbol value");
result = MU_FAILURE;
}
else
{
if (internal_decoder_data->decode_value_state.symbol_value_state.length == 0)
{
internal_decoder_data->decode_to_value->value.symbol_value.chars[0] = '\0';
/* 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;
}
}
else
{
result = 0;
}
}
else
{
size_t to_copy = internal_decoder_data->decode_value_state.symbol_value_state.length - (internal_decoder_data->bytes_decoded - 4);
if (to_copy > size)
{
to_copy = size;
}
(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 == (size_t)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;
}
break;
}
/* Codes_SRS_AMQPVALUE_01_385: [<encoding name="list8" code="0xc0" category="compound" width="1" label="up to 2^8 - 1 list elements with total size less than 2^8 octets"/>] */
case 0xC0:
/* Codes_SRS_AMQPVALUE_01_386: [<encoding name="list32" code="0xd0" category="compound" width="4" label="up to 2^32 - 1 list elements with total size less than 2^32 octets"/>] */
case 0xD0:
{
DECODE_LIST_STEP step = internal_decoder_data->decode_value_state.list_value_state.list_value_state;
switch (step)
{
default:
LogError("Invalid step in decoding list value: %d", step);
result = MU_FAILURE;
break;
case DECODE_LIST_STEP_SIZE:
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
if (internal_decoder_data->constructor_byte == 0xC0)
{
internal_decoder_data->decode_value_state.list_value_state.list_value_state = DECODE_LIST_STEP_COUNT;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->decode_to_value->value.list_value.count = 0;
result = 0;
}
else
{
if (internal_decoder_data->bytes_decoded == 4)
{
internal_decoder_data->decode_value_state.list_value_state.list_value_state = DECODE_LIST_STEP_COUNT;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->decode_to_value->value.list_value.count = 0;
}
result = 0;
}
break;
case DECODE_LIST_STEP_COUNT:
if (internal_decoder_data->constructor_byte == 0xC0)
{
internal_decoder_data->decode_to_value->value.list_value.count = buffer[0];
}
else
{
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--;
if (internal_decoder_data->decode_to_value->value.list_value.count > MAX_AMQPVALUE_ITEM_COUNT)
{
LogError("AMQP list item count exceeded MAX_AMQPVALUE_ITEM_COUNT");
result = MU_FAILURE;
size = 0;
break;
}
if (internal_decoder_data->constructor_byte == 0xC0)
{
if (internal_decoder_data->decode_to_value->value.list_value.count == 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;
}
else
{
uint32_t i;
size_t calloc_size = safe_multiply_size_t(sizeof(AMQP_VALUE), internal_decoder_data->decode_to_value->value.list_value.count);
if (calloc_size == SIZE_MAX ||
(internal_decoder_data->decode_to_value->value.list_value.items = (AMQP_VALUE*)calloc(1, calloc_size)) == NULL)
{
LogError("Could not allocate memory for decoded list value, size:%zu", calloc_size);
result = MU_FAILURE;
}
else
{
for (i = 0; i < internal_decoder_data->decode_to_value->value.list_value.count; i++)
{
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;
internal_decoder_data->decode_value_state.list_value_state.item = 0;
result = 0;
}
}
}
else
{
if (internal_decoder_data->bytes_decoded == 4)
{
if (internal_decoder_data->decode_to_value->value.list_value.count == 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;
}
else
{
uint32_t i;
size_t calloc_size = (sizeof(AMQP_VALUE) * internal_decoder_data->decode_to_value->value.list_value.count);
// bug 8819364: [FuzzAMQP] AddressSanitizer: allocator is out of memory trying to allocate 0x7fff80070 bytes
if (calloc_size < MAX_AMQPVALUE_MALLOC_SIZE_BYTES)
{
internal_decoder_data->decode_to_value->value.list_value.items = (AMQP_VALUE*)calloc(1, calloc_size);
}
else
{
LogError("Large memory allocation exceeded MAX_AMQPVALUE_MALLOC_SIZE_BYTES");
internal_decoder_data->decode_to_value->value.list_value.items = NULL;
}
if (internal_decoder_data->decode_to_value->value.list_value.items == NULL)
{
LogError("Could not allocate memory for decoded list value");
result = MU_FAILURE;
}
else
{
for (i = 0; i < internal_decoder_data->decode_to_value->value.list_value.count; i++)
{
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;
internal_decoder_data->decode_value_state.list_value_state.item = 0;
result = 0;
}
}
}
else
{
result = 0;
}
}
break;
case DECODE_LIST_STEP_ITEMS:
{
size_t inner_used_bytes;
if (internal_decoder_data->bytes_decoded == 0)
{
AMQP_VALUE_DATA* list_item = (AMQP_VALUE_DATA*)REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA);
if (list_item == NULL)
{
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
result = MU_FAILURE;
break;
}
else
{
list_item->type = AMQP_TYPE_UNKNOWN;
internal_decoder_data->decode_to_value->value.list_value.items[internal_decoder_data->decode_value_state.list_value_state.item] = list_item;
internal_decoder_data->inner_decoder = internal_decoder_create(inner_decoder_callback, internal_decoder_data, list_item, true);
if (internal_decoder_data->inner_decoder == NULL)
{
LogError("Could not create inner decoder for list items");
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
}
}
}
if (internal_decoder_data->inner_decoder == NULL)
{
LogError("NULL inner decoder. This should not happen under normal circumstances");
result = MU_FAILURE;
}
else if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, buffer, size, &inner_used_bytes) != 0)
{
LogError("Decoding list items failed");
result = MU_FAILURE;
}
else
{
INTERNAL_DECODER_DATA* inner_decoder = (INTERNAL_DECODER_DATA*)internal_decoder_data->inner_decoder;
internal_decoder_data->bytes_decoded += inner_used_bytes;
buffer += inner_used_bytes;
size -= inner_used_bytes;
if (inner_decoder->decoder_state == DECODER_STATE_DONE)
{
internal_decoder_destroy(inner_decoder);
internal_decoder_data->inner_decoder = NULL;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->decode_value_state.list_value_state.item++;
if (internal_decoder_data->decode_value_state.list_value_state.item == internal_decoder_data->decode_to_value->value.list_value.count)
{
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;
}
}
break;
}
case 0xC1:
case 0xD1:
{
DECODE_MAP_STEP step = internal_decoder_data->decode_value_state.map_value_state.map_value_state;
switch (step)
{
default:
LogError("Invalid step in decoding map value: %d", step);
result = MU_FAILURE;
break;
case DECODE_MAP_STEP_SIZE:
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
if (internal_decoder_data->constructor_byte == 0xC1)
{
internal_decoder_data->decode_value_state.map_value_state.map_value_state = DECODE_MAP_STEP_COUNT;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->decode_to_value->value.map_value.pair_count = 0;
result = 0;
}
else
{
if (internal_decoder_data->bytes_decoded == 4)
{
internal_decoder_data->decode_value_state.map_value_state.map_value_state = DECODE_MAP_STEP_COUNT;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->decode_to_value->value.map_value.pair_count = 0;
}
result = 0;
}
break;
case DECODE_MAP_STEP_COUNT:
if (internal_decoder_data->constructor_byte == 0xC1)
{
internal_decoder_data->decode_to_value->value.map_value.pair_count = buffer[0];
}
else
{
internal_decoder_data->decode_to_value->value.map_value.pair_count += buffer[0] << ((3 - internal_decoder_data->bytes_decoded) * 8);
}
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
if (internal_decoder_data->constructor_byte == 0xC1)
{
if (internal_decoder_data->decode_to_value->value.map_value.pair_count == 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;
}
else
{
uint32_t i;
internal_decoder_data->decode_to_value->value.map_value.pair_count /= 2;
size_t malloc_size = safe_multiply_size_t(sizeof(AMQP_MAP_KEY_VALUE_PAIR), (size_t)internal_decoder_data->decode_to_value->value.map_value.pair_count);
malloc_size = safe_multiply_size_t(malloc_size, 2);
if (malloc_size == SIZE_MAX)
{
LogError("Invalid map_value size exceeded max allocation");
internal_decoder_data->decode_to_value->value.map_value.pairs = NULL;
}
else
{
internal_decoder_data->decode_to_value->value.map_value.pairs = (AMQP_MAP_KEY_VALUE_PAIR*)malloc(malloc_size);
}
if (internal_decoder_data->decode_to_value->value.map_value.pairs == NULL)
{
LogError("Could not allocate memory for map value items");
result = MU_FAILURE;
}
else
{
for (i = 0; i < internal_decoder_data->decode_to_value->value.map_value.pair_count; i++)
{
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;
internal_decoder_data->decode_value_state.map_value_state.item = 0;
result = 0;
}
}
}
else
{
if (internal_decoder_data->bytes_decoded == 4)
{
if (internal_decoder_data->decode_to_value->value.map_value.pair_count == 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;
}
else
{
uint32_t i;
internal_decoder_data->decode_to_value->value.map_value.pair_count /= 2;
size_t malloc_size = safe_multiply_size_t((size_t)internal_decoder_data->decode_to_value->value.map_value.pair_count, 2);
malloc_size = safe_multiply_size_t(sizeof(AMQP_MAP_KEY_VALUE_PAIR), malloc_size);
if (internal_decoder_data->decode_to_value->value.map_value.pair_count > MAX_AMQPVALUE_ITEM_COUNT)
{
LogError("AMQP list map count exceeded MAX_AMQPVALUE_ITEM_COUNT");
result = MU_FAILURE;
}
else if (malloc_size == SIZE_MAX)
{
LogError("Invalid map_value size exceeded max allocation");
result = MU_FAILURE;
}
else if ((internal_decoder_data->decode_to_value->value.map_value.pairs =
(AMQP_MAP_KEY_VALUE_PAIR*)malloc(malloc_size))
== NULL)
{
LogError("Could not allocate memory for map value items");
result = MU_FAILURE;
}
else
{
for (i = 0; i < internal_decoder_data->decode_to_value->value.map_value.pair_count; i++)
{
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;
internal_decoder_data->decode_value_state.map_value_state.item = 0;
result = 0;
}
}
}
else
{
result = 0;
}
}
break;
case DECODE_MAP_STEP_PAIRS:
{
size_t inner_used_bytes;
if (internal_decoder_data->bytes_decoded == 0)
{
if (internal_decoder_data->decode_value_state.map_value_state.item >= internal_decoder_data->decode_to_value->value.map_value.pair_count)
{
LogError("Map item index is out of range");
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
result = MU_FAILURE;
break;
}
AMQP_VALUE_DATA* map_item = (AMQP_VALUE_DATA*)REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA);
if (map_item == NULL)
{
LogError("Could not allocate memory for map item");
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
result = MU_FAILURE;
break;
}
else
{
map_item->type = AMQP_TYPE_UNKNOWN;
if (internal_decoder_data->decode_to_value->value.map_value.pairs[internal_decoder_data->decode_value_state.map_value_state.item].key == NULL)
{
internal_decoder_data->decode_to_value->value.map_value.pairs[internal_decoder_data->decode_value_state.map_value_state.item].key = map_item;
}
else
{
internal_decoder_data->decode_to_value->value.map_value.pairs[internal_decoder_data->decode_value_state.map_value_state.item].value = map_item;
}
internal_decoder_data->inner_decoder = internal_decoder_create(inner_decoder_callback, internal_decoder_data, map_item, true);
if (internal_decoder_data->inner_decoder == NULL)
{
LogError("Could not create inner decoder for map item");
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
}
else
{
result = 0;
}
}
}
if (internal_decoder_data->inner_decoder == NULL)
{
LogError("NULL inner decoder. This should not happen under normal circumstances");
result = MU_FAILURE;
}
else if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, buffer, size, &inner_used_bytes) != 0)
{
LogError("Could not decode map item");
result = MU_FAILURE;
}
else
{
INTERNAL_DECODER_DATA* inner_decoder = (INTERNAL_DECODER_DATA*)internal_decoder_data->inner_decoder;
internal_decoder_data->bytes_decoded += inner_used_bytes;
buffer += inner_used_bytes;
size -= inner_used_bytes;
if (inner_decoder->decoder_state == DECODER_STATE_DONE)
{
internal_decoder_destroy(inner_decoder);
internal_decoder_data->inner_decoder = NULL;
internal_decoder_data->bytes_decoded = 0;
if (internal_decoder_data->decode_to_value->value.map_value.pairs[internal_decoder_data->decode_value_state.map_value_state.item].value != NULL)
{
internal_decoder_data->decode_value_state.map_value_state.item++;
if (internal_decoder_data->decode_value_state.map_value_state.item == internal_decoder_data->decode_to_value->value.map_value.pair_count)
{
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;
}
}
break;
}
case 0xE0:
case 0xF0:
{
DECODE_ARRAY_STEP step = internal_decoder_data->decode_value_state.array_value_state.array_value_state;
switch (step)
{
default:
LogError("Invalid step in decoding array value: %d", step);
result = MU_FAILURE;
break;
case DECODE_ARRAY_STEP_SIZE:
internal_decoder_data->bytes_decoded++;
buffer++;
size--;
if (internal_decoder_data->constructor_byte == 0xE0)
{
internal_decoder_data->decode_value_state.array_value_state.array_value_state = DECODE_ARRAY_STEP_COUNT;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->decode_to_value->value.array_value.count = 0;
result = 0;
}
else
{
if (internal_decoder_data->bytes_decoded == 4)
{
internal_decoder_data->decode_value_state.array_value_state.array_value_state = DECODE_ARRAY_STEP_COUNT;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->decode_to_value->value.array_value.count = 0;
}
result = 0;
}
break;
case DECODE_ARRAY_STEP_COUNT:
if (internal_decoder_data->constructor_byte == 0xE0)
{
internal_decoder_data->decode_to_value->value.array_value.count = buffer[0];
}
else
{
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--;
if (internal_decoder_data->decode_to_value->value.array_value.count > MAX_AMQPVALUE_ITEM_COUNT)
{
LogError("AMQP array item count exceeded MAX_AMQPVALUE_ITEM_COUNT");
result = MU_FAILURE;
size = 0;
break;
}
if (internal_decoder_data->constructor_byte == 0xE0)
{
if (internal_decoder_data->decode_to_value->value.array_value.count == 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;
}
else
{
uint32_t i;
size_t calloc_size = safe_multiply_size_t(sizeof(AMQP_VALUE), internal_decoder_data->decode_to_value->value.array_value.count);
if (calloc_size == SIZE_MAX ||
(internal_decoder_data->decode_to_value->value.array_value.items = (AMQP_VALUE*)calloc(1, calloc_size)) == NULL)
{
LogError("Could not allocate memory for array items, size:%zu", calloc_size);
result = MU_FAILURE;
}
else
{
for (i = 0; i < internal_decoder_data->decode_to_value->value.array_value.count; i++)
{
internal_decoder_data->decode_to_value->value.array_value.items[i] = NULL;
}
internal_decoder_data->decode_value_state.array_value_state.array_value_state = DECODE_ARRAY_STEP_ITEMS;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->inner_decoder = NULL;
internal_decoder_data->decode_value_state.array_value_state.item = 0;
result = 0;
}
}
}
else
{
if (internal_decoder_data->bytes_decoded == 4)
{
if (internal_decoder_data->decode_to_value->value.array_value.count == 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;
}
else
{
uint32_t i;
size_t calloc_size = safe_multiply_size_t(sizeof(AMQP_VALUE), internal_decoder_data->decode_to_value->value.array_value.count);
if (calloc_size == SIZE_MAX ||
(internal_decoder_data->decode_to_value->value.array_value.items = (AMQP_VALUE*)calloc(1, calloc_size)) == NULL)
{
LogError("Could not allocate memory for array items, size:%zu", calloc_size);
result = MU_FAILURE;
}
else
{
for (i = 0; i < internal_decoder_data->decode_to_value->value.array_value.count; i++)
{
internal_decoder_data->decode_to_value->value.array_value.items[i] = NULL;
}
internal_decoder_data->decode_value_state.array_value_state.array_value_state = DECODE_ARRAY_STEP_ITEMS;
internal_decoder_data->bytes_decoded = 0;
internal_decoder_data->inner_decoder = NULL;
internal_decoder_data->decode_value_state.array_value_state.item = 0;
result = 0;
}
}
}
else
{
result = 0;
}
}
break;
case DECODE_ARRAY_STEP_ITEMS:
{
size_t inner_used_bytes;
if (internal_decoder_data->bytes_decoded == 0)
{
AMQP_VALUE_DATA* array_item;
internal_decoder_data->decode_value_state.array_value_state.constructor_byte = buffer[0];
array_item = (AMQP_VALUE_DATA*)REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA);
if (array_item == NULL)
{
LogError("Could not allocate memory for array item to be decoded");
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
result = MU_FAILURE;
break;
}
else
{
array_item->type = AMQP_TYPE_UNKNOWN;
internal_decoder_data->decode_to_value->value.array_value.items[internal_decoder_data->decode_value_state.array_value_state.item] = array_item;
internal_decoder_data->inner_decoder = internal_decoder_create(inner_decoder_callback, internal_decoder_data, array_item, true);
if (internal_decoder_data->inner_decoder == NULL)
{
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
LogError("Could not create inner decoder for array items");
}
}
}
if (internal_decoder_data->inner_decoder == NULL)
{
LogError("NULL inner decoder. This should not happen under normal circumstances");
result = MU_FAILURE;
}
else if (internal_decoder_decode_bytes(internal_decoder_data->inner_decoder, buffer, size, &inner_used_bytes) != 0)
{
LogError("Could not decode array item");
result = MU_FAILURE;
}
else
{
INTERNAL_DECODER_DATA* inner_decoder = (INTERNAL_DECODER_DATA*)internal_decoder_data->inner_decoder;
internal_decoder_data->bytes_decoded += inner_used_bytes;
size -= inner_used_bytes;
if (inner_decoder->decoder_state == DECODER_STATE_DONE)
{
internal_decoder_destroy(inner_decoder);
internal_decoder_data->inner_decoder = NULL;
internal_decoder_data->decode_value_state.array_value_state.item++;
if (internal_decoder_data->decode_value_state.array_value_state.item == internal_decoder_data->decode_to_value->value.array_value.count)
{
buffer += inner_used_bytes;
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;
}
else
{
AMQP_VALUE_DATA* array_item;
if ((internal_decoder_data->decode_value_state.array_value_state.constructor_byte == 0x40) ||
(internal_decoder_data->decode_value_state.array_value_state.constructor_byte == 0x41) ||
(internal_decoder_data->decode_value_state.array_value_state.constructor_byte == 0x42) ||
(internal_decoder_data->decode_value_state.array_value_state.constructor_byte == 0x43) ||
(internal_decoder_data->decode_value_state.array_value_state.constructor_byte == 0x44) ||
(internal_decoder_data->decode_value_state.array_value_state.constructor_byte == 0x45))
{
/* Array items are constructor-only, e.g. NULL Don't increment buffer to account for implied data. */
size += inner_used_bytes;
internal_decoder_data->decoder_state = DECODER_STATE_TYPE_DATA;
}
else
{
buffer += inner_used_bytes;
}
array_item = (AMQP_VALUE_DATA*)REFCOUNT_TYPE_CREATE(AMQP_VALUE_DATA);
if (array_item == NULL)
{
LogError("Could not allocate memory for array item");
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
result = MU_FAILURE;
}
else
{
array_item->type = AMQP_TYPE_UNKNOWN;
internal_decoder_data->decode_to_value->value.array_value.items[internal_decoder_data->decode_value_state.array_value_state.item] = array_item;
internal_decoder_data->inner_decoder = internal_decoder_create(inner_decoder_callback, internal_decoder_data, array_item, true);
if (internal_decoder_data->inner_decoder == NULL)
{
LogError("Could not create inner decoder for array item");
internal_decoder_data->decoder_state = DECODER_STATE_ERROR;
result = MU_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)
{
LogError("Could not decode array item data");
result = MU_FAILURE;
}
else
{
result = 0;
}
}
}
}
}
else
{
buffer += inner_used_bytes;
result = 0;
}
}
break;
}
}
break;
}
}
break;
}
}
if (result != 0)
{
break;
}
}
}
if (used_bytes != NULL)
{
*used_bytes = initial_size - size;
}
return result;
}