qlist.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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 "qobject/qbool.h"
  14. #include "qobject/qlist.h"
  15. #include "qobject/qnull.h"
  16. #include "qobject/qnum.h"
  17. #include "qobject/qstring.h"
  18. #include "qemu/queue.h"
  19. #include "qobject-internal.h"
  20. /**
  21. * qlist_new(): Create a new QList
  22. *
  23. * Return strong reference.
  24. */
  25. QList *qlist_new(void)
  26. {
  27. QList *qlist;
  28. qlist = g_malloc(sizeof(*qlist));
  29. qobject_init(QOBJECT(qlist), QTYPE_QLIST);
  30. QTAILQ_INIT(&qlist->head);
  31. return qlist;
  32. }
  33. QList *qlist_copy(QList *src)
  34. {
  35. QList *dst = qlist_new();
  36. QListEntry *entry;
  37. QObject *elt;
  38. QLIST_FOREACH_ENTRY(src, entry) {
  39. elt = qlist_entry_obj(entry);
  40. qobject_ref(elt);
  41. qlist_append_obj(dst, elt);
  42. }
  43. return dst;
  44. }
  45. /**
  46. * qlist_append_obj(): Append an QObject into QList
  47. *
  48. * NOTE: ownership of 'value' is transferred to the QList
  49. */
  50. void qlist_append_obj(QList *qlist, QObject *value)
  51. {
  52. QListEntry *entry;
  53. entry = g_malloc(sizeof(*entry));
  54. entry->value = value;
  55. QTAILQ_INSERT_TAIL(&qlist->head, entry, next);
  56. }
  57. void qlist_append_int(QList *qlist, int64_t value)
  58. {
  59. qlist_append(qlist, qnum_from_int(value));
  60. }
  61. void qlist_append_bool(QList *qlist, bool value)
  62. {
  63. qlist_append(qlist, qbool_from_bool(value));
  64. }
  65. void qlist_append_str(QList *qlist, const char *value)
  66. {
  67. qlist_append(qlist, qstring_from_str(value));
  68. }
  69. void qlist_append_null(QList *qlist)
  70. {
  71. qlist_append(qlist, qnull());
  72. }
  73. QObject *qlist_pop(QList *qlist)
  74. {
  75. QListEntry *entry;
  76. QObject *ret;
  77. if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
  78. return NULL;
  79. }
  80. entry = QTAILQ_FIRST(&qlist->head);
  81. QTAILQ_REMOVE(&qlist->head, entry, next);
  82. ret = entry->value;
  83. g_free(entry);
  84. return ret;
  85. }
  86. QObject *qlist_peek(QList *qlist)
  87. {
  88. QListEntry *entry;
  89. if (qlist == NULL || QTAILQ_EMPTY(&qlist->head)) {
  90. return NULL;
  91. }
  92. entry = QTAILQ_FIRST(&qlist->head);
  93. return entry->value;
  94. }
  95. int qlist_empty(const QList *qlist)
  96. {
  97. return QTAILQ_EMPTY(&qlist->head);
  98. }
  99. size_t qlist_size(const QList *qlist)
  100. {
  101. size_t count = 0;
  102. QListEntry *entry;
  103. QLIST_FOREACH_ENTRY(qlist, entry) {
  104. count++;
  105. }
  106. return count;
  107. }
  108. /**
  109. * qlist_is_equal(): Test whether the two QLists are equal
  110. *
  111. * In order to be considered equal, the respective two objects at each
  112. * index of the two lists have to compare equal (regarding
  113. * qobject_is_equal()), and both lists have to have the same number of
  114. * elements.
  115. * That means both lists have to contain equal objects in equal order.
  116. */
  117. bool qlist_is_equal(const QObject *x, const QObject *y)
  118. {
  119. const QList *list_x = qobject_to(QList, x);
  120. const QList *list_y = qobject_to(QList, y);
  121. const QListEntry *entry_x, *entry_y;
  122. entry_x = qlist_first(list_x);
  123. entry_y = qlist_first(list_y);
  124. while (entry_x && entry_y) {
  125. if (!qobject_is_equal(qlist_entry_obj(entry_x),
  126. qlist_entry_obj(entry_y)))
  127. {
  128. return false;
  129. }
  130. entry_x = qlist_next(entry_x);
  131. entry_y = qlist_next(entry_y);
  132. }
  133. return !entry_x && !entry_y;
  134. }
  135. /**
  136. * qlist_destroy_obj(): Free all the memory allocated by a QList
  137. */
  138. void qlist_destroy_obj(QObject *obj)
  139. {
  140. QList *qlist;
  141. QListEntry *entry, *next_entry;
  142. assert(obj != NULL);
  143. qlist = qobject_to(QList, obj);
  144. QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) {
  145. QTAILQ_REMOVE(&qlist->head, entry, next);
  146. qobject_unref(entry->value);
  147. g_free(entry);
  148. }
  149. g_free(qlist);
  150. }
  151. void qlist_unref(QList *q)
  152. {
  153. qobject_unref(q);
  154. }