master
c 322 lines 6.77 KB
Raw
1 /*
2 * QEMU CBOR helpers
3 *
4 * Copyright (c) 2024 Dorjoy Chowdhury <dorjoychy111@gmail.com>
5 *
6 * This work is licensed under the terms of the GNU GPL, version 2 or
7 * (at your option) any later version. See the COPYING file in the
8 * top-level directory.
9 */
10
11 #include "qemu/osdep.h"
12 #include "hw/virtio/cbor-helpers.h"
13
14 bool qemu_cbor_map_add(cbor_item_t *map, cbor_item_t *key, cbor_item_t *value)
15 {
16 bool success = false;
17 struct cbor_pair pair = (struct cbor_pair) {
18 .key = cbor_move(key),
19 .value = cbor_move(value)
20 };
21
22 success = cbor_map_add(map, pair);
23 if (!success) {
24 cbor_incref(pair.key);
25 cbor_incref(pair.value);
26 }
27
28 return success;
29 }
30
31 bool qemu_cbor_array_push(cbor_item_t *array, cbor_item_t *value)
32 {
33 bool success = false;
34
35 success = cbor_array_push(array, cbor_move(value));
36 if (!success) {
37 cbor_incref(value);
38 }
39
40 return success;
41 }
42
43 bool qemu_cbor_add_bool_to_map(cbor_item_t *map, const char *key, bool value)
44 {
45 cbor_item_t *key_cbor = NULL;
46 cbor_item_t *value_cbor = NULL;
47
48 key_cbor = cbor_build_string(key);
49 if (!key_cbor) {
50 goto cleanup;
51 }
52 value_cbor = cbor_build_bool(value);
53 if (!value_cbor) {
54 goto cleanup;
55 }
56 if (!qemu_cbor_map_add(map, key_cbor, value_cbor)) {
57 goto cleanup;
58 }
59
60 return true;
61
62 cleanup:
63 if (key_cbor) {
64 cbor_decref(&key_cbor);
65 }
66 if (value_cbor) {
67 cbor_decref(&value_cbor);
68 }
69 return false;
70 }
71
72 bool qemu_cbor_add_uint8_to_map(cbor_item_t *map, const char *key,
73 uint8_t value)
74 {
75 cbor_item_t *key_cbor = NULL;
76 cbor_item_t *value_cbor = NULL;
77
78 key_cbor = cbor_build_string(key);
79 if (!key_cbor) {
80 goto cleanup;
81 }
82 value_cbor = cbor_build_uint8(value);
83 if (!value_cbor) {
84 goto cleanup;
85 }
86 if (!qemu_cbor_map_add(map, key_cbor, value_cbor)) {
87 goto cleanup;
88 }
89
90 return true;
91
92 cleanup:
93 if (key_cbor) {
94 cbor_decref(&key_cbor);
95 }
96 if (value_cbor) {
97 cbor_decref(&value_cbor);
98 }
99 return false;
100 }
101
102 bool qemu_cbor_add_map_to_map(cbor_item_t *map, const char *key,
103 size_t nested_map_size,
104 cbor_item_t **nested_map)
105 {
106 cbor_item_t *key_cbor = NULL;
107 cbor_item_t *value_cbor = NULL;
108
109 key_cbor = cbor_build_string(key);
110 if (!key_cbor) {
111 goto cleanup;
112 }
113 value_cbor = cbor_new_definite_map(nested_map_size);
114 if (!value_cbor) {
115 goto cleanup;
116 }
117 if (!qemu_cbor_map_add(map, key_cbor, value_cbor)) {
118 goto cleanup;
119 }
120 *nested_map = value_cbor;
121
122 return true;
123
124 cleanup:
125 if (key_cbor) {
126 cbor_decref(&key_cbor);
127 }
128 if (value_cbor) {
129 cbor_decref(&value_cbor);
130 }
131 return false;
132 }
133
134 bool qemu_cbor_add_bytestring_to_map(cbor_item_t *map, const char *key,
135 uint8_t *arr, size_t len)
136 {
137 cbor_item_t *key_cbor = NULL;
138 cbor_item_t *value_cbor = NULL;
139
140 key_cbor = cbor_build_string(key);
141 if (!key_cbor) {
142 goto cleanup;
143 }
144 value_cbor = cbor_build_bytestring(arr, len);
145 if (!value_cbor) {
146 goto cleanup;
147 }
148 if (!qemu_cbor_map_add(map, key_cbor, value_cbor)) {
149 goto cleanup;
150 }
151
152 return true;
153
154 cleanup:
155 if (key_cbor) {
156 cbor_decref(&key_cbor);
157 }
158 if (value_cbor) {
159 cbor_decref(&value_cbor);
160 }
161 return false;
162 }
163
164 bool qemu_cbor_add_null_to_map(cbor_item_t *map, const char *key)
165 {
166 cbor_item_t *key_cbor = NULL;
167 cbor_item_t *value_cbor = NULL;
168
169 key_cbor = cbor_build_string(key);
170 if (!key_cbor) {
171 goto cleanup;
172 }
173 value_cbor = cbor_new_null();
174 if (!value_cbor) {
175 goto cleanup;
176 }
177 if (!qemu_cbor_map_add(map, key_cbor, value_cbor)) {
178 goto cleanup;
179 }
180
181 return true;
182
183 cleanup:
184 if (key_cbor) {
185 cbor_decref(&key_cbor);
186 }
187 if (value_cbor) {
188 cbor_decref(&value_cbor);
189 }
190 return false;
191 }
192
193 bool qemu_cbor_add_string_to_map(cbor_item_t *map, const char *key,
194 const char *value)
195 {
196 cbor_item_t *key_cbor = NULL;
197 cbor_item_t *value_cbor = NULL;
198
199 key_cbor = cbor_build_string(key);
200 if (!key_cbor) {
201 goto cleanup;
202 }
203 value_cbor = cbor_build_string(value);
204 if (!value_cbor) {
205 goto cleanup;
206 }
207 if (!qemu_cbor_map_add(map, key_cbor, value_cbor)) {
208 goto cleanup;
209 }
210
211 return true;
212
213 cleanup:
214 if (key_cbor) {
215 cbor_decref(&key_cbor);
216 }
217 if (value_cbor) {
218 cbor_decref(&value_cbor);
219 }
220 return false;
221 }
222
223 bool qemu_cbor_add_uint8_array_to_map(cbor_item_t *map, const char *key,
224 uint8_t *arr, size_t len)
225 {
226 cbor_item_t *key_cbor = NULL;
227 cbor_item_t *value_cbor = NULL;
228
229 key_cbor = cbor_build_string(key);
230 if (!key_cbor) {
231 goto cleanup;
232 }
233 value_cbor = cbor_new_definite_array(len);
234 if (!value_cbor) {
235 goto cleanup;
236 }
237
238 for (int i = 0; i < len; ++i) {
239 cbor_item_t *tmp = cbor_build_uint8(arr[i]);
240 if (!tmp) {
241 goto cleanup;
242 }
243 if (!qemu_cbor_array_push(value_cbor, tmp)) {
244 cbor_decref(&tmp);
245 goto cleanup;
246 }
247 }
248 if (!qemu_cbor_map_add(map, key_cbor, value_cbor)) {
249 goto cleanup;
250 }
251
252 return true;
253
254 cleanup:
255 if (key_cbor) {
256 cbor_decref(&key_cbor);
257 }
258 if (value_cbor) {
259 cbor_decref(&value_cbor);
260 }
261 return false;
262 }
263
264 bool qemu_cbor_add_uint8_key_bytestring_to_map(cbor_item_t *map, uint8_t key,
265 uint8_t *buf, size_t len)
266 {
267 cbor_item_t *key_cbor = NULL;
268 cbor_item_t *value_cbor = NULL;
269
270 key_cbor = cbor_build_uint8(key);
271 if (!key_cbor) {
272 goto cleanup;
273 }
274 value_cbor = cbor_build_bytestring(buf, len);
275 if (!value_cbor) {
276 goto cleanup;
277 }
278 if (!qemu_cbor_map_add(map, key_cbor, value_cbor)) {
279 goto cleanup;
280 }
281
282 return true;
283
284 cleanup:
285 if (key_cbor) {
286 cbor_decref(&key_cbor);
287 }
288 if (value_cbor) {
289 cbor_decref(&value_cbor);
290 }
291 return false;
292 }
293
294 bool qemu_cbor_add_uint64_to_map(cbor_item_t *map, const char *key,
295 uint64_t value)
296 {
297 cbor_item_t *key_cbor = NULL;
298 cbor_item_t *value_cbor = NULL;
299
300 key_cbor = cbor_build_string(key);
301 if (!key_cbor) {
302 goto cleanup;
303 }
304 value_cbor = cbor_build_uint64(value);
305 if (!value_cbor) {
306 goto cleanup;
307 }
308 if (!qemu_cbor_map_add(map, key_cbor, value_cbor)) {
309 goto cleanup;
310 }
311
312 return true;
313
314 cleanup:
315 if (key_cbor) {
316 cbor_decref(&key_cbor);
317 }
318 if (value_cbor) {
319 cbor_decref(&value_cbor);
320 }
321 return false;
322 }