[lasem/properties] Start of property list store.



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]