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