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