[asterisk-commits] eliel: branch group/data_api_gsoc2009 r203541 - in /team/group/data_api_gsoc2...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Jun 25 19:53:43 CDT 2009
Author: eliel
Date: Thu Jun 25 19:53:40 2009
New Revision: 203541
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=203541
Log:
Start generating the tree based only in the path.
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=203541&r1=203540&r2=203541
==============================================================================
--- team/group/data_api_gsoc2009/include/asterisk/data.h (original)
+++ team/group/data_api_gsoc2009/include/asterisk/data.h Thu Jun 25 19:53:40 2009
@@ -204,10 +204,10 @@
/*!
* \brief Release the allocated memory of a tree.
- * \param[in] obj The sub-tree pointer returned by a call to ast_data_get.
+ * \param[in] root The sub-tree pointer returned by a call to ast_data_get.
* \see ast_data_get
*/
-void ast_data_free(void *obj);
+void ast_data_free(struct ast_data *root);
/*!
* \brief Allocate a 'data' node structure.
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=203541&r1=203540&r2=203541
==============================================================================
--- team/group/data_api_gsoc2009/main/data.c (original)
+++ team/group/data_api_gsoc2009/main/data.c Thu Jun 25 19:53:40 2009
@@ -32,7 +32,8 @@
#include "asterisk/data.h"
#include "asterisk/astobj2.h"
-#define NUM_DATA_NODE_BUCKETS 60
+#define NUM_DATA_NODE_BUCKETS 60
+#define NUM_DATA_RESULT_BUCKETS 60
/*! \brief The data tree to be returned by the callbacks and
managed by functions local to this file. */
@@ -442,7 +443,8 @@
res = __ast_data_register(data_entries[i].path, data_entries[i].handler,
registrar);
if (res) {
- /* unregister all the already registered nodes, and make this action atomic. */
+ /* unregister all the already registered nodes, and make
+ * this an atomic atomic. */
while ((--i) >= 0) {
__ast_data_unregister(data_entries[i].path, registrar);
}
@@ -479,13 +481,28 @@
*/
static void data_result_destructor(void *obj)
{
- struct ast_data *node = obj;
-
- if (node->type == AST_DATA_STRING) {
- /* If there is a string in the node, release the
- * used memory to store it. */
- ast_free(node->payload.str);
- }
+ struct ast_data *child, *root = obj;
+ struct ao2_iterator i;
+
+ switch (root->type) {
+ case AST_DATA_POINTER:
+ case AST_DATA_STRING:
+ ast_free(root->payload.ptr);
+ break;
+ case AST_DATA_CONTAINER:
+ i = ao2_iterator_init(root->children, 0);
+
+ while ((child = ao2_iterator_next(&i))) {
+ ao2_unlink(root->children, child);
+ ao2_ref(child, -1);
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ ast_free(root);
}
static struct ast_data *data_result_create(const char *name)
@@ -497,6 +514,14 @@
res = ao2_alloc(sizeof(*res) + namelen, data_result_destructor);
if (!res) {
+ return NULL;
+ }
+
+ /* initialize the children container */
+ res->children = ao2_container_alloc(NUM_DATA_RESULT_BUCKETS, data_result_hash,
+ data_result_cmp);
+ if (!res->children) {
+ ao2_ref(res, -1);
return NULL;
}
@@ -525,6 +550,7 @@
found = ao2_find(root->children, find_node, OBJ_POINTER);
+ /* release the temporary created node used for searching. */
ao2_ref(find_node, -1);
return found;
@@ -579,12 +605,14 @@
/*!
* \internal
* \brief
+ * \param[in] query
* \param[in] root_provider
* \param[in] parent_node_name
* \retval NULL on error.
* \retval non-NULL The generated result tree.
*/
-static struct ast_data *data_result_generate_node(struct data_provider *root_provider,
+static struct ast_data *data_result_generate_node(const struct ast_data_query *query,
+ const struct data_provider *root_provider,
const char *parent_node_name)
{
struct ast_data *generated, *node;
@@ -598,7 +626,7 @@
}
/* if this is a terminal node, just run the callback function. */
- if (root_provider->handler->get) {
+ if (root_provider->handler && root_provider->handler->get) {
generated = root_provider->handler->get();
if (generated) {
data_result_add_child(node, generated);
@@ -610,7 +638,7 @@
/* if this is not a terminal node, generate every child node. */
i = ao2_iterator_init(root_provider->children, 0);
while ((provider = ao2_iterator_next(&i))) {
- generated = data_result_generate_node(provider, provider->name);
+ generated = data_result_generate_node(query, provider, provider->name);
if (generated) {
data_result_add_child(node, generated);
}
@@ -623,14 +651,56 @@
/*!
* \internal
* \brief Generate a result tree based on a query.
- * \param[in] query The query used to generate the tree.
+ * \param[in] query The complete query structure.
+ * \param[in] search_path The path to retrieve.
* \retval NULL on error.
* \retval non-NULL The generated data result.
*/
-static struct ast_data *data_result_generate(const struct ast_data_query *query)
-{
- /* parse the query, and generate the syntax */
- return NULL;
+static struct ast_data *data_result_generate(const struct ast_data_query *query, const char *search_path)
+{
+ char *node_name, *tmp_path;
+ struct data_provider *provider_child, *tmp_provider_child;
+ struct ast_data *result;
+
+ if (!search_path) {
+ /* generate all the trees?. */
+ return NULL;
+ }
+
+ tmp_path = ast_strdupa(search_path);
+ if (!tmp_path) {
+ return NULL;
+ }
+
+ /* start searching the root node name */
+ node_name = next_node_name(&tmp_path);
+ provider_child = data_provider_find(root_data, node_name, NULL);
+
+ /* continue with the rest of the path. */
+ while (provider_child) {
+ node_name = next_node_name(&tmp_path);
+ if (!node_name) {
+ break;
+ }
+
+ tmp_provider_child = data_provider_find(provider_child->children, node_name, NULL);
+
+ /* release the reference from this child */
+ ao2_ref(provider_child, -1);
+
+ provider_child = tmp_provider_child;
+ }
+
+ if (!provider_child) {
+ ast_log(LOG_ERROR, "Invalid path '%s', '%s' not found.\n", tmp_path, node_name);
+ return NULL;
+ }
+
+ result = data_result_generate_node(query, provider_child, provider_child->name);
+
+ ao2_ref(provider_child, -1);
+
+ return result;
}
struct ast_data *ast_data_get(const struct ast_data_query *query)
@@ -638,7 +708,7 @@
struct ast_data *res;
data_read_lock();
- res = data_result_generate(query);
+ res = data_result_generate(query, query->path);
data_unlock();
if (!res) {
@@ -670,6 +740,8 @@
* \param name
* \param type
* \param ptr
+ * \retval NULL on error.
+ * \retval non-NULL The added child node pointer.
*/
static struct ast_data *__ast_data_add(struct ast_data *root, const char *name,
enum ast_data_type type, void *ptr)
@@ -677,10 +749,12 @@
struct ast_data *node;
size_t namelen = 1 + (ast_strlen_zero(name) ? 0 : strlen(name));
- if ((!root->children &&
- !(root->children = ao2_container_alloc(NUM_DATA_NODE_BUCKETS,
- data_result_hash, data_result_cmp))) ||
- !(node = ao2_alloc(sizeof(*node) + namelen, ast_data_free))) {
+ if (!root || !root->children) {
+ /* invalid data result node. */
+ return NULL;
+ }
+
+ if (!(node = ao2_alloc(sizeof(*node) + namelen, data_result_destructor))) {
return NULL;
}
@@ -764,35 +838,10 @@
return data_result_create(name);
}
-/*!
- * \brief Destroy an ast_data structure
- * \param[in] obj ast_data object
- */
-void ast_data_free(void *obj)
-{
- struct ast_data *root = obj;
- struct ao2_iterator i;
- struct ast_data *child;
-
- switch (root->type) {
- case AST_DATA_POINTER:
- case AST_DATA_STRING:
- ast_free(root->payload.ptr);
- break;
-
- case AST_DATA_CONTAINER:
- i = ao2_iterator_init(root->children, 0);
-
- while ((child = ao2_iterator_next(&i))) {
- ao2_ref(child, -2);
- }
-
- break;
-
- default: break;
- }
-
- ast_free(root);
+void ast_data_free(struct ast_data *root)
+{
+ /* destroy it, this will destroy all the internal nodes. */
+ ao2_ref(root, -1);
}
/* XXX: test callback */
@@ -818,9 +867,20 @@
/* XXX: test */
static void runtest(void)
{
+ struct ast_data *res;
+ struct ast_data_query query = {
+ .path = "asterisk/node1",
+ };
/* some tests */
ast_data_register_multiple(test_providers, ARRAY_LEN(test_providers));
+
+ res = ast_data_get(&query);
+
+ if (res) {
+ ast_data_free(res);
+ }
+
ast_data_unregister(NULL);
}
More information about the asterisk-commits
mailing list