1 /*
2 * Copyright (c) 2020 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdint.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <string.h>
11 #include "zcbor_encode.h"
12 #include "zcbor_common.h"
13
14 _Static_assert((sizeof(size_t) == sizeof(void *)),
15 "This code needs size_t to be the same length as pointers.");
16
17
log2ceil(size_t val)18 static uint8_t log2ceil(size_t val)
19 {
20 switch(val) {
21 case 1: return 0;
22 case 2: return 1;
23 case 3: return 2;
24 case 4: return 2;
25 case 5: return 3;
26 case 6: return 3;
27 case 7: return 3;
28 case 8: return 3;
29 }
30
31 zcbor_print("Should not come here.\r\n");
32 return 0;
33 }
34
35
get_additional(size_t len,uint8_t value0)36 static uint8_t get_additional(size_t len, uint8_t value0)
37 {
38 return len == 0 ? value0 : (uint8_t)(24 + log2ceil(len));
39 }
40
41
encode_header_byte(zcbor_state_t * state,zcbor_major_type_t major_type,uint8_t additional)42 static bool encode_header_byte(zcbor_state_t *state,
43 zcbor_major_type_t major_type, uint8_t additional)
44 {
45 ZCBOR_CHECK_ERROR();
46 ZCBOR_CHECK_PAYLOAD();
47
48 zcbor_assert_state(additional < 32, NULL);
49
50 *(state->payload_mut++) = (uint8_t)((major_type << 5) | (additional & 0x1F));
51 return true;
52 }
53
54
55 static size_t get_encoded_len(const void *const result, size_t result_len);
56
57
58 /** Encode a single value.
59 */
value_encode_len(zcbor_state_t * state,zcbor_major_type_t major_type,const void * const result,size_t result_len)60 static bool value_encode_len(zcbor_state_t *state, zcbor_major_type_t major_type,
61 const void *const result, size_t result_len)
62 {
63 uint8_t *u8_result = (uint8_t *)result;
64 size_t encoded_len = get_encoded_len(result, result_len);
65
66 if ((state->payload + 1 + encoded_len) > state->payload_end) {
67 ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
68 }
69
70 if (!encode_header_byte(state, major_type,
71 get_additional(encoded_len, u8_result[0]))) {
72 ZCBOR_FAIL();
73 }
74 state->payload_mut--;
75 zcbor_trace();
76 state->payload_mut++;
77
78 #ifdef CONFIG_BIG_ENDIAN
79 memcpy(state->payload_mut, u8_result, encoded_len);
80 state->payload_mut += encoded_len;
81 #else
82 for (; encoded_len > 0; encoded_len--) {
83 *(state->payload_mut++) = u8_result[encoded_len - 1];
84 }
85 #endif /* CONFIG_BIG_ENDIAN */
86
87 state->elem_count++;
88 return true;
89 }
90
91
get_result_len(const void * const input,size_t max_result_len)92 static size_t get_result_len(const void *const input, size_t max_result_len)
93 {
94 uint8_t *u8_result = (uint8_t *)input;
95 size_t len = max_result_len;
96
97 for (; len > 0; len--) {
98 #ifdef CONFIG_BIG_ENDIAN
99 if (u8_result[max_result_len - len] != 0) {
100 #else
101 if (u8_result[len - 1] != 0) {
102 #endif /* CONFIG_BIG_ENDIAN */
103 break;
104 }
105 }
106
107 /* Round up to nearest power of 2. */
108 return len <= 2 ? len : (uint8_t)(1 << log2ceil(len));
109 }
110
111
112 static const void *get_result(const void *const input, size_t max_result_len,
113 size_t result_len)
114 {
115 #ifdef CONFIG_BIG_ENDIAN
116 return &((uint8_t *)input)[max_result_len - (result_len ? result_len : 1)];
117 #else
118 (void)max_result_len;
119 (void)result_len;
120 return input;
121 #endif
122 }
123
124
125 static size_t get_encoded_len(const void *const result, size_t result_len)
126 {
127 const uint8_t *u8_result = (const uint8_t *)result;
128
129 if ((result_len == 1) && (u8_result[0] <= ZCBOR_VALUE_IN_HEADER)) {
130 return 0;
131 }
132 return result_len;
133 }
134
135
136 static bool value_encode(zcbor_state_t *state, zcbor_major_type_t major_type,
137 const void *const input, size_t max_result_len)
138 {
139 zcbor_assert_state(max_result_len != 0, "0-length result not supported.\r\n");
140
141 size_t result_len = get_result_len(input, max_result_len);
142 const void *const result = get_result(input, max_result_len, result_len);
143
144 return value_encode_len(state, major_type, result, result_len);
145 }
146
147
148 bool zcbor_int_encode(zcbor_state_t *state, const void *input_int, size_t int_size)
149 {
150 zcbor_major_type_t major_type;
151 uint8_t input_buf[8];
152 const uint8_t *input_uint8 = input_int;
153 const int8_t *input_int8 = input_int;
154 const uint8_t *input = input_int;
155
156 if (int_size > sizeof(int64_t)) {
157 ZCBOR_ERR(ZCBOR_ERR_INT_SIZE);
158 }
159
160 #ifdef CONFIG_BIG_ENDIAN
161 if (input_int8[0] < 0) {
162 #else
163 if (input_int8[int_size - 1] < 0) {
164 #endif
165 major_type = ZCBOR_MAJOR_TYPE_NINT;
166
167 /* Convert to CBOR's representation by flipping all bits. */
168 for (unsigned int i = 0; i < int_size; i++) {
169 input_buf[i] = (uint8_t)~input_uint8[i];
170 }
171 input = input_buf;
172 } else {
173 major_type = ZCBOR_MAJOR_TYPE_PINT;
174 }
175
176 if (!value_encode(state, major_type, input, int_size)) {
177 ZCBOR_FAIL();
178 }
179
180 return true;
181 }
182
183
184 bool zcbor_uint_encode(zcbor_state_t *state, const void *input_uint, size_t uint_size)
185 {
186 if (!value_encode(state, ZCBOR_MAJOR_TYPE_PINT, input_uint, uint_size)) {
187 zcbor_print("uint with size %d failed.\r\n", uint_size);
188 ZCBOR_FAIL();
189 }
190 return true;
191 }
192
193
194 bool zcbor_int32_encode(zcbor_state_t *state, const int32_t *input)
195 {
196 return zcbor_int_encode(state, input, sizeof(*input));
197 }
198
199
200 bool zcbor_int64_encode(zcbor_state_t *state, const int64_t *input)
201 {
202 return zcbor_int_encode(state, input, sizeof(*input));
203 }
204
205
206 bool zcbor_uint32_encode(zcbor_state_t *state, const uint32_t *input)
207 {
208 return zcbor_uint_encode(state, input, sizeof(*input));
209 }
210
211
212 bool zcbor_uint64_encode(zcbor_state_t *state, const uint64_t *input)
213 {
214 return zcbor_uint_encode(state, input, sizeof(*input));
215 }
216
217
218 bool zcbor_int32_put(zcbor_state_t *state, int32_t input)
219 {
220 return zcbor_int_encode(state, &input, sizeof(input));
221 }
222
223
224 bool zcbor_int64_put(zcbor_state_t *state, int64_t input)
225 {
226 return zcbor_int_encode(state, &input, sizeof(input));
227 }
228
229
230 bool zcbor_uint32_put(zcbor_state_t *state, uint32_t input)
231 {
232 return zcbor_uint_encode(state, &input, sizeof(input));
233 }
234
235
236 bool zcbor_uint64_put(zcbor_state_t *state, uint64_t input)
237 {
238 return zcbor_uint_encode(state, &input, sizeof(input));
239 }
240
241
242 #ifdef ZCBOR_SUPPORTS_SIZE_T
243 bool zcbor_size_put(zcbor_state_t *state, size_t input)
244 {
245 return zcbor_uint_encode(state, &input, sizeof(input));
246 }
247
248
249 bool zcbor_size_encode(zcbor_state_t *state, const size_t *input)
250 {
251 return zcbor_uint_encode(state, input, sizeof(*input));
252 }
253 #endif
254
255 static bool str_start_encode(zcbor_state_t *state,
256 const struct zcbor_string *input, zcbor_major_type_t major_type)
257 {
258 if (input->value && ((get_result_len(&input->len, sizeof(input->len))
259 + 1 + input->len + (size_t)state->payload)
260 > (size_t)state->payload_end)) {
261 ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
262 }
263 if (!value_encode(state, major_type, &input->len, sizeof(input->len))) {
264 ZCBOR_FAIL();
265 }
266
267 return true;
268 }
269
270
271 static size_t remaining_str_len(zcbor_state_t *state)
272 {
273 size_t max_len = (size_t)state->payload_end - (size_t)state->payload;
274 size_t result_len = get_result_len(&max_len, sizeof(max_len));
275
276 return max_len - result_len - 1;
277 }
278
279
280 bool zcbor_bstr_start_encode(zcbor_state_t *state)
281 {
282 if (!zcbor_new_backup(state, 0)) {
283 ZCBOR_FAIL();
284 }
285
286 uint64_t max_len = remaining_str_len(state);
287
288 /* Encode a dummy header */
289 if (!value_encode(state, ZCBOR_MAJOR_TYPE_BSTR, &max_len, sizeof(max_len))) {
290 ZCBOR_FAIL();
291 }
292 return true;
293 }
294
295
296 bool zcbor_bstr_end_encode(zcbor_state_t *state, struct zcbor_string *result)
297 {
298 const uint8_t *payload = state->payload;
299 struct zcbor_string dummy_value;
300
301 if (result == NULL) {
302 /* Use a dummy value for the sake of the length calculation below.
303 * Will not be returned.
304 */
305 result = &dummy_value;
306 }
307
308 if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME, 0xFFFFFFFF)) {
309 ZCBOR_FAIL();
310 }
311
312 result->value = state->payload_end - remaining_str_len(state);
313 result->len = (size_t)payload - (size_t)result->value;
314
315 /* Reencode header of list now that we know the number of elements. */
316 if (!zcbor_bstr_encode(state, result)) {
317 ZCBOR_FAIL();
318 }
319 return true;
320 }
321
322
323 static bool str_encode(zcbor_state_t *state,
324 const struct zcbor_string *input, zcbor_major_type_t major_type)
325 {
326 ZCBOR_CHECK_PAYLOAD(); /* To make the size_t cast below safe. */
327 if (input->len > (size_t)(state->payload_end - state->payload)) {
328 ZCBOR_ERR(ZCBOR_ERR_NO_PAYLOAD);
329 }
330 if (!str_start_encode(state, input, major_type)) {
331 ZCBOR_FAIL();
332 }
333 if (state->payload_mut != input->value) {
334 /* Use memmove since string might be encoded into the same space
335 * because of bstrx_cbor_start_encode/bstrx_cbor_end_encode. */
336 memmove(state->payload_mut, input->value, input->len);
337 }
338 state->payload += input->len;
339 return true;
340 }
341
342
343 bool zcbor_bstr_encode(zcbor_state_t *state, const struct zcbor_string *input)
344 {
345 return str_encode(state, input, ZCBOR_MAJOR_TYPE_BSTR);
346 }
347
348
349 bool zcbor_tstr_encode(zcbor_state_t *state, const struct zcbor_string *input)
350 {
351 return str_encode(state, input, ZCBOR_MAJOR_TYPE_TSTR);
352 }
353
354
355 static bool list_map_start_encode(zcbor_state_t *state, size_t max_num,
356 zcbor_major_type_t major_type)
357 {
358 #ifdef ZCBOR_CANONICAL
359 if (!zcbor_new_backup(state, 0)) {
360 ZCBOR_FAIL();
361 }
362
363 /* Encode dummy header with max number of elements. */
364 if (!value_encode(state, major_type, &max_num, sizeof(max_num))) {
365 ZCBOR_FAIL();
366 }
367 state->elem_count--; /* Because of dummy header. */
368 #else
369 (void)max_num;
370
371 if (!encode_header_byte(state, major_type, ZCBOR_VALUE_IS_INDEFINITE_LENGTH)) {
372 ZCBOR_FAIL();
373 }
374 #endif
375 return true;
376 }
377
378
379 bool zcbor_list_start_encode(zcbor_state_t *state, size_t max_num)
380 {
381 return list_map_start_encode(state, max_num, ZCBOR_MAJOR_TYPE_LIST);
382 }
383
384
385 bool zcbor_map_start_encode(zcbor_state_t *state, size_t max_num)
386 {
387 return list_map_start_encode(state, max_num, ZCBOR_MAJOR_TYPE_MAP);
388 }
389
390
391 #ifdef ZCBOR_CANONICAL
392 static size_t get_encoded_len2(const void *const input, size_t max_result_len)
393 {
394 size_t result_len = get_result_len(input, max_result_len);
395 const void *const result = get_result(input, max_result_len, result_len);
396
397 return get_encoded_len(result, result_len);
398 }
399 #endif
400
401
402 static bool list_map_end_encode(zcbor_state_t *state, size_t max_num,
403 zcbor_major_type_t major_type)
404 {
405 #ifdef ZCBOR_CANONICAL
406 size_t list_count = ((major_type == ZCBOR_MAJOR_TYPE_LIST) ?
407 state->elem_count
408 : (state->elem_count / 2));
409
410 const uint8_t *payload = state->payload;
411
412 size_t max_header_len = get_encoded_len2(&max_num, 4);
413 size_t header_len = get_encoded_len2(&list_count, 4);
414
415 if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME, 0xFFFFFFFF)) {
416 ZCBOR_FAIL();
417 }
418
419 zcbor_print("list_count: %" PRIuFAST32 "\r\n", list_count);
420
421
422 /** If max_num is smaller than the actual number of encoded elements,
423 * the value_encode() below will corrupt the data if the encoded
424 * header is larger than the previously encoded header. */
425 if (header_len > max_header_len) {
426 zcbor_print("max_num too small.\r\n");
427 ZCBOR_ERR(ZCBOR_ERR_HIGH_ELEM_COUNT);
428 }
429
430 /* Reencode header of list now that we know the number of elements. */
431 if (!(value_encode(state, major_type, &list_count, sizeof(list_count)))) {
432 ZCBOR_FAIL();
433 }
434
435 if (max_header_len != header_len) {
436 const uint8_t *start = state->payload + max_header_len - header_len;
437 size_t body_size = (size_t)payload - (size_t)start;
438
439 memmove(state->payload_mut, start, body_size);
440 /* Reset payload pointer to end of list */
441 state->payload += body_size;
442 } else {
443 /* Reset payload pointer to end of list */
444 state->payload = payload;
445 }
446 #else
447 (void)max_num;
448 (void)major_type;
449 if (!encode_header_byte(state, ZCBOR_MAJOR_TYPE_SIMPLE, ZCBOR_VALUE_IS_INDEFINITE_LENGTH)) {
450 ZCBOR_FAIL();
451 }
452 #endif
453 return true;
454 }
455
456
457 bool zcbor_list_end_encode(zcbor_state_t *state, size_t max_num)
458 {
459 return list_map_end_encode(state, max_num, ZCBOR_MAJOR_TYPE_LIST);
460 }
461
462
463 bool zcbor_map_end_encode(zcbor_state_t *state, size_t max_num)
464 {
465 return list_map_end_encode(state, max_num, ZCBOR_MAJOR_TYPE_MAP);
466 }
467
468
469 bool zcbor_list_map_end_force_encode(zcbor_state_t *state)
470 {
471 #ifdef ZCBOR_CANONICAL
472 if (!zcbor_process_backup(state, ZCBOR_FLAG_RESTORE | ZCBOR_FLAG_CONSUME,
473 ZCBOR_MAX_ELEM_COUNT)) {
474 ZCBOR_FAIL();
475 }
476 #endif
477 (void)state;
478 return true;
479 }
480
481
482 bool zcbor_simple_encode(zcbor_state_t *state, uint8_t *input)
483 {
484 if (!value_encode(state, ZCBOR_MAJOR_TYPE_SIMPLE, input, sizeof(*input))) {
485 zcbor_print("Error encoding %u (0x%p)\r\n", *input, input);
486 ZCBOR_FAIL();
487 }
488 return true;
489 }
490
491
492 bool zcbor_simple_put(zcbor_state_t *state, uint8_t input)
493 {
494 return value_encode(state, ZCBOR_MAJOR_TYPE_SIMPLE, &input, sizeof(input));
495 }
496
497
498 bool zcbor_nil_put(zcbor_state_t *state, const void *unused)
499 {
500 (void)unused;
501 return zcbor_simple_put(state, 22);
502 }
503
504
505 bool zcbor_undefined_put(zcbor_state_t *state, const void *unused)
506 {
507 (void)unused;
508 return zcbor_simple_put(state, 23);
509 }
510
511
512 bool zcbor_bool_encode(zcbor_state_t *state, const bool *input)
513 {
514 return zcbor_bool_put(state, *input);
515 }
516
517
518 bool zcbor_bool_put(zcbor_state_t *state, bool input)
519 {
520 return zcbor_simple_put(state, (!!input + ZCBOR_BOOL_TO_SIMPLE));
521 }
522
523
524 bool zcbor_float64_encode(zcbor_state_t *state, const double *input)
525 {
526 if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
527 sizeof(*input))) {
528 ZCBOR_FAIL();
529 }
530
531 return true;
532 }
533
534
535 bool zcbor_float64_put(zcbor_state_t *state, double input)
536 {
537 return zcbor_float64_encode(state, &input);
538 }
539
540
541 bool zcbor_float32_encode(zcbor_state_t *state, const float *input)
542 {
543 if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
544 sizeof(*input))) {
545 ZCBOR_FAIL();
546 }
547
548 return true;
549 }
550
551
552 bool zcbor_float32_put(zcbor_state_t *state, float input)
553 {
554 return zcbor_float32_encode(state, &input);
555 }
556
557
558 bool zcbor_float16_encode(zcbor_state_t *state, const float *input)
559 {
560 return zcbor_float16_put(state, *input);
561 }
562
563 /* Float16: */
564 #define F16_SIGN_OFFS 15 /* Bit offset of the sign bit. */
565 #define F16_EXPO_OFFS 10 /* Bit offset of the exponent. */
566 #define F16_EXPO_MSK 0x1F /* Bitmask for the exponent (right shifted by F16_EXPO_OFFS). */
567 #define F16_MANTISSA_MSK 0x3FF /* Bitmask for the mantissa. */
568 #define F16_MAX 65520 /* Lowest float32 value that rounds up to float16 infinity.
569 * (65519.996 rounds to 65504) */
570 #define F16_MIN_EXPO 24 /* Negative exponent of the non-zero float16 value closest to 0 (2^-24) */
571 #define F16_MIN (1.0 / (1 << F16_MIN_EXPO)) /* The non-zero float16 value closest to 0 (2^-24) */
572 #define F16_MIN_NORM (1.0 / (1 << 14)) /* The normalized float16 value closest to 0 (2^-14) */
573 #define F16_BIAS 15 /* The exponent bias of normalized float16 values. */
574
575 /* Float32: */
576 #define F32_SIGN_OFFS 31 /* Bit offset of the sign bit. */
577 #define F32_EXPO_OFFS 23 /* Bit offset of the exponent. */
578 #define F32_EXPO_MSK 0xFF /* Bitmask for the exponent (right shifted by F32_EXPO_OFFS). */
579 #define F32_MANTISSA_MSK 0x7FFFFF /* Bitmask for the mantissa. */
580 #define F32_BIAS 127 /* The exponent bias of normalized float32 values. */
581
582 /* Rounding: */
583 #define SUBNORM_ROUND_MSK (F32_MANTISSA_MSK | (1 << F32_EXPO_OFFS)) /* mantissa + lsb of expo for
584 * tiebreak. */
585 #define SUBNORM_ROUND_BIT_MSK (1 << (F32_EXPO_OFFS - 1)) /* msb of mantissa (0x400000) */
586 #define NORM_ROUND_MSK (F32_MANTISSA_MSK >> (F16_EXPO_OFFS - 1)) /* excess mantissa when going from
587 * float32 to float16 + 1 extra bit
588 * for tiebreak. */
589 #define NORM_ROUND_BIT_MSK (1 << (F32_EXPO_OFFS - F16_EXPO_OFFS - 1)) /* bit 12 (0x1000) */
590
591 bool zcbor_float16_put(zcbor_state_t *state, float input)
592 {
593 uint32_t value32 = *(uint32_t *)&input;
594
595 uint32_t sign = value32 >> F32_SIGN_OFFS;
596 uint32_t expo = (value32 >> F32_EXPO_OFFS) & F32_EXPO_MSK;
597 uint32_t mantissa = value32 & F32_MANTISSA_MSK;
598
599 uint16_t value16 = (uint16_t)(sign << F16_SIGN_OFFS);
600
601 float abs_input;
602 *(uint32_t *)&abs_input = value32 & ~(1 << F32_SIGN_OFFS);
603
604 if (abs_input <= (F16_MIN / 2)) {
605 /* 0 or too small for float16. Round down to 0. value16 is already correct. */
606 } else if (abs_input < F16_MIN) {
607 /* Round up to 2^(-24) (F16_MIN), has other rounding rules than larger values. */
608 value16 |= 0x0001;
609 } else if (abs_input < F16_MIN_NORM) {
610 /* Subnormal float16 (normal float32) */
611 uint32_t adjusted_mantissa =
612 /* Adjust for the purposes of checking rounding. */
613 /* The lsb of expo is needed for the cases where expo is 103 (minimum). */
614 ((value32 << (expo - (F32_BIAS - F16_MIN_EXPO))) & SUBNORM_ROUND_MSK);
615 uint16_t rounding_bit =
616 /* "Round to nearest, ties to even". */
617 /* 0x400000 means ties go down towards even. (0xC00000 means ties go up.) */
618 (adjusted_mantissa & SUBNORM_ROUND_BIT_MSK)
619 && (adjusted_mantissa != SUBNORM_ROUND_BIT_MSK);
620 value16 |= ((uint16_t)(abs_input * (1 << 24)) + rounding_bit); /* expo is 0 */
621 } else if (abs_input < F16_MAX) {
622 /* Normal float16 (normal float32) */
623 uint16_t rounding_bit =
624 /* Bit 13 of the mantissa represents which way to round, except for the */
625 /* special case where bits 0-12 and 14 are 0. */
626 /* This is because of "Round to nearest, ties to even". */
627 /* 0x1000 means ties go down towards even. (0x3000 means ties go up.) */
628 ((mantissa & NORM_ROUND_BIT_MSK)
629 && ((mantissa & NORM_ROUND_MSK) != NORM_ROUND_BIT_MSK));
630 value16 |= (uint16_t)((expo - (F32_BIAS - F16_BIAS)) << F16_EXPO_OFFS);
631 value16 |= (uint16_t)(mantissa >> (F32_EXPO_OFFS - F16_EXPO_OFFS));
632 value16 += rounding_bit; /* Might propagate to exponent. */
633 } else if (expo != F32_EXPO_MSK || !mantissa) {
634 /* Infinite, or finite normal float32 too large for float16. Round up to inf. */
635 value16 |= (F16_EXPO_MSK << F16_EXPO_OFFS);
636 } else {
637 /* NaN */
638 /* Preserve msbit of mantissa. */
639 uint16_t new_mantissa = (uint16_t)(mantissa >> (F32_EXPO_OFFS - F16_EXPO_OFFS));
640 value16 |= (F16_EXPO_MSK << F16_EXPO_OFFS) | (new_mantissa ? new_mantissa : 1);
641 }
642
643 return zcbor_float16_bytes_put(state, value16);
644 }
645
646
647 bool zcbor_float16_bytes_encode(zcbor_state_t *state, const uint16_t *input)
648 {
649 if (!value_encode_len(state, ZCBOR_MAJOR_TYPE_SIMPLE, input,
650 sizeof(*input))) {
651 ZCBOR_FAIL();
652 }
653
654 return true;
655 }
656
657
658 bool zcbor_float16_bytes_put(zcbor_state_t *state, uint16_t input)
659 {
660 return zcbor_float16_bytes_encode(state, &input);
661 }
662
663
664 bool zcbor_tag_encode(zcbor_state_t *state, uint32_t tag)
665 {
666 if (!value_encode(state, ZCBOR_MAJOR_TYPE_TAG, &tag, sizeof(tag))) {
667 ZCBOR_FAIL();
668 }
669 state->elem_count--;
670
671 return true;
672 }
673
674
675 bool zcbor_multi_encode_minmax(size_t min_encode,
676 size_t max_encode,
677 const size_t *num_encode,
678 zcbor_encoder_t encoder,
679 zcbor_state_t *state,
680 const void *input,
681 size_t result_len)
682 {
683
684 if ((*num_encode >= min_encode) && (*num_encode <= max_encode)) {
685 return zcbor_multi_encode(*num_encode, encoder, state, input, result_len);
686 } else {
687 ZCBOR_ERR(ZCBOR_ERR_ITERATIONS);
688 }
689 }
690
691
692 bool zcbor_multi_encode(size_t num_encode,
693 zcbor_encoder_t encoder,
694 zcbor_state_t *state,
695 const void *input,
696 size_t result_len)
697 {
698 ZCBOR_CHECK_ERROR();
699 for (size_t i = 0; i < num_encode; i++) {
700 if (!encoder(state, (const uint8_t *)input + i*result_len)) {
701 ZCBOR_FAIL();
702 }
703 }
704 zcbor_print("Encoded %" PRIuFAST32 " elements.\n", num_encode);
705 return true;
706 }
707
708
709 bool zcbor_present_encode(const bool *present,
710 zcbor_encoder_t encoder,
711 zcbor_state_t *state,
712 const void *input)
713 {
714 return zcbor_multi_encode(!!*present, encoder, state, input, 0);
715 }
716
717
718 void zcbor_new_encode_state(zcbor_state_t *state_array, size_t n_states,
719 uint8_t *payload, size_t payload_len, size_t elem_count)
720 {
721 zcbor_new_state(state_array, n_states, payload, payload_len, elem_count);
722 }
723