xref: /freebsd-src/contrib/libcbor/doc/source/using.rst (revision 5d3e7166f6a0187fa3f8831b16a06bd9955c21ff)
110ff414cSEd MasteUsage & preliminaries
210ff414cSEd Maste=======================
310ff414cSEd Maste
410ff414cSEd MasteVersion information
510ff414cSEd Maste--------------------
610ff414cSEd Maste
710ff414cSEd Mastelibcbor exports its version using three self-explanatory macros:
810ff414cSEd Maste
910ff414cSEd Maste - ``CBOR_MAJOR_VERSION``
1010ff414cSEd Maste - ``CBOR_MINOR_VERSION``
1110ff414cSEd Maste - ``CBOR_PATCH_VERSION``
1210ff414cSEd Maste
1310ff414cSEd MasteThe ``CBOR_VERSION`` is a string concatenating these three identifiers into one (e.g. ``0.2.0``).
1410ff414cSEd Maste
1510ff414cSEd MasteIn order to simplify version comparisons, the version is also exported as
1610ff414cSEd Maste
1710ff414cSEd Maste.. code-block:: c
1810ff414cSEd Maste
1910ff414cSEd Maste  #define CBOR_HEX_VERSION ((CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION)
2010ff414cSEd Maste
2110ff414cSEd MasteSince macros are difficult to work with through FFIs, the same information is also available through three ``uint8_t`` constants,
2210ff414cSEd Mastenamely
2310ff414cSEd Maste
2410ff414cSEd Maste - ``cbor_major_version``
2510ff414cSEd Maste - ``cbor_minor_version``
2610ff414cSEd Maste - ``cbor_patch_version``
2710ff414cSEd Maste
2810ff414cSEd Maste
2910ff414cSEd MasteHeaders to include
3010ff414cSEd Maste---------------------
3110ff414cSEd Maste
3210ff414cSEd MasteThe ``cbor.h`` header includes all the symbols. If, for any reason, you don't want to include all the exported symbols,
3310ff414cSEd Mastefeel free to use just some of the ``cbor/*.h`` headers:
3410ff414cSEd Maste
3510ff414cSEd Maste - ``cbor/arrays.h`` - :doc:`api/type_4`
3610ff414cSEd Maste - ``cbor/bytestrings.h`` - :doc:`api/type_2`
37*5d3e7166SEd Maste - ``cbor/callbacks.h`` - Callbacks used for :doc:`api/streaming_decoding`
3810ff414cSEd Maste - ``cbor/common.h`` - Common utilities - always transitively included
3910ff414cSEd Maste - ``cbor/data.h`` - Data types definitions - always transitively included
40*5d3e7166SEd Maste - ``cbor/encoding.h`` - Streaming encoders for :doc:`api/streaming_encoding`
4110ff414cSEd Maste - ``cbor/floats_ctrls.h`` - :doc:`api/type_7`
4210ff414cSEd Maste - ``cbor/ints.h`` - :doc:`api/type_0_1`
4310ff414cSEd Maste - ``cbor/maps.h`` - :doc:`api/type_5`
4410ff414cSEd Maste - ``cbor/serialization.h`` - High level serialization such as :func:`cbor_serialize`
4510ff414cSEd Maste - ``cbor/streaming.h`` - Home of :func:`cbor_stream_decode`
4610ff414cSEd Maste - ``cbor/strings.h`` - :doc:`api/type_3`
4710ff414cSEd Maste - ``cbor/tags.h`` - :doc:`api/type_6`
4810ff414cSEd Maste
4910ff414cSEd Maste
5010ff414cSEd MasteUsing libcbor
5110ff414cSEd Maste--------------
5210ff414cSEd Maste
5310ff414cSEd MasteIf you want to get more familiar with CBOR, we recommend the `cbor.io <http://cbor.io/>`_ website. Once you get the grasp
5410ff414cSEd Masteof what is it CBOR does, the examples (located in the ``examples`` directory) should give you a good feel of the API. The
5510ff414cSEd Maste:doc:`API documentation <api>` should then provide with all the information you may need.
5610ff414cSEd Maste
5710ff414cSEd Maste
5810ff414cSEd Maste**Creating and serializing items**
5910ff414cSEd Maste
6010ff414cSEd Maste.. code-block:: c
6110ff414cSEd Maste
6210ff414cSEd Maste    #include "cbor.h"
6310ff414cSEd Maste    #include <stdio.h>
6410ff414cSEd Maste
6510ff414cSEd Maste    int main(int argc, char * argv[])
6610ff414cSEd Maste    {
6710ff414cSEd Maste        /* Preallocate the map structure */
6810ff414cSEd Maste        cbor_item_t * root = cbor_new_definite_map(2);
6910ff414cSEd Maste        /* Add the content */
7010ff414cSEd Maste        cbor_map_add(root, (struct cbor_pair) {
7110ff414cSEd Maste            .key = cbor_move(cbor_build_string("Is CBOR awesome?")),
7210ff414cSEd Maste            .value = cbor_move(cbor_build_bool(true))
7310ff414cSEd Maste        });
7410ff414cSEd Maste        cbor_map_add(root, (struct cbor_pair) {
7510ff414cSEd Maste            .key = cbor_move(cbor_build_uint8(42)),
7610ff414cSEd Maste            .value = cbor_move(cbor_build_string("Is the answer"))
7710ff414cSEd Maste        });
78*5d3e7166SEd Maste        /* Output: `buffer_size` bytes of data in the `buffer` */
7910ff414cSEd Maste        unsigned char * buffer;
80*5d3e7166SEd Maste        size_t buffer_size;
81*5d3e7166SEd Maste        cbor_serialize_alloc(root, &buffer, &buffer_size);
8210ff414cSEd Maste
83*5d3e7166SEd Maste        fwrite(buffer, 1, buffer_size, stdout);
8410ff414cSEd Maste        free(buffer);
8510ff414cSEd Maste
8610ff414cSEd Maste        fflush(stdout);
8710ff414cSEd Maste        cbor_decref(&root);
8810ff414cSEd Maste    }
8910ff414cSEd Maste
9010ff414cSEd Maste
9110ff414cSEd Maste**Reading serialized data**
9210ff414cSEd Maste
9310ff414cSEd Maste.. code-block:: c
9410ff414cSEd Maste
9510ff414cSEd Maste    #include "cbor.h"
9610ff414cSEd Maste    #include <stdio.h>
9710ff414cSEd Maste
9810ff414cSEd Maste    /*
9910ff414cSEd Maste     * Reads data from a file. Example usage:
10010ff414cSEd Maste     * $ ./examples/readfile examples/data/nested_array.cbor
10110ff414cSEd Maste     */
10210ff414cSEd Maste
10310ff414cSEd Maste    int main(int argc, char * argv[])
10410ff414cSEd Maste    {
10510ff414cSEd Maste        FILE * f = fopen(argv[1], "rb");
10610ff414cSEd Maste        fseek(f, 0, SEEK_END);
10710ff414cSEd Maste        size_t length = (size_t)ftell(f);
10810ff414cSEd Maste        fseek(f, 0, SEEK_SET);
10910ff414cSEd Maste        unsigned char * buffer = malloc(length);
11010ff414cSEd Maste        fread(buffer, length, 1, f);
11110ff414cSEd Maste
11210ff414cSEd Maste        /* Assuming `buffer` contains `info.st_size` bytes of input data */
11310ff414cSEd Maste        struct cbor_load_result result;
11410ff414cSEd Maste        cbor_item_t * item = cbor_load(buffer, length, &result);
11510ff414cSEd Maste        /* Pretty-print the result */
11610ff414cSEd Maste        cbor_describe(item, stdout);
11710ff414cSEd Maste        fflush(stdout);
11810ff414cSEd Maste        /* Deallocate the result */
11910ff414cSEd Maste        cbor_decref(&item);
12010ff414cSEd Maste
12110ff414cSEd Maste        fclose(f);
12210ff414cSEd Maste    }
12310ff414cSEd Maste
12410ff414cSEd Maste
12510ff414cSEd Maste**Using the streaming parser**
12610ff414cSEd Maste
12710ff414cSEd Maste.. code-block:: c
12810ff414cSEd Maste
12910ff414cSEd Maste    #include "cbor.h"
13010ff414cSEd Maste    #include <stdio.h>
13110ff414cSEd Maste    #include <string.h>
13210ff414cSEd Maste
13310ff414cSEd Maste    /*
13410ff414cSEd Maste     * Illustrates how one might skim through a map (which is assumed to have
13510ff414cSEd Maste     * string keys and values only), looking for the value of a specific key
13610ff414cSEd Maste     *
13710ff414cSEd Maste     * Use the examples/data/map.cbor input to test this.
13810ff414cSEd Maste     */
13910ff414cSEd Maste
14010ff414cSEd Maste    const char * key = "a secret key";
14110ff414cSEd Maste    bool key_found = false;
14210ff414cSEd Maste
14310ff414cSEd Maste    void find_string(void * _ctx, cbor_data buffer, size_t len)
14410ff414cSEd Maste    {
14510ff414cSEd Maste        if (key_found) {
14610ff414cSEd Maste            printf("Found the value: %*s\n", (int) len, buffer);
14710ff414cSEd Maste            key_found = false;
14810ff414cSEd Maste        } else if (len == strlen(key)) {
14910ff414cSEd Maste            key_found = (memcmp(key, buffer, len) == 0);
15010ff414cSEd Maste        }
15110ff414cSEd Maste    }
15210ff414cSEd Maste
15310ff414cSEd Maste    int main(int argc, char * argv[])
15410ff414cSEd Maste    {
15510ff414cSEd Maste        FILE * f = fopen(argv[1], "rb");
15610ff414cSEd Maste        fseek(f, 0, SEEK_END);
15710ff414cSEd Maste        size_t length = (size_t)ftell(f);
15810ff414cSEd Maste        fseek(f, 0, SEEK_SET);
15910ff414cSEd Maste        unsigned char * buffer = malloc(length);
16010ff414cSEd Maste        fread(buffer, length, 1, f);
16110ff414cSEd Maste
16210ff414cSEd Maste        struct cbor_callbacks callbacks = cbor_empty_callbacks;
16310ff414cSEd Maste        struct cbor_decoder_result decode_result;
16410ff414cSEd Maste        size_t bytes_read = 0;
16510ff414cSEd Maste        callbacks.string = find_string;
16610ff414cSEd Maste        while (bytes_read < length) {
16710ff414cSEd Maste            decode_result = cbor_stream_decode(buffer + bytes_read,
16810ff414cSEd Maste                                               length - bytes_read,
16910ff414cSEd Maste                                               &callbacks, NULL);
17010ff414cSEd Maste            bytes_read += decode_result.read;
17110ff414cSEd Maste        }
17210ff414cSEd Maste
17310ff414cSEd Maste        fclose(f);
17410ff414cSEd Maste    }
175