[asterisk-commits] eliel: branch group/data_api_gsoc2009 r203597 - in /team/group/data_api_gsoc2...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jun 25 22:29:28 CDT 2009


Author: eliel
Date: Thu Jun 25 22:29:24 2009
New Revision: 203597

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=203597
Log:
Implement a first idea about iterators.


Modified:
    team/group/data_api_gsoc2009/include/asterisk/data.h
    team/group/data_api_gsoc2009/main/data.c

Modified: team/group/data_api_gsoc2009/include/asterisk/data.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/include/asterisk/data.h?view=diff&rev=203597&r1=203596&r2=203597
==============================================================================
--- team/group/data_api_gsoc2009/include/asterisk/data.h (original)
+++ team/group/data_api_gsoc2009/include/asterisk/data.h Thu Jun 25 22:29:24 2009
@@ -89,6 +89,9 @@
 
 /*! \brief opaque definition of an ast_data handler, a tree node. */
 struct ast_data;
+
+/*! \brief opaque definition of an ast_data_iterator handler. */
+struct ast_data_iterator;
 
 typedef struct ast_data *(*ast_data_get_cb)(void);
 typedef int *(*ast_data_put_cb)(void);
@@ -309,7 +312,7 @@
  * \param[in] iterator The iterator created by ast_data_iterator_start.
  * \see ast_data_iterator_start
  */
-struct ast_data *ast_data_iterator_end(struct ast_data_iterator *iterator);
+void ast_data_iterator_end(struct ast_data_iterator *iterator);
 
 /*!
  * \brief Get the next node of the tree.

Modified: team/group/data_api_gsoc2009/main/data.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/main/data.c?view=diff&rev=203597&r1=203596&r2=203597
==============================================================================
--- team/group/data_api_gsoc2009/main/data.c (original)
+++ team/group/data_api_gsoc2009/main/data.c Thu Jun 25 22:29:24 2009
@@ -68,6 +68,16 @@
 	const char *registrar;
 	/*! \brief Node name. */
 	char name[0];
+};
+
+/*! \brief This structure is used by the iterator. */
+struct ast_data_iterator {
+	/*! \brief The internal iterator. */
+	struct ao2_iterator internal_iterator;
+	/*! \brief The last returned node. */
+	struct ast_data *last;
+	/*! \brief The iterator pattern. */
+	const char *pattern;
 };
 
 /*! \brief The asterisk data main content structure. */
@@ -928,6 +938,63 @@
 	ao2_ref(root, -1);
 }
 
+struct ast_data_iterator *ast_data_iterator_init(struct ast_data *tree, const char *elements)
+{
+	struct ast_data_iterator *iterator;
+	struct ao2_iterator i;
+
+	iterator = ast_malloc(sizeof(*iterator));
+	if (!iterator) {
+		return NULL;
+	}
+
+	i = ao2_iterator_init(tree->children, 0);
+
+	iterator->pattern = elements;
+	iterator->last = NULL;
+	iterator->internal_iterator = i;
+
+	return iterator;
+}
+
+void ast_data_iterator_end(struct ast_data_iterator *iterator)
+{
+	if (iterator->last) {
+		ao2_ref(iterator->last, -1);
+	}
+
+	ast_free(iterator);
+}
+
+struct ast_data *ast_data_iterator_next(struct ast_data_iterator *iterator)
+{
+	struct ast_data *res;
+
+	if (iterator->last) {
+		/* release the last retrieved node reference. */
+		ao2_ref(iterator->last, -1);
+	}
+
+	while ((res = ao2_iterator_next(&iterator->internal_iterator))) {
+		if (!iterator->pattern) {
+			/* if there is no node name pattern specified, return
+			 * the next node. */
+			break;
+		}
+		if ((iterator->pattern && !strcasecmp(res->name, iterator->pattern))) {
+			/* if there is a pattern specified, check if this node matches
+			 * the wanted node names. */
+			break;
+		}
+
+		ao2_ref(res, -1);
+	}
+
+	iterator->last = res;
+
+	return res;
+}
+
 /* XXX: test callback */
 static struct ast_data *test_data_provider(void)
 {
@@ -960,17 +1027,22 @@
 /* XXX: test */
 static const struct ast_data_entry test_providers[] = {
 	AST_DATA_ENTRY("asterisk/node1/node11/node111", &test_provider),
-	AST_DATA_ENTRY("asterisk/node1/node11/node112", &test_provider),
-	AST_DATA_ENTRY("asterisk/node1/node11/node113", &test_provider),
+	AST_DATA_ENTRY("asterisk/node1/node12/node121", &test_provider),
+	AST_DATA_ENTRY("asterisk/node1/node13/node131", &test_provider),
+	AST_DATA_ENTRY("asterisk/node1/node14/node141", &test_provider),
+	AST_DATA_ENTRY("asterisk/node1/node14/node142", &test_provider),
+	AST_DATA_ENTRY("asterisk/node1/node15/node151", &test_provider),
+	AST_DATA_ENTRY("asterisk/node1/node15/node152", &test_provider),
 };
 
 /* XXX: test */
 static void runtest(void)
 {
-	struct ast_data *res;
+	struct ast_data *res, *node;
 	struct ast_data_query query = {
 		.path = "asterisk/node1",
 	};
+	struct ast_data_iterator *i;
 	struct ast_xml_doc *doc;
 	FILE *outfile;
 
@@ -978,6 +1050,13 @@
 	ast_data_register_multiple(test_providers, ARRAY_LEN(test_providers));
 
 	res = ast_data_get(&query);
+
+	/* test the iterators */
+	i = ast_data_iterator_init(res, NULL);
+	while ((node = ast_data_iterator_next(i))) {
+		ast_log(LOG_ERROR, "TESTING ITERATOR: %s\n", node->name);
+	}
+	ast_data_iterator_end(i);
 
 	if (res) {
 		ast_data_free(res);




More information about the asterisk-commits mailing list