static int internal_decoder_decode_bytes()

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;
}