[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