[svn-commits] eliel: branch eliel/data_retrieval r191623 - in /team/eliel/data_retrieval: i...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri May 1 17:10:15 CDT 2009


Author: eliel
Date: Fri May  1 17:09:55 2009
New Revision: 191623

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=191623
Log:
After discussing with Tilghman Lesher part of the DATA API design,
start writing some code, removing every code related to XML.

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=191623&r1=191622&r2=191623
==============================================================================
--- team/eliel/data_retrieval/include/asterisk/data.h (original)
+++ team/eliel/data_retrieval/include/asterisk/data.h Fri May  1 17:09:55 2009
@@ -67,34 +67,28 @@
 extern "C" {
 #endif
 
-/*! \brief Possible node content types. */
-enum ast_data_type {
-	AST_DATA_TYPE_CONTAINER,
-	AST_DATA_TYPE_LONG,
-	AST_DATA_TYPE_STRING,
-	AST_DATA_TYPE_BOOLEAN,
-	AST_DATA_TYPE_UNKNOWN
-};
-
 /*! \brief opaque definition of an ast_data handler. */
 struct ast_data;
 /*! \brief opaque definition of an ast_data_node result. */
 struct ast_data_node;
-/*! \brief opaque definition of an ast_data_iterator */
-struct ast_data_iterator;
 
-typedef struct ast_data_node *(*ast_data_cb)(void);
+typedef struct ast_data_node *(*ast_data_read_cb)(void);
+
+/*! \brief The structure of the node handler. */
+struct ast_data_handler {
+	ast_data_read_cb read;
+};
 
 /*!
  * \brief Register a data provider.
  * \param[in] path The path of the node to register.
- * \param[in] handler The function used to generate the content of the
- *                node being registered.
+ * \param[in] handler The structure defining this node handler. 
  * \see ast_data_unregister
  * \retval < 0 on error.
  * \retval 0 on success.
  */
-int ast_data_register(const char *path, ast_data_cb handler);
+int __ast_data_register(const char *path, const struct ast_data_handler *handler, const char *registrar);
+#define ast_data_register(path, handler) __ast_data_register(path, handler, __FILE__)
 
 /*!
  * \brief Unregister a data provider.
@@ -103,137 +97,8 @@
  * \retval < 0 on error.
  * \retval 0 on success.
  */
-int ast_data_unregister(const char *path);
-
-/*!
- * \brief Retrieve data from the specified path.
- * \param[in] path What data to get.
- * \retval NULL if no data was found on the specified node.
- * \retval A dynamically allocated structure with the data you asked for.
- * \see ast_data_free
- */
-struct ast_data *ast_data_get(const char *path);
-
-/*!
- * \brief Get the node content type.
- * \param[in] handler The returned ast_data handler.
- * \param[in] path The path to the node.
- * \see ast_data_get
- * \returns The type of the node pointed by 'path'.
- */
-enum ast_data_type ast_data_get_type(struct ast_data *handler, const char *path);
-
-/*!
- * \brief Release the ast_data structure.
- * \param[in] data Which data handler to release.
- * \see ast_data_get
- */
-void ast_data_free(struct ast_data *data);
-
-/*!
- * \brief Get a long from a node.
- * \param[in] handler The ast_data handler.
- * \param[in] path Which node's content to get.
- * \see ast_data_get
- * \returns The requested long integer value.
- */
-long ast_data_get_long(struct ast_data *handler, const char *path);
-
-/*!
- * \brief Get a string from a node.
- * \param[in] handler The ast_data handler.
- * \param[in] path Which node's content to get.
- * \see ast_data_get
- * \returns The requested string pointer.
- */
-char *ast_data_get_str(struct ast_data *handler, const char *path);
-
-/*!
- * \brief Get a boolean from a node.
- * \param[in] handler The ast_data handler.
- * \param[in] path Which node's conetent to get.
- * \see ast_data_get
- * \returns The requested boolean.
- */
-unsigned char ast_data_get_bool(struct ast_data *handler, const char *path);
-
-/*!
- * \brief Create a data handler.
- * \param[in] name The root node name.
- * \retval NULL on error.
- * \retval The allocated ast_data_node structure.
- */
-struct ast_data_node *ast_data_result(const char *name);
-
-/*!
- * \brief Free the result structure allocated calling ast_data_result.
- * \param[in] handler The allocated result structure.
- * \see ast_data_result
- */
-void ast_data_result_free(struct ast_data_node *result_handler);
-
-/*!
- * \brief Insert a node named 'path' with the string value 'value'.
- * \param[in] handler The result handler.
- * \param[in] path The path of the node to insert.
- * \param[in] value The content of the node to create.
- * \see ast_data_result
- * \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 long integer value 'value'.
- * \param[in] handler The result handler.
- * \param[in] path The path of the node to insert.
- * \param[in] value The content of the node to create.
- * \see ast_data_result
- * \retval 0 on success.
- * \retval -1 on error.
- */
-int ast_data_insert_long(struct ast_data_node *handler, const char *path,
-	long value);
-
-/*!
- * \brief Insert a node named 'path' with the boolean value 'value'.
- * \param[in] handler The result handler.
- * \param[in] path The path of the node to insert.
- * \param[in] value The content of the node to create.
- * \see ast_data_result
- * \retval 0 on success.
- * \retval -1 on error.
- */
-int ast_data_insert_bool(struct ast_data_node *handler, const char *path, int value);
-
-/*!
- * \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
- * \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.
- * \see ast_data_iterator_start, ast_data_iterator_next
- */
-int ast_data_iterator_stop(struct ast_data_iterator *iterator);
+int __ast_data_unregister(const char *path, const char *registrar);
+#define ast_data_unregister(path) __ast_data_unregister(path, __FILE__)
 
 #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=191623&r1=191622&r2=191623
==============================================================================
--- team/eliel/data_retrieval/main/data.c (original)
+++ team/eliel/data_retrieval/main/data.c Fri May  1 17:09:55 2009
@@ -28,36 +28,24 @@
 #include "asterisk/_private.h"
 #include "asterisk/utils.h"
 #include "asterisk/lock.h"
-#include "asterisk/xml.h"
 #include "asterisk/data.h"
 #include "asterisk/astobj2.h"
 
 #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"
-
 /*! \brief A data container node pointing to the registered handler. */
-struct data_node {
+struct data_node_provider {
 	/*! \brief node content handler. */
-	ast_data_cb read;
+	const struct ast_data_handler *handler;
 	/*! \brief children nodes. */
 	struct ao2_container *children;
-	/*! \brief node name. */
+	/*! \brief Owners of this node. */
+	const char *registrar;
+	/*! \brief Node name. */
 	char name[0];
 };
 
-/*! \brief A data iterator. */
-struct ast_data_iterator {
-	/*! \brief Current data node. */
-	struct ast_xml_node *current;
-	/*! \brief The iterator string. */
-	char path[0];
-};
-
-/*! \brief The asterisk data maint content structure. */
+/*! \brief The asterisk data main content structure. */
 static struct ao2_container *root_data;
 
 /*!
@@ -72,22 +60,21 @@
  * \brief Common string hash function.
  * \see ast_data_init
  */
-static int data_node_hash(const void *obj, const int flags)
-{
-	const struct data_node *node = obj;
+static int data_node_provider_hash(const void *obj, const int flags)
+{
+	const struct data_node_provider *node = obj;
 
 	return ast_str_hash(node->name);
 }
 
 /*!
  * \internal
- * \brief Compare two data_node's.
+ * \brief Compare two data_node_provider's.
  * \see ast_data_init
  */
-static int data_node_cmp(void *obj, void *arg, int flags)
-{
-	struct data_node *node1 = obj;
-	struct data_node *node2 = arg;
+static int data_node_provider_cmp(void *obj, void *arg, int flags)
+{
+	struct data_node_provider *node1 = obj, *node2 = arg;
 
 	return strcasecmp(node1->name, node2->name) ? 0 : CMP_MATCH;
 }
@@ -142,19 +129,17 @@
 
 /*!
  * \internal
- * \brief Create a data node new
- * \param[in] name The node name.
+ * \brief Create a new data node.
+ * \param[in] name The name of the node we are going to create. 
+ * \param[in] handler The handler registered for this node.
+ * \param[in] registrar The name of the registrar.
  * \retval NULL on error.
  * \retval The allocated data node structure.
  */
-static struct data_node *data_node_new(const char *name)
-{
-	struct data_node *node;
+static struct data_node_provider *data_node_provider_new(const char *name, const struct ast_data_handler *handler, const char *registrar)
+{
+	struct data_node_provider *node;
 	size_t namelen;
-
-	if (!name) {
-		return NULL;
-	}
 
 	namelen = strlen(name) + 1;
 
@@ -163,11 +148,13 @@
 		return NULL;
 	}
 
+	node->handler = handler;
+	node->registrar = registrar;
 	strcpy(node->name, name);
 
 	/* initialize the childrens container. */
 	if (!(node->children = ao2_container_alloc(NUM_DATA_NODE_BUCKETS,
-			data_node_hash, data_node_cmp))) {
+			data_node_provider_hash, data_node_provider_cmp))) {
 		ao2_ref(node, -1);
 		return NULL;
 	}
@@ -180,15 +167,17 @@
  * \brief Add a child node named 'name' to the 'parent' node.
  * \param[in] parent Where to add the child node.
  * \param[in] name The name of the child node.
+ * \param[in] handler The handler structure.
+ * \param[in] registrar Who registered this node.
  * \retval NULL on error.
  * \retval A newly allocated child in parent.
  */
-static struct data_node *data_node_add_child(struct ao2_container *parent,
-	const char *name)
-{
-	struct data_node *child;
-
-	child = data_node_new(name);
+static struct data_node_provider *data_node_provider_add_child(struct ao2_container *parent,
+	const char *name, const struct ast_data_handler *handler, const char *registrar)
+{
+	struct data_node_provider *child;
+
+	child = data_node_provider_new(name, handler, registrar);
 	if (!child) {
 		return NULL;
 	}
@@ -203,22 +192,33 @@
  * \brief Find a child node, based on his name.
  * \param[in] parent Where to find the node.
  * \param[in] name The node name to find.
+ * \param[in] registrar Also check if the node was being used by this registrar.
  * \retval NULL if a node wasn't found.
  * \retval The node found.
  * \note Remember to decrement the ref count of the returned node after using it.
  */
-static struct data_node *data_find_child(struct ao2_container *parent, const char *name)
-{
-	struct data_node *find_node, *found;
-
-	find_node = data_node_new(name);
+static struct data_node_provider *data_find_child(struct ao2_container *parent, const char *name, const char *registrar)
+{
+	struct data_node_provider *find_node, *found;
+
+	/* XXX avoid allocating a new data node for searching... */
+	find_node = data_node_provider_new(name, NULL, NULL);
 	if (!find_node) {
 		return NULL;
 	}
 
 	found = ao2_find(parent, find_node, OBJ_POINTER);
 
+	/* free the created node used for searching. */
 	ao2_ref(find_node, -1);
+
+	if (found && found->registrar && registrar) {
+		if (strcmp(found->registrar, registrar)) {
+			/* if the name doesn't match, do not return this node. */
+			ao2_ref(found, -1);
+			return NULL;
+		}
+	}
 
 	return found;
 }
@@ -228,14 +228,15 @@
  * \brief Release a group of nodes.
  * \param[in] parent The parent node.
  * \param[in] path The path of nodes to release.
+ * \param[in] registrar Who registered this node.
  * \retval < 0 on error.
  * \retval 0 on success.
- * \see data_nodes_create
- */
-static int data_nodes_release(struct ao2_container *parent, const char *path)
+ * \see data_node_provider_create
+ */
+static int data_node_provider_release(struct ao2_container *parent, const char *path, const char *registrar)
 {
 	char *node_name, *rpath;
-	struct data_node *child;
+	struct data_node_provider *child;
 	int ret = 0;
 
 	rpath = strdupa(path);
@@ -248,14 +249,14 @@
 		return -1;
 	}
 
-	child = data_find_child(parent, node_name);
+	child = data_find_child(parent, node_name, registrar);
 	if (!child) {
 		return -1;
 	}
 
 	/* if this is not a terminal node. */
-	if (!child->read && rpath) {
-		ret = data_nodes_release(child->children, rpath);
+	if (!child->handler && rpath) {
+		ret = data_node_provider_release(child->children, rpath, registrar);
 	}
 
 	/* if this node is empty, unlink it. */
@@ -273,14 +274,15 @@
  * \brief Create the middle nodes for the specified path (asterisk/testnode1/childnode)
  * \param[in] parent Where to add the middle nodes structure.
  * \param[in] path The path of nodes to add.
+ * \param[in] registrar
  * \retval NULL on error.
  * \retval The created node.
- * \see data_nodes_release
- */
-static struct data_node *data_nodes_create(struct ao2_container *parent, const char *path)
+ * \see data_node_provider_release
+ */
+static struct data_node_provider *data_node_provider_create(struct ao2_container *parent, const char *path, const char *registrar)
 {
 	char *rpath, *node_name;
-	struct data_node *child, *ret = NULL;
+	struct data_node_provider *child, *ret = NULL;
 
 	rpath = strdupa(path);
 	if (!rpath) {
@@ -293,14 +295,15 @@
 		return NULL;
 	}
 
-	child = data_find_child(parent, node_name);
+	child = data_find_child(parent, node_name, registrar);
 
 	if (!child) {
-		child = data_node_add_child(parent, node_name);
+		/* nodes without handler are non-terminal nodes. */
+		child = data_node_provider_add_child(parent, node_name, NULL, registrar);
 	}
 
 	if (rpath) {
-		ret = data_nodes_create(child->children, rpath);
+		ret = data_node_provider_create(child->children, rpath, registrar);
 		if (ret) {
 			ao2_ref(child, -1);
 		}
@@ -309,243 +312,9 @@
 	return ret ? ret : child;
 }
 
-/*!
- * \internal
- * \brief Generate a node with the result, the generated node will be linked to
- * the parent node when this function returns.
- * \param[in] parent The parent node (root_data is the main parent node)
- * \param[in] 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 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;
-	}
-
-	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;
-}
-
-/*!
- * \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.
- * \retval NULL on error.
- * \retval An xml document with the generated result.
- */
-static struct ast_xml_node *data_xml_retrieve(const char *path)
-{
-	struct ast_xml_node *root_node, *internal_node;
-	struct data_node *child = NULL;
-	char *rpath, *internal_path, *node_name;
-	int terminal_node = 0;
-
-	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) {
-		if (child->read) {
-			/* this is a terminal node! */
-			terminal_node = 1;
-			break;
-		}
-		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', '%s' not found.\n", path, node_name);
-		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;
-	}
-
-	/* 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;
-}
-
-/*!
- * \internal
- * \brief Create xml nodes based on the path.
- * \param[in] root The xml root node.
- * \param[in] 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,
-		const char *path)
-{
-	struct ast_xml_node *node, *child, *first = NULL, *root_node = (struct ast_xml_node *) root;
-	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(root_node), node_name)) {
-		ast_log(LOG_ERROR, "Invalid path, you already have a root node named %s\n",
-				ast_xml_node_get_name(root_node));
-		return NULL;
-	}
-	node = root_node;
-
-	node_name = next_node_name(&rpath);
-	while (node_name) {
-		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);
-				/* if there was a child node added, free it. */
-				ast_xml_free_node(first);
-				return NULL;
-			}
-			/* save first created and added child node to free it if something goes wrong. */
-			if (!first) {
-				first = child;
-			}
-			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)
-{
-	struct data_node *node;
+int __ast_data_register(const char *path, const struct ast_data_handler *handler, const char *registrar)
+{
+	struct data_node_provider *node;
 
 	if (!path) {
 		return -1;
@@ -554,23 +323,23 @@
 	/* create the node structure for the registered handler. */
 	data_write_lock();
 
-	node = data_nodes_create(root_data, path);
+	node = data_node_provider_create(root_data, path, registrar);
 	if (!node) {
-		ast_log(LOG_ERROR, "Unable to create the specified path (%s).\n", path);
+		ast_log(LOG_ERROR, "Unable to create the specified path (%s) for '%s'.\n", path, registrar);
 		data_unlock();
 		return -1;
 	}
 
-	if (ao2_container_count(node->children) || node->read) {
-		ast_log(LOG_ERROR, "The node '%s' was already registered. \
-				We were unable to register %s.\n", node->name, path);
+	if (ao2_container_count(node->children) || node->handler) {
+		ast_log(LOG_ERROR, "The node '%s' was already registered. "
+			"We were unable to register '%s' for registrar '%s'.\n", node->name, path, registrar);
 		ao2_ref(node, -1);
 		data_unlock();
 		return -1;
 	}
 
 	/* add handler to that node. */
-	node->read = read_handler;
+	node->handler = handler;
 
 	ao2_ref(node, -1);
 
@@ -579,337 +348,46 @@
 	return 0;
 }
 
-int ast_data_unregister(const char *path)
+int __ast_data_unregister(const char *path, const char *registrar)
 {
 	int ret;
 
+	/* XXX: if path is NULL, unregister every node that was registered by 'registrar' */
+
 	data_write_lock();
-	ret = data_nodes_release(root_data, path);
+	ret = data_node_provider_release(root_data, path, registrar);
 	data_unlock();
 
 	if (ret) {
-		ast_log(LOG_ERROR, "Unable to unregister %s\n", path);
+		ast_log(LOG_ERROR, "Unable to unregister '%s' for '%s'\n", path, registrar);
 	}
 
 	return ret;
 }
 
-enum ast_data_type ast_data_get_type(struct ast_data *handler, const char *path)
-{
-	struct ast_xml_node *node;
-	const char *attr;
-	enum ast_data_type ret;
-
-	node = data_xml_node_get(handler, path);
-
-	if (!node) {
-		return AST_DATA_TYPE_UNKNOWN;
-	}
-
-	attr = ast_xml_get_attribute(node, "type");
-	if (!attr) {
-		/* if this node, does not have a type attribute, it is because
-		 * this node is a container. */
-		return AST_DATA_TYPE_CONTAINER;
-	}
-	if (!strcmp(attr, DATA_TYPE_STRING)) {
-		ret = AST_DATA_TYPE_STRING;
-	} else if (!strcmp(attr, DATA_TYPE_LONG)) {
-		ret = AST_DATA_TYPE_LONG;
-	} else if (!strcmp(attr, DATA_TYPE_BOOL)) {
-		ret = AST_DATA_TYPE_BOOLEAN;
-	} else {
-		ret = AST_DATA_TYPE_UNKNOWN;
-	}
-
-	ast_xml_free_attr(attr);
-	return ret;
-}
-
-long ast_data_get_long(struct ast_data *handler, const char *path)
-{
-	struct ast_xml_node *node;
-	const char *content;
-	long ret;
-
-	node = data_xml_node_get(handler, path);
-	if (!node) {
-		ast_log(LOG_WARNING, "Invalid node path '%s'\n", path);
-		return 0;
-	}
-
-	content = ast_xml_get_text(node);	
-	if (!content) {
-		ast_log(LOG_ERROR, "Unable to get node '%s' content.\n", path);
-		return 0;
-	}
-
-	ret = atol(content); 
-
-	ast_xml_free_text(content);
-
-	return ret;
-}
-
-char *ast_data_get_str(struct ast_data *handler, const char *path)
-{
-	struct ast_xml_node *node;
-	char *ret;
-	const char *content;
-
-	node = data_xml_node_get(handler, path);
-	if (!node) {
-		ast_log(LOG_WARNING, "Invalid node path '%s'\n", path);
-		return NULL;
-	}
-
-	content = ast_xml_get_text(node);
-	if (!content) {
-		ast_log(LOG_ERROR, "Unable to get node '%s' content.\n", path);
-		return NULL;
-	}
-
-	ret = ast_strdup(content);
-
-	ast_xml_free_text(content);
-
-	return ret;
-}
-
-unsigned char ast_data_get_bool(struct ast_data *handler, const char *path)
-{
-	unsigned char ret;
-	struct ast_xml_node *node;
-	const char *content;
-
-	node = data_xml_node_get(handler, path);
-	if (!node) {
-		ast_log(LOG_WARNING, "Invalid node path '%s'\n", path);
-		return 0;
-	}
-
-	content = ast_xml_get_text(node);
-	if (!content) {
-		ast_log(LOG_ERROR, "Unable to get node '%s' content.\n", path);
-		return 0;
-	}
-
-	ret = ast_true(content);
-
-	ast_xml_free_text(content);
-
-	return ret;
-}
-
-struct ast_data *ast_data_get(const char *path)
-{
-	struct ast_xml_node *res_node;
-
-	data_read_lock();
-	res_node = data_xml_retrieve(path);
-	data_unlock();
-
-	if (!res_node) {
-		ast_log(LOG_ERROR, "Unable to get data from %s\n", path);
-		return NULL;
-	}
-
-	return (struct ast_data *) res_node;
-}
-
-void ast_data_free(struct ast_data *retrieved_data)
-{
-	struct ast_xml_node *root_node = (struct ast_xml_node *) retrieved_data;
-
-	if (root_node) {
-		ast_xml_free_node(root_node);
-	}
-}
-
-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;
-}
-
-void ast_data_result_free(struct ast_data_node *result_handler)
-{
-	ast_xml_free_node((struct ast_xml_node *) result_handler);
-}
-
-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", DATA_TYPE_STRING)) {
-		ast_log(LOG_ERROR, "Unable to set the node type\n");
-		ast_xml_free_node(node);
-		return -1;
-	}
-
-	ast_xml_set_text(node, value);
+static struct ast_data_node *test_data_provider(void)
+{
+	struct ast_data_node *res = NULL;
+
+	return res;
+}
+
+static const struct ast_data_handler test_provider = {
+	.read = test_data_provider
+};
+
+int ast_data_init(void)
+{
+	ast_rwlock_init(&root_data_lock);
+
+	if (!(root_data = ao2_container_alloc(NUM_DATA_NODE_BUCKETS,
+		data_node_provider_hash, data_node_provider_cmp))) {
+		return -1;
+	}
+
+	/* some tests */
+	ast_data_register("asterisk/node1/node11/node111", &test_provider);
+	ast_data_unregister("asterisk/node1/node11/node111");
 
 	return 0;
 }
-
-int ast_data_insert_long(struct ast_data_node *handler, const char *path, long 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", DATA_TYPE_LONG)) {
-		ast_log(LOG_ERROR, "Unable to set the node type\n");
-		ast_xml_free_node(node);
-		return -1;
-	}
-
-	snprintf(tmpbuf, sizeof(tmpbuf), "%ld", 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", DATA_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;
-}
-
-struct ast_data_iterator *ast_data_iterator_start(struct ast_data *data_handler, const char *path)
-{
-	struct ast_xml_node *node;
-	struct ast_data_iterator *iterator;
-
-	node = data_xml_node_get(data_handler, path);
-	if (!node) {
-		return NULL;
-	}
-
-	iterator = ast_calloc(1, sizeof(*iterator) + strlen(path) + 1);
-	if (!iterator) {
-		return NULL;
-	}
-
-	iterator->current = ast_xml_node_get_children(node);
-
-	strcpy(iterator->path, path);
-
-	return iterator;
-}
-
-struct ast_data *ast_data_iterator_next(struct ast_data_iterator *iterator)
-{
-	struct ast_xml_node *next;
-
-	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 *iterator)
-{
-	if (!iterator) {
-		return -1;
-	}
-
-	ast_free(iterator);
-
-	iterator = NULL;
-
-	return 0;
-}
-
-static struct ast_data_node *test_data_provider(void)
-{
-	struct ast_data_node *res;
-
-	res = ast_data_result("eliel");
-
-	ast_data_insert_long(res, "eliel/test1", 26);
-	ast_data_insert_str(res, "eliel/test2", "test string");
-
-	return res;
-}
-
-int ast_data_init(void)
-{
-	struct ast_data *res, *d;
-	struct ast_data_iterator *i;
-
-	ast_rwlock_init(&root_data_lock);
-
-	if (!(root_data = ao2_container_alloc(NUM_DATA_NODE_BUCKETS,
-		data_node_hash, data_node_cmp))) {
-		return -1;
-	}
-
-	/* some tests */
-	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/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, "/"));
-	}
-	ast_data_iterator_stop(i);
-
-	/* end of tests. */
-
-	return 0;
-}




More information about the svn-commits mailing list