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