1 /*
2 * This file has been copied from the zcbor library.
3 * Commit zcbor 0.7.0
4 */
5
6 /*
7 * Copyright (c) 2020 Nordic Semiconductor ASA
8 *
9 * SPDX-License-Identifier: Apache-2.0
10 */
11
12 #ifndef ZCBOR_ENCODE_H__
13 #define ZCBOR_ENCODE_H__
14
15 #include <stdint.h>
16 #include <stdbool.h>
17 #include <stddef.h>
18 #include "zcbor_common.h"
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 /** The zcbor_encode library provides functions for encoding CBOR data elements.
25 *
26 * See The README for an introduction to CBOR, including the meaning of pint,
27 * nint, bstr etc.
28 */
29
30
31 /** The following param and retval docs apply to all single value encoding functions
32 *
33 * @param[inout] state The current state of the encoding.
34 * @param[in] input The value to encode.
35 *
36 * @retval true Everything is ok.
37 * @retval false If the payload is exhausted. Or an unexpected error happened.
38 */
39
40 /** Encode a pint/nint. */
41 bool zcbor_int32_put(zcbor_state_t *state, int32_t input);
42 bool zcbor_int64_put(zcbor_state_t *state, int64_t input);
43 bool zcbor_uint32_put(zcbor_state_t *state, uint32_t input);
44 bool zcbor_uint64_put(zcbor_state_t *state, uint64_t input);
45 bool zcbor_size_put(zcbor_state_t *state, size_t input);
46
47 /** Encode a pint/nint from a pointer.
48 *
49 * Can be used for bulk encoding with @ref zcbor_multi_encode.
50 */
51 bool zcbor_int_encode(zcbor_state_t *state, const void *input_int, size_t int_size);
52 bool zcbor_int32_encode(zcbor_state_t *state, const int32_t *input);
53 bool zcbor_int64_encode(zcbor_state_t *state, const int64_t *input);
54 bool zcbor_uint32_encode(zcbor_state_t *state, const uint32_t *input);
55 bool zcbor_uint64_encode(zcbor_state_t *state, const uint64_t *input);
56 bool zcbor_size_encode(zcbor_state_t *state, const size_t *input);
57
58 /** Encode a bstr. */
59 bool zcbor_bstr_encode(zcbor_state_t *state, const struct zcbor_string *input);
60 /** Encode a tstr. */
61 bool zcbor_tstr_encode(zcbor_state_t *state, const struct zcbor_string *input);
62
63 /** Encode a pointer to a string as a bstr/tstr.
64 *
65 * @param[inout] state The current state of the encoding.
66 * @param[in] string The value to encode. A pointer to the string
67 * @param[in] len The length of the string pointed to by @p string.
68 */
zcbor_bstr_encode_ptr(zcbor_state_t * state,const char * ptr,size_t len)69 static inline bool zcbor_bstr_encode_ptr(zcbor_state_t *state, const char *ptr, size_t len)
70 {
71 const struct zcbor_string zs = { .value = (const uint8_t *)ptr, .len = len };
72
73 return zcbor_bstr_encode(state, &zs);
74 }
zcbor_tstr_encode_ptr(zcbor_state_t * state,const char * ptr,size_t len)75 static inline bool zcbor_tstr_encode_ptr(zcbor_state_t *state, const char *ptr, size_t len)
76 {
77 const struct zcbor_string zs = { .value = (const uint8_t *)ptr, .len = len };
78
79 return zcbor_tstr_encode(state, &zs);
80 }
81
82 /** Encode a string literal as a bstr/tstr.
83 *
84 * @param[inout] state The current state of the encoding.
85 * @param[in] string The value to encode. A string literal, e.g. "Foo", so
86 * that sizeof(string) - 1 is the length of the string.
87 */
88 #define zcbor_bstr_put_lit(state, string) \
89 zcbor_bstr_encode_ptr(state, string, sizeof(string) - 1)
90 #define zcbor_tstr_put_lit(state, string) \
91 zcbor_tstr_encode_ptr(state, string, sizeof(string) - 1)
92
93 /** Encode null-terminated string as a bstr/tstr.
94 *
95 * @param[inout] state The current state of the encoding.
96 * @param[in] string The value to encode. Must be a null-terminated string,
97 * so that strlen can be used.
98 */
99 #define zcbor_bstr_put_term(state, string) \
100 zcbor_bstr_encode_ptr(state, string, strlen(string))
101 #define zcbor_tstr_put_term(state, string) \
102 zcbor_tstr_encode_ptr(state, string, strlen(string))
103
104 /** Encode a char array literal as a bstr/tstr.
105 *
106 * @param[inout] state The current state of the encoding.
107 * @param[in] string The value to encode. An array literal, e.g. {'F', 'o', 'o'},
108 * so that sizeof(string) is the length of the string.
109 */
110 #define zcbor_bstr_put_arr(state, string) \
111 zcbor_bstr_encode_ptr(state, string, sizeof(string))
112 #define zcbor_tstr_put_arr(state, string) \
113 zcbor_tstr_encode_ptr(state, string, sizeof(string))
114
115 /** Encode a tag. Must be called before encoding the value being tagged. */
116 bool zcbor_tag_encode(zcbor_state_t *state, uint32_t input);
117
118 /** Encode a boolean primitive value. */
119 bool zcbor_bool_put(zcbor_state_t *state, bool input);
120 bool zcbor_bool_encode(zcbor_state_t *state, const bool *input);
121
122 /** Encode a float */
123 bool zcbor_float32_put(zcbor_state_t *state, float input);
124 bool zcbor_float32_encode(zcbor_state_t *state, const float *input);
125 bool zcbor_float64_put(zcbor_state_t *state, double input);
126 bool zcbor_float64_encode(zcbor_state_t *state, const double *input);
127
128 /** Encode a "nil"/"undefined" primitive value. @p unused should be NULL.
129 *
130 * @param[inout] state The current state of the encoding.
131 * @param[in] unused Unused parameter to maintain signature parity with
132 * @ref zcbor_encoder_t.
133 */
134 bool zcbor_nil_put(zcbor_state_t *state, const void *unused);
135 bool zcbor_undefined_put(zcbor_state_t *state, const void *unused);
136
137 /** Encode a bstr header.
138 *
139 * The rest of the string can be encoded as CBOR.
140 * A state backup is created to keep track of the element count.
141 * Call @ref zcbor_bstr_end_encode when done encoding the contents of the bstr.
142 *
143 * @param[inout] state The current state of the encoding.
144 *
145 * @retval true Header encoded correctly
146 * @retval false Header encoded incorrectly, or backup failed.
147 */
148 bool zcbor_bstr_start_encode(zcbor_state_t *state);
149
150 /** Finalize encoding a CBOR-encoded bstr.
151 *
152 * Restore element count from backup.
153 */
154 bool zcbor_bstr_end_encode(zcbor_state_t *state, struct zcbor_string *result);
155
156 /** Encode a list/map header.
157 *
158 * The contents of the list/map can be encoded via subsequent function calls.
159 * If ZCBOR_CANONICAL is defined, a state backup is created to keep track of the
160 * element count.
161 * When all members have been encoded, call @ref zcbor_list_end_encode /
162 * @ref zcbor_map_end_encode to close the list/map.
163 *
164 * @param[inout] state The current state of the encoding.
165 * @param[in] max_num The maximum number of members in the list/map.
166 * This serves as a size hint for the header. Must be
167 * equal to the max_num provided to the corresponding
168 * @ref zcbor_list_end_encode / @ref zcbor_map_end_encode
169 * call.
170 * Only used when ZCBOR_CANONICAL is defined.
171 */
172 bool zcbor_list_start_encode(zcbor_state_t *state, uint_fast32_t max_num);
173 bool zcbor_map_start_encode(zcbor_state_t *state, uint_fast32_t max_num);
174
175 /** Encode the end of a list/map. Do some checks and deallocate backup.
176 *
177 * - Default: Adds a list terminator (0xFF) to mark the
178 * end of the list/map.
179 * - If ZCBOR_CANONICAL is defined: Instead encodes the number of members in
180 * the list/map header. If the header ends up a different size than expected,
181 * the list/map contents are moved using memmove().
182 *
183 * Use @ref zcbor_list_map_end_force_encode to forcibly consume the backup if
184 * something has gone wrong.
185 *
186 * @param[inout] state The current state of the encoding.
187 * @param[in] max_num The maximum number of members in the list/map. Must be
188 * equal to the max_num provided to the corresponding
189 * @ref zcbor_list_start_encode call.
190 * Only used when ZCBOR_CANONICAL is defined.
191 */
192 bool zcbor_list_end_encode(zcbor_state_t *state, uint_fast32_t max_num);
193 bool zcbor_map_end_encode(zcbor_state_t *state, uint_fast32_t max_num);
194 bool zcbor_list_map_end_force_encode(zcbor_state_t *state);
195
196 /** Encode 0 or more elements with the same type and constraints.
197 *
198 * The encoded values are taken from the @p input array.
199 *
200 * The following is an example of encoding a list containing 3 INTS followed by
201 * 0 to 2 bstrs:
202 *
203 * @code{c}
204 * uint32_t ints[3] = <initialize>;
205 * struct zcbor_string bstrs[2] = <initialize>;
206 * bool res;
207 *
208 * res = zcbor_list_start_encode(state, 5);
209 * res = res && zcbor_multi_encode(3, zcbor_uint32_encode, state,
210 * ints, sizeof(uint32_t));
211 * res = res && zcbor_multi_encode(2, zcbor_bstr_encode, state,
212 * bstrs, sizeof(struct zcbor_string));
213 * res = res && zcbor_list_end_encode(state, 5);
214 * // check res
215 * @endcode
216 *
217 * The @ref zcbor_encoder_t type is designed to be compatible with all single-
218 * value encoder functions in this library, e.g. @ref zcbor_uint32_encode,
219 * @ref zcbor_tstr_put, @ref zcbor_nil_put, etc. For _put() functions,
220 * @p input will be used as a value instead of an array/pointer, so
221 * @p input_len will determine how much the value changes for each call.
222 * To encode the same value multiple times, use a @p input_len of 0.
223 * This function can also be used with custom decoder functions, such as those
224 * generated by the zcbor.py script, which for example encodes larger chunks of
225 * the data at once.
226 *
227 * @param[in] num_encode The actual number of elements.
228 * @param[in] encoder The encoder function to call under the hood. This
229 * function will be called with the provided arguments
230 * repeatedly until the function fails (returns false)
231 * or until it has been called @p max_encode times.
232 * The input pointer is moved @p input_len bytes for
233 * each call to @p encoder, i.e. @p input refers to an
234 * array of input variables.
235 * @param[in] input Source of the encoded values. Must be an array of
236 * at least @p max_encode elements.
237 * @param[in] input_len The length of the input variables. Must be the
238 * length of the individual elements in input.
239 *
240 * @retval true If at least @p min_encode variables were correctly encoded.
241 * @retval false If @p encoder failed before having encoded @p min_encode
242 * values.
243 */
244 bool zcbor_multi_encode(uint_fast32_t num_encode,
245 zcbor_encoder_t encoder,
246 zcbor_state_t *state,
247 const void *input,
248 uint_fast32_t result_len);
249
250 /** Works like @ref zcbor_multi_encode
251 *
252 * But first checks that @p num_encode is between @p min_encode and @p max_encode.
253 */
254 bool zcbor_multi_encode_minmax(uint_fast32_t min_encode, uint_fast32_t max_encode, const uint_fast32_t *num_encode,
255 zcbor_encoder_t encoder, zcbor_state_t *state, const void *input,
256 uint_fast32_t input_len);
257
258 /** Runs @p encoder on @p state and @p input if @p present is true.
259 *
260 * Calls @ref zcbor_multi_encode under the hood.
261 */
262 bool zcbor_present_encode(const uint_fast32_t *present,
263 zcbor_encoder_t encoder,
264 zcbor_state_t *state,
265 const void *input);
266
267 /** See @ref zcbor_new_state() */
268 void zcbor_new_encode_state(zcbor_state_t *state_array, uint_fast32_t n_states,
269 uint8_t *payload, size_t payload_len, uint_fast32_t elem_count);
270
271 /** Convenience macro for declaring and initializing a state with backups.
272 *
273 * This gives you a state variable named @p name. The variable functions like
274 * a pointer.
275 *
276 * @param[in] name The name of the new state variable.
277 * @param[in] num_backups The number of backup slots to keep in the state.
278 * @param[in] payload The payload to work on.
279 * @param[in] payload_size The size (in bytes) of @p payload.
280 * @param[in] elem_count The starting elem_count (typically 1).
281 */
282 #define ZCBOR_STATE_E(name, num_backups, payload, payload_size, elem_count) \
283 zcbor_state_t name[((num_backups) + 2)]; \
284 do { \
285 zcbor_new_encode_state(name, ZCBOR_ARRAY_SIZE(name), payload, payload_size, elem_count); \
286 } while(0)
287
288 #ifdef __cplusplus
289 }
290 #endif
291
292 #endif /* ZCBOR_ENCODE_H__ */
293