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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Apr 1 23:16:40 CDT 2009


Author: eliel
Date: Wed Apr  1 23:16:36 2009
New Revision: 185949

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=185949
Log:
More work on the data get API.
- Generate the xml node.
- Create the minimal API to be used in callbacks for inserting nodes, etc.

Modified:
    team/eliel/data_retrieval/include/asterisk/data.h
    team/eliel/data_retrieval/include/asterisk/xml.h
    team/eliel/data_retrieval/main/data.c
    team/eliel/data_retrieval/main/xml.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=185949&r1=185948&r2=185949
==============================================================================
--- team/eliel/data_retrieval/include/asterisk/data.h (original)
+++ team/eliel/data_retrieval/include/asterisk/data.h Wed Apr  1 23:16:36 2009
@@ -26,6 +26,14 @@
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
+
+/*! \brief Possible node content types. */
+enum ast_data_type {
+	AST_DATA_TYPE_CONTAINER,
+	AST_DATA_TYPE_UINTEGER,
+	AST_DATA_TYPE_STRING,
+	AST_DATA_TYPE_BOOLEAN
+};
 
 /*! \brief opaque definition of an ast_data handler. */
 struct ast_data;
@@ -62,6 +70,14 @@
 struct ast_data *ast_data_get(const char *path);
 
 /*!
+ * \brief Get the node content type.
+ * \param handler The returned ast_data handler.
+ * \param path The path to the node.
+ * \see ast_data_get
+ */
+enum ast_data_type ast_data_get_type(struct ast_data *handler, const char *path);
+
+/*!
  * \brief Release the ast_data structure.
  * \param data Which data handler to release.
  * \see ast_data_get
@@ -92,6 +108,44 @@
  */
 unsigned char ast_data_get_bool(struct ast_data *handler, const char *path);
 
+/*!
+ * \brief Create a data handler.
+ * \param name The root node name.
+ * \retval NULL on error.
+ * \retval The allocated ast_data structure.
+ */
+struct ast_data_node *ast_data_result(const char *name);
+
+/*!
+ * \brief Insert a node named 'path' with the string value 'value'.
+ * \param handler
+ * \param path
+ * \param value
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_data_insert_str(struct ast_data_node *handler, const char *path, const char *value);
+
+/*!
+ * \brief Insert a node named 'path' with the unsigned integer value 'value'.
+ * \param handler
+ * \param path
+ * \param value
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_data_insert_uint(struct ast_data_node *handler, const char *path, unsigned int value);
+
+/*!
+ * \brief Insert a node named 'path' with the boolean value 'value'.
+ * \param handler
+ * \param path
+ * \param value
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_data_insert_bool(struct ast_data_node *handler, const char *path, int value);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Modified: team/eliel/data_retrieval/include/asterisk/xml.h
URL: http://svn.digium.com/svn-view/asterisk/team/eliel/data_retrieval/include/asterisk/xml.h?view=diff&rev=185949&r1=185948&r2=185949
==============================================================================
--- team/eliel/data_retrieval/include/asterisk/xml.h (original)
+++ team/eliel/data_retrieval/include/asterisk/xml.h Wed Apr  1 23:16:36 2009
@@ -124,6 +124,15 @@
  */
 const char *ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname);
 
+/*! \brief Set an attribute to a node.
+ *  \param node In which node we want to insert the attribute.
+ *  \param name The attribute name.
+ *  \param value The attribute value.
+ *  \retval 0 on success.
+ *  \retval -1 on error.
+ */
+int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const char *value);
+
 /*! \brief Find a node element by name.
  *  \param node This is the node starting point.
  *  \param name Node name to find.
@@ -162,6 +171,9 @@
 /*! \brief Get the parent of a specified node. */
 struct ast_xml_node *ast_xml_node_get_parent(struct ast_xml_node *node);
 
+/*! \brief Dump the specified document to a file. */
+int ast_xml_doc_dump_file(FILE *output, struct ast_xml_doc *doc);
+
 /* Features using ast_xml_ */
 #ifdef HAVE_LIBXML2
 #define AST_XML_DOCS

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=185949&r1=185948&r2=185949
==============================================================================
--- team/eliel/data_retrieval/main/data.c (original)
+++ team/eliel/data_retrieval/main/data.c Wed Apr  1 23:16:36 2009
@@ -293,45 +293,49 @@
 
 /*!
  * \internal
- * \brief Generate a node with the result given a path, the generated node will be linked to
+ * \brief Generate a node with the result, the generated node will be linked to
  * the parent node when this function returns.
  * \param parent The parent node (root_data is the main parent node)
- * \param path Which is the node do you want?
+ * \param parent_node_name The parents node name.
  * \retval NULL on error.
  * \retval A node with the generated xml result.
  * \see root_data
  */
-static struct ast_xml_node *data_xml_node_retrieve(struct ao2_container *parent, const char *path)
-{
-	char *rpath, *node_name;
-	struct ast_xml_node *node, *generated;
-	struct data_node *child;
-
-	rpath = strdupa(path);
-	if (!rpath) {
-		return NULL;
-	}
-
-	node_name = next_node_name(&rpath);
-	if (!node_name) {
-		return NULL;
-	}
-
-	node = ast_xml_new_node(node_name);
-
-	child = data_find_child(parent, node_name);
-	if (!child) {
+static struct ast_xml_node *data_xml_node_retrieve(struct data_node *parent, const char *parent_node_name)
+{
+	struct ast_xml_node *generated, *node;
+	struct ao2_iterator i;
+	struct data_node *dnode;
+
+	/* if this is a terminal node, just run the callback function. */
+	if (parent->read) {
+		node = ast_xml_new_node(parent_node_name);
+		if (!node) {
+			ast_log(LOG_ERROR, "Unable to allocate an xml node '%s'\n", parent_node_name);
+			return NULL;
+		}
+		generated = (struct ast_xml_node *) parent->read();
+		if (generated) {
+			ast_xml_add_child(node, generated);
+		}
+
 		return node;
 	}
 
-	if (!child->read) {
-		generated = data_xml_node_retrieve(child->children, rpath);
-	} else {
-		generated = (struct ast_xml_node *) child->read();
-	}
-
-	if (generated) {
-		ast_xml_add_child(node, generated);
+	node = ast_xml_new_node(parent_node_name);
+	if (!node) {
+		ast_log(LOG_ERROR, "Unable to allocate an xml node '%s'\n", parent_node_name);
+		return NULL;
+	}
+
+	/* if this is not a terminal node, generate every child node. */
+	i = ao2_iterator_init(parent->children, 0);
+	while ((dnode = ao2_iterator_next((&i)))) {
+		generated = data_xml_node_retrieve(dnode, dnode->name);
+		ao2_ref(dnode, -1);
+		if (generated) {
+			ast_xml_add_child(node, generated);
+		}
 	}
 
 	return node;
@@ -349,6 +353,39 @@
 {
 	struct ast_xml_doc *doc;
 	struct ast_xml_node *root_node;
+	struct data_node *child = NULL;
+	char *rpath, *node_name;
+
+	if (!path) {
+		return NULL;
+	}
+
+	rpath = strdupa(path);
+	if (!rpath) {
+		ast_log(LOG_ERROR, "Unable to duplicate the path '%s'\n", path);
+		return NULL;
+	}
+
+	node_name = next_node_name(&rpath);
+	child = data_find_child(root_data, node_name);
+	while (node_name) {
+		node_name = next_node_name(&rpath);
+		if (!node_name) {
+			break;
+		}
+		child = data_find_child(child->children, node_name);
+	}
+
+	if (!child) {
+		ast_log(LOG_ERROR, "Invalid path '%s'\n", path);
+		return NULL;
+	}
+
+	root_node = data_xml_node_retrieve(child, child->name);
+	if (!root_node) {
+		ast_log(LOG_ERROR, "We couldn't retrieve data from '%s'\n", path);
+		return NULL;
+	}
 
 	doc = ast_xml_new();
 	if (!doc) {
@@ -356,15 +393,65 @@
 		return NULL;
 	}
 
-	root_node = data_xml_node_retrieve(root_data, path);
-	if (!root_node) {
-		ast_xml_close(doc);
-		return NULL;
-	}
-
 	ast_xml_set_root(doc, root_node);
 
 	return doc;
+}
+
+/*!
+ * \internal
+ * \brief Create xml nodes based on the path.
+ * \param doc The xml document.
+ * \param path The path of nodes to create.
+ * \retval NULL on error.
+ * \retval A pointer to the last allocated node.
+ */
+static struct ast_xml_node *data_xml_node_create(struct ast_data_node *root_node, const char *path)
+{
+	struct ast_xml_node *node, *child;
+	char *rpath, *node_name;
+
+	if (!root_node || !path) {
+		return NULL;
+	}
+
+	rpath = ast_strdupa(path);
+	if (!rpath) {
+		return NULL;
+	}
+
+	node_name = next_node_name(&rpath);
+	if (!node_name) {
+		/* nothing to do. */
+		return NULL;
+	}
+
+	/* check the name and continue. */
+	if (strcasecmp(ast_xml_node_get_name((struct ast_xml_node *) root_node), node_name)) {
+		ast_log(LOG_ERROR, "Invalid path, you already have a root node named %s\n",
+				ast_xml_node_get_name((struct ast_xml_node *) root_node));
+		return NULL;
+	}
+	node = (struct ast_xml_node *) root_node;
+
+	node_name = next_node_name(&rpath);
+	while (node_name) {
+		/* TODO: Check node types and do not go inside of a node that is not a CONTAINER */
+		child = ast_xml_find_element(ast_xml_node_get_children(node), node_name, NULL, NULL);
+		if (!child) {
+			/* create the missing node. */
+			child = ast_xml_new_node(node_name);
+			if (!child) {
+				ast_log(LOG_ERROR, "Unable to allocate node '%s'\n", node_name);
+				return NULL;
+			}
+			ast_xml_add_child(node, child);
+		}
+		node = child;
+		node_name = next_node_name(&rpath);
+	}
+
+	return node;
 }
 
 int ast_data_register(const char *path, ast_data_cb read_handler)
@@ -417,6 +504,30 @@
 	return ret;
 }
 
+enum ast_data_type ast_data_get_type(struct ast_data *handler, const char *path)
+{
+	/* TODO */
+	return 0;
+}
+
+unsigned int ast_data_get_uint(struct ast_data *handler, const char *path)
+{
+	/* TODO */
+	return 0;
+}
+
+char *ast_data_get_str(struct ast_data *handler, const char *path)
+{
+	/* TODO */
+	return NULL;
+}
+
+unsigned char ast_data_get_bool(struct ast_data *handler, const char *path)
+{
+	/* TODO */
+	return 0;
+}
+
 struct ast_data *ast_data_get(const char *path)
 {
 	struct ast_xml_doc *doc;
@@ -442,29 +553,130 @@
 	}
 }
 
+struct ast_data_node *ast_data_result(const char *name)
+{
+	struct ast_xml_node *node;
+
+	if (!name) {
+		return NULL;
+	}
+
+	node = ast_xml_new_node(name);
+
+	return (struct ast_data_node *) node;
+}
+
+int ast_data_insert_str(struct ast_data_node *handler, const char *path, const char *value)
+{
+	struct ast_xml_node *node;
+
+	if (!value) {
+		ast_log(LOG_ERROR, "You must insert a value\n");
+		return -1;
+	}
+
+	node = data_xml_node_create(handler, path);
+	if (!node) {
+		ast_log(LOG_ERROR, "We couldn't create the path of nodes '%s'\n", path);
+		return -1;
+	}
+
+	/* set the node type. */
+	if (ast_xml_set_attribute(node, "type", "str")) {
+		ast_log(LOG_ERROR, "Unable to set the node type\n");
+		ast_xml_free_node(node);
+		return -1;
+	}
+
+	ast_xml_set_text(node, value);
+
+	return 0;
+}
+
+int ast_data_insert_uint(struct ast_data_node *handler, const char *path, unsigned int value)
+{
+	struct ast_xml_node *node;
+	char tmpbuf[32];
+
+	node = data_xml_node_create(handler, path);
+	if (!node) {
+		ast_log(LOG_ERROR, "We couldn't create the path of nodes '%s'\n", path);
+		return -1;
+	}
+
+	/* set the node type. */
+	if (ast_xml_set_attribute(node, "type", "uint")) {
+		ast_log(LOG_ERROR, "Unable to set the node type\n");
+		ast_xml_free_node(node);
+		return -1;
+	}
+
+	snprintf(tmpbuf, sizeof(tmpbuf), "%u", value);
+
+	ast_xml_set_text(node, tmpbuf);
+
+	return 0;
+}
+
+int ast_data_insert_bool(struct ast_data_node *handler, const char *path, int value)
+{
+	struct ast_xml_node *node;
+	char tmpbuf[32];
+
+	node = data_xml_node_create(handler, path);
+	if (!node) {
+		ast_log(LOG_ERROR, "We couldn't create the path of nodes '%s'\n", path);
+		return -1;
+	}
+
+	/* set the node type. */
+	if (ast_xml_set_attribute(node, "type", "bool")) {
+		ast_log(LOG_ERROR, "Unable to set the node type\n");
+		ast_xml_free_node(node);
+		return -1;
+	}
+
+	snprintf(tmpbuf, sizeof(tmpbuf), "%s", (value ? "true" : "false"));
+
+	ast_xml_set_text(node, tmpbuf);
+
+	return 0;
+}
+
 static struct ast_data_node *test_data_provider(void)
 {
-	struct ast_xml_node *node;
-
-	node = ast_xml_new_node("jojo");
-
-	return (struct ast_data_node *) node;
+	struct ast_data_node *res;
+
+	res = ast_data_result("eliel");
+
+	ast_data_insert_uint(res, "eliel/canaan/sardanons", 26);
+	ast_data_insert_str(res, "eliel/pruebastr", "test string");
+
+	return res;
 }
 
 int ast_data_init(void)
 {
+	FILE *out;
+	struct ast_data *res;
+
 	ast_rwlock_init(&root_data_lock);
 
 	if (!(root_data = ao2_container_alloc(NUM_DATA_NODE_BUCKETS, data_node_hash, data_node_cmp))) {
 		return -1;
 	}
 
-	ast_data_register("asterisk/pepe/prueba", test_data_provider);
-
-	ast_data_unregister("asterisk/pepe/prueba");
-
-	ast_data_register("asterisk/pepe/prueba", test_data_provider);
-	ast_data_unregister("asterisk/pepe/prueba");
-
-	return 0;
-}
+	/* some tests */
+	ast_data_register("asterisk/pepe/jose/prueba", test_data_provider);
+	ast_data_register("asterisk/pepe/jojojo/pepepe/prueba222", test_data_provider);
+
+	res = ast_data_get("asterisk");
+
+	out = fopen("/tmp/xmltest", "w+");
+	ast_xml_doc_dump_file(out, (struct ast_xml_doc *)res);
+	fclose(out);
+
+	ast_data_free(res);
+
+	return 0;
+}

Modified: team/eliel/data_retrieval/main/xml.c
URL: http://svn.digium.com/svn-view/asterisk/team/eliel/data_retrieval/main/xml.c?view=diff&rev=185949&r1=185948&r2=185949
==============================================================================
--- team/eliel/data_retrieval/main/xml.c (original)
+++ team/eliel/data_retrieval/main/xml.c Wed Apr  1 23:16:36 2009
@@ -177,6 +177,19 @@
 	attrvalue = xmlGetProp((xmlNode *) node, (xmlChar *) attrname);
 
 	return (const char *) attrvalue;
+}
+
+int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const char *value)
+{
+	if (!name || !value) {
+		return -1;
+	}
+
+	if (!xmlSetProp((xmlNode *) node, (xmlChar *) name, (xmlChar *) value)) {
+		return -1;
+	}
+
+	return 0;
 }
 
 struct ast_xml_node *ast_xml_find_element(struct ast_xml_node *root_node, const char *name, const char *attrname, const char *attrvalue)
@@ -238,6 +251,11 @@
 	xmlNodeSetContent((xmlNode *) node, (const xmlChar *) content);
 }
 
+int ast_xml_doc_dump_file(FILE *output, struct ast_xml_doc *doc)
+{
+	return xmlDocDump(output, (xmlDocPtr)doc);
+}
+
 const char *ast_xml_node_get_name(struct ast_xml_node *node)
 {
 	return (const char *) ((xmlNode *) node)->name;




More information about the asterisk-commits mailing list