summaryrefslogtreecommitdiffstats
path: root/src/private-data.c
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-11-12 12:56:39 +0000
committerRichard W.M. Jones <rjones@redhat.com>2012-11-12 13:40:25 +0000
commit02ecd048d3caf7804361bb0f5dca071f97aefaa1 (patch)
tree2b17e6b2037297bc1bc93b4371be15a3b9d3aef6 /src/private-data.c
parentf9ab256f0e4c1197b505b0249e66e7614644bd0b (diff)
downloadlibguestfs-02ecd048d3caf7804361bb0f5dca071f97aefaa1.tar.gz
libguestfs-02ecd048d3caf7804361bb0f5dca071f97aefaa1.tar.xz
libguestfs-02ecd048d3caf7804361bb0f5dca071f97aefaa1.zip
lib: Split up huge src/guestfs.c into logical compilation units.
This file had grown by accretion to include: - code related to handles (now in src/handle.c) - safe allocation (src/alloc.c) - debug, errors, warnings (src/errors.c) - private data (src/private-data.c) - miscellaneous functions (src/canonical-name.c, src/utils.c) This commit also removes about a dozen #include files which were probably not really used. This is just code motion.
Diffstat (limited to 'src/private-data.c')
-rw-r--r--src/private-data.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/private-data.c b/src/private-data.c
new file mode 100644
index 00000000..870ec101
--- /dev/null
+++ b/src/private-data.c
@@ -0,0 +1,148 @@
+/* libguestfs
+ * Copyright (C) 2009-2012 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "c-ctype.h"
+#include "hash.h"
+#include "hash-pjw.h"
+
+#include "guestfs.h"
+#include "guestfs-internal.h"
+
+/* Note the private data area is allocated lazily, since the vast
+ * majority of callers will never use it. This means g->pda is
+ * likely to be NULL.
+ */
+struct pda_entry {
+ char *key; /* key */
+ void *data; /* opaque user data pointer */
+};
+
+static size_t
+hasher (void const *x, size_t table_size)
+{
+ struct pda_entry const *p = x;
+ return hash_pjw (p->key, table_size);
+}
+
+static bool
+comparator (void const *x, void const *y)
+{
+ struct pda_entry const *a = x;
+ struct pda_entry const *b = y;
+ return STREQ (a->key, b->key);
+}
+
+static void
+freer (void *x)
+{
+ if (x) {
+ struct pda_entry *p = x;
+ free (p->key);
+ free (p);
+ }
+}
+
+void
+guestfs_set_private (guestfs_h *g, const char *key, void *data)
+{
+ if (g->pda == NULL) {
+ g->pda = hash_initialize (16, NULL, hasher, comparator, freer);
+ if (g->pda == NULL)
+ g->abort_cb ();
+ }
+
+ struct pda_entry *new_entry = safe_malloc (g, sizeof *new_entry);
+ new_entry->key = safe_strdup (g, key);
+ new_entry->data = data;
+
+ struct pda_entry *old_entry = hash_delete (g->pda, new_entry);
+ freer (old_entry);
+
+ struct pda_entry *entry = hash_insert (g->pda, new_entry);
+ if (entry == NULL)
+ g->abort_cb ();
+ assert (entry == new_entry);
+}
+
+static inline char *
+bad_cast (char const *s)
+{
+ return (char *) s;
+}
+
+void *
+guestfs_get_private (guestfs_h *g, const char *key)
+{
+ if (g->pda == NULL)
+ return NULL; /* no keys have been set */
+
+ const struct pda_entry k = { .key = bad_cast (key) };
+ struct pda_entry *entry = hash_lookup (g->pda, &k);
+ if (entry)
+ return entry->data;
+ else
+ return NULL;
+}
+
+/* Iterator. */
+void *
+guestfs_first_private (guestfs_h *g, const char **key_rtn)
+{
+ if (g->pda == NULL)
+ return NULL;
+
+ g->pda_next = hash_get_first (g->pda);
+
+ /* Ignore any keys with NULL data pointers. */
+ while (g->pda_next && g->pda_next->data == NULL)
+ g->pda_next = hash_get_next (g->pda, g->pda_next);
+
+ if (g->pda_next == NULL)
+ return NULL;
+
+ *key_rtn = g->pda_next->key;
+ return g->pda_next->data;
+}
+
+void *
+guestfs_next_private (guestfs_h *g, const char **key_rtn)
+{
+ if (g->pda == NULL)
+ return NULL;
+
+ if (g->pda_next == NULL)
+ return NULL;
+
+ /* Walk to the next key with a non-NULL data pointer. */
+ do {
+ g->pda_next = hash_get_next (g->pda, g->pda_next);
+ } while (g->pda_next && g->pda_next->data == NULL);
+
+ if (g->pda_next == NULL)
+ return NULL;
+
+ *key_rtn = g->pda_next->key;
+ return g->pda_next->data;
+}