[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