[asterisk-commits] eliel: branch group/data_api_gsoc2009 r210474 - in /team/group/data_api_gsoc2...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Aug 4 16:50:34 CDT 2009
Author: eliel
Date: Tue Aug 4 16:50:30 2009
New Revision: 210474
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=210474
Log:
Implement the filtering mechanism, now the nodes being filtered wont be
added to the result tree.
Modified:
team/group/data_api_gsoc2009/apps/app_queue.c
team/group/data_api_gsoc2009/include/asterisk/channel.h
team/group/data_api_gsoc2009/include/asterisk/data.h
team/group/data_api_gsoc2009/main/channel.c
team/group/data_api_gsoc2009/main/data.c
team/group/data_api_gsoc2009/tests/test_data.c
Modified: team/group/data_api_gsoc2009/apps/app_queue.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/apps/app_queue.c?view=diff&rev=210474&r1=210473&r2=210474
==============================================================================
--- team/group/data_api_gsoc2009/apps/app_queue.c (original)
+++ team/group/data_api_gsoc2009/apps/app_queue.c Tue Aug 4 16:50:30 2009
@@ -7540,6 +7540,7 @@
* \param[in] queue The queue to add.
*/
static void queues_data_provider_get_helper(const struct ast_data_search *search,
+ const struct ast_data_filter *filter,
struct ast_data *data_root, struct call_queue *queue)
{
int member_notmatch, caller_notmatch, caller_channel_notmatch;
@@ -7555,12 +7556,12 @@
return;
}
- data_queue = ast_data_add_node(data_root, "queue");
+ data_queue = ast_data_add_node(filter, data_root, "queue");
if (!data_queue) {
return;
}
- ast_data_add_structure(call_queue, data_queue, queue);
+ ast_data_add_structure(filter, call_queue, data_queue, queue);
member_notmatch = ast_data_search_has_condition(search, "queue/members/member");
/* add queue members */
@@ -7573,20 +7574,20 @@
}
if (!data_members) {
- data_members = ast_data_add_node(data_queue, "members");
+ data_members = ast_data_add_node(filter, data_queue, "members");
if (!data_members) {
ao2_ref(member, -1);
continue;
}
}
- data_member = ast_data_add_node(data_members, "member");
+ data_member = ast_data_add_node(filter, data_members, "member");
if (!data_member) {
ao2_ref(member, -1);
continue;
}
- ast_data_add_structure(member, data_member, member);
+ ast_data_add_structure(filter, member, data_member, member);
ao2_ref(member, -1);
}
@@ -7614,26 +7615,26 @@
}
if (!data_callers) {
- data_callers = ast_data_add_node(data_queue, "callers");
+ data_callers = ast_data_add_node(filter, data_queue, "callers");
if (!data_callers) {
continue;
}
}
- data_caller = ast_data_add_node(data_callers, "caller");
+ data_caller = ast_data_add_node(filter, data_callers, "caller");
if (!data_caller) {
continue;
}
- ast_data_add_structure(queue_ent, data_caller, qe);
+ ast_data_add_structure(filter, queue_ent, data_caller, qe);
/* add the caller channel. */
- data_caller_channel = ast_data_add_node(data_caller, "channel");
+ data_caller_channel = ast_data_add_node(filter, data_caller, "channel");
if (!data_caller_channel) {
continue;
}
- ast_channel_data_add_structure(data_caller_channel, qe->chan);
+ ast_channel_data_add_structure(filter, data_caller_channel, qe->chan);
}
}
@@ -7651,6 +7652,7 @@
* \retval non-NULL The generated tree.
*/
static int queues_data_provider_get(const struct ast_data_search *search,
+ const struct ast_data_filter *filter,
struct ast_data *data_root)
{
struct ao2_iterator i;
@@ -7683,7 +7685,7 @@
queue_unref(queue_realtime);
}
- queues_data_provider_get_helper(search, data_root, queue);
+ queues_data_provider_get_helper(search, filter, data_root, queue);
ao2_unlock(queue);
queue_unref(queue);
}
Modified: team/group/data_api_gsoc2009/include/asterisk/channel.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/include/asterisk/channel.h?view=diff&rev=210474&r1=210473&r2=210474
==============================================================================
--- team/group/data_api_gsoc2009/include/asterisk/channel.h (original)
+++ team/group/data_api_gsoc2009/include/asterisk/channel.h Tue Aug 4 16:50:30 2009
@@ -2671,12 +2671,14 @@
/*!
* \brief Insert into an astdata tree, the channel structure.
+ * \param[in] filter The filtering tree.
* \param[in] tree The ast data tree.
* \param[in] chan The channel structure to add to tree.
* \retval <0 on error.
* \retval 0 on success.
*/
-int ast_channel_data_add_structure(struct ast_data *tree, struct ast_channel *chan);
+int ast_channel_data_add_structure(const struct ast_data_filter *filter,
+ struct ast_data *tree, struct ast_channel *chan);
/*!
* \brief Compare to channel structures using the data api.
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=210474&r1=210473&r2=210474
==============================================================================
--- team/group/data_api_gsoc2009/include/asterisk/data.h (original)
+++ team/group/data_api_gsoc2009/include/asterisk/data.h Tue Aug 4 16:50:30 2009
@@ -101,6 +101,9 @@
/*! \brief opaque definition of an ast_data_search structure. */
struct ast_data_search;
+/*! \brief opaque definition of an ast_data_filter structure. */
+struct ast_data_filter;
+
/*! \brief structure retrieved from a node, with the nodes content. */
struct ast_data_retrieve {
enum ast_data_type type;
@@ -118,6 +121,7 @@
};
typedef int (*ast_data_get_cb)(const struct ast_data_search *search,
+ const struct ast_data_filter *filter,
struct ast_data *root);
typedef int *(*ast_data_put_cb)(void);
@@ -431,91 +435,108 @@
/*!
* \brief Add a container child.
+ * \param[in] filter The filtering tree.
* \param[in] root The root of the ast_data to insert into.
* \param[in] childname The name of the child element to be added.
* \retval NULL on error (memory exhaustion only).
* \retval non-NULL a newly allocated node.
*/
-struct ast_data *ast_data_add_node(struct ast_data *root, const char *childname);
+struct ast_data *ast_data_add_node(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname);
/*!
* \brief Add an integer node type.
+ * \param[in] filter The filtering tree.
* \param[in] root The root of the ast_data to insert into.
* \param[in] childname The name of the child element to be added.
* \param[in] value The value for the new node.
* \retval NULL on error (memory exhaustion only).
* \retval non-NULL a newly allocated node.
*/
-struct ast_data *ast_data_add_int(struct ast_data *root, const char *childname,
+struct ast_data *ast_data_add_int(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
int value);
/*!
* \brief Add an unsigned integer node type.
+ * \param[in] filter The filtering tree.
* \param[in] root The root of the ast_data to insert into.
* \param[in] childname The name of the child element to be added.
* \param[in] value The value for the new node.
* \retval NULL on error (memory exhaustion only).
* \retval non-NULL a newly allocated node.
*/
-struct ast_data *ast_data_add_uint(struct ast_data *root, const char *childname,
+struct ast_data *ast_data_add_uint(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
unsigned int value);
/*!
* \brief Add a floating point node type.
+ * \param[in] filter The filtering tree.
* \param[in] root The root of the ast_data to insert into.
* \param[in] childname The name of the child element to be added.
* \param[in] dbl The value for the new node.
* \retval NULL on error (memory exhaustion only).
* \retval non-NULL a newly allocated node.
*/
-struct ast_data *ast_data_add_dbl(struct ast_data *root, const char *childname,
+struct ast_data *ast_data_add_dbl(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
double dbl);
/*!
* \brief Add a ipv4 address type.
+ * \param[in] filter The filtering tree.
* \param[in] root The root of the ast_data to insert into.
* \param[in] childname The name of the child element to be added.
* \param[in] addr The ipv4 address value.
* \retval NULL on error (memory exhaustion only).
* \retval non-NULL a newly allocated node.
*/
-struct ast_data *ast_data_add_ipaddr(struct ast_data *root, const char *childname,
+struct ast_data *ast_data_add_ipaddr(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
struct in_addr addr);
/*!
* \brief Add a ptr node type.
+ * \param[in] filter The filtering tree.
* \param[in] root The root of the ast_data to insert into.
* \param[in] childname The name of the child element to be added.
* \param[in] ptr The pointer value to add.
* \retval NULL on error (memory exhaustion only).
* \retval non-NULL a newly allocated node.
*/
-struct ast_data *ast_data_add_ptr(struct ast_data *root, const char *childname,
+struct ast_data *ast_data_add_ptr(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
void *ptr);
/*!
* \brief Add a string node type.
+ * \param[in] filter The filtering tree.
* \param[in] root The root of the ast_data to insert into.
* \param[in] childname The name of the child element to be added.
* \param[in] value The value for the new node.
* \retval NULL on error (memory exhaustion only).
* \retval non-NULL a newly allocated node.
*/
-struct ast_data *ast_data_add_str(struct ast_data *root, const char *childname,
+struct ast_data *ast_data_add_str(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
const char *string);
/*!
* \brief Add a boolean node type.
+ * \param[in] filter The filtering tree.
* \param[in] root The root of the ast_data to insert into.
* \param[in] childname The name of the child element to be added.
* \param[in] value The value for the new node.
* \retval NULL on error (memory exhaustion only).
* \retval non-NULL a newly allocated node.
*/
-struct ast_data *ast_data_add_bool(struct ast_data *root, const char *childname,
+struct ast_data *ast_data_add_bool(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
unsigned int boolean);
/*!
* \brief Add a complete structure to a node.
+ * \param[in] filter The filtering tree.
* \param[in] root Where to add the structure.
* \param[in] mapping The structure mapping array.
* \param[in] mapping_len The lenght of the mapping array.
@@ -523,11 +544,11 @@
* \retval 0 on success.
* \retval 1 on error.
*/
-int __ast_data_add_structure(struct ast_data *root,
- const struct ast_data_mapping_structure *mapping, size_t mapping_len,
- void *structure);
-#define ast_data_add_structure(structure_name, root, structure) \
- __ast_data_add_structure(root, __data_mapping_structure_##structure_name, \
+int __ast_data_add_structure(const struct ast_data_filter *filter,
+ struct ast_data *root, const struct ast_data_mapping_structure *mapping,
+ size_t mapping_len, void *structure);
+#define ast_data_add_structure(filter, structure_name, root, structure) \
+ __ast_data_add_structure(filter, root, __data_mapping_structure_##structure_name, \
ARRAY_LEN(__data_mapping_structure_##structure_name), structure)
/*!
Modified: team/group/data_api_gsoc2009/main/channel.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/main/channel.c?view=diff&rev=210474&r1=210473&r2=210474
==============================================================================
--- team/group/data_api_gsoc2009/main/channel.c (original)
+++ team/group/data_api_gsoc2009/main/channel.c Tue Aug 4 16:50:30 2009
@@ -257,9 +257,10 @@
return var;
}
-int ast_channel_data_add_structure(struct ast_data *tree, struct ast_channel *chan)
-{
- return ast_data_add_structure(ast_channel, tree, chan);
+int ast_channel_data_add_structure(const struct ast_data_filter *filter,
+ struct ast_data *tree, struct ast_channel *chan)
+{
+ return ast_data_add_structure(filter, ast_channel, tree, chan);
}
int ast_channel_data_cmp_structure(const struct ast_data_search *tree,
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=210474&r1=210473&r2=210474
==============================================================================
--- team/group/data_api_gsoc2009/main/data.c (original)
+++ team/group/data_api_gsoc2009/main/data.c Tue Aug 4 16:50:30 2009
@@ -40,6 +40,7 @@
#define NUM_DATA_NODE_BUCKETS 59
#define NUM_DATA_RESULT_BUCKETS 59
#define NUM_DATA_SEARCH_BUCKETS 59
+#define NUM_DATA_FILTER_BUCKETS 59
/*! \brief The last compatible version. */
static const uint32_t latest_handler_compatible_version = 0;
@@ -75,18 +76,6 @@
char name[0];
};
-struct data_filter_node;
-
-AST_LIST_HEAD(data_filter_list, data_filter_node);
-
-struct data_filter_node {
- /*! \brief The list of filter or search requirements
- ( container of type struct ast_data ) */
- struct data_filter_list children;
- AST_LIST_ENTRY(data_filter_node) next;
- char name[0];
-};
-
/*! \brief Type of comparisons allow in the search string. */
enum data_search_comparison {
DATA_CMP_UNKNOWN,
@@ -102,14 +91,19 @@
struct ast_data_search {
/*! \brief The value of the comparison. */
char *value;
-
/*! \brief The type of comparison. */
enum data_search_comparison cmp_type;
-
/*! \brief reference another node. */
struct ao2_container *children;
-
/*! \brief The name of the node we are trying to compare. */
+ char name[0];
+};
+
+/*! \brief The filter node. */
+struct ast_data_filter {
+ /*! \brief node childrens. */
+ struct ao2_container *children;
+ /*! \brief node name. */
char name[0];
};
@@ -1431,39 +1425,125 @@
/*!
* \internal
- * \brief Destroy a list of data filter nodes.
- * \param[in] Data filter list to be destroyed.
- */
-static void data_filter_list_destroy(struct data_filter_list *flist)
-{
- struct data_filter_node *node;
-
- while ((node = AST_RWLIST_REMOVE_HEAD(flist, next))) {
- data_filter_list_destroy(&(node->children));
- ast_free(node);
- }
-}
-
-/*!
- * \internal
- * \brief
- */
-static struct data_filter_node *data_filter_add_node(struct data_filter_list *flist, char *name)
-{
- struct data_filter_node *node;
-
- AST_LIST_TRAVERSE(flist, node, next) {
- if (!strcasecmp(node->name, name)) {
- return node;
- }
- }
-
- node = ast_calloc(1, sizeof(*node) + strlen(name) + 1);
+ * \brief Common string hash function for data nodes
+ */
+static int data_filter_hash(const void *obj, const int flags)
+{
+ const struct ast_data_filter *node = obj;
+ return ast_str_hash(node->name);
+}
+
+/*!
+ * \internal
+ * \brief Common string comparison function
+ */
+static int data_filter_cmp(void *obj, void *arg, int flags)
+{
+ struct ast_data_filter *node1 = obj, *node2 = arg;
+ return strcasecmp(node1->name, node2->name) ? 0 : CMP_MATCH;
+}
+
+/*!
+ * \internal
+ * \brief Destroy a data filter tree.
+ * \param[in] obj Data filter list to be destroyed.
+ */
+static void data_filter_destructor(void *obj)
+{
+ struct ast_data_filter *filter = obj;
+
+ ao2_ref(filter->children, -1);
+}
+
+/*!
+ * \internal
+ * \brief Allocate a filter node.
+ * \retval NULL on error.
+ * \retval non-NULL The allocated search node structure.
+ */
+static struct ast_data_filter *data_filter_alloc(const char *name)
+{
+ struct ast_data_filter *res;
+ size_t name_len = strlen(name) + 1;
+
+ res = ao2_alloc(sizeof(*res) + name_len, data_filter_destructor);
+ if (!res) {
+ return NULL;
+ }
+
+ res->children = ao2_container_alloc(NUM_DATA_FILTER_BUCKETS, data_filter_hash,
+ data_filter_cmp);
+
+ if (!res) {
+ ao2_ref(res, -1);
+ return NULL;
+ }
+
+ strcpy(res->name, name);
+
+ return res;
+}
+
+/*!
+ * \internal
+ * \brief Release a filter tree.
+ * \param[in] filter The filter tree root node.
+ */
+static void data_filter_release(struct ast_data_filter *filter)
+{
+ ao2_ref(filter, -1);
+}
+
+/*!
+ * \internal
+ * \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.
+ * \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 ast_data_filter *data_filter_find(struct ao2_container *parent,
+ const char *name)
+{
+ struct ast_data_filter *find_node, *found;
+
+ find_node = data_filter_alloc(name);
+ 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);
+
+ return found;
+}
+
+/*!
+ * \internal
+ * \brief Add a child to the specified node.
+ * \param[in] root The root node where to add the child.
+ * \param[in] name The name of the node to add.
+ * \note Remember to decrement the ref count after using the returned node.
+ */
+static struct ast_data_filter *data_filter_add_child(struct ao2_container *root,
+ char *name)
+{
+ struct ast_data_filter *node;
+
+ node = data_filter_find(root, name);
+ if (node) {
+ return node;
+ }
+
+ node = data_filter_alloc(name);
if (!node) {
return NULL;
}
- strcpy(node->name, name);
- AST_LIST_INSERT_TAIL(flist, node, next);
+
+ ao2_link(root, node);
return node;
}
@@ -1476,13 +1556,14 @@
* \retval NULL on error.
* \retval non-NULL A tree with the wanted nodes.
*/
-static struct data_filter_list *data_filter_add_nodes(struct data_filter_list *flist, char *path)
-{
- struct data_filter_node *node;
+static int data_filter_add_nodes(struct ao2_container *root, char *path)
+{
+ struct ast_data_filter *node;
char *savepath, *saveptr, *token, *node_name;
+ int ret = 0;
if (!path) {
- return NULL;
+ return 0;
}
savepath = ast_strdupa(path);
@@ -1490,25 +1571,21 @@
node_name = next_node_name(&savepath);
if (!node_name) {
- return NULL;
+ return 0;
}
for (token = strtok_r(node_name, "|", &saveptr);
token; token = strtok_r(NULL, "|", &saveptr)) {
- if (!flist) {
- flist = ast_calloc(1, sizeof(*flist));
- if (!flist) {
- return NULL;
- }
- }
- node = data_filter_add_node(flist, token);
+ node = data_filter_add_child(root, token);
if (!node) {
continue;
}
- data_filter_add_nodes(&(node->children), savepath);
- }
-
- return flist;
+ data_filter_add_nodes(node->children, savepath);
+ ret = 1;
+ ao2_ref(node, -1);
+ }
+
+ return ret;
}
/*!
@@ -1516,10 +1593,11 @@
* \brief Generate a filter list based on a filter string provided by the API user.
* \param[in] A filter string to create a filter from.
*/
-static struct data_filter_list *data_filter_generate(const char *constfilter)
-{
- struct data_filter_list *filter = NULL;
+static struct ast_data_filter *data_filter_generate(const char *constfilter)
+{
+ struct ast_data_filter *filter = NULL;
char *strfilter, *token, *saveptr;
+ int node_added = 0;
if (!constfilter) {
return NULL;
@@ -1527,8 +1605,18 @@
strfilter = ast_strdupa(constfilter);
+ filter = data_filter_alloc("/");
+ if (!filter) {
+ return NULL;
+ }
+
for (token = strtok_r(strfilter, ",", &saveptr); token; token = strtok_r(NULL, ",", &saveptr)) {
- filter = data_filter_add_nodes(filter, token);
+ node_added = data_filter_add_nodes(filter->children, token);
+ }
+
+ if (!node_added) {
+ ao2_ref(filter, -1);
+ return NULL;
}
return filter;
@@ -1546,12 +1634,14 @@
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,
- const struct ast_data_search *search)
-{
- struct ast_data *generated, *node;
+ const struct ast_data_search *search,
+ const struct ast_data_filter *filter)
+{
+ struct ast_data *generated = NULL, *node;
struct ao2_iterator i;
struct data_provider *provider;
struct ast_data_search *search_child = NULL;
+ struct ast_data_filter *filter_child = NULL;
node = data_result_create(parent_node_name);
if (!node) {
@@ -1565,7 +1655,7 @@
/* if this is a terminal node, just run the callback function. */
if (root_provider->handler && root_provider->handler->get) {
- root_provider->handler->get(search, node);
+ root_provider->handler->get(search, filter, node);
ast_module_unref(root_provider->module);
return node;
}
@@ -1577,12 +1667,28 @@
/* 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))) {
+ /* get the internal search node. */
if (search) {
search_child = data_search_find(search->children, provider->name);
}
- generated = data_result_generate_node(query, provider, provider->name, search_child);
+ /* get the internal filter node. */
+ if (filter) {
+ filter_child = data_filter_find(filter->children, provider->name);
+ }
+ if (!filter || filter_child) {
+ /* only generate the internal node, if we have something to
+ * generate based on the filtering string. */
+ generated = data_result_generate_node(query, provider, provider->name,
+ search_child, filter_child);
+ }
+ /* decrement the refcount of the internal search node. */
if (search_child) {
ao2_ref(search_child, -1);
+ }
+
+ /* decrement the refcount of the internal filter node. */
+ if (filter_child) {
+ ao2_ref(filter_child, -1);
}
if (generated) {
@@ -1611,7 +1717,7 @@
struct data_provider *provider_child, *tmp_provider_child;
struct ast_data *result, *result_filtered;
struct ast_data_search *search = NULL, *search_child = NULL;
- struct data_filter_list *flist = NULL;
+ struct ast_data_filter *filter = NULL, *filter_child = NULL;
if (!search_path) {
/* generate all the trees?. */
@@ -1649,15 +1755,20 @@
/* generate the search tree. */
if (query->search) {
search = data_search_generate(query->search);
- search_child = data_search_find(search->children, provider_child->name);
+ if (search) {
+ search_child = data_search_find(search->children, provider_child->name);
+ }
}
/* generate the filter tree. */
if (query->filter) {
- flist = data_filter_generate(query->filter);
- }
-
- result = data_result_generate_node(query, provider_child, provider_child->name, search_child);
+ filter = data_filter_generate(query->filter);
+ if (filter) {
+ filter_child = data_filter_find(filter->children, provider_child->name);
+ }
+ }
+
+ result = data_result_generate_node(query, provider_child, provider_child->name, search_child, filter);
/* release the requested provider. */
ao2_ref(provider_child, -1);
@@ -1666,6 +1777,11 @@
if (search_child) {
ao2_ref(search_child, -1);
}
+
+ if (filter_child) {
+ ao2_ref(filter_child, -1);
+ }
+
if (search) {
data_search_release(search);
}
@@ -1673,9 +1789,8 @@
result_filtered = result;
/* release the generated filter tree. */
- if (flist) {
- data_filter_list_destroy(flist);
- ast_free(flist);
+ if (filter) {
+ data_filter_release(filter);
}
return result_filtered;
@@ -1827,14 +1942,25 @@
* \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,
+static struct ast_data *__ast_data_add(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *name,
enum ast_data_type type, void *ptr)
{
struct ast_data *node;
+ struct ast_data_filter *filter_node;
if (!root || !root->children) {
/* invalid data result node. */
return NULL;
+ }
+
+ /* check if we need to add this node, based on the filter. */
+ if (filter) {
+ filter_node = data_filter_find(filter->children, name);
+ if (!filter_node) {
+ return NULL;
+ }
+ ao2_ref(filter_node, -1);
}
node = data_result_create(name);
@@ -1876,51 +2002,60 @@
return node;
}
-struct ast_data *ast_data_add_node(struct ast_data *root, const char *name)
-{
- return __ast_data_add(root, name, AST_DATA_CONTAINER, NULL);
-}
-
-struct ast_data *ast_data_add_int(struct ast_data *root, const char *name, int value)
-{
- return __ast_data_add(root, name, AST_DATA_INTEGER, &value);
-}
-
-struct ast_data *ast_data_add_uint(struct ast_data *root, const char *name,
+struct ast_data *ast_data_add_node(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *name)
+{
+ return __ast_data_add(filter, root, name, AST_DATA_CONTAINER, NULL);
+}
+
+struct ast_data *ast_data_add_int(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *name, int value)
+{
+ return __ast_data_add(filter, root, name, AST_DATA_INTEGER, &value);
+}
+
+struct ast_data *ast_data_add_uint(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *name,
unsigned int value)
{
- return __ast_data_add(root, name, AST_DATA_UNSIGNED_INTEGER, &value);
-}
-
-struct ast_data *ast_data_add_dbl(struct ast_data *root, const char *childname,
+ return __ast_data_add(filter, root, name, AST_DATA_UNSIGNED_INTEGER, &value);
+}
+
+struct ast_data *ast_data_add_dbl(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
double dbl)
{
- return __ast_data_add(root, childname, AST_DATA_DOUBLE, &dbl);
-}
-
-struct ast_data *ast_data_add_bool(struct ast_data *root, const char *childname,
+ return __ast_data_add(filter, root, childname, AST_DATA_DOUBLE, &dbl);
+}
+
+struct ast_data *ast_data_add_bool(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
unsigned int boolean)
{
- return __ast_data_add(root, childname, AST_DATA_BOOLEAN, &boolean);
-}
-
-struct ast_data *ast_data_add_ipaddr(struct ast_data *root, const char *childname,
+ return __ast_data_add(filter, root, childname, AST_DATA_BOOLEAN, &boolean);
+}
+
+struct ast_data *ast_data_add_ipaddr(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
struct in_addr addr)
{
- return __ast_data_add(root, childname, AST_DATA_IPADDR, &addr);
-}
-
-struct ast_data *ast_data_add_ptr(struct ast_data *root, const char *childname,
+ return __ast_data_add(filter, root, childname, AST_DATA_IPADDR, &addr);
+}
+
+struct ast_data *ast_data_add_ptr(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
void *ptr)
{
- return __ast_data_add(root, childname, AST_DATA_POINTER, ptr);
-}
-
-struct ast_data *ast_data_add_str(struct ast_data *root, const char *childname,
+ return __ast_data_add(filter, root, childname, AST_DATA_POINTER, ptr);
+}
+
+struct ast_data *ast_data_add_str(const struct ast_data_filter *filter,
+ struct ast_data *root, const char *childname,
const char *value)
{
char *name;
size_t namelen = 1 + (ast_strlen_zero(value) ? 0 : strlen(value));
+ struct ast_data *res;
if (!(name = ast_malloc(namelen))) {
return NULL;
@@ -1928,49 +2063,65 @@
strcpy(name, (ast_strlen_zero(value) ? "" : value));
- return __ast_data_add(root, childname, AST_DATA_STRING, name);
-}
-
-int __ast_data_add_structure(struct ast_data *root,
+ res = __ast_data_add(filter, root, childname, AST_DATA_STRING, name);
+ if (!res) {
+ ast_free(name);
+ }
+
+ return res;
+}
+
+int __ast_data_add_structure(const struct ast_data_filter *filter, struct ast_data *root,
const struct ast_data_mapping_structure *mapping, size_t mapping_len,
void *structure)
{
int i;
+ struct ast_data_filter *filter_child = NULL;
+
+ if (filter) {
+ filter_child = data_filter_find(filter->children, root->name);
+ if (!filter_child) {
+ return 0;
+ }
+ }
for (i = 0; i < mapping_len; i++) {
switch (mapping[i].type) {
case AST_DATA_INTEGER:
- ast_data_add_int(root, mapping[i].name,
+ ast_data_add_int(filter_child, root, mapping[i].name,
mapping[i].get.AST_DATA_INTEGER(structure));
break;
case AST_DATA_UNSIGNED_INTEGER:
- ast_data_add_uint(root, mapping[i].name,
+ ast_data_add_uint(filter_child, root, mapping[i].name,
mapping[i].get.AST_DATA_UNSIGNED_INTEGER(structure));
break;
case AST_DATA_DOUBLE:
- ast_data_add_dbl(root, mapping[i].name,
+ ast_data_add_dbl(filter_child, root, mapping[i].name,
mapping[i].get.AST_DATA_DOUBLE(structure));
break;
case AST_DATA_BOOLEAN:
- ast_data_add_bool(root, mapping[i].name,
+ ast_data_add_bool(filter_child, root, mapping[i].name,
mapping[i].get.AST_DATA_BOOLEAN(structure));
break;
case AST_DATA_STRING:
- ast_data_add_str(root, mapping[i].name,
+ ast_data_add_str(filter_child, root, mapping[i].name,
mapping[i].get.AST_DATA_STRING(structure));
break;
case AST_DATA_CONTAINER:
break;
case AST_DATA_IPADDR:
- ast_data_add_ipaddr(root, mapping[i].name,
+ ast_data_add_ipaddr(filter_child, root, mapping[i].name,
mapping[i].get.AST_DATA_IPADDR(structure));
break;
case AST_DATA_POINTER:
- ast_data_add_ptr(root, mapping[i].name,
+ ast_data_add_ptr(filter_child, root, mapping[i].name,
mapping[i].get.AST_DATA_POINTER(structure));
break;
}
}
+
+ ao2_ref(filter_child, -1);
+
return 0;
}
Modified: team/group/data_api_gsoc2009/tests/test_data.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/tests/test_data.c?view=diff&rev=210474&r1=210473&r2=210474
==============================================================================
--- team/group/data_api_gsoc2009/tests/test_data.c (original)
+++ team/group/data_api_gsoc2009/tests/test_data.c Tue Aug 4 16:50:30 2009
@@ -55,7 +55,9 @@
AST_DATA_STRUCTURE(test_structure, DATA_EXPORT_TEST_STRUCTURE);
-static int test_data_full_provider(const struct ast_data_search *search, struct ast_data *root)
+static int test_data_full_provider(const struct ast_data_search *search,
+ const struct ast_data_filter *filter,
+ struct ast_data *root)
{
struct ast_data *test_structure;
struct test_structure local_test_structure = {
@@ -65,18 +67,20 @@
.a_uint = 20
};
- test_structure = ast_data_add_node(root, "test_structure");
+ test_structure = ast_data_add_node(filter, root, "test_structure");
if (!test_structure) {
ast_debug(1, "Internal data api error\n");
return 0;
}
- ast_data_add_structure(test_structure, test_structure, &local_test_structure);
+ ast_data_add_structure(filter, test_structure, test_structure, &local_test_structure);
return 0;
}
-static int test_data_null_provider(const struct ast_data_search *search, struct ast_data *root)
+static int test_data_null_provider(const struct ast_data_search *search,
+ const struct ast_data_filter *filter,
+ struct ast_data *root)
{
return 0;
}
@@ -102,7 +106,8 @@
AST_DATA_ENTRY("test/null/node1/node2/node3/node4/node5/node6", &null_provider),
};
-static char *handle_cli_data_get_bench(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+static char *handle_cli_data_get_bench(struct ast_cli_entry *e, int cmd,
+ struct ast_cli_args *a)
{
struct ast_data_query query_null = {
.version = AST_DATA_QUERY_VERSION,
@@ -130,7 +135,8 @@
ast_cli(a->fd, "Null provider\n");
start = ast_tvnow();
res = ast_data_get(&query_null);
- ast_cli(a->fd, "Test complete - %" PRIi64 " us\n", ast_tvdiff_us(ast_tvnow(), start));
+ ast_cli(a->fd, "Test complete - %" PRIi64 " us\n",
+ ast_tvdiff_us(ast_tvnow(), start));
ast_data_free(res);
/* TODO: Show tree deph and number of nodes. */
@@ -138,14 +144,16 @@
ast_cli(a->fd, "Full test tree\n");
start = ast_tvnow();
res = ast_data_get(&query_full);
- ast_cli(a->fd, "Test complete - %" PRIi64 " us\n", ast_tvdiff_us(ast_tvnow(), start));
+ ast_cli(a->fd, "Test complete - %" PRIi64 " us\n",
+ ast_tvdiff_us(ast_tvnow(), start));
ast_data_free(res);
/* TODO: Show tree deph and number of nodes. */
return CLI_SUCCESS;
}
-static char *handle_cli_data_get_automatic(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+static char *handle_cli_data_get_automatic(struct ast_cli_entry *e, int cmd,
+ struct ast_cli_args *a)
{
struct ast_data *res, *node;
struct ast_data_iterator *i;
@@ -203,7 +211,8 @@
return CLI_SUCCESS;
}
-static char *handle_cli_data_get_dump(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+static char *handle_cli_data_get_dump(struct ast_cli_entry *e, int cmd,
+ struct ast_cli_args *a)
{
char *res = CLI_SUCCESS;
struct ast_xml_doc *doc;
More information about the asterisk-commits
mailing list