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 9
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 : : #define ZCBOR_NIL_VAL ((uint8_t)22)
256 : : #define ZCBOR_UNDEF_VAL ((uint8_t)23)
257 : :
258 : : #define ZCBOR_IS_FLOAT(header_byte) (((header_byte) >= 0xF9) && ((header_byte) <= 0xFB))
259 : :
260 : : #define ZCBOR_FLAG_RESTORE 1UL ///! Restore from the backup. Overwrite the current state with the state from the backup.
261 : : #define ZCBOR_FLAG_CONSUME 2UL ///! Consume the backup. Remove the backup from the stack of backups.
262 : : #define ZCBOR_FLAG_KEEP_PAYLOAD 4UL ///! Keep the pre-restore payload after restoring.
263 : : #define ZCBOR_FLAG_KEEP_DECODE_STATE 8UL ///! Keep the pre-restore decode state (everything only used for decoding)
264 : :
265 : : #define ZCBOR_SUCCESS 0
266 : : #define ZCBOR_ERR_NO_BACKUP_MEM 1
267 : : #define ZCBOR_ERR_NO_BACKUP_ACTIVE 2
268 : : #define ZCBOR_ERR_LOW_ELEM_COUNT 3
269 : : #define ZCBOR_ERR_HIGH_ELEM_COUNT 4
270 : : #define ZCBOR_ERR_INT_SIZE 5
271 : : #define ZCBOR_ERR_FLOAT_SIZE 6
272 : : #define ZCBOR_ERR_ADDITIONAL_INVAL 7 ///! > 27
273 : : #define ZCBOR_ERR_NO_PAYLOAD 8
274 : : #define ZCBOR_ERR_PAYLOAD_NOT_CONSUMED 9
275 : : #define ZCBOR_ERR_WRONG_TYPE 10
276 : : #define ZCBOR_ERR_WRONG_VALUE 11
277 : : #define ZCBOR_ERR_WRONG_RANGE 12
278 : : #define ZCBOR_ERR_ITERATIONS 13
279 : : #define ZCBOR_ERR_ASSERTION 14
280 : : #define ZCBOR_ERR_PAYLOAD_OUTDATED 15 ///! Because of a call to @ref zcbor_update_state
281 : : #define ZCBOR_ERR_ELEM_NOT_FOUND 16
282 : : #define ZCBOR_ERR_MAP_MISALIGNED 17
283 : : #define ZCBOR_ERR_ELEMS_NOT_PROCESSED 18
284 : : #define ZCBOR_ERR_NOT_AT_END 19
285 : : #define ZCBOR_ERR_MAP_FLAGS_NOT_AVAILABLE 20
286 : : #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.
287 : : #define ZCBOR_ERR_CONSTANT_STATE_MISSING 22
288 : : #define ZCBOR_ERR_UNKNOWN 31
289 : :
290 : : /** The largest possible elem_count. */
291 : : #define ZCBOR_MAX_ELEM_COUNT SIZE_MAX
292 : :
293 : : /** Initial value for elem_count for when it just needs to be large. */
294 : : #define ZCBOR_LARGE_ELEM_COUNT (ZCBOR_MAX_ELEM_COUNT - 15)
295 : :
296 : :
297 : : /** Take a backup of the current state. Overwrite the current elem_count. */
298 : : bool zcbor_new_backup(zcbor_state_t *state, size_t new_elem_count);
299 : :
300 : : /** Consult the most recent backup. In doing so, check whether elem_count is
301 : : * less than or equal to max_elem_count.
302 : : * Also, take action based on the flags (See ZCBOR_FLAG_*).
303 : : */
304 : : bool zcbor_process_backup(zcbor_state_t *state, uint32_t flags, size_t max_elem_count);
305 : :
306 : : /** Convenience function for starting encoding/decoding of a union.
307 : : *
308 : : * That is, for attempting to encode, or especially decode, multiple options.
309 : : * Makes a new backup.
310 : : */
311 : : bool zcbor_union_start_code(zcbor_state_t *state);
312 : :
313 : : /** Convenience function before encoding/decoding one element of a union.
314 : : *
315 : : * Call this before attempting each option.
316 : : * Restores the backup, without consuming it.
317 : : */
318 : : bool zcbor_union_elem_code(zcbor_state_t *state);
319 : :
320 : : /** Convenience function before encoding/decoding one element of a union.
321 : : *
322 : : * Consumes the backup without restoring it.
323 : : */
324 : : bool zcbor_union_end_code(zcbor_state_t *state);
325 : :
326 : : /** Initialize a state with backups.
327 : : * As long as n_states is more than 1, one of the states in the array is used
328 : : * as a struct zcbor_state_constant object.
329 : : * If there is no struct zcbor_state_constant (n_states == 1), error codes are
330 : : * not available.
331 : : * This means that you get a state with (n_states - 2) backups.
332 : : * payload, payload_len, elem_count, and elem_state are used to initialize the first state.
333 : : * The elem_state is only needed for unordered maps, when ZCBOR_MAP_SMART_SEARCH is enabled.
334 : : * It is ignored otherwise.
335 : : */
336 : : void zcbor_new_state(zcbor_state_t *state_array, size_t n_states,
337 : : const uint8_t *payload, size_t payload_len, size_t elem_count,
338 : : uint8_t *elem_state, size_t elem_state_bytes);
339 : :
340 : : /** Do boilerplate entry function procedure.
341 : : * Initialize states, call function, and check the result.
342 : : */
343 : : int zcbor_entry_function(const uint8_t *payload, size_t payload_len,
344 : : void *result, size_t *payload_len_out, zcbor_state_t *state, zcbor_decoder_t func,
345 : : size_t n_states, size_t elem_count);
346 : :
347 : : #ifdef ZCBOR_STOP_ON_ERROR
348 : : /** Check stored error and fail if present, but only if stop_on_error is true.
349 : : *
350 : : * @retval true No error found
351 : : * @retval false An error was found
352 : : */
353 : : static inline bool zcbor_check_error(const zcbor_state_t *state)
354 : : {
355 : : struct zcbor_state_constant *cs = state->constant_state;
356 : : return !(cs && cs->stop_on_error && cs->error);
357 : : }
358 : : #endif
359 : :
360 : : /** Return the current error state, replacing it with SUCCESS. */
361 : 0 : static inline int zcbor_pop_error(zcbor_state_t *state)
362 : : {
363 [ # # ]: 0 : if (!state->constant_state) {
364 : : return ZCBOR_SUCCESS;
365 : : }
366 : 0 : int err = state->constant_state->error;
367 : :
368 : 0 : state->constant_state->error = ZCBOR_SUCCESS;
369 : 0 : return err;
370 : : }
371 : :
372 : : /** Look at current error state without altering it */
373 : : static inline int zcbor_peek_error(const zcbor_state_t *state)
374 : : {
375 : : if (!state->constant_state) {
376 : : return ZCBOR_SUCCESS;
377 : : } else {
378 : : return state->constant_state->error;
379 : : }
380 : : }
381 : :
382 : : /** Write the provided error to the error state. */
383 : 157 : static inline void zcbor_error(zcbor_state_t *state, int err)
384 : : {
385 : : #ifdef ZCBOR_STOP_ON_ERROR
386 : : if (zcbor_check_error(state))
387 : : #endif
388 : : {
389 [ + - ]: 157 : if (state->constant_state) {
390 : 157 : state->constant_state->error = err;
391 : : }
392 : : }
393 : 157 : }
394 : :
395 : : /** Whether the current payload is exhausted. */
396 : : static inline bool zcbor_payload_at_end(const zcbor_state_t *state)
397 : : {
398 : : return (state->payload == state->payload_end);
399 : : }
400 : :
401 : : /** Update the current payload pointer (and payload_end).
402 : : *
403 : : * For use when the payload is divided into multiple chunks.
404 : : *
405 : : * This function also updates all backups to the new payload_end.
406 : : * This sets a flag so that @ref zcbor_process_backup fails if a backup is
407 : : * processed with the flag @ref ZCBOR_FLAG_RESTORE, but without the flag
408 : : * @ref ZCBOR_FLAG_KEEP_PAYLOAD since this would cause an invalid state.
409 : : *
410 : : * @param[inout] state The current state, will be updated with
411 : : * the new payload pointer.
412 : : * @param[in] payload The new payload chunk.
413 : : * @param[in] payload_len The length of the new payload chunk.
414 : : */
415 : : void zcbor_update_state(zcbor_state_t *state,
416 : : const uint8_t *payload, size_t payload_len);
417 : :
418 : : /** Check that the provided fragments are complete and in the right order.
419 : : *
420 : : * If the total length is not known, the total_len can have the value
421 : : * @ref ZCBOR_STRING_FRAGMENT_UNKNOWN_LENGTH. If so, all fragments will be
422 : : * updated with the actual total length.
423 : : *
424 : : * @param[in] fragments An array of string fragments. Cannot be NULL.
425 : : * @param[in] num_fragments The number of fragments in @p fragments.
426 : : *
427 : : * @retval true If the fragments are in the right order, and there are no
428 : : * fragments missing.
429 : : * @retval false If not all fragments have the same total_len, or gaps are
430 : : * found, or if any fragment value is NULL.
431 : : */
432 : : bool zcbor_validate_string_fragments(struct zcbor_string_fragment *fragments,
433 : : size_t num_fragments);
434 : :
435 : : /** Assemble the fragments into a single string.
436 : : *
437 : : * The fragments are copied in the order they appear, without regard for
438 : : * offset or total_len. To ensure that the fragments are correct, first
439 : : * validate with @ref zcbor_validate_string_fragments.
440 : : *
441 : : * @param[in] fragments An array of string fragments. Cannot be NULL.
442 : : * @param[in] num_fragments The number of fragments in @p fragments.
443 : : * @param[out] result The buffer to place the assembled string into.
444 : : * @param[inout] result_len In: The length of the @p result.
445 : : * Out: The length of the assembled string.
446 : : *
447 : : * @retval true On success.
448 : : * @retval false If the assembled string would be larger than the buffer.
449 : : * The buffer might still be written to.
450 : : */
451 : : bool zcbor_splice_string_fragments(struct zcbor_string_fragment *fragments,
452 : : size_t num_fragments, uint8_t *result, size_t *result_len);
453 : :
454 : : /** Compare two struct zcbor_string instances.
455 : : *
456 : : * @param[in] str1 A string
457 : : * @param[in] str2 A string to compare to @p str1
458 : : *
459 : : * @retval true if the strings are identical
460 : : * @retval false if length or contents don't match, or one one or both strings is NULL.
461 : : */
462 : : bool zcbor_compare_strings(const struct zcbor_string *str1,
463 : : const struct zcbor_string *str2);
464 : :
465 : : /** Calculate the length of a CBOR string, list, or map header.
466 : : *
467 : : * This can be used to find the start of the CBOR object when you have a
468 : : * pointer to the start of the contents. The function assumes that the header
469 : : * will be the shortest it can be.
470 : : *
471 : : * @param[in] num_elems The number of elements in the string, list, or map.
472 : : *
473 : : * @return The length of the header in bytes (1-9).
474 : : */
475 : : size_t zcbor_header_len(uint64_t value);
476 : :
477 : : /** Like @ref zcbor_header_len but for integer of any size <= 8. */
478 : : size_t zcbor_header_len_ptr(const void *const value, size_t value_len);
479 : :
480 : : /** If a string (header + payload) is encoded into the rest of the payload, how long would it be?
481 : : *
482 : : * Note that a string with this length doesn't necessarily fill the rest of the
483 : : * payload. For some payload lengths, e.g. 25, it's impossible to encode a
484 : : * string of that total length.
485 : : *
486 : : * @param[in] state The current state.
487 : : *
488 : : * @return The length of the string (payload, not including header) in bytes.
489 : : */
490 : : size_t zcbor_remaining_str_len(zcbor_state_t *state);
491 : :
492 : : /** Convert a float16 value to float32.
493 : : *
494 : : * @param[in] input The float16 value stored in a uint16_t.
495 : : *
496 : : * @return The resulting float32 value.
497 : : */
498 : : float zcbor_float16_to_32(uint16_t input);
499 : :
500 : : /** Convert a float32 value to float16.
501 : : *
502 : : * @param[in] input The float32 value.
503 : : *
504 : : * @return The resulting float16 value as a uint16_t.
505 : : */
506 : : uint16_t zcbor_float32_to_16(float input);
507 : :
508 : : #ifdef ZCBOR_MAP_SMART_SEARCH
509 : : #define ZCBOR_ROUND_UP(x, align) (((x) + (align) - 1) / (align) * (align))
510 : : #define ZCBOR_BITS_PER_BYTE 8
511 : :
512 : : /** Calculate the number of bytes needed to hold @p num_flags 1 bit flags
513 : : */
514 : : static inline size_t zcbor_flags_to_bytes(size_t num_flags)
515 : : {
516 : : return ZCBOR_ROUND_UP(num_flags, ZCBOR_BITS_PER_BYTE) / ZCBOR_BITS_PER_BYTE;
517 : : }
518 : :
519 : : /** Calculate the number of zcbor_state_t instances needed to hold @p num_flags 1 bit flags
520 : : */
521 : : #define ZCBOR_FLAGS_TO_STATES(num_flags) \
522 : : (ZCBOR_ROUND_UP(num_flags, sizeof(zcbor_state_t) * ZCBOR_BITS_PER_BYTE) \
523 : : / (sizeof(zcbor_state_t) * ZCBOR_BITS_PER_BYTE))
524 : :
525 : : #define ZCBOR_FLAG_STATES(n_flags) ZCBOR_FLAGS_TO_STATES(n_flags)
526 : :
527 : : #else
528 : : #define ZCBOR_FLAG_STATES(n_flags) 0
529 : : #endif
530 : :
531 : : size_t strnlen(const char *, size_t);
532 : :
533 : : #ifdef __cplusplus
534 : : }
535 : : #endif
536 : :
537 : : #endif /* ZCBOR_COMMON_H__ */
|