[aravis] genicam: implement child nodes.



commit 1f9344b6951fbe2dc4d09bc618a504ee97205812
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Fri Apr 2 15:06:12 2010 +0200

    genicam: implement child nodes.
    
    That's needed for EnumEntry and StructEntry support.

 src/arvgc.c     |  122 +++++++++++++++++++++++++++++++-----------------------
 src/arvgcnode.c |   86 ++++++++++++++++++++++++++++-----------
 src/arvgcnode.h |   10 ++---
 3 files changed, 136 insertions(+), 82 deletions(-)
---
diff --git a/src/arvgc.c b/src/arvgc.c
index 66d56f8..3399236 100644
--- a/src/arvgc.c
+++ b/src/arvgc.c
@@ -76,9 +76,6 @@ arv_gc_create_node (ArvGc *genicam, const char *type)
 		node = arv_gc_int_swiss_knife_new ();
 	else if (strcmp (type, "Port") == 0)
 		node = arv_gc_port_new ();
-	else
-		arv_debug ("genicam",
-			   "[Gc::create_node] Unknown node type (%s)", type);
 
 	if (node != NULL) {
 		arv_gc_node_set_genicam (node, genicam);
@@ -92,8 +89,8 @@ arv_gc_create_node (ArvGc *genicam, const char *type)
 typedef struct {
 	int level;
 	ArvGc *genicam;
-	ArvGcNode *current_node;
-	int current_node_level;
+	ArvGcNode *level_2_node;
+	ArvGcNode *level_3_node;
 
 	const char *current_element;
 	char **current_attrs;
@@ -106,8 +103,8 @@ arv_gc_parser_start_document (void *user_data)
 	ArvGcParserState *state = user_data;
 
 	state->level = 0;
-	state->current_node = NULL;
-	state->current_node_level = -1;
+	state->level_2_node = NULL;
+	state->level_3_node = NULL;
 	state->current_element = NULL;
 	state->current_attrs = NULL;
 	state->current_content = g_string_new ("");
@@ -132,39 +129,59 @@ arv_gc_parser_start_element(void *user_data,
 
 	state->level++;
 
-	if (state->current_node == NULL) {
-	       if (state->level > 1) {
-		       node = arv_gc_create_node (state->genicam, (char *) name);
+	node = arv_gc_create_node (state->genicam, (char *) name);
+	if (node != NULL) {
+		int i;
+		for (i = 0; attrs[i] != NULL && attrs[i+1] != NULL; i += 2)
+			arv_gc_node_set_attribute (node, (char *) attrs[i], (char *) attrs[i+1]);
+	}
 
-		       if (node != NULL) {
-			       int i;
-			       for (i = 0; attrs[i] != NULL && attrs[i+1] != NULL; i += 2)
-				       arv_gc_node_set_attribute (node, (char *) attrs[i], (char *) attrs[i+1]);
+	if (state->level == 2) {
+		state->level_2_node = node;
+		if (node != NULL)
+			g_object_ref (node);
+	} else if (state->level > 2 && state->level_2_node != NULL) {
+		if (state->level == 3 && node != NULL) {
+			state->level_3_node = node;
+			g_object_ref (node);
+		} else {
+			int n_elements, i;
+			state->current_element = (const char *) name;
 
-			       state->current_node = node;
-			       state->current_node_level = state->level;
-		       }
-	       }
-	} else {
-		int n_elements, i;
-		state->current_element = (const char *) name;
+			g_strfreev (state->current_attrs);
 
-		g_strfreev (state->current_attrs);
+			if (attrs != NULL) {
+				for (n_elements = 0; attrs[n_elements] != NULL; n_elements++);
+				n_elements++;
 
-		if (attrs != NULL) {
-			for (n_elements = 0; attrs[n_elements] != NULL; n_elements++);
-			n_elements++;
+				state->current_attrs = g_new (char *, n_elements);
+				for (i = 0; i < n_elements; i++)
+					state->current_attrs[i] = g_strdup ((char *) attrs[i]);
+			} else {
+				state->current_attrs = g_new (char *, 1);
+				state->current_attrs[0] = NULL;
+			}
 
-			state->current_attrs = g_new (char *, n_elements);
-			for (i = 0; i < n_elements; i++)
-				state->current_attrs[i] = g_strdup ((char *) attrs[i]);
-		} else {
-			state->current_attrs = g_new (char *, 1);
-			state->current_attrs[0] = NULL;
+			g_string_erase (state->current_content, 0, -1);
 		}
-
-		g_string_erase (state->current_content, 0, -1);
 	}
+
+	if (node != NULL)
+		g_object_unref (node);
+}
+
+static void
+arv_gc_parser_insert_node (ArvGcParserState *state, ArvGcNode *node)
+{
+	const char *node_name;
+
+	node_name = arv_gc_node_get_name (node);
+	if (node_name != NULL) {
+		g_hash_table_insert (state->genicam->nodes, (char *) node_name, node);
+		arv_debug ("genicam",
+			   "[GcParser::end_element] Insert node '%s'", node_name);
+	} else
+		g_object_unref (node);
 }
 
 static void
@@ -173,23 +190,25 @@ arv_gc_parser_end_element (void *user_data,
 {
 	ArvGcParserState *state = user_data;
 
-	if (state->current_node_level == state->level) {
-		const char *node_name;
-
-		node_name = arv_gc_node_get_name (state->current_node);
-		if (node_name != NULL) {
-			g_hash_table_insert (state->genicam->nodes, (char *) node_name, state->current_node);
-			arv_debug ("genicam",
-				   "[GcParser::start_element] Insert node '%s'", node_name);
-		} else
-			g_object_unref (state->current_node);
-
-		state->current_node_level = -1;
-		state->current_node = NULL;
-	} else if (state->current_node_level < state->level &&
-		   state->current_node != NULL) {
-		arv_gc_node_add_element (state->current_node, state->current_element,
-					 state->current_content->str, (const char **) state->current_attrs);
+	if (state->level == 2) {
+		if (state->level_2_node != NULL) {
+			arv_gc_parser_insert_node (state, state->level_2_node);
+			state->level_2_node = NULL;
+		}
+	} else if (state->level > 2) {
+		if (state->level == 3 && state->level_3_node != NULL) {
+			if (state->level_2_node != NULL)
+				arv_gc_node_add_child (state->level_2_node, state->level_3_node);
+			else
+				g_object_unref (state->level_3_node);
+			state->level_3_node = NULL;
+		} else if (state->level == 3 && state->level_2_node != NULL) {
+			arv_gc_node_add_element (state->level_2_node, state->current_element,
+						 state->current_content->str, (const char **) state->current_attrs);
+		} else if (state->level == 4 && state->level_3_node != NULL) {
+			arv_gc_node_add_element (state->level_3_node, state->current_element,
+						 state->current_content->str, (const char **) state->current_attrs);
+		}
 	}
 
 	state->level--;
@@ -202,8 +221,7 @@ arv_gc_parser_characters (void *user_data,
 {
 	ArvGcParserState *state = user_data;
 
-	if (state->current_node != NULL)
-		g_string_append_len (state->current_content, (char *) text, length);
+	g_string_append_len (state->current_content, (char *) text, length);
 }
 
 static void
diff --git a/src/arvgcnode.c b/src/arvgcnode.c
index ec52b60..dc9a49f 100644
--- a/src/arvgcnode.c
+++ b/src/arvgcnode.c
@@ -27,12 +27,23 @@
 
 static GObjectClass *parent_class = NULL;
 
+struct _ArvGcNodePrivate {
+	ArvGc *genicam;
+	char *name;
+	ArvGcNameSpace name_space;
+	char *tooltip;
+	char *description;
+	char *display_name;
+
+	GSList *childs;
+};
+
 const char *
 arv_gc_node_get_name (ArvGcNode *node)
 {
 	g_return_val_if_fail (ARV_IS_GC_NODE (node), NULL);
 
-	return node->name;
+	return node->priv->name;
 }
 
 const char *
@@ -40,7 +51,7 @@ arv_gc_node_get_tooltip (ArvGcNode *node)
 {
 	g_return_val_if_fail (ARV_IS_GC_NODE (node), NULL);
 
-	return node->tooltip;
+	return node->priv->tooltip;
 }
 
 const char *
@@ -48,7 +59,7 @@ arv_gc_node_get_description (ArvGcNode *node)
 {
 	g_return_val_if_fail (ARV_IS_GC_NODE (node), NULL);
 
-	return node->description;
+	return node->priv->description;
 }
 
 const char *
@@ -56,20 +67,20 @@ arv_gc_node_get_display_name (ArvGcNode *node)
 {
 	g_return_val_if_fail (ARV_IS_GC_NODE (node), NULL);
 
-	return node->display_name;
+	return node->priv->display_name;
 }
 
 static void
 _set_attribute (ArvGcNode *node, const char *name, const char *value)
 {
 	if (strcmp (name, "Name") == 0) {
-		g_free (node->name);
-		node->name = g_strdup (value);
+		g_free (node->priv->name);
+		node->priv->name = g_strdup (value);
 	} if (strcmp (name, "NameSpace") == 0) {
 		if (g_strcmp0 (value, "Standard") == 0)
-			node->name_space = ARV_GC_NAME_SPACE_STANDARD;
+			node->priv->name_space = ARV_GC_NAME_SPACE_STANDARD;
 		else
-			node->name_space = ARV_GC_NAME_SPACE_CUSTOM;
+			node->priv->name_space = ARV_GC_NAME_SPACE_CUSTOM;
 	      }
 }
 
@@ -86,14 +97,14 @@ static void
 _add_element (ArvGcNode *node, const char *name, const char *content, const char **attributes)
 {
 	if (strcmp (name, "ToolTip") == 0) {
-		g_free (node->tooltip);
-		node->tooltip = g_strdup (content);
+		g_free (node->priv->tooltip);
+		node->priv->tooltip = g_strdup (content);
 	} else if (strcmp (name, "Description") == 0) {
-		g_free (node->description);
-		node->description = g_strdup (content);
+		g_free (node->priv->description);
+		node->priv->description = g_strdup (content);
 	} else if (strcmp (name, "DisplayName") == 0) {
-		g_free (node->display_name);
-		node->display_name = g_strdup (content);
+		g_free (node->priv->display_name);
+		node->priv->display_name = g_strdup (content);
 	}
 }
 
@@ -109,6 +120,23 @@ arv_gc_node_add_element (ArvGcNode *node, const char *name, const char *content,
 	ARV_GC_NODE_GET_CLASS (node)->add_element (node, name, content, attributes);
 }
 
+void
+arv_gc_node_add_child (ArvGcNode *node, ArvGcNode *child)
+{
+	g_return_if_fail (ARV_IS_GC_NODE (node));
+	g_return_if_fail (ARV_IS_GC_NODE (child));
+
+	node->priv->childs = g_slist_append (node->priv->childs, child);
+}
+
+const GSList *
+arv_gc_node_get_childs (ArvGcNode *node)
+{
+	g_return_val_if_fail (ARV_IS_GC_NODE (node), NULL);
+
+	return node->priv->childs;
+}
+
 ArvGcNode *
 arv_gc_node_new (void)
 {
@@ -125,7 +153,7 @@ arv_gc_node_set_genicam	(ArvGcNode *node, ArvGc *genicam)
 	g_return_if_fail (ARV_IS_GC_NODE (node));
 	g_return_if_fail (genicam == NULL || ARV_IS_GC (genicam));
 
-	node->genicam = genicam;
+	node->priv->genicam = genicam;
 }
 
 ArvGc *
@@ -133,7 +161,7 @@ arv_gc_node_get_genicam	(ArvGcNode *node)
 {
 	g_return_val_if_fail (ARV_IS_GC_NODE (node), NULL);
 
-	return node->genicam;
+	return node->priv->genicam;
 }
 
 GType
@@ -153,21 +181,29 @@ arv_gc_node_get_value_type (ArvGcNode *node)
 static void
 arv_gc_node_init (ArvGcNode *gc_node)
 {
-	gc_node->name = NULL;
-	gc_node->tooltip = NULL;
-	gc_node->description = NULL;
-	gc_node->display_name = NULL;
+	gc_node->priv = G_TYPE_INSTANCE_GET_PRIVATE (gc_node, ARV_TYPE_GC_NODE, ArvGcNodePrivate);
+
+	gc_node->priv->name = NULL;
+	gc_node->priv->tooltip = NULL;
+	gc_node->priv->description = NULL;
+	gc_node->priv->display_name = NULL;
+	gc_node->priv->childs = NULL;
 }
 
 static void
 arv_gc_node_finalize (GObject *object)
 {
 	ArvGcNode *node = ARV_GC_NODE (object);
+	GSList *iter;
 
-	g_free (node->name);
-	g_free (node->tooltip);
-	g_free (node->description);
-	g_free (node->display_name);
+	for (iter = node->priv->childs; iter != NULL; iter = iter->next)
+		g_object_unref (iter->data);
+	g_slist_free (node->priv->childs);
+
+	g_free (node->priv->name);
+	g_free (node->priv->tooltip);
+	g_free (node->priv->description);
+	g_free (node->priv->display_name);
 
 	parent_class->finalize (object);
 }
@@ -177,6 +213,8 @@ arv_gc_node_class_init (ArvGcNodeClass *node_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (node_class);
 
+	g_type_class_add_private (node_class, sizeof (ArvGcNodePrivate));
+
 	parent_class = g_type_class_peek_parent (node_class);
 
 	object_class->finalize = arv_gc_node_finalize;
diff --git a/src/arvgcnode.h b/src/arvgcnode.h
index 3f06c55..e31cda1 100644
--- a/src/arvgcnode.h
+++ b/src/arvgcnode.h
@@ -34,17 +34,13 @@ G_BEGIN_DECLS
 #define ARV_IS_GC_NODE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), ARV_TYPE_GC_NODE))
 #define ARV_GC_NODE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), ARV_TYPE_GC_NODE, ArvGcNodeClass))
 
+typedef struct _ArvGcNodePrivate ArvGcNodePrivate;
 typedef struct _ArvGcNodeClass ArvGcNodeClass;
 
 struct _ArvGcNode {
 	GObject	object;
 
-	ArvGc *genicam;
-	char *name;
-	ArvGcNameSpace name_space;
-	char *tooltip;
-	char *description;
-	char *display_name;
+	ArvGcNodePrivate *priv;
 };
 
 struct _ArvGcNodeClass {
@@ -68,6 +64,8 @@ const char *	arv_gc_node_get_description		(ArvGcNode *node);
 void		arv_gc_node_set_attribute 		(ArvGcNode *node, const char *name, const char *value);
 void 		arv_gc_node_add_element 		(ArvGcNode *node, const char *name, const char *content,
 							 const char **attributes);
+void 		arv_gc_node_add_child 			(ArvGcNode *node, ArvGcNode *child);
+const GSList *	arv_gc_node_get_childs 			(ArvGcNode *node);
 
 G_END_DECLS
 



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