qlist.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * QList Module
  3. *
  4. * Copyright (C) 2009 Red Hat Inc.
  5. *
  6. * Authors:
  7. * Luiz Capitulino <lcapitulino@redhat.com>
  8. *
  9. * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
  10. * See the COPYING.LIB file in the top-level directory.
  11. */
  12. #include "qemu/osdep.h"
  13. #include "qapi/qmp/qbool.h"
  14. #include "qapi/qmp/qlist.h"
  15. #include "qapi/qmp/qnull.h"
  16. #include "qapi/qmp/qnum.h"
  17. #include "qapi/qmp/qstring.h"
  18. #include "qemu/queue.h"
  19. /**
  20. * qlist_new(): Create a new QList
  21. *
  22. * Return strong reference.
  23. */
  24. QList *qlist_new(void)
  25. {
  26. QList *qlist;
  27. qlist = g_malloc(sizeof(*qlist));
  28. qobject_init(QOBJECT(qlist), QTYPE_QLIST);
  29. QTAILQ_INIT(&qlist->head);
  30. return qlist;
  31. }
  32. static void qlist_copy_elem(QObject *obj, void *opaque)
  33. {
  34. QList *dst = opaque;
  35. qobject_ref(obj);
  36. qlist_append_obj(dst, obj);
  37. }
  38. QList *qlist_copy(QList *src)
  39. {
  40. QList *dst = qlist_new();
  41. qlist_iter(src, qlist_copy_elem, dst);
  42. return dst;
  43. }
  44. /**
  45. * qlist_append_obj(): Append an QObject into QList
  46. *
  47. * NOTE: ownership of 'value' is transferred to the QList
  48. */
  49. void qlist_append_obj(QList *qlist, QObject *value)
  50. {
  51. QListEntry *entry;
  52. entry = g_malloc(sizeof(*entry));
  53. entry->value = value;
  54. QTAILQ_INSERT_TAIL(&qlist->head, entry, next);
  55. }
  56. void qlist_append_int(QList *qlist, int64_t value)
  57. {
  58. qlist_append(qlist, qnum_from_int(value));
  59. }
  60. void qlist_append_bool(QList *qlist, bool value)
  61. {
  62. qlist_append(qlist, qbool_from_bool(value));
  63. }
  64. void qlist_append_str(QList *qlist, const char *value)
  65. {
  66. qlist_append(qlist, qstring_from_str(value));
  67. }
  68. void qlist_append_null(QList *qlist)
  69. {
  70. qlist_append(qlist, qnull());
  71. }
  72. /**
  73. * qlist_iter(): Iterate over all the list's stored values.
  74. *
  75. * This function allows the user to provide an iterator, which will be
  76. * called for each stored value in the list.
  77. */
  78. void qlist_iter(const QList *qlist,
  79. void (*iter)(QObject *obj, void *opaque), void *opaque)
  80. {
  81. QListEntry *entry;
  82. QTAILQ_FOREACH(entry, &qlist->head, next)
  83. iter(entry->value, opaque);
  84. }
  85. QObject *qlist_pop(QList *qlist)
  86. {
  87. QListEntry *entry;
  88. QObject *ret;
  89. if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
  90. return NULL;
  91. }
  92. entry = QTAILQ_FIRST(&qlist->head);
  93. QTAILQ_REMOVE(&qlist->head, entry, next);
  94. ret = entry->value;
  95. g_free(entry);
  96. return ret;
  97. }
  98. QObject *qlist_peek(QList *qlist)
  99. {
  100. QListEntry *entry;
  101. if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
  102. return NULL;
  103. }
  104. entry = QTAILQ_FIRST(&qlist->head);
  105. return entry->value;
  106. }
  107. int qlist_empty(const QList *qlist)
  108. {
  109. return QTAILQ_EMPTY(&qlist->head);
  110. }
  111. static void qlist_size_iter(QObject *obj, void *opaque)
  112. {
  113. size_t *count = opaque;
  114. (*count)++;
  115. }
  116. size_t qlist_size(const QList *qlist)
  117. {
  118. size_t count = 0;
  119. qlist_iter(qlist, qlist_size_iter, &count);
  120. return count;
  121. }
  122. /**
  123. * qlist_is_equal(): Test whether the two QLists are equal
  124. *
  125. * In order to be considered equal, the respective two objects at each
  126. * index of the two lists have to compare equal (regarding
  127. * qobject_is_equal()), and both lists have to have the same number of
  128. * elements.
  129. * That means both lists have to contain equal objects in equal order.
  130. */
  131. bool qlist_is_equal(const QObject *x, const QObject *y)
  132. {
  133. const QList *list_x = qobject_to(QList, x);
  134. const QList *list_y = qobject_to(QList, y);
  135. const QListEntry *entry_x, *entry_y;
  136. entry_x = qlist_first(list_x);
  137. entry_y = qlist_first(list_y);
  138. while (entry_x && entry_y) {
  139. if (!qobject_is_equal(qlist_entry_obj(entry_x),
  140. qlist_entry_obj(entry_y)))
  141. {
  142. return false;
  143. }
  144. entry_x = qlist_next(entry_x);
  145. entry_y = qlist_next(entry_y);
  146. }
  147. return !entry_x && !entry_y;
  148. }
  149. /**
  150. * qlist_destroy_obj(): Free all the memory allocated by a QList
  151. */
  152. void qlist_destroy_obj(QObject *obj)
  153. {
  154. QList *qlist;
  155. QListEntry *entry, *next_entry;
  156. assert(obj != NULL);
  157. qlist = qobject_to(QList, obj);
  158. QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) {
  159. QTAILQ_REMOVE(&qlist->head, entry, next);
  160. qobject_unref(entry->value);
  161. g_free(entry);
  162. }
  163. g_free(qlist);
  164. }