Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2020 Nordic Semiconductor ASA
3 : : *
4 : : * SPDX-License-Identifier: Apache-2.0
5 : : */
6 : :
7 : : #ifndef ZCBOR_COMMON_H__
8 : : #define ZCBOR_COMMON_H__
9 : :
10 : : #include <stdint.h>
11 : : #include <stdbool.h>
12 : : #include <stddef.h>
13 : : #include <string.h>
14 : : #include "zcbor_tags.h"
15 : :
16 : : #ifdef __cplusplus
17 : : extern "C" {
18 : : #endif
19 : :
20 : : #define ZCBOR_STRINGIFY_PRE(x) #x
21 : : #define ZCBOR_STRINGIFY(s) ZCBOR_STRINGIFY_PRE(s)
22 : :
23 : : #define ZCBOR_VERSION_MAJOR 0
24 : : #define ZCBOR_VERSION_MINOR 8
25 : : #define ZCBOR_VERSION_BUGFIX 99
26 : :
27 : : /** The version string with dots and not prefix. */
28 : : #define ZCBOR_VERSION_STR ZCBOR_STRINGIFY(ZCBOR_VERSION_MAJOR) \
29 : : "." ZCBOR_STRINGIFY(ZCBOR_VERSION_MINOR) \
30 : : "." ZCBOR_STRINGIFY(ZCBOR_VERSION_BUGFIX)
31 : :
32 : : /** Monotonically increasing integer representing the version. */
33 : : #define ZCBOR_VERSION ((ZCBOR_VERSION_MAJOR << 24) \
34 : : + (ZCBOR_VERSION_MINOR << 16) \
35 : : + (ZCBOR_VERSION_BUGFIX << 8))
36 : :
37 : : /** Convenience type that allows pointing to strings directly inside the payload
38 : : * without the need to copy out.
39 : : */
40 : : struct zcbor_string {
41 : : const uint8_t *value;
42 : : size_t len;
43 : : };
44 : :
45 : :
46 : : /** Type representing a string fragment.
47 : : *
48 : : * Don't modify any member variables, or subsequent calls may fail.
49 : : **/
50 : : struct zcbor_string_fragment {
51 : : struct zcbor_string fragment; ///! Location and length of the fragment.
52 : : size_t offset; ///! The offset in the full string at which this fragment belongs.
53 : : size_t total_len; ///! The total length of the string this fragment is a part of.
54 : : };
55 : :
56 : :
57 : : /** Size to use in struct zcbor_string_fragment when the real size is unknown. */
58 : : #define ZCBOR_STRING_FRAGMENT_UNKNOWN_LENGTH SIZE_MAX
59 : :
60 : : #ifndef MIN
61 : : #define MIN(a, b) (((a) < (b)) ? (a) : (b))
62 : : #endif
63 : :
64 : : #ifndef MAX
65 : : #define MAX(a, b) (((a) < (b)) ? (b) : (a))
66 : : #endif
67 : :
68 : : #ifndef ZCBOR_ARRAY_SIZE
69 : : #define ZCBOR_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
70 : : #endif
71 : :
72 : : /* Endian-dependent offset of smaller integer in a bigger one. */
73 : : #ifdef ZCBOR_BIG_ENDIAN
74 : : #define ZCBOR_ECPY_OFFS(dst_len, src_len) ((dst_len) - (src_len))
75 : : #else
76 : : #define ZCBOR_ECPY_OFFS(dst_len, src_len) (0)
77 : : #endif /* ZCBOR_BIG_ENDIAN */
78 : :
79 : : #if SIZE_MAX <= UINT64_MAX
80 : : /** The ZCBOR_SUPPORTS_SIZE_T will be defined if processing of size_t type variables directly
81 : : * with zcbor_size_ functions is supported.
82 : : **/
83 : : #define ZCBOR_SUPPORTS_SIZE_T
84 : : #else
85 : : #warning "zcbor: Unsupported size_t encoding size"
86 : : #endif
87 : :
88 : : struct zcbor_state_constant;
89 : :
90 : : /** The zcbor_state_t structure is used for both encoding and decoding. */
91 : : typedef struct {
92 : : union {
93 : : uint8_t *payload_mut;
94 : : uint8_t const *payload; /**< The current place in the payload. Will be
95 : : updated when an element is correctly
96 : : processed. */
97 : : };
98 : : uint8_t const *payload_bak; /**< Temporary backup of payload. */
99 : : size_t elem_count; /**< The current element is part of a LIST or a MAP,
100 : : and this keeps count of how many elements are
101 : : expected. This will be checked before processing
102 : : and decremented if the element is correctly
103 : : processed. */
104 : : uint8_t const *payload_end; /**< The end of the payload. This will be
105 : : checked against payload before
106 : : processing each element. */
107 : : bool payload_moved; /**< Is set to true while the state is stored as a backup
108 : : if @ref zcbor_update_state is called, since that function
109 : : updates the payload_end of all backed-up states. */
110 : :
111 : : /* This is the "decode state", the part of zcbor_state_t that is only used by zcbor_decode.c. */
112 : : struct {
113 : : bool indefinite_length_array; /**< Is set to true if the decoder is currently
114 : : decoding the contents of an indefinite-
115 : : length array. */
116 : : bool counting_map_elems; /**< Is set to true while the number of elements of the
117 : : current map are being counted. */
118 : : #ifdef ZCBOR_MAP_SMART_SEARCH
119 : : uint8_t *map_search_elem_state; /**< Optional flags to use when searching unordered
120 : : maps. If this is not NULL and map_elem_count
121 : : is non-zero, this consists of one flag per element
122 : : in the current map. The n-th bit can be set to 0
123 : : to indicate that the n-th element in the
124 : : map should not be searched. These are manipulated
125 : : via zcbor_elem_processed() or
126 : : zcbor_unordered_map_search(), and should not be
127 : : manipulated directly. */
128 : : #else
129 : : size_t map_elems_processed; /**< The number of elements of an unordered map
130 : : that have been processed. */
131 : : #endif
132 : : size_t map_elem_count; /**< Number of elements in the current unordered map.
133 : : This also serves as the number of bits (not bytes)
134 : : in the map_search_elem_state array (when applicable). */
135 : : } decode_state;
136 : : struct zcbor_state_constant *constant_state; /**< The part of the state that is
137 : : not backed up and duplicated. */
138 : : } zcbor_state_t;
139 : :
140 : : struct zcbor_state_constant {
141 : : zcbor_state_t *backup_list;
142 : : size_t current_backup;
143 : : size_t num_backups;
144 : : int error;
145 : : #ifdef ZCBOR_STOP_ON_ERROR
146 : : bool stop_on_error;
147 : : #endif
148 : : bool enforce_canonical; /**< Fail when decoding if data is non-canonical.
149 : : The default/initial value follows ZCBOR_CANONICAL */
150 : : bool manually_process_elem; /**< Whether an (unordered map) element should be automatically
151 : : marked as processed when found via @ref zcbor_search_map_key. */
152 : : #ifdef ZCBOR_MAP_SMART_SEARCH
153 : : uint8_t *map_search_elem_state_end; /**< The end of the @ref map_search_elem_state buffer. */
154 : : #endif
155 : : };
156 : :
157 : : #ifdef ZCBOR_CANONICAL
158 : : #define ZCBOR_ENFORCE_CANONICAL_DEFAULT true
159 : : #else
160 : : #define ZCBOR_ENFORCE_CANONICAL_DEFAULT false
161 : : #endif
162 : :
163 : : #define ZCBOR_ENFORCE_CANONICAL(state) (state->constant_state \
164 : : ? state->constant_state->enforce_canonical : ZCBOR_ENFORCE_CANONICAL_DEFAULT)
165 : :
166 : : #define ZCBOR_MANUALLY_PROCESS_ELEM_DEFAULT false
167 : :
168 : : #define ZCBOR_MANUALLY_PROCESS_ELEM(state) (state->constant_state \
169 : : ? state->constant_state->manually_process_elem : ZCBOR_MANUALLY_PROCESS_ELEM_DEFAULT)
170 : :
171 : : /** Function pointer type used with zcbor_multi_decode.
172 : : *
173 : : * This type is compatible with all decoding functions here and in the generated
174 : : * code, except for zcbor_multi_decode.
175 : : */
176 : : typedef bool(zcbor_encoder_t)(zcbor_state_t *, const void *);
177 : : typedef bool(zcbor_decoder_t)(zcbor_state_t *, void *);
178 : :
179 : : /** Enumeration representing the major types available in CBOR.
180 : : *
181 : : * The major type is represented in the 3 first bits of the header byte.
182 : : */
183 : : typedef enum
184 : : {
185 : : ZCBOR_MAJOR_TYPE_PINT = 0, ///! Positive Integer
186 : : ZCBOR_MAJOR_TYPE_NINT = 1, ///! Negative Integer
187 : : ZCBOR_MAJOR_TYPE_BSTR = 2, ///! Byte String
188 : : ZCBOR_MAJOR_TYPE_TSTR = 3, ///! Text String
189 : : ZCBOR_MAJOR_TYPE_LIST = 4, ///! List
190 : : ZCBOR_MAJOR_TYPE_MAP = 5, ///! Map
191 : : ZCBOR_MAJOR_TYPE_TAG = 6, ///! Semantic Tag
192 : : ZCBOR_MAJOR_TYPE_SIMPLE = 7, ///! Simple values and floats
193 : : } zcbor_major_type_t;
194 : :
195 : : /** Extract the major type, i.e. the first 3 bits of the header byte. */
196 : : #define ZCBOR_MAJOR_TYPE(header_byte) ((zcbor_major_type_t)(((header_byte) >> 5) & 0x7))
197 : :
198 : : /** Extract the additional info, i.e. the last 5 bits of the header byte. */
199 : : #define ZCBOR_ADDITIONAL(header_byte) ((header_byte) & 0x1F)
200 : :
201 : : /** Convenience macro for failing out of a decoding/encoding function.
202 : : */
203 : : #define ZCBOR_FAIL() \
204 : : do {\
205 : : zcbor_log("ZCBOR_FAIL "); \
206 : : zcbor_trace_file(state); \
207 : : return false; \
208 : : } while(0)
209 : :
210 : : #define ZCBOR_FAIL_IF(expr) \
211 : : do {\
212 : : if (expr) { \
213 : : zcbor_log("ZCBOR_FAIL_IF(" #expr ") "); \
214 : : ZCBOR_FAIL(); \
215 : : } \
216 : : } while(0)
217 : :
218 : : #define ZCBOR_ERR(err) \
219 : : do { \
220 : : zcbor_log("ZCBOR_ERR(%d) ", err); \
221 : : zcbor_error(state, err); \
222 : : ZCBOR_FAIL(); \
223 : : } while(0)
224 : :
225 : : #define ZCBOR_ERR_IF(expr, err) \
226 : : do {\
227 : : if (expr) { \
228 : : zcbor_log("ZCBOR_ERR_IF(" #expr ", %d) ", err); \
229 : : ZCBOR_ERR(err); \
230 : : } \
231 : : } while(0)
232 : :
233 : : #define ZCBOR_CHECK_PAYLOAD() \
234 : : ZCBOR_ERR_IF(state->payload >= state->payload_end, ZCBOR_ERR_NO_PAYLOAD)
235 : :
236 : : #ifdef ZCBOR_STOP_ON_ERROR
237 : : #define ZCBOR_CHECK_ERROR() \
238 : : do { \
239 : : if (!zcbor_check_error(state)) { \
240 : : ZCBOR_FAIL(); \
241 : : } \
242 : : } while(0)
243 : : #else
244 : : #define ZCBOR_CHECK_ERROR()
245 : : #endif
246 : :
247 : : #define ZCBOR_VALUE_IN_HEADER 23 ///! Values below this are encoded directly in the header.
248 : : #define ZCBOR_VALUE_IS_1_BYTE 24 ///! The next 1 byte contains the value.
249 : : #define ZCBOR_VALUE_IS_2_BYTES 25 ///! The next 2 bytes contain the value.
250 : : #define ZCBOR_VALUE_IS_4_BYTES 26 ///! The next 4 bytes contain the value.
251 : : #define ZCBOR_VALUE_IS_8_BYTES 27 ///! The next 8 bytes contain the value.
252 : : #define ZCBOR_VALUE_IS_INDEFINITE_LENGTH 31 ///! The list or map has indefinite length, and will instead be terminated by a 0xFF token.
253 : :
254 : : #define ZCBOR_BOOL_TO_SIMPLE ((uint8_t)20) ///! In CBOR, false/true have the values 20/21
255 : :
256 : : #define ZCBOR_FLAG_RESTORE 1UL ///! Restore from the backup. Overwrite the current state with the state from the backup.
257 : : #define ZCBOR_FLAG_CONSUME 2UL ///! Consume the backup. Remove the backup from the stack of backups.
258 : : #define ZCBOR_FLAG_KEEP_PAYLOAD 4UL ///! Keep the pre-restore payload after restoring.
259 : : #define ZCBOR_FLAG_KEEP_DECODE_STATE 8UL ///! Keep the pre-restore decode state (everything only used for decoding)
260 : :
261 : : #define ZCBOR_SUCCESS 0
262 : : #define ZCBOR_ERR_NO_BACKUP_MEM 1
263 : : #define ZCBOR_ERR_NO_BACKUP_ACTIVE 2
264 : : #define ZCBOR_ERR_LOW_ELEM_COUNT 3
265 : : #define ZCBOR_ERR_HIGH_ELEM_COUNT 4
266 : : #define ZCBOR_ERR_INT_SIZE 5
267 : : #define ZCBOR_ERR_FLOAT_SIZE 6
268 : : #define ZCBOR_ERR_ADDITIONAL_INVAL 7 ///! > 27
269 : : #define ZCBOR_ERR_NO_PAYLOAD 8
270 : : #define ZCBOR_ERR_PAYLOAD_NOT_CONSUMED 9
271 : : #define ZCBOR_ERR_WRONG_TYPE 10
272 : : #define ZCBOR_ERR_WRONG_VALUE 11
273 : : #define ZCBOR_ERR_WRONG_RANGE 12
274 : : #define ZCBOR_ERR_ITERATIONS 13
275 : : #define ZCBOR_ERR_ASSERTION 14
276 : : #define ZCBOR_ERR_PAYLOAD_OUTDATED 15 ///! Because of a call to @ref zcbor_update_state
277 : : #define ZCBOR_ERR_ELEM_NOT_FOUND 16
278 : : #define ZCBOR_ERR_MAP_MISALIGNED 17
279 : : #define ZCBOR_ERR_ELEMS_NOT_PROCESSED 18
280 : : #define ZCBOR_ERR_NOT_AT_END 19
281 : : #define ZCBOR_ERR_MAP_FLAGS_NOT_AVAILABLE 20
282 : : #define ZCBOR_ERR_INVALID_VALUE_ENCODING 21 ///! When ZCBOR_CANONICAL is defined, and the incoming data is not encoded with minimal length, or uses indefinite length array.
283 : : #define ZCBOR_ERR_CONSTANT_STATE_MISSING 22
284 : : #define ZCBOR_ERR_UNKNOWN 31
285 : :
286 : : /** The largest possible elem_count. */
287 : : #define ZCBOR_MAX_ELEM_COUNT SIZE_MAX
288 : :
289 : : /** Initial value for elem_count for when it just needs to be large. */
290 : : #define ZCBOR_LARGE_ELEM_COUNT (ZCBOR_MAX_ELEM_COUNT - 15)
291 : :
292 : :
293 : : /** Take a backup of the current state. Overwrite the current elem_count. */
294 : : bool zcbor_new_backup(zcbor_state_t *state, size_t new_elem_count);
295 : :
296 : : /** Consult the most recent backup. In doing so, check whether elem_count is
297 : : * less than or equal to max_elem_count.
298 : : * Also, take action based on the flags (See ZCBOR_FLAG_*).
299 : : */
300 : : bool zcbor_process_backup(zcbor_state_t *state, uint32_t flags, size_t max_elem_count);
301 : :
302 : : /** Convenience function for starting encoding/decoding of a union.
303 : : *
304 : : * That is, for attempting to encode, or especially decode, multiple options.
305 : : * Makes a new backup.
306 : : */
307 : : bool zcbor_union_start_code(zcbor_state_t *state);
308 : :
309 : : /** Convenience function before encoding/decoding one element of a union.
310 : : *
311 : : * Call this before attempting each option.
312 : : * Restores the backup, without consuming it.
313 : : */
314 : : bool zcbor_union_elem_code(zcbor_state_t *state);
315 : :
316 : : /** Convenience function before encoding/decoding one element of a union.
317 : : *
318 : : * Consumes the backup without restoring it.
319 : : */
320 : : bool zcbor_union_end_code(zcbor_state_t *state);
321 : :
322 : : /** Initialize a state with backups.
323 : : * As long as n_states is more than 1, one of the states in the array is used
324 : : * as a struct zcbor_state_constant object.
325 : : * If there is no struct zcbor_state_constant (n_states == 1), error codes are
326 : : * not available.
327 : : * This means that you get a state with (n_states - 2) backups.
328 : : * payload, payload_len, elem_count, and elem_state are used to initialize the first state.
329 : : * The elem_state is only needed for unordered maps, when ZCBOR_MAP_SMART_SEARCH is enabled.
330 : : * It is ignored otherwise.
331 : : */
332 : : void zcbor_new_state(zcbor_state_t *state_array, size_t n_states,
333 : : const uint8_t *payload, size_t payload_len, size_t elem_count,
334 : : uint8_t *elem_state, size_t elem_state_bytes);
335 : :
336 : : /** Do boilerplate entry function procedure.
337 : : * Initialize states, call function, and check the result.
338 : : */
339 : : int zcbor_entry_function(const uint8_t *payload, size_t payload_len,
340 : : void *result, size_t *payload_len_out, zcbor_state_t *state, zcbor_decoder_t func,
341 : : size_t n_states, size_t elem_count);
342 : :
343 : : #ifdef ZCBOR_STOP_ON_ERROR
344 : : /** Check stored error and fail if present, but only if stop_on_error is true.
345 : : *
346 : : * @retval true No error found
347 : : * @retval false An error was found
348 : : */
349 : : static inline bool zcbor_check_error(const zcbor_state_t *state)
350 : : {
351 : : struct zcbor_state_constant *cs = state->constant_state;
352 : : return !(cs && cs->stop_on_error && cs->error);
353 : : }
354 : : #endif
355 : :
356 : : /** Return the current error state, replacing it with SUCCESS. */
357 : 0 : static inline int zcbor_pop_error(zcbor_state_t *state)
358 : : {
359 [ # # ]: 0 : if (!state->constant_state) {
360 : : return ZCBOR_SUCCESS;
361 : : }
362 : 0 : int err = state->constant_state->error;
363 : :
364 : 0 : state->constant_state->error = ZCBOR_SUCCESS;
365 : 0 : return err;
366 : : }
367 : :
368 : : /** Look at current error state without altering it */
369 : : static inline int zcbor_peek_error(const zcbor_state_t *state)
370 : : {
371 : : if (!state->constant_state) {
372 : : return ZCBOR_SUCCESS;
373 : : } else {
374 : : return state->constant_state->error;
375 : : }
376 : : }
377 : :
378 : : /** Write the provided error to the error state. */
379 : 157 : static inline void zcbor_error(zcbor_state_t *state, int err)
380 : : {
381 : : #ifdef ZCBOR_STOP_ON_ERROR
382 : : if (zcbor_check_error(state))
383 : : #endif
384 : : {
385 [ + - ]: 157 : if (state->constant_state) {
386 : 157 : state->constant_state->error = err;
387 : : }
388 : : }
389 : 157 : }
390 : :
391 : : /** Whether the current payload is exhausted. */
392 : : static inline bool zcbor_payload_at_end(const zcbor_state_t *state)
393 : : {
394 : : return (state->payload == state->payload_end);
395 : : }
396 : :
397 : : /** Update the current payload pointer (and payload_end).
398 : : *
399 : : * For use when the payload is divided into multiple chunks.
400 : : *
401 : : * This function also updates all backups to the new payload_end.
402 : : * This sets a flag so that @ref zcbor_process_backup fails if a backup is
403 : : * processed with the flag @ref ZCBOR_FLAG_RESTORE, but without the flag
404 : : * @ref ZCBOR_FLAG_KEEP_PAYLOAD since this would cause an invalid state.
405 : : *
406 : : * @param[inout] state The current state, will be updated with
407 : : * the new payload pointer.
408 : : * @param[in] payload The new payload chunk.
409 : : * @param[in] payload_len The length of the new payload chunk.
410 : : */
411 : : void zcbor_update_state(zcbor_state_t *state,
412 : : const uint8_t *payload, size_t payload_len);
413 : :
414 : : /** Check that the provided fragments are complete and in the right order.
415 : : *
416 : : * If the total length is not known, the total_len can have the value
417 : : * @ref ZCBOR_STRING_FRAGMENT_UNKNOWN_LENGTH. If so, all fragments will be
418 : : * updated with the actual total length.
419 : : *
420 : : * @param[in] fragments An array of string fragments. Cannot be NULL.
421 : : * @param[in] num_fragments The number of fragments in @p fragments.
422 : : *
423 : : * @retval true If the fragments are in the right order, and there are no
424 : : * fragments missing.
425 : : * @retval false If not all fragments have the same total_len, or gaps are
426 : : * found, or if any fragment value is NULL.
427 : : */
428 : : bool zcbor_validate_string_fragments(struct zcbor_string_fragment *fragments,
429 : : size_t num_fragments);
430 : :
431 : : /** Assemble the fragments into a single string.
432 : : *
433 : : * The fragments are copied in the order they appear, without regard for
434 : : * offset or total_len. To ensure that the fragments are correct, first
435 : : * validate with @ref zcbor_validate_string_fragments.
436 : : *
437 : : * @param[in] fragments An array of string fragments. Cannot be NULL.
438 : : * @param[in] num_fragments The number of fragments in @p fragments.
439 : : * @param[out] result The buffer to place the assembled string into.
440 : : * @param[inout] result_len In: The length of the @p result.
441 : : * Out: The length of the assembled string.
442 : : *
443 : : * @retval true On success.
444 : : * @retval false If the assembled string would be larger than the buffer.
445 : : * The buffer might still be written to.
446 : : */
447 : : bool zcbor_splice_string_fragments(struct zcbor_string_fragment *fragments,
448 : : size_t num_fragments, uint8_t *result, size_t *result_len);
449 : :
450 : : /** Compare two struct zcbor_string instances.
451 : : *
452 : : * @param[in] str1 A string
453 : : * @param[in] str2 A string to compare to @p str1
454 : : *
455 : : * @retval true if the strings are identical
456 : : * @retval false if length or contents don't match, or one one or both strings is NULL.
457 : : */
458 : : bool zcbor_compare_strings(const struct zcbor_string *str1,
459 : : const struct zcbor_string *str2);
460 : :
461 : : /** Calculate the length of a CBOR string, list, or map header.
462 : : *
463 : : * This can be used to find the start of the CBOR object when you have a
464 : : * pointer to the start of the contents. The function assumes that the header
465 : : * will be the shortest it can be.
466 : : *
467 : : * @param[in] num_elems The number of elements in the string, list, or map.
468 : : *
469 : : * @return The length of the header in bytes (1-9).
470 : : */
471 : : size_t zcbor_header_len(uint64_t value);
472 : :
473 : : /** Like @ref zcbor_header_len but for integer of any size <= 8. */
474 : : size_t zcbor_header_len_ptr(const void *const value, size_t value_len);
475 : :
476 : : /** Convert a float16 value to float32.
477 : : *
478 : : * @param[in] input The float16 value stored in a uint16_t.
479 : : *
480 : : * @return The resulting float32 value.
481 : : */
482 : : float zcbor_float16_to_32(uint16_t input);
483 : :
484 : : /** Convert a float32 value to float16.
485 : : *
486 : : * @param[in] input The float32 value.
487 : : *
488 : : * @return The resulting float16 value as a uint16_t.
489 : : */
490 : : uint16_t zcbor_float32_to_16(float input);
491 : :
492 : : #ifdef ZCBOR_MAP_SMART_SEARCH
493 : : static inline size_t zcbor_round_up(size_t x, size_t align)
494 : : {
495 : : return (((x) + (align) - 1) / (align) * (align));
496 : : }
497 : :
498 : : #define ZCBOR_BITS_PER_BYTE 8
499 : : /** Calculate the number of bytes needed to hold @p num_flags 1 bit flags
500 : : */
501 : : static inline size_t zcbor_flags_to_bytes(size_t num_flags)
502 : : {
503 : : return zcbor_round_up(num_flags, ZCBOR_BITS_PER_BYTE) / ZCBOR_BITS_PER_BYTE;
504 : : }
505 : :
506 : : /** Calculate the number of zcbor_state_t instances needed to hold @p num_flags 1 bit flags
507 : : */
508 : : static inline size_t zcbor_flags_to_states(size_t num_flags)
509 : : {
510 : : return zcbor_round_up(num_flags, sizeof(zcbor_state_t) * ZCBOR_BITS_PER_BYTE)
511 : : / (sizeof(zcbor_state_t) * ZCBOR_BITS_PER_BYTE);
512 : : }
513 : :
514 : : #define ZCBOR_FLAG_STATES(n_flags) zcbor_flags_to_states(n_flags)
515 : :
516 : : #else
517 : : #define ZCBOR_FLAG_STATES(n_flags) 0
518 : : #endif
519 : :
520 : : size_t strnlen(const char *, size_t);
521 : :
522 : : #ifdef __cplusplus
523 : : }
524 : : #endif
525 : :
526 : : #endif /* ZCBOR_COMMON_H__ */
|