Mistake on this page?
Report an issue in GitHub or email us
Data Structures | Macros | Typedefs | Enumerations | Functions
qcbor.h File Reference

Q C B O R E n c o d e / D e c o d e. More...

#include <stdint.h>
#include <stdbool.h>
#include "UsefulBuf.h"

Go to the source code of this file.

Data Structures

struct  __QCBORTrackNesting
 
struct  _QCBOREncodeContext
 
struct  __QCBORDecodeNesting
 
struct  _QCBORDecodeContext
 
struct  _QCBORItem
 QCBORItem holds the type, value and other info for a decoded item returned by GetNextItem(). More...
 
struct  QCBORStringAllocator
 This is a set of functions and pointer context (in object-oriented parlance, an "object") used to allocate memory for coalescing the segments of an indefinite length string into one. More...
 
struct  QCBORTagListIn
 This is used to tell the decoder about tags that it should record in uTagBits in QCBORItem beyond the built-in tags. More...
 
struct  QCBORTagListOut
 This is for QCBORDecode_GetNextWithTags() to be able to return the full list of tags on an item. More...
 

Macros

#define CBOR_TAG_DATE_STRING   0
 See QCBOREncode_AddDateString() below. More...
 
#define CBOR_TAG_DATE_EPOCH   1
 See QCBOREncode_AddDateEpoch_2() More...
 
#define CBOR_TAG_URI   32
 The data in the string is a URIs, as defined in RFC3986. More...
 
#define CBOR_TAG_B64URL   33
 The data in the string is a base 64'd URL. More...
 
#define CBOR_TAG_B64   34
 The data in the string is base 64'd. More...
 
#define CBOR_TAG_REGEX   35
 regular expressions in Perl Compatible Regular Expressions (PCRE) / JavaScript syntax ECMA262. More...
 
#define CBOR_TAG_MIME   36
 MIME messages (including all headers), as defined in RFC2045. More...
 
#define CBOR_TAG_BIN_UUID   37
 Binary UUID. More...
 
#define CBOR_TAG_CBOR_MAGIC   55799
 The data is CBOR data. More...
 
#define QCBOR_MAX_ITEMS_IN_ARRAY   (UINT16_MAX-1)
 The maximum number of items in a single array or map when encoding of decoding. More...
 
#define QCBOR_MAX_ARRAY_NESTING   QCBOR_MAX_ARRAY_NESTING1
 The maximum nesting of arrays and maps when encoding or decoding. More...
 
#define QCBOR_MAX_CUSTOM_TAGS   16
 The maximum number of tags that can be in QCBORTagListIn and passed to QCBORDecode_SetCallerConfiguredTagList() More...
 
#define QCBOR_TYPE_NONE   0
 The type is unknown, unset or invalid. More...
 
#define QCBOR_TYPE_INT64   2
 Type for an integer that decoded either between INT64_MIN and INT32_MIN or INT32_MAX and INT64_MAX; val.int64. More...
 
#define QCBOR_TYPE_UINT64   3
 Type for an integer that decoded to a more than INT64_MAX and UINT64_MAX; val.uint64. More...
 
#define QCBOR_TYPE_ARRAY   4
 Type for an array. More...
 
#define QCBOR_TYPE_MAP   5
 Type for a map; number of items in map is in val.uCount. More...
 
#define QCBOR_TYPE_BYTE_STRING   6
 Type for a buffer full of bytes. More...
 
#define QCBOR_TYPE_TEXT_STRING   7
 Type for a UTF-8 string. More...
 
#define QCBOR_TYPE_POSBIGNUM   9
 Type for a positive big number. More...
 
#define QCBOR_TYPE_NEGBIGNUM   10
 Type for a negative big number. More...
 
#define QCBOR_TYPE_DATE_STRING   11
 Type for RFC 3339 date string, possibly with time zone. More...
 
#define QCBOR_TYPE_DATE_EPOCH   12
 Type for integer seconds since Jan 1970 + floating point fraction. More...
 
#define QCBOR_TYPE_UKNOWN_SIMPLE   13
 A simple type that this CBOR implementation doesn't know about; Type is in val.uSimple. More...
 
#define QCBOR_TYPE_FALSE   20
 Type for the simple value false; nothing more; nothing in val union. More...
 
#define QCBOR_TYPE_TRUE   21
 Type for the simple value true; nothing more; nothing in val union. More...
 
#define QCBOR_TYPE_NULL   22
 Type for the simple value null; nothing more; nothing in val union. More...
 
#define QCBOR_TYPE_UNDEF   23
 Type for the simple value undef; nothing more; nothing in val union. More...
 
#define QCBOR_TYPE_FLOAT   26
 Type for a floating point number. More...
 
#define QCBOR_TYPE_DOUBLE   27
 Type for a double floating point number. More...
 
#define QCBOR_TYPE_MAP_AS_ARRAY   32
 For QCBOR_DECODE_MODE_MAP_AS_ARRAY decode mode, a map that is being traversed as an array. More...
 
#define QCBOR_DECODE_MIN_MEM_POOL_SIZE   72
 This only matters if you use a string allocator and and set it up with QCBORDecode_SetMemPool(). More...
 

Typedefs

typedef struct _QCBORItem QCBORItem
 QCBORItem holds the type, value and other info for a decoded item returned by GetNextItem(). More...
 
typedef struct _QCBOREncodeContext QCBOREncodeContext
 QCBOREncodeContext is the data type that holds context for all the encoding functions. More...
 
typedef struct _QCBORDecodeContext QCBORDecodeContext
 QCBORDecodeContext is the data type that holds context decoding the data items for some received CBOR. More...
 

Enumerations

Functions

void QCBOREncode_Init (QCBOREncodeContext *pCtx, UsefulBuf Storage)
 Initialize the the encoder to prepare to encode some CBOR. More...
 
void QCBOREncode_AddInt64 (QCBOREncodeContext *pCtx, int64_t nNum)
 Add a signed 64-bit integer to the encoded output. More...
 
void QCBOREncode_AddUInt64 (QCBOREncodeContext *pCtx, uint64_t uNum)
 Add an unsigned 64-bit integer to the encoded output. More...
 
static void QCBOREncode_AddText (QCBOREncodeContext *pCtx, UsefulBufC Text)
 Add a UTF-8 text string to the encoded output. More...
 
static void QCBOREncode_AddSZString (QCBOREncodeContext *pCtx, const char *szString)
 Add a UTF-8 text string to the encoded output. More...
 
void QCBOREncode_AddDouble (QCBOREncodeContext *pCtx, double dNum)
 Add a floating-point number to the encoded output. More...
 
void QCBOREncode_AddTag (QCBOREncodeContext *pCtx, uint64_t uTag)
 [in] Add an optional tag More...
 
static void QCBOREncode_AddDateEpoch (QCBOREncodeContext *pCtx, int64_t date)
 Add an epoch-based date. More...
 
static void QCBOREncode_AddBytes (QCBOREncodeContext *pCtx, UsefulBufC Bytes)
 Add a byte string to the encoded output. More...
 
static void QCBOREncode_AddBinaryUUID (QCBOREncodeContext *pCtx, UsefulBufC Bytes)
 Add a binary UUID to the encoded output. More...
 
static void QCBOREncode_AddPositiveBignum (QCBOREncodeContext *pCtx, UsefulBufC Bytes)
 Add a positive big number to the encoded output. More...
 
static void QCBOREncode_AddNegativeBignum (QCBOREncodeContext *pCtx, UsefulBufC Bytes)
 Add a negative big number to the encoded output. More...
 
static void QCBOREncode_AddURI (QCBOREncodeContext *pCtx, UsefulBufC URI)
 Add a text URI to the encoded output. More...
 
static void QCBOREncode_AddB64Text (QCBOREncodeContext *pCtx, UsefulBufC B64Text)
 Add base 64-encoded text to encoded output. More...
 
static void QCBOREncode_AddB64URLText (QCBOREncodeContext *pCtx, UsefulBufC B64Text)
 Add base 64URL -encoded URL to encoded output. More...
 
static void QCBOREncode_AddRegex (QCBOREncodeContext *pCtx, UsefulBufC Regex)
 Add Perl Compatible Regular Expression. More...
 
static void QCBOREncode_AddMIMEData (QCBOREncodeContext *pCtx, UsefulBufC MIMEData)
 MIME encoded text to the encoded output. More...
 
static void QCBOREncode_AddDateString (QCBOREncodeContext *pCtx, const char *szDate)
 Add an RFC 3339 date string. More...
 
static void QCBOREncode_AddBool (QCBOREncodeContext *pCtx, bool b)
 Add a standard boolean. More...
 
static void QCBOREncode_AddNULL (QCBOREncodeContext *pCtx)
 Add a NULL to the encoded output. More...
 
static void QCBOREncode_AddUndef (QCBOREncodeContext *pCtx)
 Add an "undef" to the encoded output. More...
 
static void QCBOREncode_OpenArray (QCBOREncodeContext *pCtx)
 Indicates that the next items added are in an array. More...
 
static void QCBOREncode_CloseArray (QCBOREncodeContext *pCtx)
 Close an open array. More...
 
static void QCBOREncode_OpenMap (QCBOREncodeContext *pCtx)
 Indicates that the next items added are in a map. More...
 
static void QCBOREncode_CloseMap (QCBOREncodeContext *pCtx)
 Close an open map. More...
 
static void QCBOREncode_BstrWrap (QCBOREncodeContext *pCtx)
 Indicate start of encoded CBOR to be wrapped in a bstr. More...
 
static void QCBOREncode_CloseBstrWrap (QCBOREncodeContext *pCtx, UsefulBufC *pWrappedCBOR)
 Close a wrapping bstr. More...
 
static void QCBOREncode_AddEncoded (QCBOREncodeContext *pCtx, UsefulBufC Encoded)
 Add some already-encoded CBOR bytes. More...
 
QCBORError QCBOREncode_Finish (QCBOREncodeContext *pCtx, UsefulBufC *pEncodedCBOR)
 Get the encoded result. More...
 
QCBORError QCBOREncode_FinishGetSize (QCBOREncodeContext *pCtx, size_t *uEncodedLen)
 Get the encoded CBOR and error status. More...
 
void QCBORDecode_Init (QCBORDecodeContext *pCtx, UsefulBufC EncodedCBOR, QCBORDecodeMode nMode)
 Initialize the CBOR decoder context. More...
 
QCBORError QCBORDecode_SetMemPool (QCBORDecodeContext *pCtx, UsefulBuf MemPool, bool bAllStrings)
 Set up the MemPool string allocator for indefinite length strings. More...
 
void QCBORDecode_SetUpAllocator (QCBORDecodeContext *pCtx, const QCBORStringAllocator *pAllocator, bool bAllStrings)
 Sets up a custom string allocator for indefinite length strings. More...
 
void QCBORDecode_SetCallerConfiguredTagList (QCBORDecodeContext *pCtx, const QCBORTagListIn *pTagList)
 Configure list of caller selected tags to be recognized. More...
 
QCBORError QCBORDecode_GetNext (QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem)
 Gets the next item (integer, byte string, array...) in pre order traversal of CBOR tree. More...
 
QCBORError QCBORDecode_GetNextWithTags (QCBORDecodeContext *pCtx, QCBORItem *pDecodedItem, QCBORTagListOut *pTagList)
 Gets the next item including full list of tags for item. More...
 
int QCBORDecode_IsTagged (QCBORDecodeContext *pCtx, const QCBORItem *pItem, uint64_t uTag)
 Determine if a CBOR item was tagged with a particular tag. More...
 
QCBORError QCBORDecode_Finish (QCBORDecodeContext *pCtx)
 Check whether all the bytes have been decoded and maps and arrays closed. More...
 
static int QCBOR_Int64ToInt32 (int64_t src, int32_t *dest)
 Convert int64_t to smaller int's safely. More...
 
void QCBOREncode_AddBuffer (QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC Bytes)
 Semi-private method to add a buffer full of bytes to encoded output. More...
 
void QCBOREncode_OpenMapOrArray (QCBOREncodeContext *pCtx, uint8_t uMajorType)
 Semi-private method to open a map, array or bstr wrapped CBOR. More...
 
void QCBOREncode_CloseMapOrArray (QCBOREncodeContext *pCtx, uint8_t uMajorType, UsefulBufC *pWrappedCBOR)
 Semi-private method to close a map, array or bstr wrapped CBOR. More...
 
void QCBOREncode_AddType7 (QCBOREncodeContext *pCtx, size_t uSize, uint64_t uNum)
 Semi-private method to add simple types. More...
 

Detailed Description

Q C B O R E n c o d e / D e c o d e.

This implements CBOR – Concise Binary Object Representation as defined in RFC 7049. More info is at http://cbor.io. This is a near-complete implementation of the specification. Limitations are listed further down.

CBOR is intentionally designed to be translatable to JSON, but not all CBOR can convert to JSON. See RFC 7049 for more info on how to construct CBOR that is the most JSON friendly.

The memory model for encoding and decoding is that encoded CBOR must be in a contiguous buffer in memory. During encoding the caller must supply an output buffer and if the encoding would go off the end of the buffer an error is returned. During decoding the caller supplies the encoded CBOR in a contiguous buffer and the decoder returns pointers and lengths into that buffer for strings.

This implementation does not require malloc. All data structures passed in/out of the APIs can fit on the stack.

Decoding of indefinite length strings is a special case that requires a "string allocator" to allocate memory into which the segments of the string are coalesced. Without this, decoding will error out if an indefinite length string is encountered (indefinite length maps and arrays do not require the string allocator). A simple string allocator called MemPool is built-in and will work if supplied with a block of memory to allocate. The string allocator can optionally use malloc() or some other custom scheme.

Here are some terms and definitions:

CBOR has two mechanisms for tagging and labeling the data values like integers and strings. For example, an integer that represents someone's birthday in epoch seconds since Jan 1, 1970 could be encoded like this:

The encoded binary looks like this: a1 # Map of 1 item 69 # Indicates text string of 9 bytes 426972746844617465 # The text "BirthDate" c1 # Tags next int as epoch date 1a # Indicates 4 byte integer 580d4172 # unsigned integer date 1477263730

Implementors using this API will primarily work with labels. Generally tags are only needed for making up new data types. This implementation covers most of the data types defined in the RFC using tags. It also, allows for the creation of news tags if necessary.

This implementation explicitly supports labels that are text strings and integers. Text strings translate nicely into JSON objects and are very readable. Integer labels are much less readable, but can be very compact. If they are in the range of -23 to 23 they take up only one byte.

CBOR allows a label to be any type of data including an array or a map. It is possible to use this API to construct and parse such labels, but it is not explicitly supported.

A common encoding usage mode is to invoke the encoding twice. First with no output buffer to compute the length of the needed output buffer. Then the correct sized output buffer is allocated. Last the encoder is invoked again, this time with the output buffer.

The double invocation is not required if the max output buffer size can be predicted. This is usually possible for simple CBOR structures. If the double invocation is implemented, it can be in a loop or function as in the example code so that the code doesn't have to actually be written twice, saving code size.

If a buffer too small to hold the encoded output is given, the error QCBOR_ERR_BUFFER_TOO_SMALL will be returned. Data will never be written off the end of the output buffer no matter which functions here are called or what parameters are passed to them.

The error handling is simple. The only possible errors are trying to encode structures that are too large or too complex. There are no internal malloc calls so there will be no failures for out of memory. Only the final call, QCBOREncode_Finish(), returns an error code. Once an error happens, the encoder goes into an error state and calls to it will do nothing so the encoding can just go on. An error check is not needed after every data item is added.

Encoding generally proceeds by calling QCBOREncode_Init(), calling lots of "Add" functions and calling QCBOREncode_Finish(). There are many "Add" functions for various data types. The input buffers need only to be valid during the "Add" calls. The data is copied into the output buf during the "Add" call.

There are three Add functions for each data type. The first / main one for the type is for adding the data item to an array. The second one's name ends in ToMap, is used for adding data items to maps and takes a string argument that is its label in the map. The third one ends in ToMapN, is also used for adding data items to maps, and takes an integer argument that is its label in the map.

The simplest aggregate type is an array, which is a simple ordered set of items without labels the same as JSON arrays. Call QCBOREncode_OpenArray() to open a new array, then "Add" to put items in the array and then QCBOREncode_CloseArray(). Nesting to a limit is allowed. All opens must be matched by closes or an encoding error will be returned.

The other aggregate type is a map which does use labels. The Add functions that end in ToMap and ToMapN are convenient ways to add labeled data items to a map. You can also call any type of Add function once to add a label of any time and then call any type of Add again to add its value.

Note that when you nest arrays or maps in a map, the nested array or map has a label.

Usually it is not necessary to add tags explicitly as most tagged types have functions here, but they can be added by calling QCBOREncode_AddTag(). There is an IANA registry for new tags that are for broad use and standardization as per RFC 7049. It is also allowed for protocols to make up new tags in the range above 256. Note that even arrays and maps can be tagged.

Summary Limits of this implementation:

This implementation is intended to run on 32 and 64-bit CPUs. Minor modifications are needed for it to work on 16-bit CPUs.

The public interface uses size_t for all lengths. Internally the implementation uses 32-bit lengths by design to use less memory and fit structures on the stack. This limits the encoded CBOR it can work with to size UINT32_MAX (4GB) which should be enough.

This implementation assumes two's compliment integer machines. Stdint.h also requires this. It of course would be easy to fix this implementation for another integer representation, but all modern machines seem to be two's compliment.

Definition in file qcbor.h.

Macro Definition Documentation

#define CBOR_TAG_B64   34

The data in the string is base 64'd.

Definition at line 296 of file qcbor.h.

#define CBOR_TAG_B64URL   33

The data in the string is a base 64'd URL.

Definition at line 294 of file qcbor.h.

#define CBOR_TAG_BIN_UUID   37

Binary UUID.

Definition at line 302 of file qcbor.h.

#define CBOR_TAG_CBOR_MAGIC   55799

The data is CBOR data.

Definition at line 314 of file qcbor.h.

#define CBOR_TAG_DATE_EPOCH   1

See QCBOREncode_AddDateEpoch_2()

Definition at line 274 of file qcbor.h.

#define CBOR_TAG_DATE_STRING   0

See QCBOREncode_AddDateString() below.

Definition at line 272 of file qcbor.h.

#define CBOR_TAG_MIME   36

MIME messages (including all headers), as defined in RFC2045.

Definition at line 300 of file qcbor.h.

#define CBOR_TAG_REGEX   35

regular expressions in Perl Compatible Regular Expressions (PCRE) / JavaScript syntax ECMA262.

Definition at line 298 of file qcbor.h.

#define CBOR_TAG_URI   32

The data in the string is a URIs, as defined in RFC3986.

Definition at line 292 of file qcbor.h.

#define QCBOR_DECODE_MIN_MEM_POOL_SIZE   72

This only matters if you use a string allocator and and set it up with QCBORDecode_SetMemPool().

It is the size of the overhead needed needed by QCBORDecode_SetMemPool(). If you write your own string allocator or use the separately available malloc based string allocator, this size will not apply

Definition at line 800 of file qcbor.h.

#define QCBOR_MAX_ARRAY_NESTING   QCBOR_MAX_ARRAY_NESTING1

The maximum nesting of arrays and maps when encoding or decoding.

The error QCBOR_ERR_ARRAY_NESTING_TOO_DEEP will be returned on encoding of decoding if it is exceeded

Definition at line 544 of file qcbor.h.

#define QCBOR_MAX_CUSTOM_TAGS   16

The maximum number of tags that can be in QCBORTagListIn and passed to QCBORDecode_SetCallerConfiguredTagList()

Definition at line 550 of file qcbor.h.

#define QCBOR_MAX_ITEMS_IN_ARRAY   (UINT16_MAX-1)

The maximum number of items in a single array or map when encoding of decoding.

Definition at line 537 of file qcbor.h.

#define QCBOR_TYPE_ARRAY   4

Type for an array.

The number of items in the array is in val.uCount.

Definition at line 675 of file qcbor.h.

#define QCBOR_TYPE_BYTE_STRING   6

Type for a buffer full of bytes.

Data is in val.string.

Definition at line 679 of file qcbor.h.

#define QCBOR_TYPE_DATE_EPOCH   12

Type for integer seconds since Jan 1970 + floating point fraction.

Data is in val.epochDate

Definition at line 689 of file qcbor.h.

#define QCBOR_TYPE_DATE_STRING   11

Type for RFC 3339 date string, possibly with time zone.

Data is in val.dateString

Definition at line 687 of file qcbor.h.

#define QCBOR_TYPE_DOUBLE   27

Type for a double floating point number.

Data is in val.double.

Definition at line 703 of file qcbor.h.

#define QCBOR_TYPE_FALSE   20

Type for the simple value false; nothing more; nothing in val union.

Definition at line 693 of file qcbor.h.

#define QCBOR_TYPE_FLOAT   26

Type for a floating point number.

Data is in val.float.

Definition at line 701 of file qcbor.h.

#define QCBOR_TYPE_INT64   2

Type for an integer that decoded either between INT64_MIN and INT32_MIN or INT32_MAX and INT64_MAX; val.int64.

Definition at line 671 of file qcbor.h.

#define QCBOR_TYPE_MAP   5

Type for a map; number of items in map is in val.uCount.

Definition at line 677 of file qcbor.h.

#define QCBOR_TYPE_MAP_AS_ARRAY   32

For QCBOR_DECODE_MODE_MAP_AS_ARRAY decode mode, a map that is being traversed as an array.

See QCBORDecode_Init()

Definition at line 705 of file qcbor.h.

#define QCBOR_TYPE_NEGBIGNUM   10

Type for a negative big number.

Data is in val.bignum, a pointer and a length.

Definition at line 685 of file qcbor.h.

#define QCBOR_TYPE_NONE   0

The type is unknown, unset or invalid.

Definition at line 669 of file qcbor.h.

#define QCBOR_TYPE_NULL   22

Type for the simple value null; nothing more; nothing in val union.

Definition at line 697 of file qcbor.h.

#define QCBOR_TYPE_POSBIGNUM   9

Type for a positive big number.

Data is in val.bignum, a pointer and a length.

Definition at line 683 of file qcbor.h.

#define QCBOR_TYPE_TEXT_STRING   7

Type for a UTF-8 string.

It is not NULL terminated. Data is in val.string.

Definition at line 681 of file qcbor.h.

#define QCBOR_TYPE_TRUE   21

Type for the simple value true; nothing more; nothing in val union.

Definition at line 695 of file qcbor.h.

#define QCBOR_TYPE_UINT64   3

Type for an integer that decoded to a more than INT64_MAX and UINT64_MAX; val.uint64.

Definition at line 673 of file qcbor.h.

#define QCBOR_TYPE_UKNOWN_SIMPLE   13

A simple type that this CBOR implementation doesn't know about; Type is in val.uSimple.

Definition at line 691 of file qcbor.h.

#define QCBOR_TYPE_UNDEF   23

Type for the simple value undef; nothing more; nothing in val union.

Definition at line 699 of file qcbor.h.

Typedef Documentation

QCBORDecodeContext is the data type that holds context decoding the data items for some received CBOR.

It is about 100 bytes, so it can go on the stack. The contents are opaque, and the caller should not access any internal items. A context may be re used serially as long as it is re initialized.

Definition at line 1620 of file qcbor.h.

QCBOREncodeContext is the data type that holds context for all the encoding functions.

It is less than 200 bytes, so it can go on the stack. The contents are opaque, and the caller should not access any internal items. A context may be re used serially as long as it is re initialized.

Definition at line 845 of file qcbor.h.

typedef struct _QCBORItem QCBORItem

QCBORItem holds the type, value and other info for a decoded item returned by GetNextItem().

Enumeration Type Documentation

Enumerator
QCBOR_DECODE_MODE_NORMAL 

See QCBORDecode_Init()

QCBOR_DECODE_MODE_MAP_STRINGS_ONLY 

See QCBORDecode_Init()

QCBOR_DECODE_MODE_MAP_AS_ARRAY 

See QCBORDecode_Init()

Definition at line 654 of file qcbor.h.

enum QCBORError
Enumerator
QCBOR_SUCCESS 

The encode or decode completely correctly.

QCBOR_ERR_BUFFER_TOO_SMALL 

The buffer provided for the encoded output when doing encoding was too small and the encoded output will not fit.

Also, when the buffer given to QCBORDecode_SetMemPool() is too small.

QCBOR_ERR_ARRAY_NESTING_TOO_DEEP 

During encoding or decoding, the array or map nesting was deeper than this implementation can handle.

Note that in the interest of code size and memory use, this implementation has a hard limit on array nesting. The limit is defined as the constant QCBOR_MAX_ARRAY_NESTING.

QCBOR_ERR_ARRAY_TOO_LONG 

During decoding or encoding, the array or map had too many items in it.

This limit QCBOR_MAX_ITEMS_IN_ARRAY, typically 65,535.

QCBOR_ERR_TOO_MANY_CLOSES 

During encoding, more arrays or maps were closed than opened.

This is a coding error on the part of the caller of the encoder.

QCBOR_ERR_UNSUPPORTED 

During decoding, some CBOR construct was encountered that this decoder doesn't support, primarily this is the reserved additional info values, 28 through 30.

QCBOR_ERR_HIT_END 

During decoding, hit the end of the given data to decode.

For example, a byte string of 100 bytes was expected, but the end of the input was hit before finding those 100 bytes. Corrupted CBOR input will often result in this error.

QCBOR_ERR_BUFFER_TOO_LARGE 

During encoding, the length of the encoded CBOR exceeded UINT32_MAX.

QCBOR_ERR_INT_OVERFLOW 

During decoding, an integer smaller than INT64_MIN was received (CBOR can represent integers smaller than INT64_MIN, but C cannot).

QCBOR_ERR_MAP_LABEL_TYPE 

During decoding, the label for a map entry is bad.

What causes this error depends on the decoding mode.

QCBOR_ERR_ARRAY_OR_MAP_STILL_OPEN 

During encoding or decoding, the number of array or map opens was not matched by the number of closes.

QCBOR_ERR_BAD_SIMPLE 

During encoding, the simple value is not between CBOR_SIMPLEV_FALSE and CBOR_SIMPLEV_UNDEF.

QCBOR_ERR_DATE_OVERFLOW 

During decoding, a date greater than +- 292 billion years from Jan 1 1970 encountered during parsing.

QCBOR_ERR_INVALID_CBOR 

During decoding, the CBOR is not valid, primarily a simple type is encoded in a prohibited way.

QCBOR_ERR_BAD_OPT_TAG 

Optional tagging that doesn't make sense (an int is tagged as a date string) or can't be handled.

QCBOR_ERR_EXTRA_BYTES 

Returned by QCBORDecode_Finish() if all the inputs bytes have not been consumed.

QCBOR_ERR_CLOSE_MISMATCH 

During encoding, QCBOREncode_Close() call with a different type than is currently open.

QCBOR_ERR_NO_STRING_ALLOCATOR 

Unable to decode an indefinite length string because no string allocator was configured.

QCBOR_ERR_INDEFINITE_STRING_CHUNK 

One of the chunks in an indefinite length string is not of the type of the string.

QCBOR_ERR_STRING_ALLOCATE 

Error allocating space for a string, usually for an indefinite length string.

QCBOR_ERR_BAD_BREAK 

During decoding, a break occurred outside an indefinite length item.

QCBOR_ERR_TOO_MANY_TAGS 

During decoding, too many tags in the caller-configured tag list, or not enough space in QCBORTagListOut.

QCBOR_ERR_MEM_POOL_INTERNAL 

Returned by QCBORDecode_SetMemPool() when xx is too small.

This should never happen on a machine with 64-bit or smaller pointers. Fixing it is probably by increasing QCBOR_DECODE_MIN_MEM_POOL_SIZE.

Definition at line 553 of file qcbor.h.

Function Documentation

static int QCBOR_Int64ToInt32 ( int64_t  src,
int32_t *  dest 
)
static

Convert int64_t to smaller int's safely.

Parameters
[in]srcAn int64_t
[out]destA smaller sized int to convert to
Returns
0 on success -1 if not

When decoding an integer, the CBOR decoder will return the value as an int64_t unless the integer is in the range of INT64_MAX and UINT64_MAX. That is, unless the value is so large that it can only be represented as a uint64_t, it will be an int64_t.

CBOR itself doesn't size the individual integers it carries at all. The only limits it puts on the major integer types is that they are 8 bytes or less in length. Then encoders like this one use the smallest number of 1, 2, 4 or 8 bytes to represent the integer based on its value. There is thus no notion that one data item in CBOR is an 1 byte integer and another is a 4 byte integer.

The interface to this CBOR encoder only uses 64-bit integers. Some CBOR protocols or implementations of CBOR protocols may not want to work with something smaller than a 64-bit integer. Perhaps an array of 1000 integers needs to be sent and none has a value larger than 50,000 and are represented as uint16_t.

The sending / encoding side is easy. Integers are temporarily widened to 64-bits as a parameter passing through QCBOREncode_AddInt64() and encoded in the smallest way possible for their value, possibly in less than an uint16_t.

On the decoding side the integers will be returned at int64_t even if they are small and were represented by only 1 or 2 bytes in the encoded CBOR. The functions here will convert integers to a small representation with an overflow check.

(The decoder could have support 8 different integer types and represented the integer with the smallest type automatically, but this would have made the decoder more complex and code calling the decoder more complex in most use cases. In most use cases on 64-bit machines it is no burden to carry around even small integers as 64-bit values).

Definition at line 1980 of file qcbor.h.

QCBORError QCBORDecode_Finish ( QCBORDecodeContext pCtx)

Check whether all the bytes have been decoded and maps and arrays closed.

Parameters
[in]pCtxThe context to check
Returns
QCBOR_SUCCESS or error

This tells you if all the bytes given to QCBORDecode_Init() have been consumed and whether all maps and arrays were closed. The decode is considered to be incorrect or incomplete if not and an error will be returned.

QCBORError QCBORDecode_GetNext ( QCBORDecodeContext pCtx,
QCBORItem pDecodedItem 
)

Gets the next item (integer, byte string, array...) in pre order traversal of CBOR tree.

Parameters
[in]pCtxThe decoder context.
[out]pDecodedItemHolds the CBOR item just decoded.
Returns
0 or error. All errors except QCBOR_ERR_TOO_MANY_TAGS and QCBOR_ERR_STRING_ALLOCATE indicate that the CBOR input could not be decoded. In most cases this is because the CBOR is invalid. In a few cases (QCBOR_ERR_ARRAY_NESTING_TOO_DEEP, QCBOR_ERR_INT_OVERFLOW, QCBOR_ERR_DATE_OVERFLOW) it is because the CBOR is beyond the limits of what this implementation can handle. QCBOR_ERR_NO_STRING_ALLOCATOR indicates CBOR that cannot be handled unless a string allocator is configured. QCBOR_ERR_MAP_LABEL_TYPE is in a way a limitation of this implementation, but can be avoided by decoding in QCBOR_DECODE_MODE_MAP_AS_ARRAY mode.

pDecodedItem is filled in with the value parsed. Generally, the following data is returned in the structure.

  • The data type in uDataType which indicates which member of the val union the data is in. This decoder figures out the type based on the CBOR major type, the CBOR "additionalInfo", the CBOR optional tags and the value of the integer.
  • The value of the item, which might be an integer, a pointer and a length, the count of items in an array, a floating-point number or other.
  • The nesting level for maps and arrays.
  • The label for an item in a map, which may be a text or byte string or an integer.
  • The CBOR optional tag or tags.

See documentation on in the data type QCBORItem for all the details on what is returned.

This function also handles arrays and maps. When first encountered a QCBORItem will be returned with major type CBOR_MAJOR_TYPE_ARRAY or CBOR_MAJOR_TYPE_ARRAY_MAP. QCBORItem.val.uCount will indicate the number of Items in the array or map. Typically, an implementation will call QCBORDecode_GetNext() in a for loop to fetch them all. When decoding indefinite length maps and arrays, QCBORItem.val.uCount is UINT16_MAX and uNextNestLevel must be used to know when the end of a map or array is reached.

Nesting level 0 is the outside top-most nesting level. For example, in a CBOR structure with two items, an integer and a byte string only, both would be at nesting level 0. A CBOR structure with an array open, an integer and a byte string, would have the integer and byte string as nesting level 1.

Here is an example of how the nesting level is reported with no arrays or maps at all

CBOR Structure           Nesting Level
Integer                    0
Byte String                0

Here is an example of how the nesting level is reported with an a simple array and some top-level items.

Integer                    0
Array (with 2 items)       0
Byte String                1
Byte string                1
Integer                    0

Here's a more complex example

Map with 2 items           0
Text string                1
Array with 3 integers      1
integer                    2
integer                    2
integer                    2
text string                1
byte string                1

In QCBORItem, uNextNestLevel is the nesting level for the next call to QCBORDecode_GetNext(). It indicates if any maps or arrays were closed out during the processing of the just-fecthed QCBORItem. This processing includes a look-ahead for any breaks that close out indefinite length arrays or maps. This value is needed to be able to understand the hierarchical structure. If uNextNestLevel is not equal to uNestLevel the end of the current map or array has been encountered. This works the same for both definite and indefinite length arrays.

Most uses of this decoder will not need to do anything extra for tag handling. The built-in tags, those with a macro of the form CBOR_TAG_XXXX, will be enough.

If tags beyond built-in tags are to be recognized, they must be configured by calling QCBORDecode_SetCallerConfiguredTags(). If a tag is not recognized it is silently ignored.

Several tagged types are automatically recognized and decoded and returned in their decoded form.

To find out if a QCBORItem was tagged with a particular tag call QCBORDecode_IsTagged(). This works only for built-in tags and caller-configured tags.

To get the full list of tags on an Item without having to pre-configure any predetermined list of tags use QCBORDecode_GetNextWithTags().

QCBORError QCBORDecode_GetNextWithTags ( QCBORDecodeContext pCtx,
QCBORItem pDecodedItem,
QCBORTagListOut pTagList 
)

Gets the next item including full list of tags for item.

Parameters
[in]pCtxThe decoder context.
[out]pDecodedItemHolds the CBOR item just decoded.
[in,out]pTagListOn input array to put tags in; on output the tags on this item.
Returns
0 or error.

This works the same as QCBORDecode_GetNext() except that it also returns the full list of tags for the data item. This function should only be needed when parsing CBOR to print it out or convert it to some other format. It should not be needed in an actual CBOR protocol implementation.

Tags will be returned here whether or not they are in the built-in or caller-configured tag lists.

CBOR has no upper bound of limit on the number of tags that can be associated with a data item. In practice the number of tags on an item will usually be small, perhaps less than five. This will return an error if the array in pTagList is too small to hold all the tags for an item.

(This function is separate from QCBORDecode_GetNext() so as to not have to make QCBORItem large enough to be able to hold a full list of tags. Even a list of five tags would nearly double its size because tags can be a uint64_t).

void QCBORDecode_Init ( QCBORDecodeContext pCtx,
UsefulBufC  EncodedCBOR,
QCBORDecodeMode  nMode 
)

Initialize the CBOR decoder context.

Parameters
[in]pCtxThe context to initialize.
[in]EncodedCBORThe buffer with CBOR encoded bytes to be decoded.
[in]nModeOne of QCBOR_DECODE_MODE_xxx

Initialize context for a pre-order travesal of the encoded CBOR tree.

Most CBOR decoding can be completed by calling this function to start and QCBORDecode_GetNext() in a loop.

If indefinite length strings are to be decoded, then QCBORDecode_SetMemPool() or QCBORDecode_SetUpAllocator() must be called to set up a string allocator.

If tags other than built-in tags are to be recognized, then QCBORDecode_SetCallerAddedTagMap() must be called. The built-in tags are those for which a macro of the form CBOR_TAG_XXX is defined.

Three decoding modes are supported. In normal mode, QCBOR_DECODE_MODE_NORMAL, maps are decoded and strings and ints are accepted as map labels. If a label is other than these, the error QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext().

In strings-only mode, QCBOR_DECODE_MODE_MAP_STRINGS_ONLY, only text strings are accepted for map labels. This lines up with CBOR that converts to JSON. The error QCBOR_ERR_MAP_LABEL_TYPE is returned by QCBORDecode_GetNext() if anything but a text string label is encountered.

In QCBOR_DECODE_MODE_MAP_AS_ARRAY maps are treated as special arrays. They will be return with special uDataType QCBOR_TYPE_MAP_AS_ARRAY and uCount, the number of items, will be double what it would be for a normal map because the labels are also counted. This mode is useful for decoding CBOR that has labels that are not integers or text strings, but the caller must manage much of the map decoding.

int QCBORDecode_IsTagged ( QCBORDecodeContext pCtx,
const QCBORItem pItem,
uint64_t  uTag 
)

Determine if a CBOR item was tagged with a particular tag.

Parameters
[in]pCtxThe decoder context.
[in]pItemThe CBOR item to check
[in]uTagThe tag to check
Returns
1 if it was tagged, 0 if not

QCBORDecode_GetNext() processes tags by looking them up in two lists and setting a bit corresponding to the tag in uTagBits in the QCBORItem. To find out if a QCBORItem was tagged with a particular tag, call this function. It handles the mapping between the two lists of tags and the bits set for it.

The first tag list is the built-in tags, those with a macro of the form CBOR_TAG_XXX in this header file. There are up to 48 of these, corresponding to the lower 48 tag bits.

The other optional tag list is the ones the caller configured using QCBORDecode_SetCallerConfiguredTagList() There are QCBOR_MAX_CUSTOM_TAGS (16) of these corresponding to the upper 16 tag bits.

See also QCBORDecode_GetTags() and QCBORDecode_GetNextWithTags().

void QCBORDecode_SetCallerConfiguredTagList ( QCBORDecodeContext pCtx,
const QCBORTagListIn pTagList 
)

Configure list of caller selected tags to be recognized.

Parameters
[in]pCtxThe decode context.
[out]pTagListStructure holding the list of tags to configure

This is used to tell the decoder about tags beyond those that are built-in that should be recognized. The built-in tags are those with macros of the form CBOR_TAG_XXX.

See description of QCBORTagListIn.

QCBORError QCBORDecode_SetMemPool ( QCBORDecodeContext pCtx,
UsefulBuf  MemPool,
bool  bAllStrings 
)

Set up the MemPool string allocator for indefinite length strings.

Parameters
[in]pCtxThe decode context.
[in]MemPoolThe pointer and length of the memory pool.
[in]bAllStringstrue means to put even definite length strings in the pool.
Returns
error if the MemPool was less than QCBOR_DECODE_MIN_MEM_POOL_SIZE.

Indefinite length strings (text and byte) cannot be decoded unless there is a string allocator configured. MemPool is a simple built-in string allocator that allocates bytes from a memory pool handed to it by calling this function. The memory pool is just a pointer and length for some block of memory that is to be used for string allocation. It can come from the stack, heap or other.

The memory pool must be QCBOR_DECODE_MIN_MEM_POOL_SIZE plus space for all the strings allocated. There is no overhead per string allocated

This memory pool is used for all indefinite length strings that are text strings or byte strings, including strings used as labels.

The pointers to strings in QCBORItem will point into the memory pool set here. They do not need to be individually freed. Just discard the buffer when they are no longer needed.

If bAllStrings is set, then the size will be the overhead plus the space to hold all strings, definite and indefinite length, value or label. The advantage of this is that after the decode is complete, the original memory holding the encoded CBOR does not need to remain valid.

If this function is never called because there is no need to support indefinite length strings, the MemPool implementation should be dead-stripped by the loader and not add to code size.

void QCBORDecode_SetUpAllocator ( QCBORDecodeContext pCtx,
const QCBORStringAllocator pAllocator,
bool  bAllStrings 
)

Sets up a custom string allocator for indefinite length strings.

Parameters
[in]pCtxThe decoder context to set up an allocator for
[in]pAllocatorThe string allocator "object"

See QCBORStringAllocator for the requirements of the string allocator.

Typically, this is used if the simple MemPool allocator isn't desired.

A malloc based string allocator can be obtained by calling QCBOR_DMalloc(). This function is supply separately from qcbor to keep qcbor smaller and neater. It is in a separate GitHub repository.

You can also write your own allocator. Create the allocate, free, and destroy functions and put pointers to them in a QCBORStringAllocator.

static void QCBOREncode_AddB64Text ( QCBOREncodeContext pCtx,
UsefulBufC  B64Text 
)
static

Add base 64-encoded text to encoded output.

Parameters
[in]pCtxThe context to initialize.
[in]B64TextPointer and length of the base-64 encoded text.

The text content is base 64 encoded data per RFC 4648.

It is output as CBOR major type 3, a text string, with optional tag 34 indicating the text string is a URI.

Definition at line 2324 of file qcbor.h.

static void QCBOREncode_AddB64URLText ( QCBOREncodeContext pCtx,
UsefulBufC  B64Text 
)
static

Add base 64URL -encoded URL to encoded output.

Parameters
[in]pCtxThe context to initialize.
[in]B64TextPointer and length of the base-64 encoded text.

The text content is base 64 URL format encoded text as per RFC 4648.

It is output as CBOR major type 3, a text string, with optional tag 33 indicating the text string is a URI.

Definition at line 2345 of file qcbor.h.

static void QCBOREncode_AddBinaryUUID ( QCBOREncodeContext pCtx,
UsefulBufC  Bytes 
)
static

Add a binary UUID to the encoded output.

Parameters
[in]pCtxThe context to initialize.
[in]BytesPointer and length of the binary UUID.

A binary UUID as defined in RFC 4122 is added to the ouput.

It is output as CBOR major type 2, a binary string, with optional tag 36 indicating the binary string is a UUID.

Definition at line 2239 of file qcbor.h.

static void QCBOREncode_AddBool ( QCBOREncodeContext pCtx,
bool  b 
)
static

Add a standard boolean.

Parameters
[in]pCtxThe encoding context to add the simple value to.
[in]btrue or false from stdbool. Anything will result in an error.

Adds a boolean value as CBOR major type 7.

Error handling is the same as QCBOREncode_AddInt64().

Definition at line 2447 of file qcbor.h.

void QCBOREncode_AddBuffer ( QCBOREncodeContext pCtx,
uint8_t  uMajorType,
UsefulBufC  Bytes 
)

Semi-private method to add a buffer full of bytes to encoded output.

Parameters
[in]pCtxThe encoding context to add the integer to.
[in]uMajorTypeThe CBOR major type of the bytes.
[in]BytesThe bytes to add.

Use QCBOREncode_AddText() or QCBOREncode_AddBytes() or QCBOREncode_AddEncoded() instead. They are inline functions that call this and supply the correct major type. This function is public to make the inline functions work to keep the overall code size down and because the C language has no way to make it private.

If this is called the major type should be CBOR_MAJOR_TYPE_TEXT_STRING, CBOR_MAJOR_TYPE_BYTE_STRING or CBOR_MAJOR_NONE_TYPE_RAW. The last one is special for adding already-encoded CBOR.

static void QCBOREncode_AddBytes ( QCBOREncodeContext pCtx,
UsefulBufC  Bytes 
)
static

Add a byte string to the encoded output.

Parameters
[in]pCtxThe context to initialize.
[in]BytesPointer and length of the input data.

Simply adds the bytes to the encoded output as CBOR major type 2.

If called with Bytes.len equal to 0, an empty string will be added. When Bytes.len is 0, Bytes.ptr may be NULL.

Error handling is the same as QCBOREncode_AddInt64().

Definition at line 2221 of file qcbor.h.

static void QCBOREncode_AddDateEpoch ( QCBOREncodeContext pCtx,
int64_t  date 
)
static

Add an epoch-based date.

Parameters
[in]pCtxThe encoding context to add the simple value to.
[in]dateNumber of seconds since 1970-01-01T00:00Z in UTC time.

As per RFC 7049 this is similar to UNIX/Linux/POSIX dates. This is the most compact way to specify a date and time in CBOR. Note that this is always UTC and does not include the time zone. Use QCBOREncode_AddDateString() if you want to include the time zone.

The integer encoding rules apply here so the date will be encoded in a minimal number of 1, 2 4 or 8 bytes. Until about the year 2106 these dates should encode in 6 bytes – one byte for the tag, one byte for the type and 4 bytes for the integer.

If you care about leap-seconds and that level of accuracy, make sure the system you are running this code on does it correctly. This code just takes the value passed in.

This implementation cannot encode fractional seconds using float or double even though that is allowed by CBOR, but you can encode them if you want to by calling QCBOREncode_AddDouble() with the right parameters.

Error handling is the same as QCBOREncode_AddInt64().

Definition at line 2200 of file qcbor.h.

static void QCBOREncode_AddDateString ( QCBOREncodeContext pCtx,
const char *  szDate 
)
static

Add an RFC 3339 date string.

Parameters
[in]pCtxThe encoding context to add the simple value to.
[in]szDateNull-terminated string with date to add

The string szDate should be in the form of RFC 3339 as defined by section 3.3 in RFC 4287. This is as described in section 2.4.1 in RFC 7049.

Note that this function doesn't validate the format of the date string at all. If you add an incorrect format date string, the generated CBOR will be incorrect and the receiver may not be able to handle it.

Error handling is the same as QCBOREncode_AddInt64().

Definition at line 2408 of file qcbor.h.

void QCBOREncode_AddDouble ( QCBOREncodeContext pCtx,
double  dNum 
)

Add a floating-point number to the encoded output.

Parameters
[in]pCtxThe encoding context to add the float to.
[in]dNumThe double precision number to add.

This outputs a floating-point number with CBOR major type 7.

This will selectively encode the double-precision floating point number as either double-precision, single-precision or half-precision. It will always encode infinity, NaN and 0 has half precision. If no precision will be lost in the conversion to half-precision then it will be converted and encoded. If not and no precision will be lost in conversion to single-precision, then it will be converted and encoded. If not, then no conversion is performed, and it encoded as a double.

Half-precision floating point numbers take up 2 bytes, half that of single-precision, one quarter of double-precision

This automatically reduces the size of encoded messages a lot, maybe even by four if most of values are 0, infinity or NaN.

On decode, these will always be returned as a double.

Error handling is the same as QCBOREncode_AddInt64().

static void QCBOREncode_AddEncoded ( QCBOREncodeContext pCtx,
UsefulBufC  Encoded 
)
static

Add some already-encoded CBOR bytes.

Parameters
[in]pCtxThe context to add to.
[in]EncodedThe already-encoded CBOR to add to the context.

The encoded CBOR being added must be fully conforming CBOR. It must be complete with no arrays or maps that are incomplete. While this encoder doesn't ever produce indefinite lengths, it is OK for the raw CBOR added here to have indefinite lengths.

The raw CBOR added here is not checked in anyway. If it is not conforming or has open arrays or such, the final encoded CBOR will probably be wrong or not what was intended.

If the encoded CBOR being added here contains multiple items, they must be enclosed in a map or array. At the top level the raw CBOR must be a single data item.

Definition at line 2574 of file qcbor.h.

void QCBOREncode_AddInt64 ( QCBOREncodeContext pCtx,
int64_t  nNum 
)

Add a signed 64-bit integer to the encoded output.

Parameters
[in]pCtxThe encoding context to add the integer to.
[in]nNumThe integer to add.

The integer will be encoded and added to the CBOR output.

This function figures out the size and the sign and encodes in the correct minimal CBOR. Specifically, it will select CBOR major type 0 or 1 based on sign and will encode to 1, 2, 4 or 8 bytes depending on the value of the integer. Values less than 24 effectively encode to one byte because they are encoded in with the CBOR major type. This is a neat and efficient characteristic of CBOR that can be taken advantage of when designing CBOR-based protocols. If integers like tags can be kept between -23 and 23 they will be encoded in one byte including the major type.

If you pass a smaller int, say an int16_t or a small value, say 100, the encoding will still be CBOR's most compact that can represent the value. For example, CBOR always encodes the value 0 as one byte, 0x00. The representation as 0x00 includes identification of the type as an integer too as the major type for an integer is 0. See RFC 7049 Appendix A for more examples of CBOR encoding. This compact encoding is also canonical CBOR as per section 3.9 in RFC 7049.

There are no functions to add int16_t or int32_t because they are not necessary because this always encodes to the smallest number of bytes based on the value (If this code is running on a 32-bit machine having a way to add 32-bit integers would reduce code size some).

If the encoding context is in an error state, this will do nothing. If an error occurs when adding this integer, the internal error flag will be set, and the error will be returned when QCBOREncode_Finish() is called.

See also QCBOREncode_AddUInt64().

static void QCBOREncode_AddMIMEData ( QCBOREncodeContext pCtx,
UsefulBufC  MIMEData 
)
static

MIME encoded text to the encoded output.

Parameters
[in]pCtxThe context to initialize.
[in]MIMEDataPointer and length of the regular expression.

The text content is in MIME format per RFC 2045 including the headers.

It is output as CBOR major type 3, a text string, with optional tag 36 indicating the text string is MIME data.

Definition at line 2387 of file qcbor.h.

static void QCBOREncode_AddNegativeBignum ( QCBOREncodeContext pCtx,
UsefulBufC  Bytes 
)
static

Add a negative big number to the encoded output.

Parameters
[in]pCtxThe context to initialize.
[in]BytesPointer and length of the big number.

Big numbers are integers larger than 64-bits. Their format is described in RFC 7049.

It is output as CBOR major type 2, a binary string, with optional tag 2 indicating the binary string is a negative big number.

Often big numbers are used to represent cryptographic keys, however, COSE which defines representations for keys chose not to use this particular type.

Definition at line 2281 of file qcbor.h.

static void QCBOREncode_AddNULL ( QCBOREncodeContext pCtx)
static

Add a NULL to the encoded output.

Parameters
[in]pCtxThe encoding context to add the simple value to.

Adds the NULL value as CBOR major type 7.

This NULL doesn't have any special meaning in CBOR such as a terminating value for a string or an empty value.

Error handling is the same as QCBOREncode_AddInt64().

Definition at line 2469 of file qcbor.h.

static void QCBOREncode_AddPositiveBignum ( QCBOREncodeContext pCtx,
UsefulBufC  Bytes 
)
static

Add a positive big number to the encoded output.

Parameters
[in]pCtxThe context to initialize.
[in]BytesPointer and length of the big number.

Big numbers are integers larger than 64-bits. Their format is described in RFC 7049.

It is output as CBOR major type 2, a binary string, with optional tag 2 indicating the binary string is a positive big number.

Often big numbers are used to represent cryptographic keys, however, COSE which defines representations for keys chose not to use this particular type.

Definition at line 2260 of file qcbor.h.

static void QCBOREncode_AddRegex ( QCBOREncodeContext pCtx,
UsefulBufC  Regex 
)
static

Add Perl Compatible Regular Expression.

Parameters
[in]pCtxThe context to initialize.
[in]RegexPointer and length of the regular expression.

The text content is Perl Compatible Regular Expressions (PCRE) / JavaScript syntax [ECMA262].

It is output as CBOR major type 3, a text string, with optional tag 35 indicating the text string is a regular expression.

Definition at line 2366 of file qcbor.h.

static void QCBOREncode_AddSZString ( QCBOREncodeContext pCtx,
const char *  szString 
)
static

Add a UTF-8 text string to the encoded output.

Parameters
[in]pCtxThe context to initialize.
[in]szStringNull-terminated text to add.

This works the same as QCBOREncode_AddText().

Definition at line 2169 of file qcbor.h.

void QCBOREncode_AddTag ( QCBOREncodeContext pCtx,
uint64_t  uTag 
)

[in] Add an optional tag

Parameters
[in]pCtxThe encoding context to add the integer to.
[in]uTagThe tag to add

This outputs a CBOR major type 6 optional tag.

The tag is applied to the next data item added to the encoded output. That data item that is to be tagged can be of any major CBOR type. Any number of tags can be added to a data item by calling this multiple times before the data item is added.

For many of the common standard tags a function to encode data using it already exists and this is not needed. For example, QCBOREncode_AddDateEpoch() already exists to output integers representing dates with the right tag.

static void QCBOREncode_AddText ( QCBOREncodeContext pCtx,
UsefulBufC  Text 
)
static

Add a UTF-8 text string to the encoded output.

Parameters
[in]pCtxThe context to initialize.
[in]TextPointer and length of text to add.

The text passed in must be unencoded UTF-8 according to RFC

  1. There is no NULL termination. The text is added as CBOR major type 3.

If called with nBytesLen equal to 0, an empty string will be added. When nBytesLen is 0, pBytes may be NULL.

Note that the restriction of the buffer length to an uint32_t is entirely intentional as this encoder is not capable of encoding lengths greater. This limit to 4GB for a text string should not be a problem.

Error handling is the same as QCBOREncode_AddInt64().

Definition at line 2151 of file qcbor.h.

void QCBOREncode_AddType7 ( QCBOREncodeContext pCtx,
size_t  uSize,
uint64_t  uNum 
)

Semi-private method to add simple types.

Parameters
[in]pCtxThe encoding context to add the simple value to.
[in]uSizeMinimum encoding size for uNum. Usually 0.
[in]uNumOne of CBOR_SIMPLEV_FALSE through _UNDEF or other.

This is used to add simple types like true and false.

Call QCBOREncode_AddBool(), QCBOREncode_AddNULL(), QCBOREncode_AddUndef() instead of this.

This function can add simple values that are not defined by CBOR yet. This expansion point in CBOR should not be used unless they are standardized.

Error handling is the same as QCBOREncode_AddInt64().

void QCBOREncode_AddUInt64 ( QCBOREncodeContext pCtx,
uint64_t  uNum 
)

Add an unsigned 64-bit integer to the encoded output.

Parameters
[in]pCtxThe encoding context to add the integer to.
[in]uNumThe integer to add.

The integer will be encoded and added to the CBOR output.

The only reason so use this function is for integers larger than INT64_MAX and smaller than UINT64_MAX. Otherwise QCBOREncode_AddInt64() will work fine.

Error handling is the same as for QCBOREncode_AddInt64().

static void QCBOREncode_AddUndef ( QCBOREncodeContext pCtx)
static

Add an "undef" to the encoded output.

Parameters
[in]pCtxThe encoding context to add the simple value to.

Adds the undef value as CBOR major type 7.

Note that this value will not translate to JSON.

This Undef doesn't have any special meaning in CBOR such as a terminating value for a string or an empty value.

Error handling is the same as QCBOREncode_AddInt64().

Definition at line 2487 of file qcbor.h.

static void QCBOREncode_AddURI ( QCBOREncodeContext pCtx,
UsefulBufC  URI 
)
static

Add a text URI to the encoded output.

Parameters
[in]pCtxThe context to initialize.
[in]URIPointer and length of the URI.

The format of URI is RFC 3986.

It is output as CBOR major type 3, a text string, with optional tag 32 indicating the text string is a URI.

Definition at line 2302 of file qcbor.h.

static void QCBOREncode_BstrWrap ( QCBOREncodeContext pCtx)
static

Indicate start of encoded CBOR to be wrapped in a bstr.

Parameters
[in]pCtxThe context to add to.

All added encoded items between this call and a call to QCBOREncode_CloseBstrWrap() will be wrapped in a bstr. They will appear in the final output as a byte string. That byte string will contain encoded CBOR.

The typical use case is for encoded CBOR that is to be cryptographically hashed, as part of a COSE (RFC 8152) implementation. This avoids having to encode the items first in one buffer (e.g., the COSE payload) and then add that buffer as a bstr to another encoding (e.g. the COSE to-be-signed bytes, the Sig_structure) potentially saving a lot of memory.

When constructing cryptographically signed CBOR objects, maps or arrays, they typically are encoded normally and then wrapped as a byte string. The COSE standard for example does this. The wrapping is simply treating the encoded CBOR map as a byte string.

The stated purpose of this wrapping is to prevent code relaying the signed data but not verifying it from tampering with the signed data thus making the signature unverifiable. It is also quite beneficial for the signature verification code. Standard CBOR parsers usually do not give access to partially parsed CBOR as would be need to check the signature of some CBOR. With this wrapping, standard CBOR parsers can be used to get to all the data needed for a signature verification.

Definition at line 2551 of file qcbor.h.

static void QCBOREncode_CloseArray ( QCBOREncodeContext pCtx)
static

Close an open array.

Parameters
[in]pCtxThe context to add to.

The closes an array opened by QCBOREncode_OpenArray(). It reduces nesting level by one. All arrays (and maps) must be closed before calling QCBOREncode_Finish().

When an error occurs as a result of this call, the encoder records the error and enters the error state. The error will be returned when QCBOREncode_Finish() is called.

If this has been called more times than QCBOREncode_OpenArray(), then QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish() is called.

If this is called and it is not an array that is currently open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish() is called.

Definition at line 2522 of file qcbor.h.

static void QCBOREncode_CloseBstrWrap ( QCBOREncodeContext pCtx,
UsefulBufC pWrappedCBOR 
)
static

Close a wrapping bstr.

Parameters
[in]pCtxThe context to add to.
[out]pWrappedCBORUsefulBufC containing wrapped bytes

The closes a wrapping bstr opened by QCBOREncode_BstrWrap(). It reduces nesting level by one.

A pointer and length of the enclosed encoded CBOR is returned in pWrappedCBOR if it is not NULL. The main purpose of this is so this data can be hashed (e.g., with SHA-256) as part of a COSE (RFC 8152) implementation. WARNING, this pointer and length should be used right away before any other calls to QCBOREncode_xxxx() as they will move data around and the pointer and length will no longer be to the correct encoded CBOR.

When an error occurs as a result of this call, the encoder records the error and enters the error state. The error will be returned when QCBOREncode_Finish() is called.

If this has been called more times then QCBOREncode_BstrWrap(), then QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish() is called.

If this is called and it is not a wrapping bstr that is currently open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish() is called.

Definition at line 2568 of file qcbor.h.

static void QCBOREncode_CloseMap ( QCBOREncodeContext pCtx)
static

Close an open map.

Parameters
[in]pCtxThe context to add to.

The closes a map opened by QCBOREncode_OpenMap(). It reduces nesting level by one.

When an error occurs as a result of this call, the encoder records the error and enters the error state. The error will be returned when QCBOREncode_Finish() is called.

If this has been called more times than QCBOREncode_OpenMap(), then QCBOR_ERR_TOO_MANY_CLOSES will be returned when QCBOREncode_Finish() is called.

If this is called and it is not a map that is currently open, QCBOR_ERR_CLOSE_MISMATCH will be returned when QCBOREncode_Finish() is called.

Definition at line 2545 of file qcbor.h.

void QCBOREncode_CloseMapOrArray ( QCBOREncodeContext pCtx,
uint8_t  uMajorType,
UsefulBufC pWrappedCBOR 
)

Semi-private method to close a map, array or bstr wrapped CBOR.

Parameters
[in]pCtxThe context to add to.
[in]uMajorTypeThe major CBOR type to close
[out]pWrappedCBORUsefulBufC containing wrapped bytes

Call QCBOREncode_CloseArray(), QCBOREncode_CloseMap() or QCBOREncode_CloseBstrWrap() instead of this.

QCBORError QCBOREncode_Finish ( QCBOREncodeContext pCtx,
UsefulBufC pEncodedCBOR 
)

Get the encoded result.

Parameters
[in]pCtxThe context to finish encoding with.
[out]pEncodedCBORPointer and length of encoded CBOR.
Returns
One of the CBOR error codes.

If this returns success QCBOR_SUCCESS the encoding was a success and the return length is correct and complete.

If no buffer was passed to QCBOR_Init(), then only the length and number of items was computed. The length is in pEncodedCBOR->Bytes.len. pEncodedCBOR->Bytes.ptr is NULL.

If a buffer was passed, then pEncodedCBOR->Bytes.ptr is the same as the buffer passed to QCBOR_Init() and contains the encoded CBOR and the length is filled in.

If an error is returned, the buffer may have partially encoded incorrect CBOR in it and it should not be used. Likewise, the length may be incorrect and should not be used.

Note that the error could have occurred in one of the many QCBOR_AddXXX calls long before QCBOREncode_Finish() was called. This error handling approach reduces the CBOR implementation size, but makes debugging a problem a little more difficult.

QCBORError QCBOREncode_FinishGetSize ( QCBOREncodeContext pCtx,
size_t *  uEncodedLen 
)

Get the encoded CBOR and error status.

Parameters
[in]pCtxThe context to finish encoding with.
[out]uEncodedLenThe length of the encoded or potentially encoded CBOR in bytes.
Returns
One of the CBOR error codes.

If this returns success QCBOR_SUCCESS the encoding was a success and the return length is correct and complete.

If no buffer was passed to QCBOR_Init(), then only the length was computed. If a buffer was passed, then the encoded CBOR is in the buffer.

If an error is returned, the buffer may have partially encoded incorrect CBOR in it and it should not be used. Likewise, the length may be incorrect and should not be used.

Note that the error could have occurred in one of the many QCBOR_AddXXX calls long before QCBOREncode_Finish() was called. This error handling reduces the CBOR implementation size, but makes debugging harder.

void QCBOREncode_Init ( QCBOREncodeContext pCtx,
UsefulBuf  Storage 
)

Initialize the the encoder to prepare to encode some CBOR.

Parameters
[in,out]pCtxThe encoder context to initialize.
[in]StorageThe buffer into which this encoded result will be placed.

Call this once at the start of an encoding of a CBOR structure. Then call the various QCBOREncode_AddXXX() functions to add the data items. Then call QCBOREncode_Finish().

The maximum output buffer is UINT32_MAX (4GB). This is not a practical limit in any way and reduces the memory needed by the implementation. The error QCBOR_ERR_BUFFER_TOO_LARGE will be returned by QCBOR_Finish() if a larger buffer length is passed in.

If this is called with pBuf as NULL and uBufLen a large value like UINT32_MAX, all the QCBOREncode_AddXXXX() functions and QCBORE_Encode_Finish() can still be called. No data will be encoded, but the length of what would be encoded will be calculated. The length of the encoded structure will be handed back in the call to QCBOREncode_Finish(). You can then allocate a buffer of that size and call all the encoding again, this time to fill in the buffer.

A QCBORContext can be reused over and over as long as QCBOREncode_Init() is called.

static void QCBOREncode_OpenArray ( QCBOREncodeContext pCtx)
static

Indicates that the next items added are in an array.

Parameters
[in]pCtxThe encoding context to open the array in.

Arrays are the basic CBOR aggregate or structure type. Call this function to start or open an array. Then call the various AddXXX functions to add the items that go into the array. Then call QCBOREncode_CloseArray() when all items have been added. The data items in the array can be of any type and can be of mixed types.

Nesting of arrays and maps is allowed and supported just by calling QCBOREncode_OpenArray() again before calling CloseArray. While CBOR has no limit on nesting, this implementation does in order to keep it smaller and simpler. The limit is QCBOR_MAX_ARRAY_NESTING. This is the max number of times this can be called without calling QCBOREncode_CloseArray(). QCBOREncode_Finish() will return QCBOR_ERR_ARRAY_NESTING_TOO_DEEP when it is called as this function just sets an error state and returns no value when this occurs.

If you try to add more than QCBOR_MAX_ITEMS_IN_ARRAY items to a single array or map, QCBOR_ERR_ARRAY_TOO_LONG will be returned when QCBOREncode_Finish() is called.

An array itself must have a label if it is being added to a map. Note that array elements do not have labels (but map elements do).

An array itself may be tagged.

Definition at line 2505 of file qcbor.h.

static void QCBOREncode_OpenMap ( QCBOREncodeContext pCtx)
static

Indicates that the next items added are in a map.

Parameters
[in]pCtxThe context to add to.

See QCBOREncode_OpenArray() for more information, particularly error handling.

CBOR maps are an aggregate type where each item in the map consists of a label and a value. They are similar to JSON objects.

The value can be any CBOR type including another map.

The label can also be any CBOR type, but in practice they are typically, integers as this gives the most compact output. They might also be text strings which gives readability and translation to JSON.

Every QCBOREncode_AddXXX() call has once version that is "InMap" for adding items to maps with string labels and on that is "InMapN" that is for adding with integer labels.

RFC 7049 uses the term "key" instead of "label".

If you wish to use map labels that are neither integer labels or text strings, then just call the QCBOREncode_AddXXX() function explicitly to add the label. Then call it again to add the value.

See the RFC7049 for a lot more information on creating maps.

Definition at line 2528 of file qcbor.h.

void QCBOREncode_OpenMapOrArray ( QCBOREncodeContext pCtx,
uint8_t  uMajorType 
)

Semi-private method to open a map, array or bstr wrapped CBOR.

Parameters
[in]pCtxThe context to add to.
[in]uMajorTypeThe major CBOR type to close

Call QCBOREncode_OpenArray(), QCBOREncode_OpenMap() or QCBOREncode_BstrWrap() instead of this.

Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.