[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