Types of items

Every cbor_item_t has a cbor_type associated with it - these constants correspond to the types specified by the CBOR standard:

enum cbor_type

Specifies the Major type of cbor_item_t.

Values:

enumerator CBOR_TYPE_UINT

0 - positive integers

enumerator CBOR_TYPE_NEGINT

1 - negative integers

enumerator CBOR_TYPE_BYTESTRING

2 - byte strings

enumerator CBOR_TYPE_STRING

3 - strings

enumerator CBOR_TYPE_ARRAY

4 - arrays

enumerator CBOR_TYPE_MAP

5 - maps

enumerator CBOR_TYPE_TAG

6 - tags

enumerator CBOR_TYPE_FLOAT_CTRL

7 - decimals and special values (true, false, nil, …)

To find out the type of an item, one can use

cbor_type cbor_typeof(const cbor_item_t *item)

Get the type of the item.

param item:

return:

The type

Please note the distinction between functions like cbor_isa_uint() and cbor_is_int(). The following functions work solely with the major type value.

Binary queries

Alternatively, there are functions to query each particular type.

Warning

Passing an invalid cbor_item_t reference to any of these functions results in undefined behavior.

bool cbor_isa_uint(const cbor_item_t *item)

Does the item have the appropriate major type?

param item:

the item

return:

Is the item an CBOR_TYPE_UINT?

bool cbor_isa_negint(const cbor_item_t *item)

Does the item have the appropriate major type?

param item:

the item

return:

Is the item a CBOR_TYPE_NEGINT?

bool cbor_isa_bytestring(const cbor_item_t *item)

Does the item have the appropriate major type?

param item:

the item

return:

Is the item a CBOR_TYPE_BYTESTRING?

bool cbor_isa_string(const cbor_item_t *item)

Does the item have the appropriate major type?

param item:

the item

return:

Is the item a CBOR_TYPE_STRING?

bool cbor_isa_array(const cbor_item_t *item)

Does the item have the appropriate major type?

param item:

the item

return:

Is the item an CBOR_TYPE_ARRAY?

bool cbor_isa_map(const cbor_item_t *item)

Does the item have the appropriate major type?

param item:

the item

return:

Is the item a CBOR_TYPE_MAP?

bool cbor_isa_tag(const cbor_item_t *item)

Does the item have the appropriate major type?

param item:

the item

return:

Is the item a CBOR_TYPE_TAG?

bool cbor_isa_float_ctrl(const cbor_item_t *item)

Does the item have the appropriate major type?

param item:

the item

return:

Is the item a CBOR_TYPE_FLOAT_CTRL?

Logical queries

These functions provide information about the item type from a more high-level perspective

bool cbor_is_int(const cbor_item_t *item)

Is the item an integer, either positive or negative?

param item:

the item

return:

Is the item an integer, either positive or negative?

bool cbor_is_float(const cbor_item_t *item)

Is the item an a floating point number?

param item:

the item

return:

Is the item a floating point number?

bool cbor_is_bool(const cbor_item_t *item)

Is the item an a boolean?

param item:

the item

return:

Is the item a boolean?

bool cbor_is_null(const cbor_item_t *item)

Does this item represent null

Warning

This is in no way related to the value of the pointer. Passing a null pointer will most likely result in a crash.

param item:

the item

return:

Is the item (CBOR logical) null?

bool cbor_is_undef(const cbor_item_t *item)

Does this item represent undefined

Warning

Care must be taken to distinguish nulls and undefined values in C.

param item:

the item

return:

Is the item (CBOR logical) undefined?

Comparing items

bool cbor_structurally_equal(const cbor_item_t *item1, const cbor_item_t *item2)

Compares two items for structural (encoding-level) equality.

Two items are structurally equal when they would produce identical bytes if serialized by a correct CBOR encoder that preserves the in-memory representation. Every aspect of the encoding counts:

  • Major type: CBOR_TYPE_UINT and CBOR_TYPE_NEGINT are distinct even if the argument bytes happen to be the same.

  • Integer encoding width: cbor_build_uint8(1) and cbor_build_uint16(1) are not structurally equal, even though both represent the integer 1. Use the integer value accessors (cbor_get_uint64 etc.) if you need value-level comparison.

  • Definite vs. indefinite length: a definite-length array and an indefinite-length array with the same elements are not structurally equal.

  • Chunk boundaries: two indefinite bytestrings or strings that carry the same bytes but split them across a different number of chunks are not structurally equal.

  • Map entry order: maps are compared positionally — entry at index i in item1 must match entry at index i in item2. Maps that carry the same key-value pairs in a different order are not structurally equal. (CBOR maps are unordered in the data model; for data-model equality see RFC 8949 §5.6.1.)

  • Float encoding width: cbor_build_float2(1.5) and cbor_build_float4(1.5) are not structurally equal.

  • NaN payload: floating-point NaN values with different bit patterns are not structurally equal.

  • Tag number: tags with different tag numbers are not structurally equal.

Runs in time linear in the encoded byte size of the items and performs no additional memory allocations.

Neither item1 nor item2 may be NULL. Passing NULL is a programming error and will trigger an assertion failure in debug builds.

Note

This function implements structural equality, not the data-model equality defined by RFC 8949. In the CBOR data model, encoding width is invisible and maps are unordered sets of key-value pairs. If you need data-model equality (e.g., uint8(1) == uint64(1)), you must implement it on top of this library.

param item1:

First item; must not be NULL

param item2:

Second item; must not be NULL

return:

true if item1 and item2 are structurally equal

Note

cbor_structurally_equal implements structural equality: every aspect of the encoding is significant, including integer width, float width, definite-vs-indefinite length, chunk boundaries, and map entry order. This is intentionally stricter than the data-model equality defined by RFC 8949.

Key differences from data-model equality:

  • cbor_build_uint8(1) and cbor_build_uint16(1) are not structurally equal, even though both represent the integer 1.

  • Two maps with the same key-value pairs but in a different encoded order are not structurally equal. (RFC 8949 §5.6.1 defines maps as unordered sets of key-value pairs at the data-model level.)

  • Two indefinite-length byte strings that carry the same bytes split across different chunk boundaries are not structurally equal.

  • Floating-point NaN values with different bit patterns are not structurally equal.

If you need data-model equality (e.g. uint8(1) == uint64(1)), you must implement it on top of this library using the value accessors (cbor_get_uint64, etc.).

Complexity: because structural equality short-circuits on the first mismatch and otherwise visits each byte of data exactly once, the runtime is O(n) in the encoded byte size of the items being compared. No additional memory is allocated.