1 /*
2  * This file has been copied from the cddl-gen submodule.
3  * Commit 9f77837f9950da1633d22abf6181a830521a6688
4  */
5 
6 /*
7  * Copyright (c) 2020 Nordic Semiconductor ASA
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #ifndef CBOR_ENCODE_H__
13 #define CBOR_ENCODE_H__
14 #include <stdint.h>
15 #include <stdbool.h>
16 #include <stddef.h>
17 #include "cbor_common.h"
18 
19 
20 /** Encode a PINT/NINT into a int32_t.
21  *
22  * @param[inout] state        The current state of the decoding.
23  * @param[out]   result       Where to place the encoded value.
24  *
25  * @retval true   Everything is ok.
26  * @retval false  If the payload is exhausted.
27  */
28 bool intx32_encode(cbor_state_t *state, const int32_t *input);
29 bool intx32_put(cbor_state_t *state, int32_t result);
30 
31 /** Encode a PINT into a uint32_t. */
32 bool uintx32_encode(cbor_state_t *state, const uint32_t *result);
33 bool uintx32_put(cbor_state_t *state, uint32_t result);
34 
35 /** Encode a BSTR header.
36  *
37  * The rest of the string can be encoded as CBOR.
38  * A state backup is created to keep track of the element count.
39  *
40  * @retval true   Header encoded correctly
41  * @retval false  Header encoded incorrectly, or backup failed.
42  */
43 bool bstrx_cbor_start_encode(cbor_state_t *state, const cbor_string_type_t *result);
44 
45 /** Finalize encoding a CBOR-encoded BSTR.
46  *
47  * Restore element count from backup.
48  */
49 bool bstrx_cbor_end_encode(cbor_state_t *state);
50 
51 /** Encode a BSTR, */
52 bool bstrx_encode(cbor_state_t *state, const cbor_string_type_t *result);
53 
54 /** Encode a TSTR. */
55 bool tstrx_encode(cbor_state_t *state, const cbor_string_type_t *result);
56 
57 #define tstrx_put(state, string) \
58 	tstrx_encode(state, &(cbor_string_type_t){.value = (const uint8_t *)string, .len = (sizeof(string) - 1)})
59 
60 #define tstrx_put_term(state, string) \
61 	tstrx_encode(state, &(cbor_string_type_t){.value = (const uint8_t *)string, .len = strlen((const char *)string)})
62 
63 /** Encode a LIST header.
64  *
65  * The contents of the list can be decoded via subsequent function calls.
66  * A state backup is created to keep track of the element count.
67  */
68 bool list_start_encode(cbor_state_t *state, uint32_t max_num);
69 
70 /** Encode a MAP header. */
71 bool map_start_encode(cbor_state_t *state, uint32_t max_num);
72 
73 /** Encode end of a LIST. Do some checks and deallocate backup. */
74 bool list_end_encode(cbor_state_t *state, uint32_t max_num);
75 
76 /** Encode end of a MAP. Do some checks and deallocate backup. */
77 bool map_end_encode(cbor_state_t *state, uint32_t max_num);
78 
79 /** Encode a "nil" primitive value. result should be NULL. */
80 bool nilx_put(cbor_state_t *state, const void *result);
81 
82 /** Encode a boolean primitive value. */
83 bool boolx_encode(cbor_state_t *state, const bool *result);
84 bool boolx_put(cbor_state_t *state, bool result);
85 
86 /** Encode a float */
87 bool float_encode(cbor_state_t *state, double *result);
88 bool float_put(cbor_state_t *state, double result);
89 
90 /** Dummy encode "any": Encode a "nil". input should be NULL. */
91 bool any_encode(cbor_state_t *state, void *input);
92 
93 /** Encode a tag. */
94 bool tag_encode(cbor_state_t *state, uint32_t tag);
95 
96 /** Encode 0 or more elements with the same type and constraints.
97  *
98  * @details This must not necessarily encode all elements in a list. E.g. if
99  *          the list contains 3 INTS between 0 and 100 followed by 0 to 2 BSTRs
100  *          with length 8, that could be done with:
101  *
102  *          @code{c}
103  *              uint32_t int_min = 0;
104  *              uint32_t int_max = 100;
105  *              uint32_t bstr_size = 8;
106  *              uint32_t ints[3];
107  *              cbor_string_type_t bstrs[2] = <initialize here>;
108  *              bool res;
109  *
110  *              res = list_start_encode(state, 5);
111  *              // check res
112  *              res = multi_encode(3, 3, &num_encode, uintx32_encode, state,
113  *                           ints, 4);
114  *              // check res
115  *              res = multi_encode(0, 2, &num_encode, strx_encode, state,
116  *                           bstrs, sizeof(cbor_string_type_t));
117  *              // check res
118  *              res = list_end_encode(state, 5);
119  *              // check res
120  *          @endcode
121  *
122  * @param[in]  min_encode    The minimum acceptable number of elements.
123  * @param[in]  max_encode    The maximum acceptable number of elements.
124  * @param[in]  num_encode    The actual number of elements.
125  * @param[in]  encoder       The encoder function to call under the hood. This
126  *                           function will be called with the provided arguments
127  *                           repeatedly until the function fails (returns false)
128  *                           or until it has been called @p max_encode times.
129  *                           result is moved @p result_len bytes for each call
130  *                           to @p encoder, i.e. @p result refers to an array
131  *                           of result variables.
132  * @param[in]  input         Source of the encoded values. Must be an array
133  *                           of length at least @p max_encode.
134  * @param[in]  result_len    The length of the result variables. Must be the
135  *                           length of the elements in result.
136  *
137  * @retval true   If at least @p min_encode variables were correctly encoded.
138  * @retval false  If @p encoder failed before having encoded @p min_encode
139  *                values.
140  */
141 bool multi_encode(uint32_t min_encode, uint32_t max_encode, const uint32_t *num_encode,
142 		cbor_encoder_t encoder, cbor_state_t *state, const void *input,
143 		uint32_t result_len);
144 
145 bool present_encode(const uint32_t *present,
146 		cbor_encoder_t encoder,
147 		cbor_state_t *state,
148 		const void *input);
149 
150 #endif /* CBOR_ENCODE_H__ */
151