From e72b888cb6225c94f2e257017bc4dff5f8620f41 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Mon, 5 Aug 2019 17:27:00 +0200 Subject: [PATCH] Added object ZakAptrArray (associative pointer array). --- .gitignore | 5 +- src/Makefile.am | 6 +- src/aptrarray.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++ src/aptrarray.h | 49 ++++++++++ src/libzakutils.h | 3 +- tests/Makefile.am | 3 +- tests/aptrarray.c | 53 +++++++++++ 7 files changed, 339 insertions(+), 6 deletions(-) create mode 100644 src/aptrarray.c create mode 100644 src/aptrarray.h create mode 100644 tests/aptrarray.c diff --git a/.gitignore b/.gitignore index ff98f93..86c1936 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ examples/gdatetime_from_string build/ test-driver tests/generic -tests/generic.log -tests/generic.trs +tests/aptrarray +tests/*.log +tests/*.trs tests/test-suite* diff --git a/src/Makefile.am b/src/Makefile.am index d6efe00..a88ba27 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,13 +9,15 @@ lib_LTLIBRARIES = libzakutils.la libzakutils_la_SOURCES = \ generic.c \ - datetime.c + datetime.c \ + aptrarray.c libzakutils_la_LDFLAGS = -no-undefined libzakutils_include_HEADERS = \ libzakutils.h \ generic.h \ - datetime.h + datetime.h \ + aptrarray.h libzakutils_includedir = $(includedir)/libzakutils diff --git a/src/aptrarray.c b/src/aptrarray.c new file mode 100644 index 0000000..132a83a --- /dev/null +++ b/src/aptrarray.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2019 Andrea Zagli + * + * 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.1 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 + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#include "aptrarray.h" + +static void zak_aptr_array_class_init (ZakAptrArrayClass *class); +static void zak_aptr_array_init (ZakAptrArray *zak_aptr_array); + +static void zak_aptr_array_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void zak_aptr_array_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void zak_aptr_array_dispose (GObject *gobject); +static void zak_aptr_array_finalize (GObject *gobject); + +struct _ZakAptrArray + { + GObject parent_instance; + + GHashTable *ht; + GPtrArray *ar; + }; + +G_DEFINE_TYPE (ZakAptrArray, zak_aptr_array, G_TYPE_OBJECT) + +static void +zak_aptr_array_class_init (ZakAptrArrayClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = zak_aptr_array_set_property; + object_class->get_property = zak_aptr_array_get_property; + object_class->dispose = zak_aptr_array_dispose; + object_class->finalize = zak_aptr_array_finalize; +} + +static void +zak_aptr_array_init (ZakAptrArray *zak_aptr_array) +{ + zak_aptr_array->ht = g_hash_table_new (g_str_hash, g_str_equal); + zak_aptr_array->ar = g_ptr_array_new (); +} + +/** + * zak_aptr_array_new: + * + * Returns: the newly created #ZakAptrArray object. + */ +ZakAptrArray +*zak_aptr_array_new () +{ + ZakAptrArray *zak_aptr_array; + + zak_aptr_array = g_object_new (ZAK_APTR_TYPE_ARRAY, NULL); + + return zak_aptr_array; +} + +/** + * zak_aptr_array_add: + * @zak_aptr_array: + * @name: + * @data: + * + */ +void +zak_aptr_array_add (ZakAptrArray *zak_aptr_array, const gchar *name, gpointer data) +{ + g_ptr_array_add (zak_aptr_array->ar, data); + zak_aptr_array_bind (zak_aptr_array, zak_aptr_array->ar->len - 1, name); +} + +/** + * zak_aptr_array_get_array: + * @zak_aptr_array: + * + * Returns: the #GPtrArray. + */ +GPtrArray +*zak_aptr_array_get_array (ZakAptrArray *zak_aptr_array) +{ + return zak_aptr_array->ar; +} + +/** + * zak_aptr_array_bind: + * @zak_aptr_array: + * @index: + * @name: + * + */ +void +zak_aptr_array_bind (ZakAptrArray *zak_aptr_array, guint index, const gchar *name) +{ + /* with 0 (zero) the function GUINT_TO_POINTER doesn't work */ + g_hash_table_insert (zak_aptr_array->ht, (gpointer)g_strdup (name), GUINT_TO_POINTER (index + 1)); +} + +/** + * zak_aptr_array_lookup: + * @zak_aptr_array: + * @name: + * + * Returns: the data associated to @name. + */ +gpointer +zak_aptr_array_lookup (ZakAptrArray *zak_aptr_array, const gchar *name) +{ + gint index; + gpointer ret; + + index = zak_aptr_array_lookup_get_index (zak_aptr_array, name); + + ret = NULL; + if (index >= 0) + { + ret = g_ptr_array_index (zak_aptr_array->ar, index); + } + + return ret; +} + +/** + * zak_aptr_array_lookup_get_index: + * @zak_aptr_array: + * @name: + * + * Returns: the index associated to @name; or -1; + */ +gint +zak_aptr_array_lookup_get_index (ZakAptrArray *zak_aptr_array, const gchar *name) +{ + gpointer index; + gint ret; + + index = g_hash_table_lookup (zak_aptr_array->ht, (gconstpointer)name); + + ret = -1; + if (index != NULL) + { + ret = GPOINTER_TO_UINT(index) - 1; + } + + return ret; +} + +/* PRIVATE */ +static void +zak_aptr_array_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ZakAptrArray *zak_aptr_array = (ZakAptrArray *)object; + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zak_aptr_array_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ZakAptrArray *zak_aptr_array = (ZakAptrArray *)object; + + switch (property_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +zak_aptr_array_dispose (GObject *gobject) +{ + ZakAptrArray *zak_aptr_array = (ZakAptrArray *)gobject; + + + + GObjectClass *parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (gobject)); + parent_class->dispose (gobject); +} + +static void +zak_aptr_array_finalize (GObject *gobject) +{ + ZakAptrArray *zak_aptr_array = (ZakAptrArray *)gobject; + + + + GObjectClass *parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (gobject)); + parent_class->finalize (gobject); +} diff --git a/src/aptrarray.h b/src/aptrarray.h new file mode 100644 index 0000000..80735a0 --- /dev/null +++ b/src/aptrarray.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2019 Andrea Zagli + * + * 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.1 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 + */ + +#ifndef __ZAK_APTR_ARRAY_H__ +#define __ZAK_APTR_ARRAY_H__ + + +#include +#include + + +G_BEGIN_DECLS + + +#define ZAK_APTR_TYPE_ARRAY zak_aptr_array_get_type () +G_DECLARE_FINAL_TYPE (ZakAptrArray, zak_aptr_array, ZAK_APTR, ARRAY, GObject) + +ZakAptrArray *zak_aptr_array_new (); + +void zak_aptr_array_add (ZakAptrArray *zak_aptr_array, const gchar *name, gpointer data); + +GPtrArray *zak_aptr_array_get_array (ZakAptrArray *zak_aptr_array); + +void zak_aptr_array_bind (ZakAptrArray *zak_aptr_array, guint index, const gchar *name); + +gpointer zak_aptr_array_lookup (ZakAptrArray *zak_aptr_array, const gchar *name); + +gint zak_aptr_array_lookup_get_index (ZakAptrArray *zak_aptr_array, const gchar *name); + + +G_END_DECLS + + +#endif /* __ZAK_APTR_ARRAY_H__ */ diff --git a/src/libzakutils.h b/src/libzakutils.h index 20ffe19..a048bed 100644 --- a/src/libzakutils.h +++ b/src/libzakutils.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Andrea Zagli + * Copyright (C) 2015-2019 Andrea Zagli * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,6 +22,7 @@ #include #include +#include #endif /* __LIBZAKUTILS_H__ */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 5e0bb9e..3978017 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -12,4 +12,5 @@ include $(top_srcdir)/glib-tap.mk # test binaries test_programs = \ - generic + generic \ + aptrarray diff --git a/tests/aptrarray.c b/tests/aptrarray.c new file mode 100644 index 0000000..dbb2678 --- /dev/null +++ b/tests/aptrarray.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2019 Andrea Zagli + * + * 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.1 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 "aptrarray.h" + +static void +tests () +{ + ZakAptrArray *aptr; + + aptr = zak_aptr_array_new (); + + zak_aptr_array_add (aptr, "first", g_strdup ("the first item in the array")); + + g_assert_cmpstr ((const gchar *)zak_aptr_array_lookup (aptr, "first"), ==, "the first item in the array"); + + GPtrArray *ar; + + ar = zak_aptr_array_get_array (aptr); + + g_ptr_array_add (ar, g_strdup ("the second item")); + zak_aptr_array_bind (aptr, ar->len - 1, "secondone"); + + g_assert_cmpstr ((const gchar *)zak_aptr_array_lookup (aptr, "secondone"), ==, "the second item"); + + g_assert_cmpint (zak_aptr_array_lookup_get_index (aptr, "first"), ==, 0); +} + + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/aptrarray/tests", tests); + + return g_test_run (); +} -- 2.49.0