[gnome-builder/wip/slaf/xml-pack: 21/56] xml-pack: add a chained hash table object



commit 03a5482b05fc68b540658b61e77917c208d425f5
Author: Sebastien Lafargue <slafargue gnome org>
Date:   Sun May 14 23:03:45 2017 +0200

    xml-pack: add a chained hash table object
    
    Using GHashTable, we can add multiple chained
    values to a key.

 plugins/xml-pack/ide-xml-hash-table.c |  162 +++++++++++++++++++++++++++++++++
 plugins/xml-pack/ide-xml-hash-table.h |   69 ++++++++++++++
 plugins/xml-pack/meson.build          |    2 +
 3 files changed, 233 insertions(+), 0 deletions(-)
---
diff --git a/plugins/xml-pack/ide-xml-hash-table.c b/plugins/xml-pack/ide-xml-hash-table.c
new file mode 100644
index 0000000..ae90db8
--- /dev/null
+++ b/plugins/xml-pack/ide-xml-hash-table.c
@@ -0,0 +1,162 @@
+/* ide-xml-hash-table.c
+ *
+ * Copyright (C) 2017 Sebastien Lafargue <slafargue gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <ide.h>
+
+#include "ide-xml-hash-table.h"
+
+G_DEFINE_BOXED_TYPE (IdeXmlHashTable, ide_xml_hash_table, ide_xml_hash_table_ref, ide_xml_hash_table_unref)
+
+IdeXmlHashTable *
+ide_xml_hash_table_new (GDestroyNotify free_func)
+{
+  IdeXmlHashTable *self;
+
+  g_return_val_if_fail (free_func != NULL, NULL);
+
+  self = g_slice_new0 (IdeXmlHashTable);
+  self->ref_count = 1;
+
+  self->free_func = free_func;
+  self->table = g_hash_table_new_full (g_str_hash,
+                                       g_str_equal,
+                                       g_free,
+                                       (GDestroyNotify)g_ptr_array_unref);
+
+  return self;
+}
+
+void
+ide_xml_hash_table_array_scan (IdeXmlHashTable              *self,
+                               IdeXmlHashTableArrayScanFunc  func,
+                               gpointer                      data)
+{
+  GHashTableIter iter;
+  gpointer key, value;
+  GPtrArray *array;
+  const gchar *name;
+
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (func != NULL);
+  g_return_if_fail (data != NULL);
+
+  g_hash_table_iter_init (&iter, self->table);
+  while (g_hash_table_iter_next (&iter, &key, &value))
+  {
+    array = (GPtrArray *)value;
+    name = (const gchar *)key;
+
+    func (name, array, data);
+  }
+}
+
+void
+ide_xml_hash_table_full_scan (IdeXmlHashTable         *self,
+                              IdeXmlHashTableScanFunc  func,
+                              gpointer                 data)
+{
+  GHashTableIter iter;
+  gpointer key, value;
+  GPtrArray *array;
+  const gchar *name;
+  gpointer content;
+
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (func != NULL);
+  g_return_if_fail (data != NULL);
+
+  g_hash_table_iter_init (&iter, self->table);
+  while (g_hash_table_iter_next (&iter, &key, &value))
+  {
+    array = (GPtrArray *)value;
+    name = (const gchar *)key;
+
+    for (gint i = 0; i < array->len; ++i)
+      {
+        content = g_ptr_array_index (array, i);
+        func (name, content, data);
+      }
+  }
+}
+
+gboolean
+ide_xml_hash_table_add (IdeXmlHashTable *self,
+                        const gchar     *name,
+                        gpointer         data)
+{
+  GPtrArray *array;
+
+  g_return_val_if_fail (self != NULL, FALSE);
+  g_return_val_if_fail (!ide_str_empty0 (name), FALSE);
+  g_return_val_if_fail (data != NULL, FALSE);
+
+  if (NULL == (array = g_hash_table_lookup (self->table, name)))
+    {
+      array = g_ptr_array_new_with_free_func (self->free_func);
+      g_hash_table_insert (self->table, g_strdup (name), array);
+    }
+  else
+    for (gint i = 0; i < array->len; ++i)
+      if (data == g_ptr_array_index (array, i))
+        return FALSE;
+
+  g_ptr_array_add (array, data);
+  return TRUE;
+}
+
+GPtrArray *
+ide_xml_hash_table_lookup (IdeXmlHashTable *self,
+                           const gchar     *name)
+{
+  g_return_val_if_fail (self != NULL, NULL);
+  g_return_val_if_fail (!ide_str_empty0 (name), NULL);
+
+  return g_hash_table_lookup (self->table, name);
+}
+
+static void
+ide_xml_hash_table_free (IdeXmlHashTable *self)
+{
+  g_assert (self);
+  g_assert_cmpint (self->ref_count, ==, 0);
+
+  g_hash_table_unref (self->table);
+
+  g_slice_free (IdeXmlHashTable, self);
+}
+
+IdeXmlHashTable *
+ide_xml_hash_table_ref (IdeXmlHashTable *self)
+{
+  g_return_val_if_fail (self, NULL);
+  g_return_val_if_fail (self->ref_count, NULL);
+
+  g_atomic_int_inc (&self->ref_count);
+
+  return self;
+}
+
+void
+ide_xml_hash_table_unref (IdeXmlHashTable *self)
+{
+  g_return_if_fail (self);
+  g_return_if_fail (self->ref_count);
+
+  if (g_atomic_int_dec_and_test (&self->ref_count))
+    ide_xml_hash_table_free (self);
+}
diff --git a/plugins/xml-pack/ide-xml-hash-table.h b/plugins/xml-pack/ide-xml-hash-table.h
new file mode 100644
index 0000000..4f9b3da
--- /dev/null
+++ b/plugins/xml-pack/ide-xml-hash-table.h
@@ -0,0 +1,69 @@
+/* ide-xml-hash-table.h
+ *
+ * Copyright (C) 2017 Sebastien Lafargue <slafargue gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IDE_XML_HASH_TABLE_H
+#define IDE_XML_HASH_TABLE_H
+
+#include <libxml/xmlstring.h>
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_XML_HASH_TABLE (ide_xml_hash_table_get_type())
+
+typedef struct _IdeXmlHashTable IdeXmlHashTable;
+
+struct _IdeXmlHashTable
+{
+  guint ref_count;
+
+  GHashTable     *table;
+  GDestroyNotify  free_func;
+};
+
+typedef void (*IdeXmlHashTableScanFunc)      (const gchar *name,
+                                              gpointer     value,
+                                              gpointer     data);
+
+typedef void (*IdeXmlHashTableArrayScanFunc) (const gchar *name,
+                                              GPtrArray   *array,
+                                              gpointer     data);
+
+IdeXmlHashTable     *ide_xml_hash_table_new         (GDestroyNotify                free_func);
+gboolean             ide_xml_hash_table_add         (IdeXmlHashTable              *self,
+                                                     const gchar                  *name,
+                                                     gpointer                      data);
+IdeXmlHashTable     *ide_xml_hash_table_copy        (IdeXmlHashTable              *self);
+void                 ide_xml_hash_table_array_scan  (IdeXmlHashTable              *self,
+                                                     IdeXmlHashTableArrayScanFunc  func,
+                                                     gpointer                      data);
+void                 ide_xml_hash_table_full_scan   (IdeXmlHashTable              *self,
+                                                     IdeXmlHashTableScanFunc       func,
+                                                     gpointer                      data);
+GPtrArray           *ide_xml_hash_table_lookup      (IdeXmlHashTable              *self,
+                                                     const gchar                  *name);
+IdeXmlHashTable     *ide_xml_hash_table_ref         (IdeXmlHashTable              *self);
+void                 ide_xml_hash_table_unref       (IdeXmlHashTable              *self);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (IdeXmlHashTable, ide_xml_hash_table_unref)
+
+G_END_DECLS
+
+#endif /* IDE_XML_HASH_TABLE_H */
+
diff --git a/plugins/xml-pack/meson.build b/plugins/xml-pack/meson.build
index bd18442..09b8354 100644
--- a/plugins/xml-pack/meson.build
+++ b/plugins/xml-pack/meson.build
@@ -7,6 +7,8 @@ xml_pack_sources = [
   'ide-xml-completion-provider.h',
   'ide-xml-diagnostic-provider.c',
   'ide-xml-diagnostic-provider.h',
+  'ide-xml-hash-table.c',
+  'ide-xml-hash-table.h',
   'ide-xml-highlighter.c',
   'ide-xml-highlighter.h',
   'ide-xml-indenter.c',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]