xref: /freebsd/contrib/libcbor/doc/source/using.rst (revision 5d3e7166)
1Usage & preliminaries
2=======================
3
4Version information
5--------------------
6
7libcbor exports its version using three self-explanatory macros:
8
9 - ``CBOR_MAJOR_VERSION``
10 - ``CBOR_MINOR_VERSION``
11 - ``CBOR_PATCH_VERSION``
12
13The ``CBOR_VERSION`` is a string concatenating these three identifiers into one (e.g. ``0.2.0``).
14
15In order to simplify version comparisons, the version is also exported as
16
17.. code-block:: c
18
19  #define CBOR_HEX_VERSION ((CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION)
20
21Since macros are difficult to work with through FFIs, the same information is also available through three ``uint8_t`` constants,
22namely
23
24 - ``cbor_major_version``
25 - ``cbor_minor_version``
26 - ``cbor_patch_version``
27
28
29Headers to include
30---------------------
31
32The ``cbor.h`` header includes all the symbols. If, for any reason, you don't want to include all the exported symbols,
33feel free to use just some of the ``cbor/*.h`` headers:
34
35 - ``cbor/arrays.h`` - :doc:`api/type_4`
36 - ``cbor/bytestrings.h`` - :doc:`api/type_2`
37 - ``cbor/callbacks.h`` - Callbacks used for :doc:`api/streaming_decoding`
38 - ``cbor/common.h`` - Common utilities - always transitively included
39 - ``cbor/data.h`` - Data types definitions - always transitively included
40 - ``cbor/encoding.h`` - Streaming encoders for :doc:`api/streaming_encoding`
41 - ``cbor/floats_ctrls.h`` - :doc:`api/type_7`
42 - ``cbor/ints.h`` - :doc:`api/type_0_1`
43 - ``cbor/maps.h`` - :doc:`api/type_5`
44 - ``cbor/serialization.h`` - High level serialization such as :func:`cbor_serialize`
45 - ``cbor/streaming.h`` - Home of :func:`cbor_stream_decode`
46 - ``cbor/strings.h`` - :doc:`api/type_3`
47 - ``cbor/tags.h`` - :doc:`api/type_6`
48
49
50Using libcbor
51--------------
52
53If you want to get more familiar with CBOR, we recommend the `cbor.io <http://cbor.io/>`_ website. Once you get the grasp
54of what is it CBOR does, the examples (located in the ``examples`` directory) should give you a good feel of the API. The
55:doc:`API documentation <api>` should then provide with all the information you may need.
56
57
58**Creating and serializing items**
59
60.. code-block:: c
61
62    #include "cbor.h"
63    #include <stdio.h>
64
65    int main(int argc, char * argv[])
66    {
67        /* Preallocate the map structure */
68        cbor_item_t * root = cbor_new_definite_map(2);
69        /* Add the content */
70        cbor_map_add(root, (struct cbor_pair) {
71            .key = cbor_move(cbor_build_string("Is CBOR awesome?")),
72            .value = cbor_move(cbor_build_bool(true))
73        });
74        cbor_map_add(root, (struct cbor_pair) {
75            .key = cbor_move(cbor_build_uint8(42)),
76            .value = cbor_move(cbor_build_string("Is the answer"))
77        });
78        /* Output: `buffer_size` bytes of data in the `buffer` */
79        unsigned char * buffer;
80        size_t buffer_size;
81        cbor_serialize_alloc(root, &buffer, &buffer_size);
82
83        fwrite(buffer, 1, buffer_size, stdout);
84        free(buffer);
85
86        fflush(stdout);
87        cbor_decref(&root);
88    }
89
90
91**Reading serialized data**
92
93.. code-block:: c
94
95    #include "cbor.h"
96    #include <stdio.h>
97
98    /*
99     * Reads data from a file. Example usage:
100     * $ ./examples/readfile examples/data/nested_array.cbor
101     */
102
103    int main(int argc, char * argv[])
104    {
105        FILE * f = fopen(argv[1], "rb");
106        fseek(f, 0, SEEK_END);
107        size_t length = (size_t)ftell(f);
108        fseek(f, 0, SEEK_SET);
109        unsigned char * buffer = malloc(length);
110        fread(buffer, length, 1, f);
111
112        /* Assuming `buffer` contains `info.st_size` bytes of input data */
113        struct cbor_load_result result;
114        cbor_item_t * item = cbor_load(buffer, length, &result);
115        /* Pretty-print the result */
116        cbor_describe(item, stdout);
117        fflush(stdout);
118        /* Deallocate the result */
119        cbor_decref(&item);
120
121        fclose(f);
122    }
123
124
125**Using the streaming parser**
126
127.. code-block:: c
128
129    #include "cbor.h"
130    #include <stdio.h>
131    #include <string.h>
132
133    /*
134     * Illustrates how one might skim through a map (which is assumed to have
135     * string keys and values only), looking for the value of a specific key
136     *
137     * Use the examples/data/map.cbor input to test this.
138     */
139
140    const char * key = "a secret key";
141    bool key_found = false;
142
143    void find_string(void * _ctx, cbor_data buffer, size_t len)
144    {
145        if (key_found) {
146            printf("Found the value: %*s\n", (int) len, buffer);
147            key_found = false;
148        } else if (len == strlen(key)) {
149            key_found = (memcmp(key, buffer, len) == 0);
150        }
151    }
152
153    int main(int argc, char * argv[])
154    {
155        FILE * f = fopen(argv[1], "rb");
156        fseek(f, 0, SEEK_END);
157        size_t length = (size_t)ftell(f);
158        fseek(f, 0, SEEK_SET);
159        unsigned char * buffer = malloc(length);
160        fread(buffer, length, 1, f);
161
162        struct cbor_callbacks callbacks = cbor_empty_callbacks;
163        struct cbor_decoder_result decode_result;
164        size_t bytes_read = 0;
165        callbacks.string = find_string;
166        while (bytes_read < length) {
167            decode_result = cbor_stream_decode(buffer + bytes_read,
168                                               length - bytes_read,
169                                               &callbacks, NULL);
170            bytes_read += decode_result.read;
171        }
172
173        fclose(f);
174    }
175