Parser: Save the fact that we found a 64-bit number

We don't need to skimp on bits in the CborValue::flags, so save the fact
that the preparser found a 64-bit number in there. This saves us from
having to re-read the descriptor byte again in
_cbor_value_decode_int64_internal().

Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Thiago Macieira
2021-09-03 13:08:25 -07:00
parent b8ea2eb29a
commit 14299a2be1
3 changed files with 40 additions and 15 deletions
+5 -4
View File
@@ -269,10 +269,11 @@ CBOR_INLINE_API size_t cbor_encoder_get_extra_bytes_needed(const CborEncoder *en
enum CborParserIteratorFlags
{
CborIteratorFlag_IntegerValueTooLarge = 0x01,
CborIteratorFlag_NegativeInteger = 0x02,
CborIteratorFlag_IteratingStringChunks = 0x02,
CborIteratorFlag_UnknownLength = 0x04,
CborIteratorFlag_IntegerValueIs64Bit = 0x01,
CborIteratorFlag_IntegerValueTooLarge = 0x02,
CborIteratorFlag_NegativeInteger = 0x04,
CborIteratorFlag_IteratingStringChunks = 0x08,
CborIteratorFlag_UnknownLength = 0x10,
CborIteratorFlag_ContainerIsMap = 0x20,
CborIteratorFlag_NextIsMapKey = 0x40
};
+28
View File
@@ -185,4 +185,32 @@ static inline void *read_bytes(const CborValue *it, void *dst, size_t offset, si
return NULL;
}
static inline uint16_t read_uint8(const CborValue *it, size_t offset)
{
uint8_t result;
read_bytes_unchecked(it, &result, offset, sizeof(result));
return result;
}
static inline uint16_t read_uint16(const CborValue *it, size_t offset)
{
uint16_t result;
read_bytes_unchecked(it, &result, offset, sizeof(result));
return cbor_ntohs(result);
}
static inline uint32_t read_uint32(const CborValue *it, size_t offset)
{
uint32_t result;
read_bytes_unchecked(it, &result, offset, sizeof(result));
return cbor_ntohl(result);
}
static inline uint64_t read_uint64(const CborValue *it, size_t offset)
{
uint64_t result;
read_bytes_unchecked(it, &result, offset, sizeof(result));
return cbor_ntohll(result);
}
#endif /* CBORINTERNAL_P_H */
+7 -11
View File
@@ -256,7 +256,10 @@ static CborError preparse_value(CborValue *it)
if (bytesNeeded == 2)
it->extra = cbor_ntohs(it->extra);
} else {
it->flags |= CborIteratorFlag_IntegerValueTooLarge; /* Value32Bit or Value64Bit */
cbor_static_assert(CborIteratorFlag_IntegerValueTooLarge == (Value32Bit & 3));
cbor_static_assert((CborIteratorFlag_IntegerValueIs64Bit |
CborIteratorFlag_IntegerValueTooLarge) == (Value64Bit & 3));
it->flags |= (descriptor & 3);
}
}
@@ -370,17 +373,10 @@ uint64_t _cbor_value_decode_int64_internal(const CborValue *value)
{
cbor_assert(value->flags & CborIteratorFlag_IntegerValueTooLarge ||
value->type == CborFloatType || value->type == CborDoubleType);
if (value->flags & CborIteratorFlag_IntegerValueIs64Bit)
return read_uint64(value, 1);
/* since the additional information can only be Value32Bit or Value64Bit,
* we just need to test for the one bit those two options differ */
uint8_t byte;
read_bytes_unchecked(value, &byte, 0, 1);
cbor_assert((byte & SmallValueMask) == Value32Bit || (byte & SmallValueMask) == Value64Bit);
if ((byte & 1) == (Value32Bit & 1))
return get32(value->ptr + 1);
cbor_assert((byte & SmallValueMask) == Value64Bit);
return get64(value->ptr + 1);
return read_uint32(value, 1);
}
/**