1 /*
2 * This file has been copied from the zcbor library.
3 * Commit zcbor 0.8.1
4 */
5
6 /*
7 * Copyright (c) 2020 Nordic Semiconductor ASA
8 *
9 * SPDX-License-Identifier: Apache-2.0
10 */
11
12 #include <stdint.h>
13 #include <stdbool.h>
14 #include <stddef.h>
15 #include <string.h>
16 #include "zcbor_encode.h"
17 #include "zcbor_common.h"
18 #include "zcbor_print.h"
19
20 _Static_assert((sizeof(size_t) == sizeof(void *)),
21 "This code needs size_t to be the same length as pointers.");
22
23
log2ceil(size_t val)24 static uint8_t log2ceil(size_t val)
25 {
26 switch(val) {
27 case 1: return 0;
28 case 2: return 1;
29 case 3: return 2;
30 case 4: return 2;
31 case 5: return 3;
32 case 6: return 3;
33 case 7: return 3;
34 case 8: return 3;
35 }
36
37 zcbor_log("Should not come here.\r\n");
38 return 0;
39 }
40
41
get_additional(size_t len,uint8_t value0)42 static uint8_t get_additional(size_t len, uint8_t value0)
43 {
44 return len == 0 ? value0 : (uint8_t)(24 + log2ceil(len));
45 }
46
47
encode_header_byte(zcbor_state_t * state,zcbor_major_type_t major_type,uint8_t additional)48 static bool encode_header_byte(zcbor_state_t *state,
49 zcbor_major_type_t major_type, uint8_t additional)
50 {
51 ZCBOR_CHECK_ERROR();
52 ZCBOR_CHECK_PAYLOAD();
53
54 zcbor_assert_state(additional < 32, "Unsupported additional value: %d\r\n", additional);
55
56 *(state->payload_mut++) = (uint8_t)((major_type << 5) | (additional & 0x1F));
57 return true;
58 }
59
60
61 /** Encode a single value.
62 */
value_encode_len(zcbor_state_t * state,zcbor_major_type_t major_type,const void * const result,size_t result_len)63 static bool value_encode_len(zcbor_state_t *state, zcbor_major_type_t major_type,
64 const void *const result, size_t result_len)
65 {
66 uint8_t *u8_result = (uint8_t *)result;
67
68 if ((state->payload + 1 + result_len) > state->payload_end) {
69 ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
70 }
71
72 if (!encode_header_byte(state, major_type,
73 get_additional(result_len, u8_result[0]))) {
74 ZCBOR_FAIL();
75 }
76 state->payload_mut--;
77 zcbor_trace(state, "value_encode_len");
78 state->payload_mut++;
79
80 #ifdef ZCBOR_BIG_ENDIAN
81 memcpy(state->payload_mut, u8_result, result_len);
82 state->payload_mut += result_len;
83 #else
84 for (; result_len > 0; result_len--) {
85 *(state->payload_mut++) = u8_result[result_len - 1];
86 }
87 #endif /* ZCBOR_BIG_ENDIAN */
88
89 state->elem_count++;
90 return true;
91 }
92
93
value_encode(zcbor_state_t * state,zcbor_major_type_t major_type,const void * const input,size_t max_result_len)94 static bool value_encode(zcbor_state_t *state, zcbor_major_type_t major_type,
95 const void *const input, size_t max_result_len)
96 {
97 zcbor_assert_state(max_result_len != 0, "0-length result not supported.\r\n");
98
99 size_t result_len = zcbor_header_len_ptr(input, max_result_len) - 1;
100 const void *result = input;
101
102 #ifdef ZCBOR_BIG_ENDIAN
103 result = (uint8_t *)input + max_result_len - (result_len ? result_len : 1);
104 #endif
105
106 return value_encode_len(state, major_type, result, result_len);
107 }
108
109
zcbor_int_encode(zcbor_state_t * state,const void * input_int,size_t int_size)110 bool zcbor_int_encode(zcbor_state_t *state, const void *input_int, size_t int_size)
111 {
112 zcbor_major_type_t major_type;
113 uint8_t input_buf[8];
114 const uint8_t *input_uint8 = input_int;
115 const int8_t *input_int8 = input_int;
116 const uint8_t *input = input_int;
117
118 if (int_size > sizeof(int64_t)) {
119 ZCBOR_ERR(ZCBOR_ERR_INT_SIZE);
120 }
121
122 #ifdef ZCBOR_BIG_ENDIAN
123 if (input_int8[0] < 0) {
124 #else
125 if (input_int8[int_size - 1] < 0) {
126 #endif
127 major_type = ZCBOR_MAJOR_TYPE_NINT;
128
129 /* Convert to CBOR's representation by flipping all bits. */
130 for (unsigned int i = 0; i < int_size; i++) {
131 input_buf[i] = (uint8_t)~input_uint8[i];
132 }
133 input = input_buf;
134 } else {
135 major_type = ZCBOR_MAJOR_TYPE_PINT;
136 }
137
138 if (!value_encode(state, major_type, input, int_size)) {
139 ZCBOR_FAIL();
140 }
141
142 return true;
143 }
144
145
146 bool zcbor_uint_encode(zcbor_state_t *state, const void *input_uint, size_t uint_size)
147 {
148 if (!value_encode(state, ZCBOR_MAJOR_TYPE_PINT, input_uint, uint_size)) {
149 zcbor_log("uint with size %zu failed.\r\n", uint_size);
150 ZCBOR_FAIL();
151 }
152 return true;
153 }
154
155
156 bool zcbor_int32_encode(zcbor_state_t *state, const int32_t *input)
157 {
158 return zcbor_int_encode(state, input, sizeof(*input));
159 }
160
161
162 bool zcbor_int64_encode(zcbor_state_t *state, const int64_t *input)
163 {
164 return zcbor_int_encode(state, input, sizeof(*input));
165 }
166
167
168 bool zcbor_uint32_encode(zcbor_state_t *state, const uint32_t *input)
169 {
170 return zcbor_uint_encode(state, input, sizeof(*input));
171 }
172
173
174 bool zcbor_uint64_encode(zcbor_state_t *state, const uint64_t *input)
175 {
176 return zcbor_uint_encode(state, input, sizeof(*input));
177 }
178
179
180 bool zcbor_int32_put(zcbor_state_t *state, int32_t input)
181 {
182 return zcbor_int_encode(state, &input, sizeof(input));
183 }
184
185
186 bool zcbor_int64_put(zcbor_state_t *state, int64_t input)
187 {
188 return zcbor_int_encode(state, &input, sizeof(input));
189 }
190
191
192 bool zcbor_uint32_put(zcbor_state_t *state, uint32_t input)
193 {
194 return zcbor_uint_encode(state, &input, sizeof(input));
195 }
196
197
198 bool zcbor_uint64_put(zcbor_state_t *state, uint64_t input)
199 {
200 return zcbor_uint_encode(state, &input, sizeof(input));
201 }
202
203
204 #ifdef ZCBOR_SUPPORTS_SIZE_T
205 bool zcbor_size_put(zcbor_state_t *state, size_t input)
206 {
207 return zcbor_uint_encode(state, &input, sizeof(input));
208 }
209
210
211 bool zcbor_size_encode(zcbor_state_t *state, const size_t *input)
212 {
213 return zcbor_uint_encode(state, input, sizeof(*input));
214 }
215 #endif
216
217 static bool str_start_encode(zcbor_state_t *state,
218 const struct zcbor_string *input, zcbor_major_type_t major_type)
219 {
220 if (input->value && ((zcbor_header_len_ptr(&input->len, sizeof(input->len))
221 + input->len + (size_t)state->payload)
222 > (size_t)state->payload_end)) {
223 ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
224 }
225 if (!value_encode(state, major_type, &input->len, sizeof(input->len))) {
226 ZCBOR_FAIL();
227 }
228
229 return true;
230 }
231
232
233 static size_t remaining_str_len(zcbor_state_t *state)
234 {
235 size_t max_len = (size_t)state->payload_end - (size_t)state->payload;
236 size_t result_len = zcbor_header_len_ptr(&max_len, sizeof(max_len)) - 1;
237
238 return max_len - result_len - 1;
239 }
240
241
242 bool zcbor_bstr_start_encode(zcbor_state_t *state)
243 {
244 if (!zcbor_new_backup(state, 0)) {
245 ZCBOR_FAIL();
246 }
247
248 uint64_t max_len = remaining_str_len(state);
249
250 /* Encode a dummy header */
251 if (!value_encode(state, ZCBOR_MAJOR_TYPE_BSTR, &max_len, sizeof(max_len))) {
252 ZCBOR_FAIL();
253 }
254 return true;
255 }
256
257
258 bool zcbor_bstr_end_encode(zcbor_state_t *state, struct zcbor_string *result)
259 {
260 const uint8_t *payload = state->payload;
261 struct zcbor_string dummy_value;
262
263 if (result == NULL) {
264 /* Use a dummy value for the sake of the length calculation below.
265 * Will not be returned.
266 */
267 result = &dummy_value;
268 }
269
270 if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME, 0xFFFFFFFF)) {
271 ZCBOR_FAIL();
272 }
273
274 result->value = state->payload_end - remaining_str_len(state);
275 result->len = (size_t)payload - (size_t)result->value;
276
277 /* Reencode header of list now that we know the number of elements. */
278 if (!zcbor_bstr_encode(state, result)) {
279 ZCBOR_FAIL();
280 }
281 return true;
282 }
283
284
285 static bool str_encode(zcbor_state_t *state,
286 const struct zcbor_string *input, zcbor_major_type_t major_type)
287 {
288 ZCBOR_CHECK_PAYLOAD(); /* To make the size_t cast below safe. */
289 if (input->len > (size_t)(state->payload_end - state->payload)) {
290 ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
291 }
292 if (!str_start_encode(state, input, major_type)) {
293 ZCBOR_FAIL();
294 }
295 if (state->payload_mut != input->value) {
296 /* Use memmove since string might be encoded into the same space
297 * because of bstrx_cbor_start_encode/bstrx_cbor_end_encode. */
298 memmove(state->payload_mut, input->value, input->len);
299 }
300 state->payload += input->len;
301 return true;
302 }
303
304
305 bool zcbor_bstr_encode(zcbor_state_t *state, const struct zcbor_string *input)
306 {
307 return str_encode(state, input, ZCBOR_MAJOR_TYPE_BSTR);
308 }
309
310
311 bool zcbor_tstr_encode(zcbor_state_t *state, const struct zcbor_string *input)
312 {
313 return str_encode(state, input, ZCBOR_MAJOR_TYPE_TSTR);
314 }
315
316
317 bool zcbor_bstr_encode_ptr(zcbor_state_t *state, const char *str, size_t len)
318 {
319 const struct zcbor_string zs = { .value = (const uint8_t *)str, .len = len };
320
321 return zcbor_bstr_encode(state, &zs);
322 }
323
324
325 bool zcbor_tstr_encode_ptr(zcbor_state_t *state, const char *str, size_t len)
326 {
327 const struct zcbor_string zs = { .value = (const uint8_t *)str, .len = len };
328
329 return zcbor_tstr_encode(state, &zs);
330 }
331
332
333 bool zcbor_bstr_put_term(zcbor_state_t *state, char const *str, size_t maxlen)
334 {
335 return zcbor_bstr_encode_ptr(state, str, strnlen(str, maxlen));
336 }
337
338
339 bool zcbor_tstr_put_term(zcbor_state_t *state, char const *str, size_t maxlen)
340 {
341 return zcbor_tstr_encode_ptr(state, str, strnlen(str, maxlen));
342 }
343
344
345 static bool list_map_start_encode(zcbor_state_t *state, size_t max_num,
346 zcbor_major_type_t major_type)
347 {
348 #ifdef ZCBOR_CANONICAL
349 if (!zcbor_new_backup(state, 0)) {
350 ZCBOR_FAIL();
351 }
352
353 /* Encode dummy header with max number of elements. */
354 if (!value_encode(state, major_type, &max_num, sizeof(max_num))) {
355 ZCBOR_FAIL();
356 }
357 state->elem_count--; /* Because of dummy header. */
358 #else
359 (void)max_num;
360
361 if (!encode_header_byte(state, major_type, ZCBOR_VALUE_IS_INDEFINITE_LENGTH)) {
362 ZCBOR_FAIL();
363 }
364 #endif
365 return true;
366 }
367
368
369 bool zcbor_list_start_encode(zcbor_state_t *state, size_t max_num)
370 {
371 return list_map_start_encode(state, max_num, ZCBOR_MAJOR_TYPE_LIST);
372 }
373
374
375 bool zcbor_map_start_encode(zcbor_state_t *state, size_t max_num)
376 {
377 return list_map_start_encode(state, max_num, ZCBOR_MAJOR_TYPE_MAP);
378 }
379
380
381 static bool list_map_end_encode(zcbor_state_t *state, size_t max_num,
382 zcbor_major_type_t major_type)
383 {
384 #ifdef ZCBOR_CANONICAL
385 size_t list_count = ((major_type == ZCBOR_MAJOR_TYPE_LIST) ?
386 state->elem_count
387 : (state->elem_count / 2));
388
389 const uint8_t *payload = state->payload;
390
391 size_t max_header_len = zcbor_header_len_ptr(&max_num, 4) - 1;
392 size_t header_len = zcbor_header_len_ptr(&list_count, 4) - 1;
393
394 if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME, 0xFFFFFFFF)) {
395 ZCBOR_FAIL();
396 }
397
398 zcbor_log("list_count: %zu\r\n", list_count);
399
400
401 /** If max_num is smaller than the actual number of encoded elements,
402 * the value_encode() below will corrupt the data if the encoded
403 * header is larger than the previously encoded header. */
404 if (header_len > max_header_len) {
405 zcbor_log("max_num too small.\r\n");
406 ZCBOR_ERR(ZCBOR_ERR_HIGH_ELEM_COUNT);
407 }
408
409 /* Reencode header of list now that we know the number of elements. */
410 if (!(value_encode(state, major_type, &list_count, sizeof(list_count)))) {
411 ZCBOR_FAIL();
412 }
413
414 if (max_header_len != header_len) {
415 const uint8_t *start = state->payload + max_header_len - header_len;
416 size_t body_size = (size_t)payload - (size_t)start;
417
418 memmove(state->payload_mut, start, body_size);
419 /* Reset payload pointer to end of list */
420 state->payload += body_size;
421 } else {
422 /* Reset payload pointer to end of list */
423 state->payload = payload;
424 }
425 #else
426 (void)max_num;
427 (void)major_type;
428 if (!encode_header_byte(state, ZCBOR_MAJOR_TYPE_SIMPLE, ZCBOR_VALUE_IS_INDEFINITE_LENGTH)) {
429 ZCBOR_FAIL();
430 }
431 #endif
432 return true;
433 }
434
435
436 bool zcbor_list_end_encode(zcbor_state_t *state, size_t max_num)
437 {
438 return list_map_end_encode(state, max_num, ZCBOR_MAJOR_TYPE_LIST);
439 }
440
441
442 bool zcbor_map_end_encode(zcbor_state_t *state, size_t max_num)
443 {
444 return list_map_end_encode(state, max_num, ZCBOR_MAJOR_TYPE_MAP);
445 }
446
447
448 bool zcbor_list_map_end_force_encode(zcbor_state_t *state)
449 {
450 #ifdef ZCBOR_CANONICAL
451 if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME,
452 ZCBOR_MAX_ELEM_COUNT)) {
453 ZCBOR_FAIL();
454 }
455 #endif
456 (void)state;
457 return true;
458 }
459
460
461 bool zcbor_simple_encode(zcbor_state_t *state, uint8_t *input)
462 {
463 if (!value_encode(state, ZCBOR_MAJOR_TYPE_SIMPLE, input, sizeof(*input))) {
464 zcbor_log("Error encoding %u (0x%p)\r\n", *input, input);
465 ZCBOR_FAIL();
466 }
467 return true;
468 }
469
470
471 bool zcbor_simple_put(zcbor_state_t *state, uint8_t input)
472 {
473 return value_encode(state, ZCBOR_MAJOR_TYPE_SIMPLE, &input, sizeof(input));
474 }
475
476
477 bool zcbor_nil_put(zcbor_state_t *state, const void *unused)
478 {
479 (void)unused;
480 return zcbor_simple_put(state, 22);
481 }
482
483
484 bool zcbor_undefined_put(zcbor_state_t *state, const void *unused)
485 {
486 (void)unused;
487 return zcbor_simple_put(state, 23);
488 }
489
490
491 bool zcbor_bool_encode(zcbor_state_t *state, const bool *input)
492 {
493 return zcbor_bool_put(state, *input);
494 }
495
496
497 bool zcbor_bool_put(zcbor_state_t *state, bool input)
498 {
499 return zcbor_simple_put(state, (!!input + ZCBOR_BOOL_TO_SIMPLE));
500 }
501
502
503 bool zcbor_float64_encode(zcbor_state_t *state, const double *input)
504 {
505 if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
506 sizeof(*input))) {
507 ZCBOR_FAIL();
508 }
509
510 return true;
511 }
512
513
514 bool zcbor_float64_put(zcbor_state_t *state, double input)
515 {
516 return zcbor_float64_encode(state, &input);
517 }
518
519
520 bool zcbor_float32_encode(zcbor_state_t *state, const float *input)
521 {
522 if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
523 sizeof(*input))) {
524 ZCBOR_FAIL();
525 }
526
527 return true;
528 }
529
530
531 bool zcbor_float32_put(zcbor_state_t *state, float input)
532 {
533 return zcbor_float32_encode(state, &input);
534 }
535
536
537 bool zcbor_float16_encode(zcbor_state_t *state, const float *input)
538 {
539 return zcbor_float16_put(state, *input);
540 }
541
542
543 bool zcbor_float16_put(zcbor_state_t *state, float input)
544 {
545 return zcbor_float16_bytes_put(state, zcbor_float32_to_16(input));
546 }
547
548
549 bool zcbor_float16_bytes_encode(zcbor_state_t *state, const uint16_t *input)
550 {
551 if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
552 sizeof(*input))) {
553 ZCBOR_FAIL();
554 }
555
556 return true;
557 }
558
559
560 bool zcbor_float16_bytes_put(zcbor_state_t *state, uint16_t input)
561 {
562 return zcbor_float16_bytes_encode(state, &input);
563 }
564
565
566 bool zcbor_tag_put(zcbor_state_t *state, uint32_t tag)
567 {
568 if (!value_encode(state, ZCBOR_MAJOR_TYPE_TAG, &tag, sizeof(tag))) {
569 ZCBOR_FAIL();
570 }
571 state->elem_count--;
572
573 return true;
574 }
575
576
577 bool zcbor_tag_encode(zcbor_state_t *state, uint32_t *tag)
578 {
579 return zcbor_tag_put(state, *tag);
580 }
581
582
583 bool zcbor_multi_encode_minmax(size_t min_encode, size_t max_encode,
584 const size_t *num_encode, zcbor_encoder_t encoder,
585 zcbor_state_t *state, const void *input, size_t result_len)
586 {
587
588 if ((*num_encode >= min_encode) && (*num_encode <= max_encode)) {
589 return zcbor_multi_encode(*num_encode, encoder, state, input, result_len);
590 } else {
591 ZCBOR_ERR(ZCBOR_ERR_ITERATIONS);
592 }
593 }
594
595
596 bool zcbor_multi_encode(const size_t num_encode, zcbor_encoder_t encoder,
597 zcbor_state_t *state, const void *input, size_t result_len)
598 {
599 ZCBOR_CHECK_ERROR();
600 for (size_t i = 0; i < num_encode; i++) {
601 if (!encoder(state, (const uint8_t *)input + i*result_len)) {
602 ZCBOR_FAIL();
603 }
604 }
605 zcbor_log("Encoded %zu elements.\n", num_encode);
606 return true;
607 }
608
609
610 void zcbor_new_encode_state(zcbor_state_t *state_array, size_t n_states,
611 uint8_t *payload, size_t payload_len, size_t elem_count)
612 {
613 zcbor_new_state(state_array, n_states, payload, payload_len, elem_count, NULL, 0);
614 }
615