]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/idxset.c
remap: Change remapping function argument type from void to int16_t / float as approp...
[pulseaudio] / src / pulsecore / idxset.c
index b6423efd1e612a0cb79797ae8c316952af589179..eec73c6ee01e28d4d8f98b43fa5b5b62a1876276 100644 (file)
@@ -29,7 +29,6 @@
 #include <string.h>
 
 #include <pulse/xmalloc.h>
-#include <pulsecore/log.h>
 #include <pulsecore/flist.h>
 #include <pulsecore/macro.h>
 
@@ -80,7 +79,7 @@ unsigned pa_idxset_trivial_hash_func(const void *p) {
 }
 
 int pa_idxset_trivial_compare_func(const void *a, const void *b) {
-    return a != b;
+    return a < b ? -1 : (a > b ? 1 : 0);
 }
 
 pa_idxset* pa_idxset_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func) {
@@ -140,18 +139,10 @@ static void remove_entry(pa_idxset *s, struct idxset_entry *e) {
     s->n_entries--;
 }
 
-void pa_idxset_free(pa_idxset *s, pa_free2_cb_t free_cb, void *userdata) {
+void pa_idxset_free(pa_idxset *s, pa_free_cb_t free_cb) {
     pa_assert(s);
 
-    while (s->iterate_list_head) {
-        void *data = s->iterate_list_head->data;
-
-        remove_entry(s, s->iterate_list_head);
-
-        if (free_cb)
-            free_cb(data, userdata);
-    }
-
+    pa_idxset_remove_all(s, free_cb);
     pa_xfree(s);
 }
 
@@ -309,6 +300,19 @@ void* pa_idxset_remove_by_data(pa_idxset*s, const void *data, uint32_t *idx) {
     return r;
 }
 
+void pa_idxset_remove_all(pa_idxset *s, pa_free_cb_t free_cb) {
+    pa_assert(s);
+
+    while (s->iterate_list_head) {
+        void *data = s->iterate_list_head->data;
+
+        remove_entry(s, s->iterate_list_head);
+
+        if (free_cb)
+            free_cb(data);
+    }
+}
+
 void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx) {
     unsigned hash;
     struct idxset_entry *e;
@@ -318,8 +322,7 @@ void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx) {
 
     hash = *idx % NBUCKETS;
 
-    if (!(e = index_scan(s, hash, *idx)))
-        return NULL;
+    e = index_scan(s, hash, *idx);
 
     if (e && e->iterate_next)
         e = e->iterate_next;
@@ -387,8 +390,11 @@ void* pa_idxset_steal_first(pa_idxset *s, uint32_t *idx) {
 void* pa_idxset_first(pa_idxset *s, uint32_t *idx) {
     pa_assert(s);
 
-    if (!s->iterate_list_head)
+    if (!s->iterate_list_head) {
+        if (idx)
+            *idx = PA_IDXSET_INVALID;
         return NULL;
+    }
 
     if (idx)
         *idx = s->iterate_list_head->idx;
@@ -403,20 +409,41 @@ void *pa_idxset_next(pa_idxset *s, uint32_t *idx) {
     pa_assert(s);
     pa_assert(idx);
 
+    if (*idx == PA_IDXSET_INVALID)
+        return NULL;
+
     hash = *idx % NBUCKETS;
 
-    if (!(e = index_scan(s, hash, *idx)))
-        return NULL;
+    if ((e = index_scan(s, hash, *idx))) {
+
+        e = e->iterate_next;
+
+        if (e) {
+            *idx = e->idx;
+            return e->data;
+        } else {
+            *idx = PA_IDXSET_INVALID;
+            return NULL;
+        }
+
+    } else {
+
+        /* If the entry passed doesn't exist anymore we try to find
+         * the next following */
+
+        for ((*idx)++; *idx < s->current_index; (*idx)++) {
+
+            hash = *idx % NBUCKETS;
+
+            if ((e = index_scan(s, hash, *idx))) {
+                *idx = e->idx;
+                return e->data;
+            }
+        }
 
-    if (!e->iterate_next) {
         *idx = PA_IDXSET_INVALID;
         return NULL;
     }
-
-    e = e->iterate_next;
-
-    *idx = e->idx;
-    return e->data;
 }
 
 unsigned pa_idxset_size(pa_idxset*s) {
@@ -425,8 +452,22 @@ unsigned pa_idxset_size(pa_idxset*s) {
     return s->n_entries;
 }
 
-pa_bool_t pa_idxset_isempty(pa_idxset *s) {
+bool pa_idxset_isempty(pa_idxset *s) {
     pa_assert(s);
 
     return s->n_entries == 0;
 }
+
+pa_idxset *pa_idxset_copy(pa_idxset *s, pa_copy_func_t copy_func) {
+    pa_idxset *copy;
+    struct idxset_entry *i;
+
+    pa_assert(s);
+
+    copy = pa_idxset_new(s->hash_func, s->compare_func);
+
+    for (i = s->iterate_list_head; i; i = i->iterate_next)
+        pa_idxset_put(copy, copy_func ? copy_func(i->data) : i->data, NULL);
+
+    return copy;
+}