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, …)
-
enumerator CBOR_TYPE_UINT
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
nullWarning
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
undefinedWarning
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_UINTandCBOR_TYPE_NEGINTare distinct even if the argument bytes happen to be the same.Integer encoding width:
cbor_build_uint8(1)andcbor_build_uint16(1)are not structurally equal, even though both represent the integer 1. Use the integer value accessors (cbor_get_uint64etc.) 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
item1must match entry at index i initem2. 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)andcbor_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
item1noritem2may beNULL. PassingNULLis 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:
trueifitem1anditem2are 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)andcbor_build_uint16(1)are not structurally equal, even though both represent the integer1.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.