File libcbor.1 of Package libcbor.23968

.\" Man page generated from reStructuredText.
.
.TH "LIBCBOR" "1" "Jun 25, 2021" "0.5" "libcbor"
.SH NAME
libcbor \- libcbor Documentation
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.sp
Documentation for version 0.5.0, updated on Jun 25, 2021\&.
.SH OVERVIEW
.sp
\fIlibcbor\fP is a C library for parsing and generating \fI\%CBOR\fP, the general\-purpose schema\-less binary data format.
.INDENT 0.0
.TP
.B Main features
.INDENT 7.0
.IP \(bu 2
Complete RFC conformance [1]
.IP \(bu 2
Robust C99 implementation
.IP \(bu 2
Layered architecture offers both control and convenience
.IP \(bu 2
Flexible memory management
.IP \(bu 2
No shared global state \- threading friendly [2]
.IP \(bu 2
Proper handling of UTF\-8
.IP \(bu 2
Full support for streams & incremental processing
.IP \(bu 2
Extensive documentation and test suite
.IP \(bu 2
No runtime dependencies, small footprint
.UNINDENT
.UNINDENT
.IP [1] 5
See rfc_conformance
.IP [2] 5
With the exception of custom memory allocators (see api/item_reference_counting)
.SH CONTENTS
.SS Getting started
.sp
Pre\-built Linux packages are distributed from \fI\%the libcbor website\fP\&.
.sp
OS X users can use \fI\%Homebrew\fP:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
brew tap pjk/libcbor
brew install libcbor
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
For other platforms, you will need to compile it from source.
.SS Building & installing libcbor
.INDENT 0.0
.TP
.B Prerequisites:
.INDENT 7.0
.IP \(bu 2
C99 compiler
.IP \(bu 2
\fI\%CMake\fP 2.8 or newer (might also be called \fBcmakesetup\fP, \fBcmake\-gui\fP or \fBccmake\fP depending on the installed version and system)
.IP \(bu 2
C build system CMake can target (make, Apple Xcode, MinGW, ...)
.UNINDENT
.UNINDENT
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
As of May 2015, not even the 2015 release candidate of Visual Studio supports C99. While CMake will be happy to generate a VS solution that you can play with, libcbor currently cannot be compiled using the MSVC toolchain. \fI\%ICC\fP, GCC under \fI\%Cygwin\fP, and \fI\%MinGW\(aqs\fP GCC will all work. The MinGW build process is described below.
.UNINDENT
.UNINDENT
.sp
\fBConfiguration options\fP
.sp
A handful of configuration flags can be passed to \fIcmake\fP\&. The following table lists libcbor compile\-time directives and several important generic flags.
.TS
center;
|l|l|l|l|.
_
T{
Option
T}	T{
Meaning
T}	T{
Default
T}	T{
Possible values
T}
_
T{
\fBCMAKE_C_COMPILER\fP
T}	T{
C compiler to use
T}	T{
\fBcc\fP
T}	T{
\fBgcc\fP, \fBclang\fP, \fBclang\-3.5\fP, ...
T}
_
T{
\fBCMAKE_INSTALL_PREFIX\fP
T}	T{
Installation prefix
T}	T{
System\-dependent
T}	T{
\fB/usr/local/lib\fP, ...
T}
_
T{
\fBHUGE_FUZZ\fP
T}	T{
Fuzz test with 8GB of data
T}	T{
\fBOFF\fP
T}	T{
\fBON\fP, \fBOFF\fP
T}
_
T{
\fBSANE_MALLOC\fP
T}	T{
Assume \fBmalloc\fP will refuse unreasonable allocations
T}	T{
\fBOFF\fP
T}	T{
\fBON\fP, \fBOFF\fP
T}
_
T{
\fBCOVERAGE\fP
T}	T{
Generate test coverage instrumentation
T}	T{
\fBOFF\fP
T}	T{
\fBON\fP, \fBOFF\fP
T}
_
T{
\fBWITH_TESTS\fP
T}	T{
Build unit tests (see development)
T}	T{
\fBOFF\fP
T}	T{
\fBON\fP, \fBOFF\fP
T}
_
.TE
.sp
The following configuration options will also be defined as macros[#]_ in \fB<cbor/common.h>\fP and can therefore be used in client code:
.TS
center;
|l|l|l|l|.
_
T{
Option
T}	T{
Meaning
T}	T{
Default
T}	T{
Possible values
T}
_
T{
\fBCBOR_CUSTOM_ALLOC\fP
T}	T{
Enable custom allocator support
T}	T{
\fBOFF\fP
T}	T{
\fBON\fP, \fBOFF\fP
T}
_
T{
\fBCBOR_PRETTY_PRINTER\fP
T}	T{
Include a pretty\-printing routine
T}	T{
\fBON\fP
T}	T{
\fBON\fP, \fBOFF\fP
T}
_
T{
\fBCBOR_BUFFER_GROWTH\fP
T}	T{
Factor for buffer growth & shrinking
T}	T{
\fB2\fP
T}	T{
Decimals > 1
T}
_
.TE
.IP [1] 5
\fBON\fP & \fBOFF\fP will be translated to \fB1\fP and \fB0\fP using \fI\%cmakedefine\fP\&.
.sp
If you want to pass other custom configuration options, please refer to \fI\%http://www.cmake.org/Wiki/CMake_Useful_Variables\fP\&.
.sp
\fBBuilding using make\fP
.sp
CMake will generate a Makefile and other configuration files for the build. As a rule of thumb, you should configure the
build \fIoutside of the source tree\fP in order to keep different configurations isolated. If you are unsure where to
execute the build, just use a temporary directory:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
cd $(mktemp \-d /tmp/cbor_build.XXXX)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Now, assuming you are in the directory where you want to build, execute the following to configure the build and run make
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
cmake \-DCMAKE_BUILD_TYPE=Release path_to_libcbor_dir
make cbor cbor_shared
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Both the shared (\fBlibcbor.so\fP) and the static (\fBlibcbor.a\fP) libraries should now be in the \fBsrc\fP subdirectory.
.sp
In order to install the libcbor headers and libraries, the usual
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
make install
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
is what your\(aqre looking for. Root permissions are required on most systems when using the default installation prefix.
.sp
\fBPortability\fP
.sp
libcbor is highly portable and works on both little\- and big\-endian systems regardless of the operating system. After building
on an exotic platform, you might wish to verify the result by running the test suite\&. If you encounter any problems, please
report them to the \fI\%issue tracker\fP\&.
.sp
libcbor is known to successfully work on ARM Android devices. Cross\-compilation is possible with \fBarm\-linux\-gnueabi\-gcc\fP\&.
.SS Linking with libcbor
.sp
If you include and linker paths include the directories to which libcbor has been installed, compiling programs that uses libcbor requires
no extra considerations.
.sp
You can verify that everything has been set up properly by creating a file with the following contents
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
#include <cbor.h>
#include <stdio.h>

int main(int argc, char * argv[])
{
    printf("Hello from libcbor %s\en", CBOR_VERSION);
}
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
and compiling it
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
cc hello_cbor.c \-lcbor \-o hello_cbor
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
libcbor also comes with \fI\%pkg\-config\fP support. If you install libcbor with a custom prefix, you can use pkg\-config to resolve the headers and objects:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
cc $(pkg\-config \-\-cflags libcbor) hello_cbor.c $(pkg\-config \-\-libs libcbor) \-o hello_cbor
.ft P
.fi
.UNINDENT
.UNINDENT
.SS MinGW build instructions
.INDENT 0.0
.TP
.B Prerequisites:
.INDENT 7.0
.IP \(bu 2
MinGW
.IP \(bu 2
CMake GUI
.UNINDENT
.UNINDENT
.sp
First of all, create a folder that will be used for the output. For this demonstration, we will use \fBcbor_out\fP\&. Start CMake and select the source path and the destination folder.
[image]
.sp
Then hit the \(aqConfigure\(aq button. You will be prompted to select the build system:
[image]
.sp
Choose MinGW and confirm.
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
If you select Visual Studio at this point, a MSVC project will be generated for you. This is useful if you just want to browse through the source code.
.UNINDENT
.UNINDENT
.sp
You can then adjust the build options. The defaults will work just fine. Hit \(aqGenerate\(aq when you are done.
[image]
.sp
You can then adjust the build options. The defaults will work just fine. Hit \(aqGenerate\(aq when you are done.
.sp
Open the shell, navigate to the output directory, and run \fBmingw32\-make cbor cbor_shared\fP\&.
[image]
.sp
\fIlibcbor\fP will be built and your \fB\&.dll\fP should be ready at this point
[image]
.sp
Feel free to also try building and running some of the examples, e.g. \fBmingw32\-make sort\fP
[image]
.SS Troubleshooting
.sp
\fBcbor.h not found\fP: The headers directory is probably not in your include path. First, verify the installation
location by checking the installation log. If you used make, it will look something like
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
\&...
\-\- Installing: /usr/local/include/cbor
\-\- Installing: /usr/local/include/cbor/callbacks.h
\-\- Installing: /usr/local/include/cbor/encoding.h
\&...
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Make sure that \fBCMAKE_INSTALL_PREFIX\fP (if you provided it) was correct. Including the path path during compilation should suffice, e.g.:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
cc \-I/usr/local/include hello_cbor.c \-lcbor \-o hello_cbor
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
\fBcannot find \-lcbor during linking\fP: Most likely the same problem as before. Include the installation directory in the
linker shared path using \fB\-R\fP, e.g.:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
cc \-Wl,\-rpath,/usr/local/lib \-lcbor \-o hello_cbor
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
\fBshared library missing during execution\fP: Verify the linkage using \fBldd\fP, \fBotool\fP, or similar and adjust the compilation directives accordingly:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
⇒  ldd hello_cbor
    linux\-vdso.so.1 =>  (0x00007ffe85585000)
    libcbor.so => /usr/local/lib/libcbor.so (0x00007f9af69da000)
    libc.so.6 => /lib/x86_64\-linux\-gnu/libc.so.6 (0x00007f9af65eb000)
    /lib64/ld\-linux\-x86\-64.so.2 (0x00007f9af6be9000)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
\fBcompilation failed\fP: If your compiler supports C99 yet the compilation has failed, please report the issue to the \fI\%issue tracker\fP\&.
.SS Usage & preliminaries
.SS Version information
.sp
libcbor exports its version using three self\-explanatory macros:
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
\fBCBOR_MAJOR_VERSION\fP
.IP \(bu 2
\fBCBOR_MINOR_VERSION\fP
.IP \(bu 2
\fBCBOR_PATCH_VERSION\fP
.UNINDENT
.UNINDENT
.UNINDENT
.sp
The \fBCBOR_VERSION\fP is a string concatenating these three identifiers into one (e.g. \fB0.2.0\fP).
.sp
In order to simplify version comparisons, the version is also exported as
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
#define CBOR_HEX_VERSION ((CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Since macros are difficult to work with through FFIs, the same information is also available through three \fBuint8_t\fP constants,
namely
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
\fBcbor_major_version\fP
.IP \(bu 2
\fBcbor_minor_version\fP
.IP \(bu 2
\fBcbor_patch_version\fP
.UNINDENT
.UNINDENT
.UNINDENT
.SS Headers to include
.sp
The \fBcbor.h\fP header includes all the symbols. If, for any reason, you don\(aqt want to include all the exported symbols,
feel free to use just some of the \fBcbor/*.h\fP headers:
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
\fBcbor/arrays.h\fP \- api/type_4
.IP \(bu 2
\fBcbor/bytestrings.h\fP \- api/type_2
.IP \(bu 2
\fBcbor/callbacks.h\fP \- Callbacks used for streaming/decoding
.IP \(bu 2
\fBcbor/common.h\fP \- Common utilities \- always transitively included
.IP \(bu 2
\fBcbor/data.h\fP \- Data types definitions \- always transitively included
.IP \(bu 2
\fBcbor/encoding.h\fP \- Streaming encoders for streaming/encoding
.IP \(bu 2
\fBcbor/floats_ctrls.h\fP \- api/type_7
.IP \(bu 2
\fBcbor/ints.h\fP \- api/type_0_1
.IP \(bu 2
\fBcbor/maps.h\fP \- api/type_5
.IP \(bu 2
\fBcbor/serialization.h\fP \- High level serialization such as \fBcbor_serialize()\fP
.IP \(bu 2
\fBcbor/streaming.h\fP \- Home of \fBcbor_stream_decode()\fP
.IP \(bu 2
\fBcbor/strings.h\fP \- api/type_3
.IP \(bu 2
\fBcbor/tags.h\fP \- api/type_6
.UNINDENT
.UNINDENT
.UNINDENT
.SS Using libcbor
.sp
If you want to get more familiar with CBOR, we recommend the \fI\%cbor.io\fP website. Once you get the grasp
of what is it CBOR does, the examples (located in the \fBexamples\fP directory) should give you a good feel of the API. The
API documentation should then provide with all the information you may need.
.sp
\fBCreating and serializing items\fP
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
#include "cbor.h"
#include <stdio.h>

int main(int argc, char * argv[])
{
    /* Preallocate the map structure */
    cbor_item_t * root = cbor_new_definite_map(2);
    /* Add the content */
    cbor_map_add(root, (struct cbor_pair) {
        .key = cbor_move(cbor_build_string("Is CBOR awesome?")),
        .value = cbor_move(cbor_build_bool(true))
    });
    cbor_map_add(root, (struct cbor_pair) {
        .key = cbor_move(cbor_build_uint8(42)),
        .value = cbor_move(cbor_build_string("Is the answer"))
    });
    /* Output: \(galength\(ga bytes of data in the \(gabuffer\(ga */
    unsigned char * buffer;
    size_t buffer_size, length = cbor_serialize_alloc(root, &buffer, &buffer_size);

    fwrite(buffer, 1, length, stdout);
    free(buffer);

    fflush(stdout);
    cbor_decref(&root);
}
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
\fBReading serialized data\fP
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
#include "cbor.h"
#include <stdio.h>

/*
 * Reads data from a file. Example usage:
 * $ ./examples/readfile examples/data/nested_array.cbor
 */

int main(int argc, char * argv[])
{
    FILE * f = fopen(argv[1], "rb");
    fseek(f, 0, SEEK_END);
    size_t length = (size_t)ftell(f);
    fseek(f, 0, SEEK_SET);
    unsigned char * buffer = malloc(length);
    fread(buffer, length, 1, f);

    /* Assuming \(gabuffer\(ga contains \(gainfo.st_size\(ga bytes of input data */
    struct cbor_load_result result;
    cbor_item_t * item = cbor_load(buffer, length, &result);
    /* Pretty\-print the result */
    cbor_describe(item, stdout);
    fflush(stdout);
    /* Deallocate the result */
    cbor_decref(&item);

    fclose(f);
}
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
\fBUsing the streaming parser\fP
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
#include "cbor.h"
#include <stdio.h>
#include <string.h>

/*
 * Illustrates how one might skim through a map (which is assumed to have
 * string keys and values only), looking for the value of a specific key
 *
 * Use the examples/data/map.cbor input to test this.
 */

const char * key = "a secret key";
bool key_found = false;

void find_string(void * _ctx, cbor_data buffer, size_t len)
{
    if (key_found) {
        printf("Found the value: %*s\en", (int) len, buffer);
        key_found = false;
    } else if (len == strlen(key)) {
        key_found = (memcmp(key, buffer, len) == 0);
    }
}

int main(int argc, char * argv[])
{
    FILE * f = fopen(argv[1], "rb");
    fseek(f, 0, SEEK_END);
    size_t length = (size_t)ftell(f);
    fseek(f, 0, SEEK_SET);
    unsigned char * buffer = malloc(length);
    fread(buffer, length, 1, f);

    struct cbor_callbacks callbacks = cbor_empty_callbacks;
    struct cbor_decoder_result decode_result;
    size_t bytes_read = 0;
    callbacks.string = find_string;
    while (bytes_read < length) {
        decode_result = cbor_stream_decode(buffer + bytes_read,
                                           length \- bytes_read,
                                           &callbacks, NULL);
        bytes_read += decode_result.read;
    }

    fclose(f);
}
.ft P
.fi
.UNINDENT
.UNINDENT
.SS API
.sp
The data API is centered around \fBcbor_item_t\fP, a generic handle for any CBOR item. There are functions to
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
create items,
.IP \(bu 2
set items\(aq data,
.IP \(bu 2
parse serialized data into items,
.IP \(bu 2
manage, move, and links item together.
.UNINDENT
.UNINDENT
.UNINDENT
.sp
The single most important thing to keep in mind is: \fBcbor_item_t\fP \fBis an opaque type and should only be manipulated using the appropriate functions!\fP Think of it as an object.
.sp
The \fIlibcbor\fP API closely follows the semantics outlined by \fI\%CBOR standard\fP\&. This part of the documentation provides a short overview of the CBOR constructs, as well as a general introduction to the \fIlibcbor\fP API. Remaining reference can be found in the following files structured by data types.
.sp
The API is designed to allow both very tight control & flexibility and general convenience with sane defaults. [1] For example, client with very specific requirements (constrained environment, custom application protocol built on top of CBOR, etc.) may choose to take full control (and responsibility) of memory and data structures management by interacting directly with the decoder. Other clients might want to take control of specific aspects (streamed collections, hash maps storage), but leave other responsibilities to \fIlibcbor\fP\&. More general clients might prefer to be abstracted away from all aforementioned details and only be presented complete data structures.
.INDENT 0.0
.TP
.B \fIlibcbor\fP provides
.INDENT 7.0
.IP \(bu 2
stateless encoders and decoders
.IP \(bu 2
encoding and decoding \fIdrivers\fP, routines that coordinate encoding and decoding of complex structures
.IP \(bu 2
data structures to represent and transform CBOR structures
.IP \(bu 2
routines for building and manipulating these structures
.IP \(bu 2
utilities for inspection and debugging
.UNINDENT
.UNINDENT
.SS Types of items
.sp
Every \fBcbor_item_t\fP has a \fI\%cbor_type\fP associated with it \- these constants correspond to the types specified by the \fI\%CBOR standard\fP:
.INDENT 0.0
.TP
.B enum cbor_type 
Specifies the Major type of cbor_item_t\&. 
.sp
\fIValues:\fP
.INDENT 7.0
.TP
.B CBOR_TYPE_UINT 
0 \- positive integers 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_TYPE_NEGINT 
1 \- negative integers 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_TYPE_BYTESTRING 
2 \- byte strings 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_TYPE_STRING 
3 \- strings 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_TYPE_ARRAY 
4 \- arrays 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_TYPE_MAP 
5 \- maps 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_TYPE_TAG 
6 \- tags 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_TYPE_FLOAT_CTRL 
7 \- decimals and special values (true, false, nil, ...) 
.UNINDENT
.UNINDENT
.sp
To find out the type of an item, one can use
.INDENT 0.0
.TP
.B cbor_type cbor_typeof(const cbor_item_t *\fIitem\fP) 
Get the type of the item. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
The type 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: 
.UNINDENT
.UNINDENT

.UNINDENT
.sp
Please note the distinction between functions like \fI\%cbor_isa_uint()\fP and \fI\%cbor_is_int()\fP\&. The following functions work solely with the major type value.
.SS Binary queries
.sp
Alternatively, there are functions to query each particular type.
.sp
\fBWARNING:\fP
.INDENT 0.0
.INDENT 3.5
Passing an invalid \fBcbor_item_t\fP reference to any of these functions results in undefined behavior.
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_isa_uint(const cbor_item_t *\fIitem\fP) 
Does the item have the appropriate major type? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item an CBOR_TYPE_UINT? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_isa_negint(const cbor_item_t *\fIitem\fP) 
Does the item have the appropriate major type? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item a CBOR_TYPE_NEGINT? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_isa_bytestring(const cbor_item_t *\fIitem\fP) 
Does the item have the appropriate major type? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item a CBOR_TYPE_BYTESTRING? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_isa_string(const cbor_item_t *\fIitem\fP) 
Does the item have the appropriate major type? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item a CBOR_TYPE_STRING? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_isa_array(const cbor_item_t *\fIitem\fP) 
Does the item have the appropriate major type? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item an CBOR_TYPE_ARRAY? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_isa_map(const cbor_item_t *\fIitem\fP) 
Does the item have the appropriate major type? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item a CBOR_TYPE_MAP? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_isa_tag(const cbor_item_t *\fIitem\fP) 
Does the item have the appropriate major type? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item a CBOR_TYPE_TAG? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_isa_float_ctrl(const cbor_item_t *\fIitem\fP) 
Does the item have the appropriate major type? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item a CBOR_TYPE_FLOAT_CTRL? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Logical queries
.sp
These functions provide information about the item type from a more high\-level perspective
.INDENT 0.0
.TP
.B bool cbor_is_int(const cbor_item_t *\fIitem\fP) 
Is the item an integer, either positive or negative? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item an integer, either positive or negative? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_is_float(const cbor_item_t *\fIitem\fP) 
Is the item an a floating point number? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item a floating point number? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_is_bool(const cbor_item_t *\fIitem\fP) 
Is the item an a boolean? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the item a boolean? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_is_null(const cbor_item_t *\fIitem\fP) 
Does this item represent \fBnull\fP 
.sp
.sp
\fBWARNING:\fP
.INDENT 7.0
.INDENT 3.5
This is in no way related to the value of the pointer. Passing a null pointer will most likely result in a crash.
.UNINDENT
.UNINDENT
 .INDENT 7.0
.TP
\fBReturn\fP
Is the item (CBOR logical) null? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_is_undef(const cbor_item_t *\fIitem\fP) 
Does this item represent \fBundefined\fP 
.sp
.sp
\fBWARNING:\fP
.INDENT 7.0
.INDENT 3.5
Care must be taken to distinguish nulls and undefined values in C.
.UNINDENT
.UNINDENT
 .INDENT 7.0
.TP
\fBReturn\fP
Is the item (CBOR logical) undefined? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Memory management and reference counting
.sp
Due to the nature of its domain \fIlibcbor\fP will need to work with heap memory. The stateless decoder and encoder don\(aqt allocate any memory.
.sp
If you have specific requirements, you should consider rolling your own driver for the stateless API.
.SS Using custom allocator
.sp
\fIlibcbor\fP gives you with the ability to provide your own implementations of \fBmalloc\fP, \fBrealloc\fP, and \fBfree\fP\&. This can be useful if you are using a custom allocator throughout your application, or if you want to implement custom policies (e.g. tighter restrictions on the amount of allocated memory).
.sp
In order to use this feature, \fIlibcbor\fP has to be compiled with the appropriate flags\&. You can verify the configuration using the \fBCBOR_CUSTOM_ALLOC\fP macro. A simple usage might be as follows:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
#if CBOR_CUSTOM_ALLOC
    cbor_set_allocs(malloc, realloc, free);
#else
   #error "libcbor built with support for custom allocation is required"
#endif
.ft P
.fi
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
.B void cbor_set_allocs(_cbor_malloc_t \fIcustom_malloc\fP, _cbor_realloc_t \fIcustom_realloc\fP, _cbor_free_t \fIcustom_free\fP) 
Sets the memory management routines to use. 
.sp
Only available when CBOR_CUSTOM_ALLOC is truthy
.sp
.sp
\fBWARNING:\fP
.INDENT 7.0
.INDENT 3.5
This function modifies the global state and should therefore be used accordingly. Changing the memory handlers while allocated items exist will result in a \fBfree\fP/\fBmalloc\fP mismatch. This function is not thread safe with respect to both itself and all the other \fIlibcbor\fP functions that work with the heap.
.UNINDENT
.UNINDENT
.sp
\fBNOTE:\fP
.INDENT 7.0
.INDENT 3.5
\fIrealloc\fP implementation must correctly support \fINULL\fP reallocation
.UNINDENT
.UNINDENT

.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBcustom_malloc\fP: malloc implementation 
.IP \(bu 2
\fBcustom_realloc\fP: realloc implementation 
.IP \(bu 2
\fBcustom_free\fP: free implementation 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Reference counting
.sp
As CBOR items may require complex cleanups at the end of their lifetime, there is a reference counting mechanism in place. This also enables very simple GC when integrating \fIlibcbor\fP into managed environment. Every item starts its life (by either explicit creation, or as a result of parsing) with reference count set to 1. When the refcount reaches zero, it will be destroyed.
.sp
Items containing nested items will be destroyed recursively \- refcount of every nested item will be decreased by one.
.sp
The destruction is synchronous and renders any pointers to items with refcount zero invalid immediately after calling the \fI\%cbor_decref()\fP\&.
.INDENT 0.0
.TP
.B cbor_item_t *cbor_incref(cbor_item_t *\fIitem\fP) 
Increases the reference count by one. 
.sp
No dependent items are affected.
.sp
.INDENT 7.0
.TP
\fBReturn\fP
the input reference 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[incref]\fP: item the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B void cbor_decref(cbor_item_t **\fIitem\fP) 
Decreases the reference count by one, deallocating the item if needed. 
.sp
In case the item is deallocated, the reference count of any dependent items is adjusted accordingly in a recursive manner.
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[take]\fP: the item. Set to \fBNULL\fP if deallocated 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B void cbor_intermediate_decref(cbor_item_t *\fIitem\fP) 
Decreases the reference count by one, deallocating the item if needed. 
.sp
Convenience wrapper for cbor_decref when its set\-to\-null behavior is not needed
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[take]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_refcount(const cbor_item_t *\fIitem\fP) 
Get the reference count. 
.sp
.sp
\fBWARNING:\fP
.INDENT 7.0
.INDENT 3.5
This does \fInot\fP account for transitive references.
.UNINDENT
.UNINDENT

.sp
.INDENT 7.0
.TP
\fBReturn\fP
the reference count 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_move(cbor_item_t *\fIitem\fP) 
Provides CPP\-like move construct. 
.sp
Decreases the reference count by one, but does not deallocate the item even if its refcount reaches zero. This is useful for passing intermediate values to functions that increase reference count. Should only be used with functions that \fBincref\fP their arguments.
.sp
.sp
\fBWARNING:\fP
.INDENT 7.0
.INDENT 3.5
If the item is moved without correctly increasing the reference count afterwards, the memory will be leaked.
.UNINDENT
.UNINDENT

.sp
.INDENT 7.0
.TP
\fBReturn\fP
the item with reference count decreased by one 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[take]\fP: the item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_copy(cbor_item_t *\fIitem\fP) 
Deep copy of an item. 
.sp
All the reference counts in the new structure are set to one.
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP CBOR deep copy 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: item to copy 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Decoding
.sp
The following diagram illustrates the relationship among different parts of libcbor from the decoding standpoint.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
┌──────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                              │
│                                      Client application                                      │
│                                                                                              │
│                                                 ┌────────────────────────────────────────────┘
│                                                 │                     ↕
│                                                 │ ┌──────────────────────────────────────────┐
│                                                 │ │                                          │
│                                                 │ │          Manipulation routines           │
│                                                 │ │                                          │
│           ┌─────────────────────────────────────┘ └──────────────────────────────────────────┘
│           │     ↑    ↑                  ↑                              ↑
│           │     │    │    ┌─────────────╫──────────┬───────────────────┴─┐
│           │     │   CDS   │             ║          │                     │
│           │     │    │   PDS            ║         PDS                   PDS
│           │     ↓    ↓    ↓             ↓          ↓                     ↓
│           │ ┌─────────────────┐   ┌────────────────────┐   ┌────────────────────────────┐
│           │ │                 │   │                    │   │                            │
│           │ │  Custom driver  │ ↔ │  Streaming driver  │ ↔ │       Default driver       │ ↔ CD
│           │ │                 │   │                    │   │                            │
└───────────┘ └─────────────────┘   └────────────────────┘   └────────────────────────────┘
      ↕                ↕                        ↕                           ↕
┌──────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                                                              │
│                            Stateless event─driven decoder                                    │
│                                                                                              │
└──────────────────────────────────────────────────────────────────────────────────────────────┘

              (PSD = Provided Data Structures, CDS = Custom Data Structures)
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
This section will deal with the API that is labeled as the "Default driver" in the diagram. That is, routines that
decode complete libcbor data items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_load(cbor_data \fIsource\fP, size_t \fIsource_size\fP, struct cbor_load_result *\fIresult\fP) 
Loads data item from a buffer. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP CBOR item or \fBNULL\fP on failure. In that case, \fBresult\fP contains location and description of the error. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBsource\fP: The buffer 
.IP \(bu 2
\fBsource_size\fP: 
.IP \(bu 2
\fBresult[out]\fP: Result indicator. CBOR_ERR_NONE on success 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Associated data structures
.INDENT 0.0
.TP
.B enum cbor_error_code 
Possible decoding errors. 
.sp
\fIValues:\fP
.INDENT 7.0
.TP
.B CBOR_ERR_NONE 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_ERR_NOTENOUGHDATA 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_ERR_NODATA 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_ERR_MALFORMATED 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_ERR_MEMERROR 
Memory error \- item allocation failed. 
.sp
Is it too big for your allocator? 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_ERR_SYNTAXERROR 
Stack parsing algorithm failed. 
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
.B struct cbor_load_result 
High\-level decoding result. 
Public Members.INDENT 7.0
.TP
.B struct cbor_error error 
Error indicator. 
.UNINDENT
.INDENT 7.0
.TP
.B size_t read 
Number of bytes read. 
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
.B struct cbor_error 
High\-level decoding error. 
Public Members.INDENT 7.0
.TP
.B size_t position 
Aproximate position. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_error_code code 
Description. 
.UNINDENT
.UNINDENT
.SS Encoding
.sp
The easiest way to encode data items is using the \fI\%cbor_serialize()\fP or \fI\%cbor_serialize_alloc()\fP functions:
.INDENT 0.0
.TP
.B size_t cbor_serialize(const cbor_item_t *\fIitem\fP, cbor_mutable_data \fIbuffer\fP, size_t \fIbuffer_size\fP) 
Serialize the given item. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Length of the result. 0 on failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A data item 
.IP \(bu 2
\fBbuffer\fP: Buffer to serialize to 
.IP \(bu 2
\fBbuffer_size\fP: Size of the \fBbuffer\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_serialize_alloc(const cbor_item_t *\fIitem\fP, cbor_mutable_data *\fIbuffer\fP, size_t *\fIbuffer_size\fP) 
Serialize the given item, allocating buffers as needed. 
.sp
.sp
\fBWARNING:\fP
.INDENT 7.0
.INDENT 3.5
It is your responsibility to free the buffer using an appropriate \fBfree\fP implementation.
.UNINDENT
.UNINDENT

.sp
.INDENT 7.0
.TP
\fBReturn\fP
Length of the result. 0 on failure, in which case \fBbuffer\fP is \fBNULL\fP\&. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A data item 
.IP \(bu 2
\fBbuffer[out]\fP: Buffer containing the result 
.IP \(bu 2
\fBbuffer_size[out]\fP: Size of the \fBbuffer\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Type\-specific serializers
.sp
In case you know the type of the item you want to serialize beforehand, you can use one
of the type\-specific serializers.
.sp
\fBNOTE:\fP
.INDENT 0.0
.INDENT 3.5
Unless compiled in debug mode, these do not verify the type. Passing an incorrect item will result in an undefined behavior.
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_serialize_uint(const cbor_item_t *, cbor_mutable_data, size_t) 
Serialize an uint. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Length of the result. 0 on failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A uint 
.IP \(bu 2
\fBbuffer\fP: Buffer to serialize to 
.IP \(bu 2
\fBbuffer_size\fP: Size of the \fBbuffer\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_serialize_negint(const cbor_item_t *, cbor_mutable_data, size_t) 
Serialize a negint. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Length of the result. 0 on failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A neging 
.IP \(bu 2
\fBbuffer\fP: Buffer to serialize to 
.IP \(bu 2
\fBbuffer_size\fP: Size of the \fBbuffer\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_serialize_bytestring(const cbor_item_t *, cbor_mutable_data, size_t) 
Serialize a bytestring. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Length of the result. 0 on failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A bytestring 
.IP \(bu 2
\fBbuffer\fP: Buffer to serialize to 
.IP \(bu 2
\fBbuffer_size\fP: Size of the \fBbuffer\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_serialize_string(const cbor_item_t *, cbor_mutable_data, size_t) 
Serialize a string. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Length of the result. 0 on failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A string 
.IP \(bu 2
\fBbuffer\fP: Buffer to serialize to 
.IP \(bu 2
\fBbuffer_size\fP: Size of the \fBbuffer\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_serialize_array(const cbor_item_t *, cbor_mutable_data, size_t) 
Serialize an array. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Length of the result. 0 on failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An array 
.IP \(bu 2
\fBbuffer\fP: Buffer to serialize to 
.IP \(bu 2
\fBbuffer_size\fP: Size of the \fBbuffer\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_serialize_map(const cbor_item_t *, cbor_mutable_data, size_t) 
Serialize a map. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Length of the result. 0 on failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A map 
.IP \(bu 2
\fBbuffer\fP: Buffer to serialize to 
.IP \(bu 2
\fBbuffer_size\fP: Size of the \fBbuffer\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_serialize_tag(const cbor_item_t *, cbor_mutable_data, size_t) 
Serialize a tag. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Length of the result. 0 on failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A tag 
.IP \(bu 2
\fBbuffer\fP: Buffer to serialize to 
.IP \(bu 2
\fBbuffer_size\fP: Size of the \fBbuffer\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_serialize_float_ctrl(const cbor_item_t *, cbor_mutable_data, size_t) 
Serialize a. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Length of the result. 0 on failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A float or ctrl 
.IP \(bu 2
\fBbuffer\fP: Buffer to serialize to 
.IP \(bu 2
\fBbuffer_size\fP: Size of the \fBbuffer\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Types 0 & 1 – Positive and negative integers
.sp
\fICBOR\fP has two types of integers – positive (which may be effectively regarded as unsigned), and negative. There are four possible widths for an integer – 1, 2, 4, or 8 bytes. These are represented by
.INDENT 0.0
.TP
.B enum cbor_int_width 
Possible widths of CBOR_TYPE_UINT items. 
.sp
\fIValues:\fP
.INDENT 7.0
.TP
.B CBOR_INT_8 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_INT_16 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_INT_32 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_INT_64 
.UNINDENT
.UNINDENT
.SS Type 0 \- positive integers
.TS
center;
|l|l|.
_
T{
Corresponding \fBcbor_type\fP
T}	T{
\fBCBOR_TYPE_UINT\fP
T}
_
T{
Number of allocations
T}	T{
One per lifetime
T}
_
T{
Storage requirements
T}	T{
\fBsizeof(cbor_item_t) + sizeof(uint*_t)\fP
T}
_
.TE
.sp
\fBNote:\fP once a positive integer has been created, its width \fIcannot\fP be changed.
.SS Type 1 \- negative integers
.TS
center;
|l|l|.
_
T{
Corresponding \fBcbor_type\fP
T}	T{
\fBCBOR_TYPE_NEGINT\fP
T}
_
T{
Number of allocations
T}	T{
One per lifetime
T}
_
T{
Storage requirements
T}	T{
\fBsizeof(cbor_item_t) + sizeof(uint*_t)\fP
T}
_
.TE
.sp
\fBNote:\fP once a positive integer has been created, its width \fIcannot\fP be changed.
.SS Type 0 & 1
.sp
Due to their largely similar semantics, the following functions can be used for both Type 0 and Type 1 items. One can convert between them freely using \fI\%the conversion functions\fP\&.
.sp
Actual Type of the integer can be checked using item types API\&.
.sp
An integer item is created with one of the four widths. Because integers\(aq \fI\%storage is bundled together with the handle\fP, the width cannot be changed over its lifetime.
.sp
\fBWARNING:\fP
.INDENT 0.0
.INDENT 3.5
Due to the fact that CBOR negative integers represent integers in the range [-1, -2^N], \fBcbor_set_uint\fP API is somewhat counter\-intuitive as the resulting logical value is 1 less. This behavior is necessary in order to permit uniform manipulation with the full range of permitted values. For example, the following snippet
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
cbor_item_t * item = cbor_new_int8();
cbor_mark_negint(item);
cbor_set_uint8(0);
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
will produce an item with the logical value of -1\&. There is, however, an upside to this as well: There is only one representation of zero.
.UNINDENT
.UNINDENT
.SS Building new items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_uint8(uint8_t \fIvalue\fP) 
Constructs a new positive integer. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP positive integer 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: the value to use 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_uint16(uint16_t \fIvalue\fP) 
Constructs a new positive integer. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP positive integer 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: the value to use 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_uint32(uint32_t \fIvalue\fP) 
Constructs a new positive integer. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP positive integer 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: the value to use 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_uint64(uint64_t \fIvalue\fP) 
Constructs a new positive integer. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP positive integer 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: the value to use 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Retrieving values
.INDENT 0.0
.TP
.B uint8_t cbor_get_uint8(const cbor_item_t *\fIitem\fP) 
Extracts the integer value. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
the value 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B uint16_t cbor_get_uint16(const cbor_item_t *\fIitem\fP) 
Extracts the integer value. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
the value 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B uint32_t cbor_get_uint32(const cbor_item_t *\fIitem\fP) 
Extracts the integer value. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
the value 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B uint64_t cbor_get_uint64(const cbor_item_t *\fIitem\fP) 
Extracts the integer value. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
the value 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Setting values
.INDENT 0.0
.TP
.B void cbor_set_uint8(cbor_item_t *\fIitem\fP, uint8_t \fIvalue\fP) 
Assigns the integer value. 
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer item 
.IP \(bu 2
\fBvalue\fP: the value to assign. For negative integer, the logical value is \fB\-value \- 1\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B void cbor_set_uint16(cbor_item_t *\fIitem\fP, uint16_t \fIvalue\fP) 
Assigns the integer value. 
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer item 
.IP \(bu 2
\fBvalue\fP: the value to assign. For negative integer, the logical value is \fB\-value \- 1\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B void cbor_set_uint32(cbor_item_t *\fIitem\fP, uint32_t \fIvalue\fP) 
Assigns the integer value. 
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer item 
.IP \(bu 2
\fBvalue\fP: the value to assign. For negative integer, the logical value is \fB\-value \- 1\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B void cbor_set_uint64(cbor_item_t *\fIitem\fP, uint64_t \fIvalue\fP) 
Assigns the integer value. 
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer item 
.IP \(bu 2
\fBvalue\fP: the value to assign. For negative integer, the logical value is \fB\-value \- 1\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Dealing with width
.INDENT 0.0
.TP
.B cbor_int_width cbor_int_get_width(const cbor_item_t *\fIitem\fP) 
Queries the integer width. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
the width 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer item 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Dealing with signedness
.INDENT 0.0
.TP
.B void cbor_mark_uint(cbor_item_t *\fIitem\fP) 
Marks the integer item as a positive integer. 
.sp
The data value is not changed
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B void cbor_mark_negint(cbor_item_t *\fIitem\fP) 
Marks the integer item as a negative integer. 
.sp
The data value is not changed
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: positive or negative integer item 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Creating new items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_int8() 
Allocates new integer with 1B width. 
.sp
The width cannot be changed once allocated
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP positive integer. The value is not initialized. 
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_int16() 
Allocates new integer with 2B width. 
.sp
The width cannot be changed once allocated
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP positive integer. The value is not initialized. 
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_int32() 
Allocates new integer with 4B width. 
.sp
The width cannot be changed once allocated
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP positive integer. The value is not initialized. 
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_int64() 
Allocates new integer with 8B width. 
.sp
The width cannot be changed once allocated
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP positive integer. The value is not initialized. 
.UNINDENT

.UNINDENT
.SS Type 2 – Byte strings
.sp
CBOR byte strings are just (ordered) series of bytes without further interpretation (unless there is a tag). Byte string\(aqs length may or may not be known during encoding. These two kinds of byte strings can be distinguished using \fI\%cbor_bytestring_is_definite()\fP and \fI\%cbor_bytestring_is_indefinite()\fP respectively.
.sp
In case a byte string is indefinite, it is encoded as a series of definite byte strings. These are called "chunks". For example, the encoded item
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
0xf5            Start indefinite byte string
    0x41        Byte string (1B long)
        0x00
    0x41        Byte string (1B long)
        0xff
    0xff        "Break" control token
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
represents two bytes, \fB0x00\fP and \fB0xff\fP\&. This on one hand enables streaming messages even before they are fully generated, but on the other hand it adds more complexity to the client code.
.TS
center;
|l|l|.
_
T{
Corresponding \fBcbor_type\fP
T}	T{
\fBCBOR_TYPE_BYTESTRING\fP
T}
_
T{
Number of allocations (definite)
T}	T{
One plus any manipulations with the data
T}
_
T{
Number of allocations (indefinite)
T}	T{
One plus logarithmically many
reallocations relative  to chunk count
T}
_
T{
Storage requirements (definite)
T}	T{
\fBsizeof(cbor_item_t) + length(handle)\fP
T}
_
T{
Storage requirements (indefinite)
T}	T{
\fBsizeof(cbor_item_t) * (1 + chunk_count) + chunks\fP
T}
_
.TE
.SS Streaming indefinite byte strings
.sp
Please refer to /streaming\&.
.SS Getting metadata
.INDENT 0.0
.TP
.B size_t cbor_bytestring_length(const cbor_item_t *\fIitem\fP) 
Returns the length of the binary data. 
.sp
For definite byte strings only
.sp
.INDENT 7.0
.TP
\fBReturn\fP
length of the binary data. Zero if no chunk has been attached yet 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: a definite bytestring 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_bytestring_is_definite(const cbor_item_t *\fIitem\fP) 
Is the byte string definite? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the byte string definite? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: a byte string 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_bytestring_is_indefinite(const cbor_item_t *\fIitem\fP) 
Is the byte string indefinite? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the byte string indefinite? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: a byte string 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_bytestring_chunk_count(const cbor_item_t *\fIitem\fP) 
Get the number of chunks this string consist of. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
The chunk count. 0 for freshly created items. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A indefinite bytestring 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Reading data
.INDENT 0.0
.TP
.B cbor_mutable_data cbor_bytestring_handle(const cbor_item_t *\fIitem\fP) 
Get the handle to the binary data. 
.sp
Definite items only. Modifying the data is allowed. In that case, the caller takes responsibility for the effect on items this item might be a part of
.sp
.INDENT 7.0
.TP
\fBReturn\fP
The address of the binary data. \fBNULL\fP if no data have been assigned yet. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A definite byte string 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t **cbor_bytestring_chunks_handle(const cbor_item_t *\fIitem\fP) 
Get the handle to the array of chunks. 
.sp
Manipulations with the memory block (e.g. sorting it) are allowed, but the validity and the number of chunks must be retained.
.sp
.INDENT 7.0
.TP
\fBReturn\fP
array of cbor_bytestring_chunk_count definite bytestrings 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A indefinite byte string 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Creating new items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_definite_bytestring() 
Creates a new definite byte string. 
.sp
The handle is initialized to \fBNULL\fP and length to 0
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP definite bytestring. \fBNULL\fP on malloc failure. 
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_indefinite_bytestring() 
Creates a new indefinite byte string. 
.sp
The chunks array is initialized to \fBNULL\fP and chunkcount to 0
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP indefinite bytestring. \fBNULL\fP on malloc failure. 
.UNINDENT

.UNINDENT
.SS Building items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_bytestring(cbor_data \fIhandle\fP, size_t \fIlength\fP) 
Creates a new byte string and initializes it. 
.sp
The \fBhandle\fP will be copied to a newly allocated block
.sp
.INDENT 7.0
.TP
\fBReturn\fP
A \fBnew\fP byte string with content \fBhandle\fP\&. \fBNULL\fP on malloc failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBhandle\fP: Block of binary data 
.IP \(bu 2
\fBlength\fP: Length of \fBdata\fP 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Manipulating existing items
.INDENT 0.0
.TP
.B void cbor_bytestring_set_handle(cbor_item_t  * item, cbor_mutable_data   CBOR_RESTRICT_POINTER data, size_t length)
Set the handle to the binary data. 
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A definite byte string 
.IP \(bu 2
\fBdata\fP: The memory block. The caller gives up the ownership of the block. libcbor will deallocate it when appropriate using its free function 
.IP \(bu 2
\fBlength\fP: Length of the data block 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_bytestring_add_chunk(cbor_item_t *\fIitem\fP, cbor_item_t *\fIchunk\fP) 
Appends a chunk to the bytestring. 
.sp
Indefinite byte strings only.
.sp
May realloc the chunk storage.
.sp
.INDENT 7.0
.TP
\fBReturn\fP
true on success, false on realloc failure. In that case, the refcount of \fBchunk\fP is not increased and the \fBitem\fP is left intact. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An indefinite byte string 
.IP \(bu 2
\fBitem[incref]\fP: A definite byte string 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Type 3 – UTF\-8 strings
.sp
CBOR strings work in much the same ways as type_2\&.
.TS
center;
|l|l|.
_
T{
Corresponding \fBcbor_type\fP
T}	T{
\fBCBOR_TYPE_STRING\fP
T}
_
T{
Number of allocations (definite)
T}	T{
One plus any manipulations with the data
T}
_
T{
Number of allocations (indefinite)
T}	T{
One plus logarithmically many
reallocations relative  to chunk count
T}
_
T{
Storage requirements (definite)
T}	T{
\fBsizeof(cbor_item_t) + length(handle)\fP
T}
_
T{
Storage requirements (indefinite)
T}	T{
\fBsizeof(cbor_item_t) * (1 + chunk_count) + chunks\fP
T}
_
.TE
.SS Streaming indefinite strings
.sp
Please refer to /streaming\&.
.SS UTF\-8 encoding validation
.sp
\fIlibcbor\fP considers UTF\-8 encoding validity to be a part of the well\-formedness notion of CBOR and therefore invalid UTF\-8 strings will be rejected by the parser. Strings created by the user are not checked.
.SS Getting metadata
.INDENT 0.0
.TP
.B size_t cbor_string_length(const cbor_item_t *\fIitem\fP) 
Returns the length of the underlying string. 
.sp
For definite strings only
.sp
.INDENT 7.0
.TP
\fBReturn\fP
length of the string. Zero if no chunk has been attached yet 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: a definite string 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_string_is_definite(const cbor_item_t *\fIitem\fP) 
Is the string definite? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the string definite? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: a string 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_string_is_indefinite(const cbor_item_t *\fIitem\fP) 
Is the string indefinite? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the string indefinite? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: a string 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_string_chunk_count(const cbor_item_t *\fIitem\fP) 
Get the number of chunks this string consist of. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
The chunk count. 0 for freshly created items. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A indefinite string 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Reading data
.INDENT 0.0
.TP
.B cbor_mutable_data cbor_string_handle(const cbor_item_t *\fIitem\fP) 
Get the handle to the underlying string. 
.sp
Definite items only. Modifying the data is allowed. In that case, the caller takes responsibility for the effect on items this item might be a part of
.sp
.INDENT 7.0
.TP
\fBReturn\fP
The address of the underlying string. \fBNULL\fP if no data have been assigned yet. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A definite string 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t **cbor_string_chunks_handle(const cbor_item_t *\fIitem\fP) 
Get the handle to the array of chunks. 
.sp
Manipulations with the memory block (e.g. sorting it) are allowed, but the validity and the number of chunks must be retained.
.sp
.INDENT 7.0
.TP
\fBReturn\fP
array of cbor_string_chunk_count definite strings 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A indefinite string 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Creating new items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_definite_string() 
Creates a new definite string. 
.sp
The handle is initialized to \fBNULL\fP and length to 0
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP definite string. \fBNULL\fP on malloc failure. 
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_indefinite_string() 
Creates a new indefinite string. 
.sp
The chunks array is initialized to \fBNULL\fP and chunkcount to 0
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP indefinite string. \fBNULL\fP on malloc failure. 
.UNINDENT

.UNINDENT
.SS Building items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_string(const char *\fIval\fP) 
Creates a new string and initializes it. 
.sp
The \fBval\fP will be copied to a newly allocated block
.sp
.INDENT 7.0
.TP
\fBReturn\fP
A \fBnew\fP string with content \fBhandle\fP\&. \fBNULL\fP on malloc failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBval\fP: A null\-terminated UTF\-8 string 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Manipulating existing items
.INDENT 0.0
.TP
.B void cbor_string_set_handle(cbor_item_t  * item, cbor_mutable_data   CBOR_RESTRICT_POINTER data, size_t length)
Set the handle to the underlying string. 
.sp
.sp
\fBWARNING:\fP
.INDENT 7.0
.INDENT 3.5
Using a pointer to a stack allocated constant is a common mistake. Lifetime of the string will expire when it goes out of scope and the CBOR item will be left inconsistent.
.UNINDENT
.UNINDENT

.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A definite string 
.IP \(bu 2
\fBdata\fP: The memory block. The caller gives up the ownership of the block. libcbor will deallocate it when appropriate using its free function 
.IP \(bu 2
\fBlength\fP: Length of the data block 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_string_add_chunk(cbor_item_t *\fIitem\fP, cbor_item_t *\fIchunk\fP) 
Appends a chunk to the string. 
.sp
Indefinite strings only.
.sp
May realloc the chunk storage.
.sp
.INDENT 7.0
.TP
\fBReturn\fP
true on success. false on realloc failure. In that case, the refcount of \fBchunk\fP is not increased and the \fBitem\fP is left intact. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An indefinite string 
.IP \(bu 2
\fBitem[incref]\fP: A definite string 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Type 4 – Arrays
.sp
CBOR arrays, just like byte strings and strings, can be encoded either as definite, or as indefinite.
.TS
center;
|l|l|.
_
T{
Corresponding \fBcbor_type\fP
T}	T{
\fBCBOR_TYPE_ARRAY\fP
T}
_
T{
Number of allocations (definite)
T}	T{
Two plus any manipulations with the data
T}
_
T{
Number of allocations (indefinite)
T}	T{
Two plus logarithmically many
reallocations relative to additions
T}
_
T{
Storage requirements (definite)
T}	T{
\fB(sizeof(cbor_item_t) + 1) * size\fP
T}
_
T{
Storage requirements (indefinite)
T}	T{
\fB<= sizeof(cbor_item_t) + sizeof(cbor_item_t) * size * BUFFER_GROWTH\fP
T}
_
.TE
.SS Examples
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
0x9f        Start indefinite array
    0x01        Unsigned integer 1
    0xff        "Break" control token
.ft P
.fi
.UNINDENT
.UNINDENT
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
0x9f        Start array, 1B length follows
0x20        Unsigned integer 32
    ...        32 items follow
.ft P
.fi
.UNINDENT
.UNINDENT
.SS Streaming indefinite arrays
.sp
Please refer to /streaming\&.
.SS Getting metadata
.INDENT 0.0
.TP
.B size_t cbor_array_size(const cbor_item_t *\fIitem\fP) 
Get the number of members. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
The number of members 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An array 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_array_allocated(const cbor_item_t *\fIitem\fP) 
Get the size of the allocated storage. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
The size of the allocated storage (number of items) 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An array 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_array_is_definite(const cbor_item_t *\fIitem\fP) 
Is the array definite? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the array definite? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An array 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_array_is_indefinite(const cbor_item_t *\fIitem\fP) 
Is the array indefinite? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is the array indefinite? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An array 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Reading data
.INDENT 0.0
.TP
.B cbor_item_t **cbor_array_handle(const cbor_item_t *\fIitem\fP) 
Get the array contents. 
.sp
The items may be reordered and modified as long as references remain consistent.
.sp
.INDENT 7.0
.TP
\fBReturn\fP
cbor_array_size items 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An array 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_array_get(const cbor_item_t *\fIitem\fP, size_t \fIindex\fP) 
Get item by index. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBincref\fP The item, or \fBNULL\fP in case of boundary violation 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An array 
.IP \(bu 2
\fBindex\fP: The index 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Creating new items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_definite_array(size_t \fIsize\fP) 
Create new definite array. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP array or \fBNULL\fP upon malloc failure 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBsize\fP: Number of slots to preallocate 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_indefinite_array() 
Create new indefinite array. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP array or \fBNULL\fP upon malloc failure 
.UNINDENT

.UNINDENT
.SS Modifying items
.INDENT 0.0
.TP
.B bool cbor_array_push(cbor_item_t *\fIarray\fP, cbor_item_t *\fIpushee\fP) 
Append to the end. 
.sp
For indefinite items, storage may be realloacted. For definite items, only the preallocated capacity is available.
.sp
.INDENT 7.0
.TP
\fBReturn\fP
true on success, false on failure 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBarray[borrow]\fP: An array 
.IP \(bu 2
\fBpushee[incref]\fP: The item to push 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_array_replace(cbor_item_t *\fIitem\fP, size_t \fIindex\fP, cbor_item_t *\fIvalue\fP) 
Replace item at an index. 
.sp
The item being replace will be cbor_decref \(aqed.
.sp
.INDENT 7.0
.TP
\fBReturn\fP
true on success, false on allocation failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An array 
.IP \(bu 2
\fBvalue[incref]\fP: The item to assign 
.IP \(bu 2
\fBindex\fP: The index, first item is 0. 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_array_set(cbor_item_t *\fIitem\fP, size_t \fIindex\fP, cbor_item_t *\fIvalue\fP) 
Set item by index. 
.sp
Creating arrays with holes is not possible
.sp
.INDENT 7.0
.TP
\fBReturn\fP
true on success, false on allocation failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: An array 
.IP \(bu 2
\fBvalue[incref]\fP: The item to assign 
.IP \(bu 2
\fBindex\fP: The index, first item is 0. 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Type 5 – Maps
.sp
CBOR maps are the plain old associate hash maps known from JSON and many other formats and languages, with one exception: any CBOR data item can be a key, not just strings. This is somewhat unusual and you, as an application developer, should keep that in mind.
.sp
Maps can be either definite or indefinite, in much the same way as type_4\&.
.TS
center;
|l|l|.
_
T{
Corresponding \fBcbor_type\fP
T}	T{
\fBCBOR_TYPE_MAP\fP
T}
_
T{
Number of allocations (definite)
T}	T{
Two plus any manipulations with the data
T}
_
T{
Number of allocations (indefinite)
T}	T{
Two plus logarithmically many
reallocations relative to additions
T}
_
T{
Storage requirements (definite)
T}	T{
\fBsizeof(cbor_pair) * size + sizeof(cbor_item_t)\fP
T}
_
T{
Storage requirements (indefinite)
T}	T{
\fB<= sizeof(cbor_item_t) + sizeof(cbor_pair) * size * BUFFER_GROWTH\fP
T}
_
.TE
.SS Streaming maps
.sp
Please refer to /streaming\&.
.SS Getting metadata
.INDENT 0.0
.TP
.B size_t cbor_map_size(const cbor_item_t *\fIitem\fP) 
Get the number of pairs. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
The number of pairs 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A map 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B size_t cbor_map_allocated(const cbor_item_t *\fIitem\fP) 
Get the size of the allocated storage. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Allocated storage size (as the number of cbor_pair items) 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A map 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_map_is_definite(const cbor_item_t *\fIitem\fP) 
Is this map definite? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is this map definite? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A map 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_map_is_indefinite(const cbor_item_t *\fIitem\fP) 
Is this map indefinite? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is this map indefinite? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A map 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Reading data
.INDENT 0.0
.TP
.B struct cbor_pair *cbor_map_handle(const cbor_item_t *\fIitem\fP) 
Get the pairs storage. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Array of cbor_map_size pairs. Manipulation is possible as long as references remain valid. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A map 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Creating new items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_definite_map(size_t \fIsize\fP) 
Create a new definite map. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP definite map. \fBNULL\fP on malloc failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBsize\fP: The number of slots to preallocate 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_indefinite_map() 
Create a new indefinite map. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP definite map. \fBNULL\fP on malloc failure. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBsize\fP: The number of slots to preallocate 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Modifying items
.INDENT 0.0
.TP
.B bool cbor_map_add(cbor_item_t *\fIitem\fP, struct cbor_pair \fIpair\fP) 
Add a pair to the map. 
.sp
For definite maps, items can only be added to the preallocated space. For indefinite maps, the storage will be expanded as needed
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBtrue\fP on success, \fBfalse\fP if either reallocation failed or the preallcoated storage is full 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A map 
.IP \(bu 2
\fBpair[incref]\fP: The key\-value pair to add (incref is member\-wise) 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Type 6 – Semantic tags
.sp
Tag are additional metadata that can be used to extend or specialize the meaning or interpretation of the other data items.
.sp
For example, one might tag an array of numbers to communicate that it should be interpreted as a vector.
.sp
Please consult the official \fI\%IANA repository of CBOR tags\fP before inventing new ones.
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_tag(uint64_t \fIvalue\fP) 
Create a new tag. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP tag. Item reference is \fBNULL\fP\&. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: The tag value. Please consult the tag repository 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_tag_item(const cbor_item_t *\fIitem\fP) 
Get the tagged item. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBincref\fP the tagged item 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A tag 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B uint64_t cbor_tag_value(const cbor_item_t *\fIitem\fP) 
Get tag value. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
The tag value. Please consult the tag repository 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A tag 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B void cbor_tag_set_item(cbor_item_t *\fIitem\fP, cbor_item_t *\fItagged_item\fP) 
Set the tagged item. 
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A tag 
.IP \(bu 2
\fBtagged_item[incref]\fP: The item to tag 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Type 7 – Floats & control tokens
.sp
This type combines two completely unrelated types of items \-\- floating point numbers and special values such as true, false, null, etc. We refer to these special values as \(aqcontrol values\(aq or \(aqctrls\(aq for short throughout the code.
.sp
Just like integers, they have different possible width (resulting in different value ranges and precisions).
.INDENT 0.0
.TP
.B enum cbor_float_width 
Possible widths of CBOR_TYPE_FLOAT_CTRL items. 
.sp
\fIValues:\fP
.INDENT 7.0
.TP
.B CBOR_FLOAT_0 
Internal use \- ctrl and special values. 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_FLOAT_16 
Half float. 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_FLOAT_32 
Single float. 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_FLOAT_64 
Double. 
.UNINDENT
.UNINDENT
.TS
center;
|l|l|.
_
T{
Corresponding \fBcbor_type\fP
T}	T{
\fBCBOR_TYPE_FLOAT_CTRL\fP
T}
_
T{
Number of allocations
T}	T{
One per lifetime
T}
_
T{
Storage requirements
T}	T{
\fBsizeof(cbor_item_t) + 1/4/8\fP
T}
_
.TE
.SS Getting metadata
.INDENT 0.0
.TP
.B bool cbor_float_ctrl_is_ctrl(const cbor_item_t *\fIitem\fP) 
Is this a ctrl value? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is this a ctrl value? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A float or ctrl item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_float_width cbor_float_get_width(const cbor_item_t *\fIitem\fP) 
Get the float width. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
The width. 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A float or ctrl item 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B bool cbor_ctrl_is_bool(const cbor_item_t *\fIitem\fP) 
Is this ctrl item a boolean? 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
Is this ctrl item a boolean? 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A ctrl item 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Reading data
.INDENT 0.0
.TP
.B float cbor_float_get_float2(const cbor_item_t *\fIitem\fP) 
Get a half precision float. 
.sp
The item must have the corresponding width
.sp
.INDENT 7.0
.TP
\fBReturn\fP
half precision value 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fB[borrow]\fP: A half precision float 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B float cbor_float_get_float4(const cbor_item_t *\fIitem\fP) 
Get a single precision float. 
.sp
The item must have the corresponding width
.sp
.INDENT 7.0
.TP
\fBReturn\fP
single precision value 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fB[borrow]\fP: A signle precision float 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B double cbor_float_get_float8(const cbor_item_t *\fIitem\fP) 
Get a double precision float. 
.sp
The item must have the corresponding width
.sp
.INDENT 7.0
.TP
\fBReturn\fP
double precision value 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fB[borrow]\fP: A double precision float 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B double cbor_float_get_float(const cbor_item_t *\fIitem\fP) 
Get the float value represented as double. 
.sp
Can be used regardless of the width.
.sp
.INDENT 7.0
.TP
\fBReturn\fP
double precision value 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fB[borrow]\fP: Any float 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B uint8_t cbor_ctrl_value(const cbor_item_t *\fIitem\fP) 
Reads the control value. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
the simple value 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A ctrl item 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Creating new items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_ctrl() 
Constructs a new ctrl item. 
.sp
The width cannot be changed once the item is created
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP 1B ctrl 
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_float2() 
Constructs a new float item. 
.sp
The width cannot be changed once the item is created
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP 2B float 
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_float4() 
Constructs a new float item. 
.sp
The width cannot be changed once the item is created
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP 4B float 
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_float8() 
Constructs a new float item. 
.sp
The width cannot be changed once the item is created
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP 8B float 
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_null() 
Constructs new null ctrl item. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP null ctrl item 
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_new_undef() 
Constructs new under ctrl item. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP under ctrl item 
.UNINDENT

.UNINDENT
.SS Building items
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_bool(bool \fIvalue\fP) 
Constructs new boolean ctrl item. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP boolen ctrl item 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: The value to use 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_ctrl(uint8_t \fIvalue\fP) 
Constructs a ctrl item. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP ctrl item 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: the value to use 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_float2(float \fIvalue\fP) 
Constructs a new float. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP float 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: the value to use 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_float4(float \fIvalue\fP) 
Constructs a new float. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP float 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: the value to use 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B cbor_item_t *cbor_build_float8(double \fIvalue\fP) 
Constructs a new float. 
.sp
.INDENT 7.0
.TP
\fBReturn\fP
\fBnew\fP float 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: the value to use 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Manipulating existing items
.INDENT 0.0
.TP
.B void cbor_set_ctrl(cbor_item_t *\fIitem\fP, uint8_t \fIvalue\fP) 
Assign a control value. 
.sp
.sp
\fBWARNING:\fP
.INDENT 7.0
.INDENT 3.5
It is possible to produce an invalid CBOR value by assigning a invalid value using this mechanism. Please consult the standard before use.
.UNINDENT
.UNINDENT

.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A ctrl item 
.IP \(bu 2
\fBvalue\fP: The simple value to assign. Please consult the standard for allowed values 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B void cbor_set_float2(cbor_item_t *\fIitem\fP, float \fIvalue\fP) 
Assigns a float value. 
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A half precision float 
.IP \(bu 2
\fBvalue\fP: The value to assign 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B void cbor_set_float4(cbor_item_t *\fIitem\fP, float \fIvalue\fP) 
Assigns a float value. 
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A single precision float 
.IP \(bu 2
\fBvalue\fP: The value to assign 
.UNINDENT
.UNINDENT

.UNINDENT
.INDENT 0.0
.TP
.B void cbor_set_float8(cbor_item_t *\fIitem\fP, double \fIvalue\fP) 
Assigns a float value. 
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBitem[borrow]\fP: A double precision float 
.IP \(bu 2
\fBvalue\fP: The value to assign 
.UNINDENT
.UNINDENT

.UNINDENT
.SS Half floats
.sp
CBOR supports two \fI\%bytes wide ("half\-precision")\fP
floats which are not supported by the C language. \fIlibcbor\fP represents them using \fBfloat\fP
values throughout the API, which has important implications when manipulating these values.
.sp
In particular, if a user uses some of the manipulation APIs
(e.g. \fI\%cbor_set_float2()\fP, \fI\%cbor_new_float2()\fP)
to introduce a value that doesn\(aqt have an exect half\-float representation,
the encoding semantics are given by \fI\%cbor_encode_half()\fP as follows:
.INDENT 0.0
.TP
.B size_t cbor_encode_half(float, unsigned char *, size_t) 
Encodes a half\-precision float. 
.sp
Since there is no native representation or semantics for half floats in the language, we use single\-precision floats, as every value that can be expressed as a half\-float can also be expressed as a float.
.sp
This however means that not all floats passed to this function can be unambiguously encoded. The behavior is as follows:.INDENT 7.0
.IP \(bu 2
Infinity, NaN are preserved
.IP \(bu 2
Zero is preserved
.IP \(bu 2
Denormalized numbers keep their sign bit and 10 most significant bit of the significand
.IP \(bu 2
All other numbers.INDENT 2.0
.IP \(bu 2
If the logical value of the exponent is < \-24, the output is zero
.IP \(bu 2
If the logical value of the exponent is between \-23 and \-14, the output is cut off to represent the \(aqmagnitude\(aq of the input, by which we mean (\-1)^{signbit} x 1.0e{exponent}. The value in the significand is lost.
.IP \(bu 2
In all other cases, the sign bit, the exponent, and 10 most significant bits of the significand are kept
.UNINDENT

.UNINDENT

.sp
.INDENT 7.0
.TP
\fBReturn\fP
number of bytes written 
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBvalue\fP: 
.IP \(bu 2
\fBbuffer\fP: Target buffer 
.IP \(bu 2
\fBbuffer_size\fP: Available space in the buffer 
.UNINDENT
.UNINDENT

.UNINDENT
.IP [1] 5
\fI\%http://softwareengineering.vazexqi.com/files/pattern.html\fP
.SS Streaming & indefinite items
.sp
CBOR strings, byte strings, arrays, and maps can be encoded as \fIindefinite\fP, meaning their length or size is not specified. Instead, they are divided into \fIchunks\fP (strings, byte strings), or explicitly terminated (arrays, maps).
.sp
This is one of the most important (and due to poor implementations, underutilized) features of CBOR. It enables low\-overhead streaming just about anywhere without dealing with channels or pub/sub mechanism. It is, however, important to recognize that CBOR streaming is not a substitute for  Websockets [1] and similar technologies.
.IP [1] 5
\fI\%RFC 6455\fP
.SS Decoding
.sp
Another way to decode data using libcbor is to specify a callbacks that will be invoked when upon finding certain items in the input. This service is provided by
.INDENT 0.0
.TP
.B struct cbor_decoder_result cbor_stream_decode(cbor_data \fIbuffer\fP, size_t \fIbuffer_size\fP, const struct cbor_callbacks *\fIcallbacks\fP, void *\fIcontext\fP) 
Stateless decoder. 
.sp
Will try parsing the \fBbuffer\fP and will invoke the appropriate callback on success. Decodes one item at a time. No memory allocations occur.
.sp
.INDENT 7.0
.TP
\fBParameters\fP
.INDENT 7.0
.IP \(bu 2
\fBbuffer\fP: Input buffer 
.IP \(bu 2
\fBbuffer_size\fP: Length of the buffer 
.IP \(bu 2
\fBcallbacks\fP: The callback bundle 
.IP \(bu 2
\fBcontext\fP: An arbitrary pointer to allow for maintaining context. 
.UNINDENT
.UNINDENT

.UNINDENT
.sp
To get started, you might want to have a look at the simple streaming example:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
#include "cbor.h"
#include <stdio.h>
#include <string.h>

/*
 * Illustrates how one might skim through a map (which is assumed to have
 * string keys and values only), looking for the value of a specific key
 *
 * Use the examples/data/map.cbor input to test this.
 */

const char * key = "a secret key";
bool key_found = false;

void find_string(void * _ctx, cbor_data buffer, size_t len)
{
    if (key_found) {
        printf("Found the value: %*s\en", (int) len, buffer);
        key_found = false;
    } else if (len == strlen(key)) {
        key_found = (memcmp(key, buffer, len) == 0);
    }
}

int main(int argc, char * argv[])
{
    FILE * f = fopen(argv[1], "rb");
    fseek(f, 0, SEEK_END);
    size_t length = (size_t)ftell(f);
    fseek(f, 0, SEEK_SET);
    unsigned char * buffer = malloc(length);
    fread(buffer, length, 1, f);

    struct cbor_callbacks callbacks = cbor_empty_callbacks;
    struct cbor_decoder_result decode_result;
    size_t bytes_read = 0;
    callbacks.string = find_string;
    while (bytes_read < length) {
        decode_result = cbor_stream_decode(buffer + bytes_read,
                                           length \- bytes_read,
                                           &callbacks, NULL);
        bytes_read += decode_result.read;
    }

    free(buffer);
    fclose(f);
}
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
The callbacks are defined by
.INDENT 0.0
.TP
.B struct cbor_callbacks 
Callback bundle  passed to the decoder. 
Public Members.INDENT 7.0
.TP
.B cbor_int8_callback uint8 
Unsigned int. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_int16_callback uint16 
Unsigned int. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_int32_callback uint32 
Unsigned int. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_int64_callback uint64 
Unsigned int. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_int64_callback negint64 
Negative int. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_int32_callback negint32 
Negative int. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_int16_callback negint16 
Negative int. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_int8_callback negint8 
Negative int. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_simple_callback byte_string_start 
Definite byte string. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_string_callback byte_string 
Indefinite byte string start. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_string_callback string 
Definite string. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_simple_callback string_start 
Indefinite string start. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_simple_callback indef_array_start 
Definite array. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_collection_callback array_start 
Indefinite array. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_simple_callback indef_map_start 
Definite map. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_collection_callback map_start 
Indefinite map. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_int64_callback tag 
Tags. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_float_callback float2 
Half float. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_float_callback float4 
Single float. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_double_callback float8 
Double float. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_simple_callback undefined 
Undef. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_simple_callback null 
Null. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_bool_callback boolean 
Bool. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_simple_callback indef_break 
Indefinite item break. 
.UNINDENT
.UNINDENT
.sp
When building custom sets of callbacks, feel free to start from
.INDENT 0.0
.TP
.B const struct cbor_callbacks cbor_empty_callbacks 
Dummy callback bundle \- does nothing. 
.UNINDENT
.SS Related structures
.INDENT 0.0
.TP
.B enum cbor_decoder_status 
Streaming decoder result \- status. 
.sp
\fIValues:\fP
.INDENT 7.0
.TP
.B CBOR_DECODER_FINISHED 
OK, finished. 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_DECODER_NEDATA 
Not enough data \- mismatch with MTB. 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_DECODER_EBUFFER 
Buffer manipulation problem. 
.UNINDENT
.INDENT 7.0
.TP
.B CBOR_DECODER_ERROR 
Malformed or reserved MTB/value. 
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
.B struct cbor_decoder_result 
Streaming decoder result. 
Public Members.INDENT 7.0
.TP
.B size_t read 
Bytes read. 
.UNINDENT
.INDENT 7.0
.TP
.B cbor_decoder_status status 
The result. 
.UNINDENT
.UNINDENT
.SS Callback types definition
.INDENT 0.0
.TP
.B typedef void (*cbor_int8_callback)(void *, uint8_t) 
Callback prototype. 
.UNINDENT
.INDENT 0.0
.TP
.B typedef void (*cbor_int16_callback)(void *, uint16_t) 
Callback prototype. 
.UNINDENT
.INDENT 0.0
.TP
.B typedef void (*cbor_int32_callback)(void *, uint32_t) 
Callback prototype. 
.UNINDENT
.INDENT 0.0
.TP
.B typedef void (*cbor_int64_callback)(void *, uint64_t) 
Callback prototype. 
.UNINDENT
.INDENT 0.0
.TP
.B typedef void (*cbor_simple_callback)(void *) 
Callback prototype. 
.UNINDENT
.INDENT 0.0
.TP
.B typedef void (*cbor_string_callback)(void *, cbor_data, size_t) 
Callback prototype. 
.UNINDENT
.INDENT 0.0
.TP
.B typedef void (*cbor_collection_callback)(void *, size_t) 
Callback prototype. 
.UNINDENT
.INDENT 0.0
.TP
.B typedef void (*cbor_float_callback)(void *, float) 
Callback prototype. 
.UNINDENT
.INDENT 0.0
.TP
.B typedef void (*cbor_double_callback)(void *, double) 
Callback prototype. 
.UNINDENT
.INDENT 0.0
.TP
.B typedef void (*cbor_bool_callback)(void *, bool) 
Callback prototype. 
.UNINDENT
.SS Encoding
.sp
TODO
.SS Tests
.SS Unit tests
.sp
There is a comprehensive test suite employing \fI\%CMocka\fP\&. You can run all of them using \fBctest\fP in the build directory. Individual tests are themselves runnable. Please refer to \fI\%CTest\fP documentation for detailed information on how to specify particular subset of tests.
.SS Testing for memory leaks
.sp
Every release is tested for memory correctness. You can run these tests by passing the \fB\-T memcheck\fP flag to \fBctest\fP\&. [1]
.IP [1] 5
Project should be configured with \fB\-DCMAKE_BUILD_TYPE=Debug\fP to obtain meaningful description of location of the leak. You might also need \fB\-\-dsymutil=yes\fP on OS X.
.SS Code coverage
.sp
Every release is inspected using \fI\%GCOV/LCOV\fP\&. Platform\-independent code should be fully covered by the test suite. Simply run
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
make coverage
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
or alternatively run \fBlcov\fP by hand using
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
lcov \-\-capture \-\-directory . \-\-output\-file coverage.info
genhtml coverage.info \-\-output\-directory out
.ft P
.fi
.UNINDENT
.UNINDENT
.SS Fuzz testing
.sp
Every release is tested using a fuzz test. In this test, a huge buffer filled with random data is passed to the decoder. We require that it either succeeds or fail with a sensible error, without leaking any memory. This is intended to simulate real\-world situations where data received from the network are CBOR\-decoded before any further processing.
.SS RFC conformance
.sp
\fIlibcbor\fP is, generally speaking, very faithful implementation of \fI\%RFC 7049\fP\&. There are, however, some limitations imposed by technical constraints.
.SS Bytestring length
.sp
There is no explicit limitation of indefinite length byte strings. [1] \fIlibcbor\fP will not handle byte strings with more chunks than the maximum value of \fBsize_t\fP\&. On any sane platform, such string would not fit in the memory anyway. It is, however, possible to process arbitrarily long strings and byte strings using the streaming decoder.
.IP [1] 5
\fI\%http://tools.ietf.org/html/rfc7049#section\-2.2.2\fP
.SS "Half\-precision" IEEE 754 floats
.sp
As of C99 and even C11, there is no standard implementation for 2 bytes floats. \fIlibcbor\fP packs them as a \fBfloat\fP\&. When encoding, \fIlibcbor\fP selects the appropriate wire representation based on metadata and the actual value. This applies both to canonical and normal mode.
.sp
For more information on half\-float serialization, please refer to the section on api_type_7_hard_floats\&.
.SS Internal mechanics
.sp
Internal workings of \fIlibcbor\fP are mostly derived from the specification. The purpose of this document is to describe technical choices made during design & implementation and to explicate the reasoning behind those choices.
.SS Terminology
.TS
center;
|l|l|l|.
_
T{
MTB
T}	T{
Major Type Byte
T}	T{
\fI\%http://tools.ietf.org/html/rfc7049#section\-2.1\fP
T}
_
T{
DST
T}	T{
Dynamically Sized Type
T}	T{
Type whose storage requirements cannot be determined
.sp
during compilation (originated in the \fI\%Rust\fP community)
T}
_
.TE
.SS Conventions
.sp
API symbols start with \fBcbor_\fP or \fBCBOR_\fP prefix, internal symbols have \fB_cbor_\fP or \fB_CBOR_\fP prefix.
.SS Inspiration & related projects
.sp
Most of the API is largely modelled after existing JSON libraries, including
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
\fI\%Jansson\fP
.IP \(bu 2
\fI\%json\-c\fP
.IP \(bu 2
Gnome\(aqs \fI\%JsonGlib\fP
.UNINDENT
.UNINDENT
.UNINDENT
.sp
and also borrowing from
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
\fI\%msgpack\-c\fP
.IP \(bu 2
\fI\%Google Protocol Buffers\fP\&.
.UNINDENT
.UNINDENT
.UNINDENT
.SS General notes on the API design
.sp
The API design has two main driving priciples:
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP 1. 3
Let the client manage the memory as much as possible
.IP 2. 3
Behave exactly as specified by the standard
.UNINDENT
.UNINDENT
.UNINDENT
.sp
Combining these two principles in practice turns out to be quite difficult. Indefinite\-length strings, arrays, and maps require client to handle every fixed\-size chunk explicitly in order to
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
ensure the client never runs out of memory due to \fIlibcbor\fP
.IP \(bu 2
use \fBrealloc()\fP sparsely and predictably [1]
.INDENT 2.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
provide strong guarantees about its usage (to prevent latency spikes)
.IP \(bu 2
provide APIs to avoid \fBrealloc()\fP altogether
.UNINDENT
.UNINDENT
.UNINDENT
.IP \(bu 2
allow proper handling of (streamed) data bigger than available memory
.UNINDENT
.IP [1] 5
Reasonable handling of DSTs requires reallocation if the API is to remain sane.
.UNINDENT
.UNINDENT
.SS Coding style
.sp
This code loosely follows the \fI\%Linux kernel coding style\fP\&. Tabs are tabs, and they are 4 characters wide.
.SS Memory layout
.sp
CBOR is very dynamic in the sense that it contains many data elements of variable length, sometimes even indefinite length. This section describes internal representation of all CBOR data types.
.sp
Generally speaking, data items consist of three parts:
.INDENT 0.0
.INDENT 3.5
.INDENT 0.0
.IP \(bu 2
a generic \fI\%handle\fP,
.IP \(bu 2
the associated \fBmetadata\fP,
.IP \(bu 2
and the \fBactual data\fP
.UNINDENT
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
.B type cbor_item_t 
Represents the item. Used as an opaque type
.INDENT 7.0
.TP
.B cbor_type type 
Type discriminator
.UNINDENT
.INDENT 7.0
.TP
.B size_t refcount 
Reference counter. Used by \fBcbor_decref()\fP, \fBcbor_incref()\fP
.UNINDENT
.INDENT 7.0
.TP
.B union cbor_item_metadata metadata 
Union discriminated by \fBcbor_item_t.type\fP\&. Contains type\-specific metadata
.UNINDENT
.INDENT 7.0
.TP
.B unsigned char *data 
Contains pointer to the actual data. Small, fixed size items (api/type_0_1, api/type_6, api/type_7) are allocated as a single memory block.
.sp
Consider the following snippet
.INDENT 7.0
.INDENT 3.5
.sp
.nf
.ft C
cbor_item_t * item = cbor_new_int8();
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
then the memory is laid out as follows
.INDENT 7.0
.INDENT 3.5
.sp
.nf
.ft C
+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-++\-\-\-\-\-\-\-\-\-\-\-+
|           |               |               |                                   ||           |
|   type    |   refcount    |   metadata    |              data                 ||  uint8_t  |
|           |               |               |   (= item + sizeof(cbor_item_t))  ||           |
+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-++\-\-\-\-\-\-\-\-\-\-\-+
^                                                                                ^
|                                                                                |
+\-\-\- item                                                                        +\-\-\- item\->data
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Dynamically sized types (api/type_2, api/type_3, api/type_4, api/type_5) may store handle and data in separate locations. This enables creating large items (e.g byte strings) without \fBrealloc()\fP or copying large blocks of memory. One simply attaches the correct pointer to the handle.
.UNINDENT
.UNINDENT
.INDENT 0.0
.TP
.B union cbor_item_metadata
.INDENT 7.0
.TP
.B struct _cbor_int_metadata int_metadata;
Used both by both api/type_0_1
.UNINDENT
.INDENT 7.0
.TP
.B struct _cbor_bytestring_metadata bytestring_metadata;
.UNINDENT
.INDENT 7.0
.TP
.B struct _cbor_string_metadata string_metadata;
.UNINDENT
.INDENT 7.0
.TP
.B struct _cbor_array_metadata array_metadata;
.UNINDENT
.INDENT 7.0
.TP
.B struct _cbor_map_metadata map_metadata;
.UNINDENT
.INDENT 7.0
.TP
.B struct _cbor_tag_metadata tag_metadata;
.UNINDENT
.INDENT 7.0
.TP
.B struct _cbor_float_ctrl_metadata float_ctrl_metadata;
.UNINDENT
.UNINDENT
.SS Decoding
.sp
As outlined in api, there decoding is based on the streaming decoder Essentially, the decoder is a custom set of callbacks for the streaming decoder.
.SS Changelog
.SS Next
.SS 0.5.0 (2017\-02\-06)
.INDENT 0.0
.IP \(bu 2
Remove cmocka from the subtree (always rely on system or user\-provided version)
.IP \(bu 2
Windows CI
.IP \(bu 2
Only build tests if explicitly enabled (\fI\-DWITH_TESTS=ON\fP)
.IP \(bu 2
Fixed static header declarations (by cedric\-d)
.IP \(bu 2
Improved documentation (by Michael Richardson)
.IP \(bu 2
Improved \fIexamples/readfile.c\fP
.IP \(bu 2
Reworked (re)allocation to handle huge inputs and overflows in size_t [#16]
.IP \(bu 2
Improvements to C++ linkage (corrected \fIcbor_empty_callbacks\fP, fixed \fIrestrict\fP pointers) (by Dennis Bijwaard)
.IP \(bu 2
Fixed Linux installation directory depending on architecture [#34] (by jvymazal)
.IP \(bu 2
Improved 32\-bit support [#35]
.IP \(bu 2
Fixed MSVC compatibility [#31]
.IP \(bu 2
Fixed and improved half\-float encoding [#5] [#11]
.UNINDENT
.SS 0.4.0 (2015\-12\-25)
.sp
Breaks build & header compatibility due to:
.INDENT 0.0
.IP \(bu 2
Improved build configuration and feature check macros
.IP \(bu 2
Endianess configuration fixes (by Erwin Kroon and David Grigsby)
.IP \(bu 2
pkg\-config compatibility (by Vincent Bernat)
.IP \(bu 2
enable use of versioned SONAME (by Vincent Bernat)
.IP \(bu 2
better fuzzer (wasn\(aqt random until now, ooops)
.UNINDENT
.SS 0.3.1 (2015\-05\-21)
.INDENT 0.0
.IP \(bu 2
documentation and comments improvements, mostly for the API reference
.UNINDENT
.SS 0.3.0 (2015\-05\-21)
.INDENT 0.0
.IP \(bu 2
Fixes, polishing, niceties across the code base
.IP \(bu 2
Updated examples
.IP \(bu 2
\fIcbor_copy\fP
.IP \(bu 2
\fIcbor_build_negint8\fP, 16, 32, 64, matching asserts
.IP \(bu 2
\fIcbor_build_stringn\fP
.IP \(bu 2
\fIcbor_build_tag\fP
.IP \(bu 2
\fIcbor_build_float2\fP, ...
.UNINDENT
.SS 0.2.1 (2015\-05\-17)
.INDENT 0.0
.IP \(bu 2
C99 support
.UNINDENT
.SS 0.2.0 (2015\-05\-17)
.INDENT 0.0
.IP \(bu 2
\fIcbor_ctrl_bool\fP \-> \fIcbor_ctrl_is_bool\fP
.IP \(bu 2
Added \fIcbor_array_allocated\fP & map equivalent
.IP \(bu 2
Overhauled endianess conversion \- ARM now works as expected
.IP \(bu 2
\(aqsort.c\(aq example added
.IP \(bu 2
Significantly improved and doxyfied documentation
.UNINDENT
.SS 0.1.0 (2015\-05\-06)
.sp
The initial release, yay!
.SS Development
.SS Development dependencies
.INDENT 0.0
.IP \(bu 2
\fI\%CMocka\fP (testing)
.IP \(bu 2
\fI\%Python\fP and \fI\%pip\fP (Sphinx platform)
.IP \(bu 2
\fI\%Doxygen\fP
.IP \(bu 2
\fI\%Sphinx\fP (documentation)
.IP \(bu 2
There are some \fI\%Ruby\fP scripts in \fBmisc\fP
.IP \(bu 2
\fI\%Valgrind\fP (memory correctness & profiling)
.IP \(bu 2
\fI\%GCOV/LCOV\fP (test coverage)
.UNINDENT
.SS Installing \fIsphinx\fP
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
pip install sphinx
pip install sphinx_rtd_theme
pip install breathe
pip install https://github.com/lepture/python\-livereload/archive/master.zip
pip install sphinx\-autobuild
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Further instructions on configuring advanced features can be found at \fI\%http://read\-the\-docs.readthedocs.org/en/latest/install.html\fP\&.
.SS Live preview of docs
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
cd doc
make livehtml
.ft P
.fi
.UNINDENT
.UNINDENT
.SS Set up git hooks
.sp
A git hook that automatically refereshes the \fI\%GH pages\fP contents located in \fBdocs\fP can be symlinked:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
ln \-s misc/hooks/pre\-commit .git/hooks
.ft P
.fi
.UNINDENT
.UNINDENT
.SS Testing and code coverage
.sp
Please refer to tests
.SH AUTHOR
Pavel Kalvoda
.SH COPYRIGHT
2021 - 2017, Pavel Kalvoda
.\" Generated by docutils manpage writer.
.
openSUSE Build Service is sponsored by