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