[lasem/properties] Start of property list store.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Subject: [lasem/properties] Start of property list store.
- Date: Mon, 20 Jul 2009 15:42:32 +0000 (UTC)
commit f0f3e2cc9a80ac9f9fa307f64f1807b8ad90acdf
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Mon Jul 20 17:41:13 2009 +0200
Start of property list store.
src/Makefile.am | 14 +++-
src/lasempropertytest.c | 133 ++++++++++++++++++++++++++++++++
src/lsmproperties.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++
src/lsmproperties.h | 67 ++++++++++++++++
4 files changed, 407 insertions(+), 2 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index dc76bd8..e6c115c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,7 +7,8 @@ INCLUDES = \
AM_CFLAGS =\
-Wall\
-Werror \
- -g
+ -g \
+ -O0
lib_LTLIBRARIES = liblasem.la
@@ -17,6 +18,7 @@ liblasem_la_LIBADD = \
liblasem_la_SOURCES = \
lsmdebug.c \
+ lsmproperties.c \
lsmdomnode.c \
lsmdomnodelist.c \
lsmdomdocument.c \
@@ -97,6 +99,7 @@ liblasem_la_SOURCES = \
liblasem_ladir = $(includedir)/lasem
liblasem_la_HEADERS = \
lsmdebug.h \
+ lsmproperties.h \
lsmdom.h \
lsmdomnode.h \
lsmdomnodelist.h \
@@ -177,7 +180,7 @@ liblasem_la_HEADERS = \
lsmsvgview.h \
lsmsvgmatrix.h
-bin_PROGRAMS = lasemtest lasemrender
+bin_PROGRAMS = lasemtest lasemrender lasempropertytest
lasemrender_SOURCES = \
lasemrender.c
@@ -192,3 +195,10 @@ lasemtest_SOURCES = \
lasemtest_LDFLAGS =
lasemtest_LDADD = $(LASEM_LIBS) liblasem.la ../itex2mml/libitex2mml.la
+
+lasempropertytest_SOURCES = \
+ lasempropertytest.c
+
+lasempropertytest_LDFLAGS =
+
+lasempropertytest_LDADD = $(LASEM_LIBS) liblasem.la ../itex2mml/libitex2mml.la
diff --git a/src/lasempropertytest.c b/src/lasempropertytest.c
new file mode 100644
index 0000000..e1a99af
--- /dev/null
+++ b/src/lasempropertytest.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright © 2007-2008 Emmanuel Pacaud
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <lsmdebug.h>
+#include <lsmproperties.h>
+
+typedef struct {
+ LsmProperty base;
+ double value;
+} LsmNumberProperty;
+
+static gboolean
+lsm_number_property_from_text (LsmProperty *property, const char *value)
+{
+ LsmNumberProperty *number_property = (LsmNumberProperty *) property;
+
+ if (value == NULL)
+ return FALSE;
+
+ number_property->value = g_strtod (value, NULL);
+
+ return TRUE;
+}
+
+char *
+lsm_number_property_to_text (LsmProperty *property)
+{
+ LsmNumberProperty *number_property = (LsmNumberProperty *) property;
+
+ return g_strdup_printf ("%g", number_property->value);
+}
+
+static const LsmPropertyClass lsm_property_class = {
+ .size = sizeof (LsmNumberProperty)
+};
+
+static const LsmPropertyClass lsm_number_property_class = {
+ .size = sizeof (LsmNumberProperty),
+ .from_text = lsm_number_property_from_text,
+ .to_text = lsm_number_property_to_text
+};
+
+typedef struct {
+ LsmProperty * mask;
+ LsmNumberProperty * number;
+ LsmNumberProperty * other_number;
+} LsmSvgPropertySet;
+
+LsmPropertyInfos infos[] = {
+ {
+ .name = "mask",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgPropertySet, mask),
+ .property_class = &lsm_property_class
+ },
+ {
+ .name = "number",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgPropertySet, number),
+ .property_class = &lsm_number_property_class
+ },
+ {
+ .name = "other-number",
+ .id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgPropertySet, other_number),
+ .property_class = &lsm_number_property_class
+ }
+};
+
+int
+main (int argc, char **argv)
+{
+ LsmPropertyManager *manager;
+ LsmSvgPropertySet property_set;
+ GSList *property_list = NULL;
+ const char *value;
+
+ manager = lsm_property_manager_new (G_N_ELEMENTS (infos), infos);
+
+ lsm_property_list_set_property (&property_list, manager, "number", NULL);
+ lsm_property_list_set_property (&property_list, manager, "number", "1.2");
+ lsm_property_list_set_property (&property_list, manager, "mask", "url(#clip)");
+ lsm_property_list_set_property (&property_list, manager, "none", "toto");
+ lsm_property_list_set_property (&property_list, manager, "other-number", "1.4");
+ lsm_property_list_set_property (&property_list, manager, "other-number", NULL);
+
+ value = lsm_property_list_get_property (&property_list, manager, "mask");
+ g_message ("mask = '%s'", value);
+ value = lsm_property_list_get_property (&property_list, manager, "number");
+ g_message ("number = '%s'", value);
+ value = lsm_property_list_get_property (&property_list, manager, "none");
+ g_message ("none = '%s'", value);
+ value = lsm_property_list_get_property (&property_list, manager, "other-number");
+ g_message ("other-number = '%s'", value);
+
+ lsm_property_manager_apply_list (manager, property_list, (void **) &property_set, sizeof (property_set));
+
+ g_message ("number = %g", property_set.number->value);
+ g_message ("other-number = %g", property_set.other_number->value);
+
+ lsm_property_list_free (&property_list, manager);
+
+ lsm_property_manager_free (manager);
+
+ return 0;
+}
+
+/* vim: set sw=8 sts=8: -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
diff --git a/src/lsmproperties.c b/src/lsmproperties.c
new file mode 100644
index 0000000..028ca51
--- /dev/null
+++ b/src/lsmproperties.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright © 2007-2009 Emmanuel Pacaud
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <lsmproperties.h>
+
+struct _LsmPropertyManager {
+ unsigned int n_properties;
+ const LsmPropertyInfos *property_infos;
+ GHashTable * hash_by_names;
+};
+
+LsmPropertyManager *
+lsm_property_manager_new (unsigned int n_properties, const LsmPropertyInfos *property_infos)
+{
+ LsmPropertyManager *manager;
+ guint16 i;
+
+ g_return_val_if_fail (n_properties > 0, NULL);
+ g_return_val_if_fail (property_infos != NULL, NULL);
+
+ manager = g_new (LsmPropertyManager, 1);
+ manager->hash_by_names = g_hash_table_new (g_str_hash, g_str_equal);
+ manager->n_properties = n_properties;
+ manager->property_infos = property_infos;
+
+ for (i = 0; i < n_properties; i++) {
+
+ g_assert (property_infos[i].name != NULL);
+ g_assert (property_infos[i].property_class != NULL);
+ g_assert (property_infos[i].property_class->size > 0);
+
+ g_hash_table_insert (manager->hash_by_names,
+ (void *) property_infos[i].name,
+ (void *) &property_infos[i]);
+ }
+
+ return manager;
+}
+
+void
+lsm_property_manager_free (LsmPropertyManager *manager)
+{
+ g_return_if_fail (manager != NULL);
+
+ g_hash_table_unref (manager->hash_by_names);
+ g_free (manager);
+}
+
+const LsmPropertyInfos *
+lsm_property_manager_find_infos (LsmPropertyManager *manager, const char *name)
+{
+ g_return_val_if_fail (manager != NULL, NULL);
+
+ return g_hash_table_lookup (manager->hash_by_names, name);
+}
+
+const LsmPropertyInfos *
+lsm_property_manager_find_infos_by_id (LsmPropertyManager *manager, guint16 id)
+{
+ g_return_val_if_fail (manager != NULL, NULL);
+ g_return_val_if_fail (id < manager->n_properties, NULL);
+
+ return &manager->property_infos[id];
+}
+
+static void
+property_free (LsmProperty *property, const LsmPropertyClass *property_class)
+{
+ if (property_class != NULL && property_class->finalize != NULL)
+ property_class->finalize (property);
+
+ g_free (property->value);
+ g_slice_free1 (property_class->size, property);
+}
+
+void
+lsm_property_list_set_property (GSList **property_list,
+ LsmPropertyManager *manager,
+ const char *name, const char *value)
+{
+ LsmProperty *property;
+ const LsmPropertyInfos *property_infos;
+ const LsmPropertyClass *property_class;
+
+ g_return_if_fail (property_list != NULL);
+ g_return_if_fail (manager != NULL);
+
+ property_infos = lsm_property_manager_find_infos (manager, name);
+ if (property_infos == NULL)
+ return;
+
+ property_class = property_infos->property_class;
+
+ /* We don't check for existing property in the list. The cleanup will be done later. */
+
+ property = g_slice_alloc (property_class->size);
+ property->id = property_infos->id;
+ property->value = g_strdup (value);
+
+ if (property_class->init)
+ property_class->init (property);
+
+ if (property->value != NULL && property_class->from_text) {
+ if (!property_class->from_text (property, value)) {
+ g_free (property->value);
+ property->value = NULL;
+ return;
+ }
+ }
+
+ *property_list = g_slist_prepend (*property_list, property);
+}
+
+const char *
+lsm_property_list_get_property (GSList **property_list,
+ LsmPropertyManager *manager,
+ const char *name)
+{
+ LsmProperty *property = NULL;
+ const LsmPropertyInfos *property_infos;
+ GSList *iter;
+
+ g_return_val_if_fail (property_list != NULL, NULL);
+ g_return_val_if_fail (manager != NULL, NULL);
+
+ property_infos = lsm_property_manager_find_infos (manager, name);
+ if (property_infos == NULL)
+ return NULL;
+
+ g_message ("Get property with name %s (%d)", name, property_infos->id);
+
+ for (iter = *property_list; iter != NULL; iter = iter->next) {
+ property = iter->data;
+ if (property->id == property_infos->id)
+ break;
+ }
+
+ if (property == NULL)
+ return NULL;
+
+ return property->value;
+}
+
+void
+lsm_property_list_free (GSList **property_list, LsmPropertyManager *manager)
+{
+ LsmProperty *property;
+ const LsmPropertyInfos *property_infos;
+ GSList *iter;
+
+ g_return_if_fail (property_list != NULL);
+ g_return_if_fail (manager != NULL);
+
+ for (iter = *property_list; iter != NULL; iter = iter->next) {
+ property = iter->data;
+
+ property_infos = lsm_property_manager_find_infos_by_id (manager, property->id);
+
+ property_free (property, property_infos->property_class);
+ }
+
+ g_slist_free (*property_list);
+ *property_list = NULL;
+}
+
+void
+lsm_property_manager_apply_list (LsmPropertyManager *manager, GSList *property_list,
+ void **property_set, size_t set_size)
+{
+ LsmProperty *property;
+ GSList *iter;
+
+ for (iter = property_list; iter != NULL; iter = iter->next) {
+ property = iter->data;
+ property_set[property->id] = property;
+ }
+}
diff --git a/src/lsmproperties.h b/src/lsmproperties.h
new file mode 100644
index 0000000..565f437
--- /dev/null
+++ b/src/lsmproperties.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2007-2009 Emmanuel Pacaud
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Emmanuel Pacaud <emmanuel gnome org>
+ */
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define LSM_PROPERTY_OFFSET_TO_ID(structure,member) offsetof (structure, member) / sizeof (void *)
+#define LSM_PROPERTY_ID_TO_OFFSET(id) id * sizeof (void *)
+
+typedef struct {
+ guint16 id;
+ guint16 flags;
+ char * value;
+} LsmProperty;
+
+typedef struct {
+ size_t size;
+ void (*init) (LsmProperty *property);
+ void (*finalize) (LsmProperty *property);
+ gboolean (*from_text) (LsmProperty *property, const char *value);
+ char * (*to_text) (LsmProperty *property);
+} LsmPropertyClass;
+
+typedef struct {
+ char const * name;
+ guint16 id;
+ const LsmPropertyClass * property_class;
+} LsmPropertyInfos;
+
+typedef struct _LsmPropertyManager LsmPropertyManager;
+
+LsmPropertyManager * lsm_property_manager_new (unsigned int n_properties,
+ const LsmPropertyInfos *property_infos);
+void lsm_property_manager_free (LsmPropertyManager *manager);
+
+void lsm_property_list_set_property (GSList **property_list,
+ LsmPropertyManager *manager,
+ const char *name, const char *value);
+const char * lsm_property_list_get_property (GSList **property_list,
+ LsmPropertyManager *manager,
+ const char *name);
+void lsm_property_list_free (GSList **property_list,
+ LsmPropertyManager *manager);
+
+void lsm_property_manager_apply_list (LsmPropertyManager *manager, GSList *property_list,
+ void **property_set, size_t set_size);
+
+G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]