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