From 4b79ff71b4759c5fb5dd3b43394257c343ec11c9 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 21 Feb 2018 13:04:14 -0500 Subject: [PATCH] glib_compat: backport hashtable iterator interfaces --- qemu/glib_compat.c | 102 +++++++++++++++++++++++++++++++++++++ qemu/include/glib_compat.h | 18 +++++++ 2 files changed, 120 insertions(+) diff --git a/qemu/glib_compat.c b/qemu/glib_compat.c index 3afa7fe5..ee2568a4 100644 --- a/qemu/glib_compat.c +++ b/qemu/glib_compat.c @@ -1206,6 +1206,108 @@ guint g_hash_table_size(GHashTable *hash_table) return hash_table->nnodes; } +typedef struct +{ + GHashTable *hash_table; + gpointer dummy1; + gpointer dummy2; + int position; + gboolean dummy3; + int version; +} RealIter; + +#define HASH_IS_UNUSED(h_) ((h_) == UNUSED_HASH_VALUE) +#define HASH_IS_TOMBSTONE(h_) ((h_) == TOMBSTONE_HASH_VALUE) +#define HASH_IS_REAL(h_) ((h_) >= 2) + +void g_hash_table_iter_init(GHashTableIter *iter, GHashTable *hash_table) +{ + RealIter *ri = (RealIter *) iter; + + if (iter == NULL) { + return; + } + if (hash_table == NULL) { + return; + } + + ri->hash_table = hash_table; + ri->position = -1; +} + +gboolean g_hash_table_iter_next(GHashTableIter *iter, gpointer *key, gpointer *value) +{ + RealIter *ri = (RealIter *) iter; + GHashNode *node; + gint position; + + if (iter == NULL) + { + return FALSE; + } + if (ri->position >= ri->hash_table->size) + { + return FALSE; + } + + position = ri->position; + + do + { + position++; + if (position >= ri->hash_table->size) + { + ri->position = position; + return FALSE; + } + + node = &ri->hash_table->nodes [position]; + } + while (node->key_hash <= 1); + + if (key != NULL) + *key = node->key; + if (value != NULL) + *value = node->value; + + ri->position = position; + return TRUE; +} + +GHashTable *g_hash_table_iter_get_hash_table(GHashTableIter *iter) +{ + if (iter == NULL) { + return NULL; + } + + return ((RealIter *) iter)->hash_table; +} + +static void iter_remove_or_steal(RealIter *ri, gboolean notify) +{ + if (ri == NULL) { + return; + } + if (ri->position < 0) { + return; + } + if (ri->position >= ri->hash_table->size) { + return; + } + +g_hash_table_remove_node (ri->hash_table, &ri->hash_table->nodes[ri->position], notify); +} + +void g_hash_table_iter_remove(GHashTableIter *iter) +{ + iter_remove_or_steal((RealIter *) iter, TRUE); +} + +void g_hash_table_iter_steal(GHashTableIter *iter) +{ + iter_remove_or_steal((RealIter *) iter, FALSE); +} + /* END of g_hash_table related functions */ /* general g_XXX substitutes */ diff --git a/qemu/include/glib_compat.h b/qemu/include/glib_compat.h index 6eb3827b..9a9a82a2 100644 --- a/qemu/include/glib_compat.h +++ b/qemu/include/glib_compat.h @@ -94,6 +94,18 @@ typedef void (*GHFunc)(gpointer key, gpointer value, gpointer user_data); typedef gboolean (*GHRFunc)(gpointer key, gpointer value, gpointer user_data); typedef struct _GHashTable GHashTable; +typedef struct _GHashTableIter GHashTableIter; + +struct _GHashTableIter +{ + /*< private >*/ + gpointer dummy1; + gpointer dummy2; + gpointer dummy3; + int dummy4; + gboolean dummy5; + gpointer dummy6; +}; void g_hash_table_destroy(GHashTable *hash_table); gpointer g_hash_table_find(GHashTable *hash_table, GHRFunc predicate, gpointer user_data); @@ -109,6 +121,12 @@ void g_hash_table_unref(GHashTable *hash_table); GHashTable *g_hash_table_ref(GHashTable *hash_table); guint g_hash_table_size(GHashTable *hash_table); +void g_hash_table_iter_init(GHashTableIter *iter, GHashTable *hash_table); +gboolean g_hash_table_iter_next(GHashTableIter *iter, gpointer *key, gpointer *value); +GHashTable *g_hash_table_iter_get_hash_table(GHashTableIter *iter); +void g_hash_table_iter_remove(GHashTableIter *iter); +void g_hash_table_iter_steal(GHashTableIter *iter); + /* replacement for g_malloc dependency */ void g_free(gpointer ptr); gpointer g_malloc(size_t size);