From c77d7718a2e845fb2d68b1a8d2d22731cd3cb552 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 17 Jul 2015 16:50:49 +0200 Subject: [PATCH] properties: add generic property bag Add a structure to hold string key/value pairs. This is basically a thin wrapper around GHashTable with some extra API. --- src/Makefile.am | 3 + src/client/pinos.h | 1 + src/client/properties.c | 203 ++++++++++++++++++++++++++++++++++++++++ src/client/properties.h | 54 +++++++++++ 4 files changed, 261 insertions(+) create mode 100644 src/client/properties.c create mode 100644 src/client/properties.h diff --git a/src/Makefile.am b/src/Makefile.am index af5872354..9c051a1ef 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -154,6 +154,8 @@ pinosinclude_HEADERS = \ client/context.h \ client/enumtypes.h \ client/introspect.h \ + client/mainloop.h \ + client/properties.h \ client/stream.h \ client/subscribe.h @@ -166,6 +168,7 @@ libpinos_@PINOS_MAJORMINOR@_la_SOURCES = \ client/enumtypes.h client/enumtypes.c \ client/introspect.h client/introspect.c \ client/mainloop.h client/mainloop.c \ + client/properties.h client/properties.c \ client/stream.h client/stream.c \ client/pinos.c client/pinos.h \ client/subscribe.c client/subscribe.h \ diff --git a/src/client/pinos.h b/src/client/pinos.h index 06d32e779..9bb9a128e 100644 --- a/src/client/pinos.h +++ b/src/client/pinos.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/src/client/properties.c b/src/client/properties.c new file mode 100644 index 000000000..2f2276d0f --- /dev/null +++ b/src/client/properties.c @@ -0,0 +1,203 @@ +/* Pinos + * Copyright (C) 2015 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include + +#include "client/properties.h" + +struct _PinosProperties { + GHashTable *hashtable; +}; + +static void +copy_func (const gchar *key, const gchar *value, GHashTable *copy) +{ + g_hash_table_insert (copy, g_strdup (key), g_strdup (value)); +} + +/** + * pinos_properties_new: + * @key: first key + * @...: value + * + * Make a new #PinosProperties with given, NULL-terminated key/value pairs. + * + * Returns: a new #PinosProperties + */ +PinosProperties * +pinos_properties_new (const gchar *key, ...) +{ + PinosProperties *props; + va_list varargs; + const gchar *value; + + props = g_new (PinosProperties, 1); + props->hashtable = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + va_start (varargs, key); + while (key != NULL) { + value = va_arg (varargs, gchar *); + copy_func (key, value, props->hashtable); + key = va_arg (varargs, gchar *); + } + va_end (varargs); + + return props; +} + +/** + * pinos_properties_copy: + * @properties: a #PinosProperties + * + * Make a copy of @properties. + * + * Returns: a copy of @properties + */ +PinosProperties * +pinos_properties_copy (PinosProperties *properties) +{ + PinosProperties *copy; + + g_return_val_if_fail (properties != NULL, NULL); + + copy = pinos_properties_new (NULL); + g_hash_table_foreach (properties->hashtable, (GHFunc) copy_func, copy->hashtable); + + return copy; +} + +/** + * pinos_properties_free: + * @properties: a #PinosProperties + * + * Free @properties + */ +void +pinos_properties_free (PinosProperties *properties) +{ + g_return_if_fail (properties != NULL); + + g_hash_table_unref (properties->hashtable); + g_free (properties); +} + +void +pinos_properties_set (PinosProperties *properties, + const gchar *key, + const gchar *value) +{ + g_return_if_fail (properties != NULL); + g_return_if_fail (key != NULL); + g_return_if_fail (value != NULL); + + g_hash_table_replace (properties->hashtable, g_strdup (key), g_strdup (value)); +} + +const gchar * +pinos_properties_get (PinosProperties *properties, + const gchar *key) +{ + g_return_val_if_fail (properties != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + return g_hash_table_lookup (properties->hashtable, key); +} +void +pinos_properties_remove (PinosProperties *properties, + const gchar *key) +{ + g_return_if_fail (properties != NULL); + g_return_if_fail (key != NULL); + + g_hash_table_remove (properties->hashtable, key); +} + +const gchar * +pinos_properties_iterate (PinosProperties *properties, + gpointer *state) +{ + static gpointer dummy = GINT_TO_POINTER (1); + const gchar *res = NULL; + GList *items; + + g_return_val_if_fail (properties != NULL, NULL); + g_return_val_if_fail (state != NULL, NULL); + + if (*state == dummy) + return NULL; + + if (*state == NULL) { + items = g_hash_table_get_keys (properties->hashtable); + } else { + items = *state; + } + + if (items) { + res = items->data; + items = g_list_delete_link (items, items); + if (items == NULL) + items = dummy; + } + *state = items; + + return res; +} + +static void +add_to_variant (const gchar *key, const gchar *value, GVariantBuilder *b) +{ + g_variant_builder_add (b, "{sv}", key, g_variant_new_string (value)); +} + +GVariant * +pinos_properties_to_variant (PinosProperties *properties) +{ + GVariantBuilder builder; + + g_return_val_if_fail (properties != NULL, NULL); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + g_hash_table_foreach (properties->hashtable, (GHFunc) add_to_variant, &builder); + return g_variant_builder_end (&builder); +} + +PinosProperties * +pinos_properties_from_variant (GVariant *variant) +{ + PinosProperties *props; + GVariantIter iter; + GVariant *value; + gchar *key; + + g_return_val_if_fail (variant != NULL, NULL); + + props = pinos_properties_new (NULL); + + g_variant_iter_init (&iter, variant); + while (g_variant_iter_loop (&iter, "{sv}", &key, &value)) + g_hash_table_replace (props->hashtable, + g_strdup (key), + g_variant_dup_string (value, NULL)); + + return props; +} + +G_DEFINE_BOXED_TYPE (PinosProperties, pinos_properties, + pinos_properties_copy, pinos_properties_free); + diff --git a/src/client/properties.h b/src/client/properties.h new file mode 100644 index 000000000..ea52d1d0e --- /dev/null +++ b/src/client/properties.h @@ -0,0 +1,54 @@ +/* Pinos + * Copyright (C) 2015 Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __PINOS_PROPERTIES_H__ +#define __PINOS_PROPERTIES_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _PinosProperties PinosProperties; + +#define PINOS_TYPE_PROPERTIES (pinos_properties_get_type()) +GType pinos_properties_get_type (void); + +PinosProperties * pinos_properties_new (const gchar *key, ...); +PinosProperties * pinos_properties_copy (PinosProperties *properties); +void pinos_properties_free (PinosProperties *properties); + +void pinos_properties_set (PinosProperties *properties, + const gchar *key, + const gchar *value); +const gchar * pinos_properties_get (PinosProperties *properties, + const gchar *key); +void pinos_properties_remove (PinosProperties *properties, + const gchar *key); + +const gchar * pinos_properties_iterate (PinosProperties *properties, + gpointer *state); + +GVariant * pinos_properties_to_variant (PinosProperties *properties); +PinosProperties * pinos_properties_from_variant (GVariant *variant); + + +G_END_DECLS + +#endif /* __PINOS_PROPERTIES_H__ */ +