1da0d961cSdjm /*
2d3425be1Sdjm * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3da0d961cSdjm *
4da0d961cSdjm * libcbor is free software; you can redistribute it and/or modify
5da0d961cSdjm * it under the terms of the MIT license. See LICENSE for details.
6da0d961cSdjm */
7da0d961cSdjm
8da0d961cSdjm #include "serialization.h"
99e5c2ddcSdjm #include <string.h>
10da0d961cSdjm #include "cbor/arrays.h"
11da0d961cSdjm #include "cbor/bytestrings.h"
12da0d961cSdjm #include "cbor/floats_ctrls.h"
13da0d961cSdjm #include "cbor/ints.h"
14da0d961cSdjm #include "cbor/maps.h"
15da0d961cSdjm #include "cbor/strings.h"
16da0d961cSdjm #include "cbor/tags.h"
179e5c2ddcSdjm #include "encoding.h"
18da0d961cSdjm #include "internal/memory_utils.h"
19da0d961cSdjm
cbor_serialize(const cbor_item_t * item,unsigned char * buffer,size_t buffer_size)209e5c2ddcSdjm size_t cbor_serialize(const cbor_item_t *item, unsigned char *buffer,
219e5c2ddcSdjm size_t buffer_size) {
22*4dcc46c4Sdjm // cppcheck-suppress missingReturn
23da0d961cSdjm switch (cbor_typeof(item)) {
24da0d961cSdjm case CBOR_TYPE_UINT:
25da0d961cSdjm return cbor_serialize_uint(item, buffer, buffer_size);
26da0d961cSdjm case CBOR_TYPE_NEGINT:
27da0d961cSdjm return cbor_serialize_negint(item, buffer, buffer_size);
28da0d961cSdjm case CBOR_TYPE_BYTESTRING:
29da0d961cSdjm return cbor_serialize_bytestring(item, buffer, buffer_size);
30da0d961cSdjm case CBOR_TYPE_STRING:
31da0d961cSdjm return cbor_serialize_string(item, buffer, buffer_size);
32da0d961cSdjm case CBOR_TYPE_ARRAY:
33da0d961cSdjm return cbor_serialize_array(item, buffer, buffer_size);
34da0d961cSdjm case CBOR_TYPE_MAP:
35da0d961cSdjm return cbor_serialize_map(item, buffer, buffer_size);
36da0d961cSdjm case CBOR_TYPE_TAG:
37da0d961cSdjm return cbor_serialize_tag(item, buffer, buffer_size);
38da0d961cSdjm case CBOR_TYPE_FLOAT_CTRL:
39da0d961cSdjm return cbor_serialize_float_ctrl(item, buffer, buffer_size);
40*4dcc46c4Sdjm }
41*4dcc46c4Sdjm }
42*4dcc46c4Sdjm
43*4dcc46c4Sdjm /** Largest integer that can be encoded as embedded in the item leading byte. */
44*4dcc46c4Sdjm const uint64_t kMaxEmbeddedInt = 23;
45*4dcc46c4Sdjm
46*4dcc46c4Sdjm /** How many bytes will a tag for a nested item of a given `size` take when
47*4dcc46c4Sdjm * encoded.*/
_cbor_encoded_header_size(uint64_t size)48*4dcc46c4Sdjm size_t _cbor_encoded_header_size(uint64_t size) {
49*4dcc46c4Sdjm if (size <= kMaxEmbeddedInt)
50*4dcc46c4Sdjm return 1;
51*4dcc46c4Sdjm else if (size <= UINT8_MAX)
52*4dcc46c4Sdjm return 2;
53*4dcc46c4Sdjm else if (size <= UINT16_MAX)
54*4dcc46c4Sdjm return 3;
55*4dcc46c4Sdjm else if (size <= UINT32_MAX)
56*4dcc46c4Sdjm return 5;
57*4dcc46c4Sdjm else
58*4dcc46c4Sdjm return 9;
59*4dcc46c4Sdjm }
60*4dcc46c4Sdjm
cbor_serialized_size(const cbor_item_t * item)61*4dcc46c4Sdjm size_t cbor_serialized_size(const cbor_item_t *item) {
62*4dcc46c4Sdjm // cppcheck-suppress missingReturn
63*4dcc46c4Sdjm switch (cbor_typeof(item)) {
64*4dcc46c4Sdjm case CBOR_TYPE_UINT:
65*4dcc46c4Sdjm case CBOR_TYPE_NEGINT:
66*4dcc46c4Sdjm switch (cbor_int_get_width(item)) {
67*4dcc46c4Sdjm case CBOR_INT_8:
68*4dcc46c4Sdjm if (cbor_get_uint8(item) <= kMaxEmbeddedInt) return 1;
69*4dcc46c4Sdjm return 2;
70*4dcc46c4Sdjm case CBOR_INT_16:
71*4dcc46c4Sdjm return 3;
72*4dcc46c4Sdjm case CBOR_INT_32:
73*4dcc46c4Sdjm return 5;
74*4dcc46c4Sdjm case CBOR_INT_64:
75*4dcc46c4Sdjm return 9;
76*4dcc46c4Sdjm }
77*4dcc46c4Sdjm // Note: We do not _cbor_safe_signaling_add zero-length definite strings,
78*4dcc46c4Sdjm // they would cause zeroes to propagate. All other items are at least one
79*4dcc46c4Sdjm // byte.
80*4dcc46c4Sdjm case CBOR_TYPE_BYTESTRING: {
81*4dcc46c4Sdjm if (cbor_bytestring_is_definite(item)) {
82*4dcc46c4Sdjm size_t header_size =
83*4dcc46c4Sdjm _cbor_encoded_header_size(cbor_bytestring_length(item));
84*4dcc46c4Sdjm if (cbor_bytestring_length(item) == 0) return header_size;
85*4dcc46c4Sdjm return _cbor_safe_signaling_add(header_size,
86*4dcc46c4Sdjm cbor_bytestring_length(item));
87*4dcc46c4Sdjm }
88*4dcc46c4Sdjm size_t indef_bytestring_size = 2; // Leading byte + break
89*4dcc46c4Sdjm cbor_item_t **chunks = cbor_bytestring_chunks_handle(item);
90*4dcc46c4Sdjm for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++) {
91*4dcc46c4Sdjm indef_bytestring_size = _cbor_safe_signaling_add(
92*4dcc46c4Sdjm indef_bytestring_size, cbor_serialized_size(chunks[i]));
93*4dcc46c4Sdjm }
94*4dcc46c4Sdjm return indef_bytestring_size;
95*4dcc46c4Sdjm }
96*4dcc46c4Sdjm case CBOR_TYPE_STRING: {
97*4dcc46c4Sdjm if (cbor_string_is_definite(item)) {
98*4dcc46c4Sdjm size_t header_size =
99*4dcc46c4Sdjm _cbor_encoded_header_size(cbor_string_length(item));
100*4dcc46c4Sdjm if (cbor_string_length(item) == 0) return header_size;
101*4dcc46c4Sdjm return _cbor_safe_signaling_add(header_size, cbor_string_length(item));
102*4dcc46c4Sdjm }
103*4dcc46c4Sdjm size_t indef_string_size = 2; // Leading byte + break
104*4dcc46c4Sdjm cbor_item_t **chunks = cbor_string_chunks_handle(item);
105*4dcc46c4Sdjm for (size_t i = 0; i < cbor_string_chunk_count(item); i++) {
106*4dcc46c4Sdjm indef_string_size = _cbor_safe_signaling_add(
107*4dcc46c4Sdjm indef_string_size, cbor_serialized_size(chunks[i]));
108*4dcc46c4Sdjm }
109*4dcc46c4Sdjm return indef_string_size;
110*4dcc46c4Sdjm }
111*4dcc46c4Sdjm case CBOR_TYPE_ARRAY: {
112*4dcc46c4Sdjm size_t array_size = cbor_array_is_definite(item)
113*4dcc46c4Sdjm ? _cbor_encoded_header_size(cbor_array_size(item))
114*4dcc46c4Sdjm : 2; // Leading byte + break
115*4dcc46c4Sdjm cbor_item_t **items = cbor_array_handle(item);
116*4dcc46c4Sdjm for (size_t i = 0; i < cbor_array_size(item); i++) {
117*4dcc46c4Sdjm array_size = _cbor_safe_signaling_add(array_size,
118*4dcc46c4Sdjm cbor_serialized_size(items[i]));
119*4dcc46c4Sdjm }
120*4dcc46c4Sdjm return array_size;
121*4dcc46c4Sdjm }
122*4dcc46c4Sdjm case CBOR_TYPE_MAP: {
123*4dcc46c4Sdjm size_t map_size = cbor_map_is_definite(item)
124*4dcc46c4Sdjm ? _cbor_encoded_header_size(cbor_map_size(item))
125*4dcc46c4Sdjm : 2; // Leading byte + break
126*4dcc46c4Sdjm struct cbor_pair *items = cbor_map_handle(item);
127*4dcc46c4Sdjm for (size_t i = 0; i < cbor_map_size(item); i++) {
128*4dcc46c4Sdjm map_size = _cbor_safe_signaling_add(
129*4dcc46c4Sdjm map_size,
130*4dcc46c4Sdjm _cbor_safe_signaling_add(cbor_serialized_size(items[i].key),
131*4dcc46c4Sdjm cbor_serialized_size(items[i].value)));
132*4dcc46c4Sdjm }
133*4dcc46c4Sdjm return map_size;
134*4dcc46c4Sdjm }
135*4dcc46c4Sdjm case CBOR_TYPE_TAG: {
136*4dcc46c4Sdjm return _cbor_safe_signaling_add(
137*4dcc46c4Sdjm _cbor_encoded_header_size(cbor_tag_value(item)),
138*4dcc46c4Sdjm cbor_serialized_size(cbor_move(cbor_tag_item(item))));
139*4dcc46c4Sdjm }
140*4dcc46c4Sdjm case CBOR_TYPE_FLOAT_CTRL:
141*4dcc46c4Sdjm switch (cbor_float_get_width(item)) {
142*4dcc46c4Sdjm case CBOR_FLOAT_0:
143*4dcc46c4Sdjm return _cbor_encoded_header_size(cbor_ctrl_value(item));
144*4dcc46c4Sdjm case CBOR_FLOAT_16:
145*4dcc46c4Sdjm return 3;
146*4dcc46c4Sdjm case CBOR_FLOAT_32:
147*4dcc46c4Sdjm return 5;
148*4dcc46c4Sdjm case CBOR_FLOAT_64:
149*4dcc46c4Sdjm return 9;
150*4dcc46c4Sdjm }
151da0d961cSdjm }
152da0d961cSdjm }
153da0d961cSdjm
cbor_serialize_alloc(const cbor_item_t * item,unsigned char ** buffer,size_t * buffer_size)1549e5c2ddcSdjm size_t cbor_serialize_alloc(const cbor_item_t *item, unsigned char **buffer,
1559e5c2ddcSdjm size_t *buffer_size) {
156*4dcc46c4Sdjm *buffer = NULL;
157*4dcc46c4Sdjm size_t serialized_size = cbor_serialized_size(item);
158*4dcc46c4Sdjm if (serialized_size == 0) {
159*4dcc46c4Sdjm if (buffer_size != NULL) *buffer_size = 0;
160*4dcc46c4Sdjm return 0;
161*4dcc46c4Sdjm }
162*4dcc46c4Sdjm *buffer = _cbor_malloc(serialized_size);
163*4dcc46c4Sdjm if (*buffer == NULL) {
164*4dcc46c4Sdjm if (buffer_size != NULL) *buffer_size = 0;
165da0d961cSdjm return 0;
166da0d961cSdjm }
167da0d961cSdjm
168*4dcc46c4Sdjm size_t written = cbor_serialize(item, *buffer, serialized_size);
169*4dcc46c4Sdjm CBOR_ASSERT(written == serialized_size);
170*4dcc46c4Sdjm if (buffer_size != NULL) *buffer_size = serialized_size;
171da0d961cSdjm return written;
172da0d961cSdjm }
173da0d961cSdjm
cbor_serialize_uint(const cbor_item_t * item,unsigned char * buffer,size_t buffer_size)1749e5c2ddcSdjm size_t cbor_serialize_uint(const cbor_item_t *item, unsigned char *buffer,
1759e5c2ddcSdjm size_t buffer_size) {
176*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_uint(item));
177*4dcc46c4Sdjm // cppcheck-suppress missingReturn
178da0d961cSdjm switch (cbor_int_get_width(item)) {
179da0d961cSdjm case CBOR_INT_8:
180da0d961cSdjm return cbor_encode_uint8(cbor_get_uint8(item), buffer, buffer_size);
181da0d961cSdjm case CBOR_INT_16:
182da0d961cSdjm return cbor_encode_uint16(cbor_get_uint16(item), buffer, buffer_size);
183da0d961cSdjm case CBOR_INT_32:
184da0d961cSdjm return cbor_encode_uint32(cbor_get_uint32(item), buffer, buffer_size);
185da0d961cSdjm case CBOR_INT_64:
186da0d961cSdjm return cbor_encode_uint64(cbor_get_uint64(item), buffer, buffer_size);
187da0d961cSdjm }
188da0d961cSdjm }
189da0d961cSdjm
cbor_serialize_negint(const cbor_item_t * item,unsigned char * buffer,size_t buffer_size)1909e5c2ddcSdjm size_t cbor_serialize_negint(const cbor_item_t *item, unsigned char *buffer,
1919e5c2ddcSdjm size_t buffer_size) {
192*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_negint(item));
193*4dcc46c4Sdjm // cppcheck-suppress missingReturn
194da0d961cSdjm switch (cbor_int_get_width(item)) {
195da0d961cSdjm case CBOR_INT_8:
196da0d961cSdjm return cbor_encode_negint8(cbor_get_uint8(item), buffer, buffer_size);
197da0d961cSdjm case CBOR_INT_16:
198da0d961cSdjm return cbor_encode_negint16(cbor_get_uint16(item), buffer, buffer_size);
199da0d961cSdjm case CBOR_INT_32:
200da0d961cSdjm return cbor_encode_negint32(cbor_get_uint32(item), buffer, buffer_size);
201da0d961cSdjm case CBOR_INT_64:
202da0d961cSdjm return cbor_encode_negint64(cbor_get_uint64(item), buffer, buffer_size);
203da0d961cSdjm }
204da0d961cSdjm }
205da0d961cSdjm
cbor_serialize_bytestring(const cbor_item_t * item,unsigned char * buffer,size_t buffer_size)2069e5c2ddcSdjm size_t cbor_serialize_bytestring(const cbor_item_t *item, unsigned char *buffer,
2079e5c2ddcSdjm size_t buffer_size) {
208*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_bytestring(item));
209da0d961cSdjm if (cbor_bytestring_is_definite(item)) {
210da0d961cSdjm size_t length = cbor_bytestring_length(item);
211da0d961cSdjm size_t written = cbor_encode_bytestring_start(length, buffer, buffer_size);
212*4dcc46c4Sdjm if (written > 0 && (buffer_size - written >= length)) {
213da0d961cSdjm memcpy(buffer + written, cbor_bytestring_handle(item), length);
214da0d961cSdjm return written + length;
215*4dcc46c4Sdjm }
216da0d961cSdjm return 0;
217da0d961cSdjm } else {
218*4dcc46c4Sdjm CBOR_ASSERT(cbor_bytestring_is_indefinite(item));
219da0d961cSdjm size_t chunk_count = cbor_bytestring_chunk_count(item);
220da0d961cSdjm size_t written = cbor_encode_indef_bytestring_start(buffer, buffer_size);
2219e5c2ddcSdjm if (written == 0) return 0;
222da0d961cSdjm
223da0d961cSdjm cbor_item_t **chunks = cbor_bytestring_chunks_handle(item);
224da0d961cSdjm for (size_t i = 0; i < chunk_count; i++) {
2259e5c2ddcSdjm size_t chunk_written = cbor_serialize_bytestring(
2269e5c2ddcSdjm chunks[i], buffer + written, buffer_size - written);
227*4dcc46c4Sdjm if (chunk_written == 0) return 0;
228da0d961cSdjm written += chunk_written;
229da0d961cSdjm }
230*4dcc46c4Sdjm
231*4dcc46c4Sdjm size_t break_written =
232*4dcc46c4Sdjm cbor_encode_break(buffer + written, buffer_size - written);
233*4dcc46c4Sdjm if (break_written == 0) return 0;
234*4dcc46c4Sdjm return written + break_written;
235da0d961cSdjm }
236da0d961cSdjm }
237da0d961cSdjm
cbor_serialize_string(const cbor_item_t * item,unsigned char * buffer,size_t buffer_size)2389e5c2ddcSdjm size_t cbor_serialize_string(const cbor_item_t *item, unsigned char *buffer,
2399e5c2ddcSdjm size_t buffer_size) {
240*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_string(item));
241da0d961cSdjm if (cbor_string_is_definite(item)) {
242da0d961cSdjm size_t length = cbor_string_length(item);
243da0d961cSdjm size_t written = cbor_encode_string_start(length, buffer, buffer_size);
244da0d961cSdjm if (written && (buffer_size - written >= length)) {
245da0d961cSdjm memcpy(buffer + written, cbor_string_handle(item), length);
246da0d961cSdjm return written + length;
247*4dcc46c4Sdjm }
248da0d961cSdjm return 0;
249da0d961cSdjm } else {
250*4dcc46c4Sdjm CBOR_ASSERT(cbor_string_is_indefinite(item));
251da0d961cSdjm size_t chunk_count = cbor_string_chunk_count(item);
252da0d961cSdjm size_t written = cbor_encode_indef_string_start(buffer, buffer_size);
2539e5c2ddcSdjm if (written == 0) return 0;
254da0d961cSdjm
255da0d961cSdjm cbor_item_t **chunks = cbor_string_chunks_handle(item);
256da0d961cSdjm for (size_t i = 0; i < chunk_count; i++) {
2579e5c2ddcSdjm size_t chunk_written = cbor_serialize_string(chunks[i], buffer + written,
2589e5c2ddcSdjm buffer_size - written);
259*4dcc46c4Sdjm if (chunk_written == 0) return 0;
260da0d961cSdjm written += chunk_written;
261da0d961cSdjm }
262*4dcc46c4Sdjm
263*4dcc46c4Sdjm size_t break_written =
264*4dcc46c4Sdjm cbor_encode_break(buffer + written, buffer_size - written);
265*4dcc46c4Sdjm if (break_written == 0) return 0;
266*4dcc46c4Sdjm return written + break_written;
267da0d961cSdjm }
268da0d961cSdjm }
269da0d961cSdjm
cbor_serialize_array(const cbor_item_t * item,unsigned char * buffer,size_t buffer_size)2709e5c2ddcSdjm size_t cbor_serialize_array(const cbor_item_t *item, unsigned char *buffer,
2719e5c2ddcSdjm size_t buffer_size) {
272*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_array(item));
2739e5c2ddcSdjm size_t size = cbor_array_size(item), written = 0;
274da0d961cSdjm cbor_item_t **handle = cbor_array_handle(item);
275da0d961cSdjm if (cbor_array_is_definite(item)) {
276da0d961cSdjm written = cbor_encode_array_start(size, buffer, buffer_size);
277da0d961cSdjm } else {
278*4dcc46c4Sdjm CBOR_ASSERT(cbor_array_is_indefinite(item));
279da0d961cSdjm written = cbor_encode_indef_array_start(buffer, buffer_size);
280da0d961cSdjm }
2819e5c2ddcSdjm if (written == 0) return 0;
282da0d961cSdjm
283da0d961cSdjm for (size_t i = 0; i < size; i++) {
284*4dcc46c4Sdjm size_t item_written =
2859e5c2ddcSdjm cbor_serialize(*(handle++), buffer + written, buffer_size - written);
286*4dcc46c4Sdjm if (item_written == 0) return 0;
287da0d961cSdjm written += item_written;
288da0d961cSdjm }
289da0d961cSdjm
290da0d961cSdjm if (cbor_array_is_definite(item)) {
291da0d961cSdjm return written;
292da0d961cSdjm } else {
293*4dcc46c4Sdjm CBOR_ASSERT(cbor_array_is_indefinite(item));
294*4dcc46c4Sdjm size_t break_written =
295*4dcc46c4Sdjm cbor_encode_break(buffer + written, buffer_size - written);
296*4dcc46c4Sdjm if (break_written == 0) return 0;
297*4dcc46c4Sdjm return written + break_written;
298da0d961cSdjm }
299da0d961cSdjm }
300da0d961cSdjm
cbor_serialize_map(const cbor_item_t * item,unsigned char * buffer,size_t buffer_size)3019e5c2ddcSdjm size_t cbor_serialize_map(const cbor_item_t *item, unsigned char *buffer,
3029e5c2ddcSdjm size_t buffer_size) {
303*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_map(item));
3049e5c2ddcSdjm size_t size = cbor_map_size(item), written = 0;
305da0d961cSdjm struct cbor_pair *handle = cbor_map_handle(item);
306da0d961cSdjm
307da0d961cSdjm if (cbor_map_is_definite(item)) {
308da0d961cSdjm written = cbor_encode_map_start(size, buffer, buffer_size);
309da0d961cSdjm } else {
310*4dcc46c4Sdjm CBOR_ASSERT(cbor_map_is_indefinite(item));
311da0d961cSdjm written = cbor_encode_indef_map_start(buffer, buffer_size);
312da0d961cSdjm }
3139e5c2ddcSdjm if (written == 0) return 0;
314da0d961cSdjm
315da0d961cSdjm for (size_t i = 0; i < size; i++) {
316*4dcc46c4Sdjm size_t item_written =
3179e5c2ddcSdjm cbor_serialize(handle->key, buffer + written, buffer_size - written);
318*4dcc46c4Sdjm if (item_written == 0) {
319da0d961cSdjm return 0;
320*4dcc46c4Sdjm }
321da0d961cSdjm written += item_written;
3229e5c2ddcSdjm item_written = cbor_serialize((handle++)->value, buffer + written,
3239e5c2ddcSdjm buffer_size - written);
324*4dcc46c4Sdjm if (item_written == 0) return 0;
325da0d961cSdjm written += item_written;
326da0d961cSdjm }
327da0d961cSdjm
328da0d961cSdjm if (cbor_map_is_definite(item)) {
329da0d961cSdjm return written;
330da0d961cSdjm } else {
331*4dcc46c4Sdjm CBOR_ASSERT(cbor_map_is_indefinite(item));
332*4dcc46c4Sdjm size_t break_written =
333*4dcc46c4Sdjm cbor_encode_break(buffer + written, buffer_size - written);
334*4dcc46c4Sdjm if (break_written == 0) return 0;
335*4dcc46c4Sdjm return written + break_written;
336da0d961cSdjm }
337da0d961cSdjm }
338da0d961cSdjm
cbor_serialize_tag(const cbor_item_t * item,unsigned char * buffer,size_t buffer_size)3399e5c2ddcSdjm size_t cbor_serialize_tag(const cbor_item_t *item, unsigned char *buffer,
3409e5c2ddcSdjm size_t buffer_size) {
341*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_tag(item));
342da0d961cSdjm size_t written = cbor_encode_tag(cbor_tag_value(item), buffer, buffer_size);
3439e5c2ddcSdjm if (written == 0) return 0;
344da0d961cSdjm
345*4dcc46c4Sdjm size_t item_written = cbor_serialize(cbor_move(cbor_tag_item(item)),
346*4dcc46c4Sdjm buffer + written, buffer_size - written);
347*4dcc46c4Sdjm if (item_written == 0) return 0;
348da0d961cSdjm return written + item_written;
349da0d961cSdjm }
350da0d961cSdjm
cbor_serialize_float_ctrl(const cbor_item_t * item,unsigned char * buffer,size_t buffer_size)3519e5c2ddcSdjm size_t cbor_serialize_float_ctrl(const cbor_item_t *item, unsigned char *buffer,
3529e5c2ddcSdjm size_t buffer_size) {
353*4dcc46c4Sdjm CBOR_ASSERT(cbor_isa_float_ctrl(item));
354*4dcc46c4Sdjm // cppcheck-suppress missingReturn
355da0d961cSdjm switch (cbor_float_get_width(item)) {
356da0d961cSdjm case CBOR_FLOAT_0:
357da0d961cSdjm /* CTRL - special treatment */
358da0d961cSdjm return cbor_encode_ctrl(cbor_ctrl_value(item), buffer, buffer_size);
359da0d961cSdjm case CBOR_FLOAT_16:
360da0d961cSdjm return cbor_encode_half(cbor_float_get_float2(item), buffer, buffer_size);
361da0d961cSdjm case CBOR_FLOAT_32:
3629e5c2ddcSdjm return cbor_encode_single(cbor_float_get_float4(item), buffer,
3639e5c2ddcSdjm buffer_size);
364da0d961cSdjm case CBOR_FLOAT_64:
3659e5c2ddcSdjm return cbor_encode_double(cbor_float_get_float8(item), buffer,
3669e5c2ddcSdjm buffer_size);
367da0d961cSdjm }
368da0d961cSdjm }
369