aboutsummaryrefslogtreecommitdiff
path: root/doc/source/using.rst
blob: dbc09819d46beea79ea494e2a43a453d9973fd41 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
Usage & preliminaries
=======================

Version information
--------------------

libcbor exports its version using three self-explanatory macros:

 - ``CBOR_MAJOR_VERSION``
 - ``CBOR_MINOR_VERSION``
 - ``CBOR_PATCH_VERSION``

The ``CBOR_VERSION`` is a string concatenating these three identifiers into one (e.g. ``0.2.0``).

In order to simplify version comparisons, the version is also exported as

.. code-block:: c

  #define CBOR_HEX_VERSION ((CBOR_MAJOR_VERSION << 16) | (CBOR_MINOR_VERSION << 8) | CBOR_PATCH_VERSION)

Since macros are difficult to work with through FFIs, the same information is also available through three ``uint8_t`` constants,
namely

 - ``cbor_major_version``
 - ``cbor_minor_version``
 - ``cbor_patch_version``


Headers to include
---------------------

The ``cbor.h`` header includes all the symbols. If, for any reason, you don't want to include all the exported symbols,
feel free to use just some of the ``cbor/*.h`` headers:

 - ``cbor/arrays.h`` - :doc:`api/type_4`
 - ``cbor/bytestrings.h`` - :doc:`api/type_2`
 - ``cbor/callbacks.h`` - Callbacks used for :doc:`streaming/decoding`
 - ``cbor/common.h`` - Common utilities - always transitively included
 - ``cbor/data.h`` - Data types definitions - always transitively included
 - ``cbor/encoding.h`` - Streaming encoders for :doc:`streaming/encoding`
 - ``cbor/floats_ctrls.h`` - :doc:`api/type_7`
 - ``cbor/ints.h`` - :doc:`api/type_0_1`
 - ``cbor/maps.h`` - :doc:`api/type_5`
 - ``cbor/serialization.h`` - High level serialization such as :func:`cbor_serialize`
 - ``cbor/streaming.h`` - Home of :func:`cbor_stream_decode`
 - ``cbor/strings.h`` - :doc:`api/type_3`
 - ``cbor/tags.h`` - :doc:`api/type_6`


Using libcbor
--------------

If you want to get more familiar with CBOR, we recommend the `cbor.io <http://cbor.io/>`_ website. Once you get the grasp
of what is it CBOR does, the examples (located in the ``examples`` directory) should give you a good feel of the API. The
:doc:`API documentation <api>` should then provide with all the information you may need.


**Creating and serializing items**

.. code-block:: 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: `length` bytes of data in the `buffer` */
        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);
    }


**Reading serialized data**

.. code-block:: 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 `buffer` contains `info.st_size` 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);
    }


**Using the streaming parser**

.. code-block:: 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\n", (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);
    }