1
2
3
4
5
6
7
8
9
10
11
12
13#include "qemu/osdep.h"
14#include "qapi/qmp/qnum.h"
15#include "qapi/qmp/qdict.h"
16#include "qapi/qmp/qbool.h"
17#include "qapi/qmp/qstring.h"
18#include "qapi/qmp/qobject.h"
19#include "qapi/error.h"
20#include "qemu/queue.h"
21#include "qemu-common.h"
22#include "qemu/cutils.h"
23
24
25
26
27
28
29QDict *qdict_new(void)
30{
31 QDict *qdict;
32
33 qdict = g_malloc0(sizeof(*qdict));
34 qobject_init(QOBJECT(qdict), QTYPE_QDICT);
35
36 return qdict;
37}
38
39
40
41
42QDict *qobject_to_qdict(const QObject *obj)
43{
44 if (!obj || qobject_type(obj) != QTYPE_QDICT) {
45 return NULL;
46 }
47 return container_of(obj, QDict, base);
48}
49
50
51
52
53
54static unsigned int tdb_hash(const char *name)
55{
56 unsigned value;
57 unsigned i;
58
59
60 for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
61 value = (value + (((const unsigned char *)name)[i] << (i*5 % 24)));
62
63 return (1103515243 * value + 12345);
64}
65
66
67
68
69static QDictEntry *alloc_entry(const char *key, QObject *value)
70{
71 QDictEntry *entry;
72
73 entry = g_malloc0(sizeof(*entry));
74 entry->key = g_strdup(key);
75 entry->value = value;
76
77 return entry;
78}
79
80
81
82
83
84
85QObject *qdict_entry_value(const QDictEntry *entry)
86{
87 return entry->value;
88}
89
90
91
92
93
94
95
96const char *qdict_entry_key(const QDictEntry *entry)
97{
98 return entry->key;
99}
100
101
102
103
104static QDictEntry *qdict_find(const QDict *qdict,
105 const char *key, unsigned int bucket)
106{
107 QDictEntry *entry;
108
109 QLIST_FOREACH(entry, &qdict->table[bucket], next)
110 if (!strcmp(entry->key, key))
111 return entry;
112
113 return NULL;
114}
115
116
117
118
119
120
121
122
123
124
125
126
127void qdict_put_obj(QDict *qdict, const char *key, QObject *value)
128{
129 unsigned int bucket;
130 QDictEntry *entry;
131
132 bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
133 entry = qdict_find(qdict, key, bucket);
134 if (entry) {
135
136 qobject_decref(entry->value);
137 entry->value = value;
138 } else {
139
140 entry = alloc_entry(key, value);
141 QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next);
142 qdict->size++;
143 }
144}
145
146
147
148
149
150
151
152QObject *qdict_get(const QDict *qdict, const char *key)
153{
154 QDictEntry *entry;
155
156 entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
157 return (entry == NULL ? NULL : entry->value);
158}
159
160
161
162
163
164
165int qdict_haskey(const QDict *qdict, const char *key)
166{
167 unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX;
168 return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1);
169}
170
171
172
173
174size_t qdict_size(const QDict *qdict)
175{
176 return qdict->size;
177}
178
179
180
181
182
183
184
185
186double qdict_get_double(const QDict *qdict, const char *key)
187{
188 return qnum_get_double(qobject_to_qnum(qdict_get(qdict, key)));
189}
190
191
192
193
194
195
196
197
198
199int64_t qdict_get_int(const QDict *qdict, const char *key)
200{
201 return qnum_get_int(qobject_to_qnum(qdict_get(qdict, key)));
202}
203
204
205
206
207
208
209
210
211
212bool qdict_get_bool(const QDict *qdict, const char *key)
213{
214 return qbool_get_bool(qobject_to_qbool(qdict_get(qdict, key)));
215}
216
217
218
219
220QList *qdict_get_qlist(const QDict *qdict, const char *key)
221{
222 return qobject_to_qlist(qdict_get(qdict, key));
223}
224
225
226
227
228QDict *qdict_get_qdict(const QDict *qdict, const char *key)
229{
230 return qobject_to_qdict(qdict_get(qdict, key));
231}
232
233
234
235
236
237
238
239
240
241
242const char *qdict_get_str(const QDict *qdict, const char *key)
243{
244 return qstring_get_str(qobject_to_qstring(qdict_get(qdict, key)));
245}
246
247
248
249
250
251
252
253
254int64_t qdict_get_try_int(const QDict *qdict, const char *key,
255 int64_t def_value)
256{
257 QNum *qnum = qobject_to_qnum(qdict_get(qdict, key));
258 int64_t val;
259
260 if (!qnum || !qnum_get_try_int(qnum, &val)) {
261 return def_value;
262 }
263
264 return val;
265}
266
267
268
269
270
271
272
273
274bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value)
275{
276 QBool *qbool = qobject_to_qbool(qdict_get(qdict, key));
277
278 return qbool ? qbool_get_bool(qbool) : def_value;
279}
280
281
282
283
284
285
286
287
288
289const char *qdict_get_try_str(const QDict *qdict, const char *key)
290{
291 QString *qstr = qobject_to_qstring(qdict_get(qdict, key));
292
293 return qstr ? qstring_get_str(qstr) : NULL;
294}
295
296
297
298
299
300
301
302void qdict_iter(const QDict *qdict,
303 void (*iter)(const char *key, QObject *obj, void *opaque),
304 void *opaque)
305{
306 int i;
307 QDictEntry *entry;
308
309 for (i = 0; i < QDICT_BUCKET_MAX; i++) {
310 QLIST_FOREACH(entry, &qdict->table[i], next)
311 iter(entry->key, entry->value, opaque);
312 }
313}
314
315static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket)
316{
317 int i;
318
319 for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) {
320 if (!QLIST_EMPTY(&qdict->table[i])) {
321 return QLIST_FIRST(&qdict->table[i]);
322 }
323 }
324
325 return NULL;
326}
327
328
329
330
331const QDictEntry *qdict_first(const QDict *qdict)
332{
333 return qdict_next_entry(qdict, 0);
334}
335
336
337
338
339const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry)
340{
341 QDictEntry *ret;
342
343 ret = QLIST_NEXT(entry, next);
344 if (!ret) {
345 unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX;
346 ret = qdict_next_entry(qdict, bucket + 1);
347 }
348
349 return ret;
350}
351
352
353
354
355
356QDict *qdict_clone_shallow(const QDict *src)
357{
358 QDict *dest;
359 QDictEntry *entry;
360 int i;
361
362 dest = qdict_new();
363
364 for (i = 0; i < QDICT_BUCKET_MAX; i++) {
365 QLIST_FOREACH(entry, &src->table[i], next) {
366 qobject_incref(entry->value);
367 qdict_put_obj(dest, entry->key, entry->value);
368 }
369 }
370
371 return dest;
372}
373
374
375
376
377static void qentry_destroy(QDictEntry *e)
378{
379 assert(e != NULL);
380 assert(e->key != NULL);
381 assert(e->value != NULL);
382
383 qobject_decref(e->value);
384 g_free(e->key);
385 g_free(e);
386}
387
388
389
390
391
392
393void qdict_del(QDict *qdict, const char *key)
394{
395 QDictEntry *entry;
396
397 entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX);
398 if (entry) {
399 QLIST_REMOVE(entry, next);
400 qentry_destroy(entry);
401 qdict->size--;
402 }
403}
404
405
406
407
408
409
410
411
412bool qdict_is_equal(const QObject *x, const QObject *y)
413{
414 const QDict *dict_x = qobject_to_qdict(x);
415 const QDict *dict_y = qobject_to_qdict(y);
416 const QDictEntry *e;
417
418 if (qdict_size(dict_x) != qdict_size(dict_y)) {
419 return false;
420 }
421
422 for (e = qdict_first(dict_x); e; e = qdict_next(dict_x, e)) {
423 const QObject *obj_x = qdict_entry_value(e);
424 const QObject *obj_y = qdict_get(dict_y, qdict_entry_key(e));
425
426 if (!qobject_is_equal(obj_x, obj_y)) {
427 return false;
428 }
429 }
430
431 return true;
432}
433
434
435
436
437void qdict_destroy_obj(QObject *obj)
438{
439 int i;
440 QDict *qdict;
441
442 assert(obj != NULL);
443 qdict = qobject_to_qdict(obj);
444
445 for (i = 0; i < QDICT_BUCKET_MAX; i++) {
446 QDictEntry *entry = QLIST_FIRST(&qdict->table[i]);
447 while (entry) {
448 QDictEntry *tmp = QLIST_NEXT(entry, next);
449 QLIST_REMOVE(entry, next);
450 qentry_destroy(entry);
451 entry = tmp;
452 }
453 }
454
455 g_free(qdict);
456}
457
458
459
460
461
462
463void qdict_copy_default(QDict *dst, QDict *src, const char *key)
464{
465 QObject *val;
466
467 if (qdict_haskey(dst, key)) {
468 return;
469 }
470
471 val = qdict_get(src, key);
472 if (val) {
473 qobject_incref(val);
474 qdict_put_obj(dst, key, val);
475 }
476}
477
478
479
480
481
482void qdict_set_default_str(QDict *dst, const char *key, const char *val)
483{
484 if (qdict_haskey(dst, key)) {
485 return;
486 }
487
488 qdict_put_str(dst, key, val);
489}
490
491static void qdict_flatten_qdict(QDict *qdict, QDict *target,
492 const char *prefix);
493
494static void qdict_flatten_qlist(QList *qlist, QDict *target, const char *prefix)
495{
496 QObject *value;
497 const QListEntry *entry;
498 char *new_key;
499 int i;
500
501
502
503
504
505 assert(prefix);
506
507 entry = qlist_first(qlist);
508
509 for (i = 0; entry; entry = qlist_next(entry), i++) {
510 value = qlist_entry_obj(entry);
511 new_key = g_strdup_printf("%s.%i", prefix, i);
512
513 if (qobject_type(value) == QTYPE_QDICT) {
514 qdict_flatten_qdict(qobject_to_qdict(value), target, new_key);
515 } else if (qobject_type(value) == QTYPE_QLIST) {
516 qdict_flatten_qlist(qobject_to_qlist(value), target, new_key);
517 } else {
518
519 qobject_incref(value);
520 qdict_put_obj(target, new_key, value);
521 }
522
523 g_free(new_key);
524 }
525}
526
527static void qdict_flatten_qdict(QDict *qdict, QDict *target, const char *prefix)
528{
529 QObject *value;
530 const QDictEntry *entry, *next;
531 char *new_key;
532 bool delete;
533
534 entry = qdict_first(qdict);
535
536 while (entry != NULL) {
537
538 next = qdict_next(qdict, entry);
539 value = qdict_entry_value(entry);
540 new_key = NULL;
541 delete = false;
542
543 if (prefix) {
544 new_key = g_strdup_printf("%s.%s", prefix, entry->key);
545 }
546
547 if (qobject_type(value) == QTYPE_QDICT) {
548
549
550 qdict_flatten_qdict(qobject_to_qdict(value), target,
551 new_key ? new_key : entry->key);
552 delete = true;
553 } else if (qobject_type(value) == QTYPE_QLIST) {
554 qdict_flatten_qlist(qobject_to_qlist(value), target,
555 new_key ? new_key : entry->key);
556 delete = true;
557 } else if (prefix) {
558
559 qobject_incref(value);
560 qdict_put_obj(target, new_key, value);
561 delete = true;
562 }
563
564 g_free(new_key);
565
566 if (delete) {
567 qdict_del(qdict, entry->key);
568
569
570 entry = qdict_first(qdict);
571 continue;
572 }
573
574 entry = next;
575 }
576}
577
578
579
580
581
582
583
584
585void qdict_flatten(QDict *qdict)
586{
587 qdict_flatten_qdict(qdict, qdict, NULL);
588}
589
590
591void qdict_extract_subqdict(QDict *src, QDict **dst, const char *start)
592
593{
594 const QDictEntry *entry, *next;
595 const char *p;
596
597 *dst = qdict_new();
598 entry = qdict_first(src);
599
600 while (entry != NULL) {
601 next = qdict_next(src, entry);
602 if (strstart(entry->key, start, &p)) {
603 qobject_incref(entry->value);
604 qdict_put_obj(*dst, p, entry->value);
605 qdict_del(src, entry->key);
606 }
607 entry = next;
608 }
609}
610
611static int qdict_count_prefixed_entries(const QDict *src, const char *start)
612{
613 const QDictEntry *entry;
614 int count = 0;
615
616 for (entry = qdict_first(src); entry; entry = qdict_next(src, entry)) {
617 if (strstart(entry->key, start, NULL)) {
618 if (count == INT_MAX) {
619 return -ERANGE;
620 }
621 count++;
622 }
623 }
624
625 return count;
626}
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643void qdict_array_split(QDict *src, QList **dst)
644{
645 unsigned i;
646
647 *dst = qlist_new();
648
649 for (i = 0; i < UINT_MAX; i++) {
650 QObject *subqobj;
651 bool is_subqdict;
652 QDict *subqdict;
653 char indexstr[32], prefix[32];
654 size_t snprintf_ret;
655
656 snprintf_ret = snprintf(indexstr, 32, "%u", i);
657 assert(snprintf_ret < 32);
658
659 subqobj = qdict_get(src, indexstr);
660
661 snprintf_ret = snprintf(prefix, 32, "%u.", i);
662 assert(snprintf_ret < 32);
663
664
665 is_subqdict = qdict_count_prefixed_entries(src, prefix);
666
667
668
669 if (!subqobj == !is_subqdict) {
670 break;
671 }
672
673 if (is_subqdict) {
674 qdict_extract_subqdict(src, &subqdict, prefix);
675 assert(qdict_size(subqdict) > 0);
676 } else {
677 qobject_incref(subqobj);
678 qdict_del(src, indexstr);
679 }
680
681 qlist_append_obj(*dst, subqobj ?: QOBJECT(subqdict));
682 }
683}
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707static void qdict_split_flat_key(const char *key, char **prefix,
708 const char **suffix)
709{
710 const char *separator;
711 size_t i, j;
712
713
714
715 separator = NULL;
716 do {
717 if (separator) {
718 separator += 2;
719 } else {
720 separator = key;
721 }
722 separator = strchr(separator, '.');
723 } while (separator && separator[1] == '.');
724
725 if (separator) {
726 *prefix = g_strndup(key, separator - key);
727 *suffix = separator + 1;
728 } else {
729 *prefix = g_strdup(key);
730 *suffix = NULL;
731 }
732
733
734 for (i = 0, j = 0; (*prefix)[i] != '\0'; i++, j++) {
735 if ((*prefix)[i] == '.') {
736 assert((*prefix)[i + 1] == '.');
737 i++;
738 }
739 (*prefix)[j] = (*prefix)[i];
740 }
741 (*prefix)[j] = '\0';
742}
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757static int qdict_is_list(QDict *maybe_list, Error **errp)
758{
759 const QDictEntry *ent;
760 ssize_t len = 0;
761 ssize_t max = -1;
762 int is_list = -1;
763 int64_t val;
764
765 for (ent = qdict_first(maybe_list); ent != NULL;
766 ent = qdict_next(maybe_list, ent)) {
767
768 if (qemu_strtoi64(ent->key, NULL, 10, &val) == 0) {
769 if (is_list == -1) {
770 is_list = 1;
771 } else if (!is_list) {
772 error_setg(errp,
773 "Cannot mix list and non-list keys");
774 return -1;
775 }
776 len++;
777 if (val > max) {
778 max = val;
779 }
780 } else {
781 if (is_list == -1) {
782 is_list = 0;
783 } else if (is_list) {
784 error_setg(errp,
785 "Cannot mix list and non-list keys");
786 return -1;
787 }
788 }
789 }
790
791 if (is_list == -1) {
792 assert(!qdict_size(maybe_list));
793 is_list = 0;
794 }
795
796
797
798
799
800
801 if (len != (max + 1)) {
802 error_setg(errp, "List indices are not contiguous, "
803 "saw %zd elements but %zd largest index",
804 len, max);
805 return -1;
806 }
807
808 return is_list;
809}
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850QObject *qdict_crumple(const QDict *src, Error **errp)
851{
852 const QDictEntry *ent;
853 QDict *two_level, *multi_level = NULL;
854 QObject *dst = NULL, *child;
855 size_t i;
856 char *prefix = NULL;
857 const char *suffix = NULL;
858 int is_list;
859
860 two_level = qdict_new();
861
862
863 for (ent = qdict_first(src); ent != NULL; ent = qdict_next(src, ent)) {
864 if (qobject_type(ent->value) == QTYPE_QDICT ||
865 qobject_type(ent->value) == QTYPE_QLIST) {
866 error_setg(errp, "Value %s is not a scalar",
867 ent->key);
868 goto error;
869 }
870
871 qdict_split_flat_key(ent->key, &prefix, &suffix);
872
873 child = qdict_get(two_level, prefix);
874 if (suffix) {
875 if (child) {
876 if (qobject_type(child) != QTYPE_QDICT) {
877 error_setg(errp, "Key %s prefix is already set as a scalar",
878 prefix);
879 goto error;
880 }
881 } else {
882 child = QOBJECT(qdict_new());
883 qdict_put_obj(two_level, prefix, child);
884 }
885 qobject_incref(ent->value);
886 qdict_put_obj(qobject_to_qdict(child), suffix, ent->value);
887 } else {
888 if (child) {
889 error_setg(errp, "Key %s prefix is already set as a dict",
890 prefix);
891 goto error;
892 }
893 qobject_incref(ent->value);
894 qdict_put_obj(two_level, prefix, ent->value);
895 }
896
897 g_free(prefix);
898 prefix = NULL;
899 }
900
901
902
903 multi_level = qdict_new();
904 for (ent = qdict_first(two_level); ent != NULL;
905 ent = qdict_next(two_level, ent)) {
906
907 if (qobject_type(ent->value) == QTYPE_QDICT) {
908 child = qdict_crumple(qobject_to_qdict(ent->value), errp);
909 if (!child) {
910 goto error;
911 }
912
913 qdict_put_obj(multi_level, ent->key, child);
914 } else {
915 qobject_incref(ent->value);
916 qdict_put_obj(multi_level, ent->key, ent->value);
917 }
918 }
919 QDECREF(two_level);
920 two_level = NULL;
921
922
923 is_list = qdict_is_list(multi_level, errp);
924 if (is_list < 0) {
925 goto error;
926 }
927
928 if (is_list) {
929 dst = QOBJECT(qlist_new());
930
931 for (i = 0; i < qdict_size(multi_level); i++) {
932 char *key = g_strdup_printf("%zu", i);
933
934 child = qdict_get(multi_level, key);
935 g_free(key);
936
937 if (!child) {
938 error_setg(errp, "Missing list index %zu", i);
939 goto error;
940 }
941
942 qobject_incref(child);
943 qlist_append_obj(qobject_to_qlist(dst), child);
944 }
945 QDECREF(multi_level);
946 multi_level = NULL;
947 } else {
948 dst = QOBJECT(multi_level);
949 }
950
951 return dst;
952
953 error:
954 g_free(prefix);
955 QDECREF(multi_level);
956 QDECREF(two_level);
957 qobject_decref(dst);
958 return NULL;
959}
960
961
962
963
964
965
966
967
968int qdict_array_entries(QDict *src, const char *subqdict)
969{
970 const QDictEntry *entry;
971 unsigned i;
972 unsigned entries = 0;
973 size_t subqdict_len = strlen(subqdict);
974
975 assert(!subqdict_len || subqdict[subqdict_len - 1] == '.');
976
977
978
979
980 for (i = 0; i < INT_MAX; i++) {
981 QObject *subqobj;
982 int subqdict_entries;
983 char *prefix = g_strdup_printf("%s%u.", subqdict, i);
984
985 subqdict_entries = qdict_count_prefixed_entries(src, prefix);
986
987
988 prefix[strlen(prefix) - 1] = 0;
989 subqobj = qdict_get(src, prefix);
990
991 g_free(prefix);
992
993 if (subqdict_entries < 0) {
994 return subqdict_entries;
995 }
996
997
998
999 if (subqobj && subqdict_entries) {
1000 return -EINVAL;
1001 } else if (!subqobj && !subqdict_entries) {
1002 break;
1003 }
1004
1005 entries += subqdict_entries ? subqdict_entries : 1;
1006 }
1007
1008
1009 for (entry = qdict_first(src); entry; entry = qdict_next(src, entry)) {
1010 if (!strstart(qdict_entry_key(entry), subqdict, NULL)) {
1011 entries++;
1012 }
1013 }
1014
1015
1016 if (qdict_size(src) != entries) {
1017 return -EINVAL;
1018 }
1019
1020 return i;
1021}
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037void qdict_join(QDict *dest, QDict *src, bool overwrite)
1038{
1039 const QDictEntry *entry, *next;
1040
1041 entry = qdict_first(src);
1042 while (entry) {
1043 next = qdict_next(src, entry);
1044
1045 if (overwrite || !qdict_haskey(dest, entry->key)) {
1046 qobject_incref(entry->value);
1047 qdict_put_obj(dest, entry->key, entry->value);
1048 qdict_del(src, entry->key);
1049 }
1050
1051 entry = next;
1052 }
1053}
1054