int64_t qd_parse_as_long()

in src/parse.c [459:566]


int64_t qd_parse_as_long(qd_parsed_field_t *parsed_field)
{
    int64_t result = 0;

    qd_buffer_field_t field = parsed_field->amqp.value;

    switch (parsed_field->amqp.tag) {
    case QD_AMQP_LONG: {
        uint64_t convert;
        uint32_t tmp32 = 0;
        qd_buffer_field_uint32(&field, &tmp32);
        convert = ((uint64_t) tmp32) << 32;
        qd_buffer_field_uint32(&field, &tmp32);
        convert |= (uint64_t) tmp32;
        result = (int64_t) convert;
        break;
    }

    case QD_AMQP_INT: {
        uint32_t tmp = 0;
        qd_buffer_field_uint32(&field, &tmp);
        result = (int32_t) tmp;
        break;
    }

    case QD_AMQP_SHORT: {
        uint16_t convert;
        uint8_t octet = 0;
        qd_buffer_field_octet(&field, &octet);
        convert = ((uint16_t) octet) << 8;
        qd_buffer_field_octet(&field, &octet);
        convert |= ((uint16_t) octet);
        result = (int16_t) convert;
        break;
    }

    case QD_AMQP_BYTE:
    case QD_AMQP_BOOLEAN:
    case QD_AMQP_SMALLLONG:
    case QD_AMQP_SMALLINT: {
        uint8_t octet = 0;
        qd_buffer_field_octet(&field, &octet);
        result = (int8_t) octet;
        break;
    }

    case QD_AMQP_TRUE:
        result = 1;
        break;

    case QD_AMQP_FALSE:
    case QD_AMQP_UINT0:
    case QD_AMQP_ULONG0:
        // already zeroed
        break;

    case QD_AMQP_STR8_UTF8:
    case QD_AMQP_STR32_UTF8:
    case QD_AMQP_SYM8:
    case QD_AMQP_SYM32:
        {
            // conversion from string to 64 bit integer:
            char *value = qd_buffer_field_strdup(&field);
            if (sscanf(value, "%"SCNi64, &result) != 1)
                parsed_field->parse_error = "Cannot convert string to long";
            free(value);
        }
        break;

    case QD_AMQP_UBYTE:
    case QD_AMQP_SMALLUINT:
    case QD_AMQP_SMALLULONG:
    case QD_AMQP_USHORT:
    case QD_AMQP_UINT:
    case QD_AMQP_ULONG:
    {
        // if an unsigned integer "fits" accept it
        uint64_t utmp = qd_parse_as_ulong(parsed_field);
        if (qd_parse_ok(parsed_field)) {
            uint64_t max = INT8_MAX;
            switch (parsed_field->amqp.tag) {
            case QD_AMQP_USHORT:
                max = INT16_MAX;
                break;
            case QD_AMQP_UINT:
                max = INT32_MAX;
                break;
            case QD_AMQP_ULONG:
                max = INT64_MAX;
                break;
            }
            if (utmp <= max) {
                result = (int64_t)utmp;
            } else {
                parsed_field->parse_error = "Unable to parse unsigned integer as a signed integer";
            }
        }
    }
    break;

    default:
        parsed_field->parse_error = "Unable to parse as a signed integer";
        // catch any missing types during development
        assert(false);
    }

    return result;
}