[asterisk-commits] eliel: branch eliel/data_retrieval r189602 - in /team/eliel/data_retrieval: i...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 21 09:14:57 CDT 2009


Author: eliel
Date: Tue Apr 21 09:14:54 2009
New Revision: 189602

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=189602
Log:
If the path tell us to get into the generated xml, generate the xml, and continue
walking the path.
Added missing doxygen documentation.


Modified:
    team/eliel/data_retrieval/include/asterisk/data.h
    team/eliel/data_retrieval/main/data.c

Modified: team/eliel/data_retrieval/include/asterisk/data.h
URL: http://svn.digium.com/svn-view/asterisk/team/eliel/data_retrieval/include/asterisk/data.h?view=diff&rev=189602&r1=189601&r2=189602
==============================================================================
--- team/eliel/data_retrieval/include/asterisk/data.h (original)
+++ team/eliel/data_retrieval/include/asterisk/data.h Tue Apr 21 09:14:54 2009
@@ -208,29 +208,32 @@
 int ast_data_insert_bool(struct ast_data_node *handler, const char *path, int value);
 
 /*!
- * \brief Initialize the iterator structure for a path.
- * \param d
- * \param path
+ * \brief Initialize the iterator structure for a specified path.
+ * \param data_handler The data handler. 
+ * \param path The path where we want to start iterating.
+ * \retval NULL on error.
+ * \retval The allocated iterator structure.
+ * \see ast_data_get, ast_data_iterator_next, ast_data_iterator_stop
+ */
+struct ast_data_iterator *ast_data_iterator_start(struct ast_data *data_handler, const char *path);
+
+/*!
+ * \brief Get the next node when iterating.
+ * \param iterator The iterator handler.
  * \retval NULL on error.
  * \retval
- */
-struct ast_data_iterator *ast_data_iterator_start(struct ast_data *d, const char *path);
-
-/*!
- * \brief
- * \param i
- * \retval NULL on error.
- * \retval
- */
-struct ast_data *ast_data_iterator_next(struct ast_data_iterator *i);
-
-/*!
- * \brief
- * \param i
+ * \see ast_data_iterator_start, ast_data_iterator_stop
+ */
+struct ast_data *ast_data_iterator_next(struct ast_data_iterator *iterator);
+
+/*!
+ * \brief Cleanup the iterator structure.
+ * \param iterator The iterator handler.
  * \retval < 0 on error.
  * \retval 0 on success.
- */
-int ast_data_iterator_stop(struct ast_data_iterator *i);
+ * \see ast_data_iterator_start, ast_data_iterator_next
+ */
+int ast_data_iterator_stop(struct ast_data_iterator *iterator);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: team/eliel/data_retrieval/main/data.c
URL: http://svn.digium.com/svn-view/asterisk/team/eliel/data_retrieval/main/data.c?view=diff&rev=189602&r1=189601&r2=189602
==============================================================================
--- team/eliel/data_retrieval/main/data.c (original)
+++ team/eliel/data_retrieval/main/data.c Tue Apr 21 09:14:54 2009
@@ -34,6 +34,7 @@
 
 #define NUM_DATA_NODE_BUCKETS 60
 
+/*! \brief  Define the string added to each node when defining its type. */
 #define DATA_TYPE_LONG		"long"
 #define DATA_TYPE_STRING	"str"
 #define DATA_TYPE_BOOL		"bool"
@@ -361,6 +362,53 @@
 
 /*!
  * \internal
+ * \brief Get the node structure passing a path to it.
+ * \param[in] handler The ast_data handler.
+ * \param[in] path The path of the node.
+ * \retval NULL if the node wasn't found.
+ * \retval The xml node referenced by path.
+ */
+static struct ast_xml_node *data_xml_node_get(struct ast_data *handler, const char *path)
+{
+	struct ast_xml_node *node;
+	char *rpath, *node_name;
+
+	if (!path || !handler) {
+		return NULL;
+	}
+
+	node = (struct ast_xml_node *) handler;
+
+	rpath = ast_strdupa(path);
+	if (!rpath || !node) {
+		return NULL;
+	}
+
+	/* check the root node. */
+	node_name = next_node_name(&rpath);
+	if (!node_name) {
+		return node;
+	}
+
+	if (strcasecmp(ast_xml_node_get_name(node), node_name)) {
+		ast_log(LOG_WARNING, "Invalid path '%s', unknown root node '%s'\n", path, node_name);
+		return NULL;
+	}
+
+	node_name = next_node_name(&rpath);
+	while (node_name && node) {
+		node = ast_xml_find_element(ast_xml_node_get_children(node), node_name, NULL, NULL);
+		if (!node) {
+			ast_log(LOG_ERROR, "Unknown node children: %s\n", node_name);
+		}
+		node_name = next_node_name(&rpath);
+	}
+
+	return node;
+}
+
+/*!
+ * \internal
  * \brief Generate an xml document based on the registered callbacks and the
  * given path.
  * \param[in] path What to get.
@@ -369,9 +417,10 @@
  */
 static struct ast_xml_node *data_xml_retrieve(const char *path)
 {
-	struct ast_xml_node *root_node;
+	struct ast_xml_node *root_node, *internal_node;
 	struct data_node *child = NULL;
-	char *rpath, *node_name;
+	char *rpath, *internal_path, *node_name;
+	int terminal_node = 0;
 
 	if (!path) {
 		return NULL;
@@ -386,6 +435,11 @@
 	node_name = next_node_name(&rpath);
 	child = data_find_child(root_data, node_name);
 	while (node_name) {
+		if (child->read) {
+			/* this is a terminal node! */
+			terminal_node = 1;
+			break;
+		}
 		node_name = next_node_name(&rpath);
 		if (!node_name) {
 			break;
@@ -402,6 +456,26 @@
 	if (!root_node) {
 		ast_log(LOG_ERROR, "We couldn't retrieve data from '%s'\n", path);
 		return NULL;
+	}
+
+	/* we have found a terminal node before walking all the path. */
+	if (terminal_node) {
+		/* re-generate the path, we need the root node also. */
+		internal_path = alloca(strlen(rpath) + strlen(node_name) + 2);
+		if (!internal_path) {
+			ast_log(LOG_ERROR, "Unable to re-generate the internal path\n");
+			ast_xml_free_node(root_node);
+			return NULL;
+		}
+		sprintf(internal_path, "%s/%s", node_name, rpath);
+
+		/* we have to get into another node! (an internal node generated by the callback)  */
+		internal_node = data_xml_node_get((struct ast_data *) root_node, internal_path);
+		if (!internal_node) {
+			ast_log(LOG_ERROR, "Unable to get internal node '%s'\n", rpath);
+			ast_xml_free_node(root_node);
+		}
+		root_node = internal_node;
 	}
 
 	return root_node;
@@ -469,53 +543,6 @@
 	return node;
 }
 
-/*!
- * \internal
- * \brief Get the node structure passing a path to it.
- * \param[in] handler The ast_data handler.
- * \param[in] path The path of the node.
- * \retval NULL if the node wasn't found.
- * \retval The xml node referenced by path.
- */
-static struct ast_xml_node *data_xml_node_get(struct ast_data *handler, const char *path)
-{
-	struct ast_xml_node *node;
-	char *rpath, *node_name;
-
-	if (!path || !handler) {
-		return NULL;
-	}
-
-	node = (struct ast_xml_node *) handler;
-
-	rpath = ast_strdupa(path);
-	if (!rpath || !node) {
-		return NULL;
-	}
-
-	/* check the root node. */
-	node_name = next_node_name(&rpath);
-	if (!node_name) {
-		return node;
-	}
-
-	if (strcasecmp(ast_xml_node_get_name(node), node_name)) {
-		ast_log(LOG_WARNING, "Invalid path '%s', unknown root node '%s'\n", path, node_name);
-		return NULL;
-	}
-
-	node_name = next_node_name(&rpath);
-	while (node_name && node) {
-		node = ast_xml_find_element(ast_xml_node_get_children(node), node_name, NULL, NULL);
-		if (!node) {
-			ast_log(LOG_ERROR, "Unknown node children: %s\n", node_name);
-		}
-		node_name = next_node_name(&rpath);
-	}
-
-	return node;
-}
-
 int ast_data_register(const char *path, ast_data_cb read_handler)
 {
 	struct data_node *node;
@@ -816,32 +843,32 @@
 	return iterator;
 }
 
-struct ast_data *ast_data_iterator_next(struct ast_data_iterator *i)
+struct ast_data *ast_data_iterator_next(struct ast_data_iterator *iterator)
 {
 	struct ast_xml_node *next;
 
-	if (!i) {
-		return NULL;
-	}
-
-	next = i->current;
-
-	if (i->current) {
-		i->current = ast_xml_node_get_next(i->current);
+	if (!iterator) {
+		return NULL;
+	}
+
+	next = iterator->current;
+
+	if (iterator->current) {
+		iterator->current = ast_xml_node_get_next(iterator->current);
 	}
 
 	return (struct ast_data *) next;
 }
 
-int ast_data_iterator_stop(struct ast_data_iterator *i)
-{
-	if (!i) {
-		return -1;
-	}
-
-	ast_free(i);
-
-	i = NULL;
+int ast_data_iterator_stop(struct ast_data_iterator *iterator)
+{
+	if (!iterator) {
+		return -1;
+	}
+
+	ast_free(iterator);
+
+	iterator = NULL;
 
 	return 0;
 }
@@ -874,9 +901,9 @@
 	ast_data_register("asterisk/node1/node11/node111", test_data_provider);
 	ast_data_register("asterisk/node2/node21/node211", test_data_provider);
 
-	res = ast_data_get("asterisk");
-
-	i = ast_data_iterator_start(res, "/asterisk/node1/node11/node111/eliel");
+	res = ast_data_get("asterisk/node1/node11/node111/eliel");
+
+	i = ast_data_iterator_start(res, "eliel");
 	while ((d = ast_data_iterator_next(i))) {
 		ast_log(LOG_ERROR, "Node type = %d\n", ast_data_get_type(d, "/"));
 	}




More information about the asterisk-commits mailing list