[asterisk-commits] eliel: branch eliel/data_api_providers_gsoc2010 r260562 - in /team/eliel/data...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sun May 2 02:41:03 CDT 2010
Author: eliel
Date: Sun May 2 02:41:00 2010
New Revision: 260562
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=260562
Log:
- Hide a big part of the API not needed anymore to be public.
- Fix a memory leak.
Modified:
team/eliel/data_api_providers_gsoc2010/include/asterisk/data.h
team/eliel/data_api_providers_gsoc2010/main/channel.c
team/eliel/data_api_providers_gsoc2010/main/data.c
Modified: team/eliel/data_api_providers_gsoc2010/include/asterisk/data.h
URL: http://svnview.digium.com/svn/asterisk/team/eliel/data_api_providers_gsoc2010/include/asterisk/data.h?view=diff&rev=260562&r1=260561&r2=260562
==============================================================================
--- team/eliel/data_api_providers_gsoc2010/include/asterisk/data.h (original)
+++ team/eliel/data_api_providers_gsoc2010/include/asterisk/data.h Sun May 2 02:41:00 2010
@@ -106,16 +106,16 @@
* .b = 20
* };
*
- * if (ast_data_search_cmp_structure(search, test_structure, "test_node")) {
- * return 0;
- * }
- *
* internal_node = ast_data_add_node(root_node, "test_node");
* if (!internal_node) {
* return -1;
* }
*
* ast_data_add_structure(test_structure, internal_node, ts);
+ *
+ * if (!ast_data_search_match(search, internal_node)) {
+ * ast_data_remove_node(root_node, internal_node);
+ * }
*
* return 0;
* }
@@ -372,102 +372,6 @@
int ast_data_search_match(const struct ast_data_search *search, struct ast_data *data);
/*!
- * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
- * current string value.
- * .search = "somename=somestring"
- * name = "somename"
- * value is the current value of something and will be evaluated against "somestring".
- * \param[in] root The root node pointer of the search tree.
- * \param[in] name The name of the specific.
- * \param[in] value The value to compare.
- * \returns The strcmp return value.
- */
-int ast_data_search_cmp_string(const struct ast_data_search *root, const char *name, char *value);
-
-/*!
- * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
- * current pointer address value.
- * .search = "something=0x32323232"
- * name = "something"
- * value is the current value of something and will be evaluated against "0x32323232".
- * \param[in] root The root node pointer of the search tree.
- * \param[in] name The name of the specific.
- * \param[in] ptr The pointer address to compare.
- * \returns The (value - current_value) result.
- */
-int ast_data_search_cmp_ptr(const struct ast_data_search *root, const char *name,
- void *ptr);
-
-/*!
- * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
- * current ipv4 address value.
- * .search = "something=192.168.2.2"
- * name = "something"
- * value is the current value of something and will be evaluated against "192.168.2.2".
- * \param[in] root The root node pointer of the search tree.
- * \param[in] name The name of the specific.
- * \param[in] addr The ipv4 address value to compare.
- * \returns The (value - current_value) result.
- */
-int ast_data_search_cmp_ipaddr(const struct ast_data_search *root, const char *name,
- struct in_addr addr);
-
-/*!
- * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
- * current double value.
- * .search = "something=222"
- * name = "something"
- * value is the current value of something and will be evaluated against "222".
- * \param[in] root The root node pointer of the search tree.
- * \param[in] name The name of the specific.
- * \param[in] value The double value to compare.
- * \returns The (value - current_value) result.
- */
-int ast_data_search_cmp_dbl(const struct ast_data_search *root, const char *name,
- double value);
-
-/*!
- * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
- * current boolean value.
- * .search = "something=true"
- * name = "something"
- * value is the current value of something and will be evaluated against "true".
- * \param[in] root The root node pointer of the search tree.
- * \param[in] name The name of the specific.
- * \param[in] value The boolean value to compare.
- * \returns The (value - current_value) result.
- */
-int ast_data_search_cmp_bool(const struct ast_data_search *root, const char *name,
- unsigned int value);
-
-/*!
- * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
- * current unsigned integer value.
- * .search = "something=10"
- * name = "something"
- * value is the current value of something and will be evaluated against "10".
- * \param[in] root The root node pointer of the search tree.
- * \param[in] name The name of the specific.
- * \param[in] value The unsigned value to compare.
- * \returns The strcmp return value.
- */
-int ast_data_search_cmp_uint(const struct ast_data_search *root, const char *name,
- unsigned int value);
-
-/*!
- * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
- * current signed integer value.
- * .search = "something=10"
- * name = "something"
- * value is the current value of something and will be evaluated against "10".
- * \param[in] root The root node pointer of the search tree.
- * \param[in] name The name of the specific.
- * \param[in] value The value to compare.
- * \returns The strcmp return value.
- */
-int ast_data_search_cmp_int(const struct ast_data_search *root, const char *name, int value);
-
-/*!
* \brief Based on a search tree, evaluate every member of a structure against it.
* \param[in] search The search tree.
* \param[in] mapping The structure mapping.
@@ -485,17 +389,6 @@
ARRAY_LEN(__data_mapping_structure_##structure_name), structure, structure_name_cmp)
/*!
- * \brief Check if there is a compare condition inside the search tree with the
- * passed 'compare_condition' node names.
- * \param[in] search The search tree.
- * \param[in] compare_condition The path of the compare condition.
- * \retval 0 There is no compare condition.
- * \retval 1 There is a compare condition.
- */
-int ast_data_search_has_condition(const struct ast_data_search *search,
- const char *compare_condition);
-
-/*!
* \brief Retrieve a subtree from the asterisk data API.
* \param[in] query The query structure specifying what nodes to retrieve.
* \retval NULL on error.
Modified: team/eliel/data_api_providers_gsoc2010/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/eliel/data_api_providers_gsoc2010/main/channel.c?view=diff&rev=260562&r1=260561&r2=260562
==============================================================================
--- team/eliel/data_api_providers_gsoc2010/main/channel.c (original)
+++ team/eliel/data_api_providers_gsoc2010/main/channel.c Sun May 2 02:41:00 2010
@@ -6503,30 +6503,10 @@
struct ast_channel *c, *bc;
struct ast_channel_iterator *iter = NULL;
struct ast_data *data_channel, *data_bridged;
- int channel_match, bridged_match;
-
- channel_match = ast_data_search_has_condition(search,
- "channel");
- bridged_match = ast_data_search_has_condition(search,
- "channel/bridged");
for (iter = ast_channel_iterator_all_new();
iter && (c = ast_channel_iterator_next(iter)); ast_channel_unref(c)) {
ast_channel_lock(c);
-
- if (channel_match &&
- ast_channel_data_cmp_structure(search, c, "channel")) {
- ast_channel_unlock(c);
- continue;
- }
-
- bc = ast_bridged_channel(c);
-
- if (bridged_match && bc &&
- ast_channel_data_cmp_structure(search, bc, "channel/bridged")) {
- ast_channel_unlock(c);
- continue;
- }
data_channel = ast_data_add_node(root, "channel");
if (!data_channel) {
@@ -6536,6 +6516,7 @@
ast_channel_data_add_structure(data_channel, c);
+ bc = ast_bridged_channel(c);
if (bc) {
data_bridged = ast_data_add_node(data_channel, "bridged");
if (!data_bridged) {
@@ -6546,6 +6527,10 @@
}
ast_channel_unlock(c);
+
+ if (!ast_data_search_match(search, data_channel)) {
+ ast_data_remove_node(root, data_channel);
+ }
}
if (iter) {
ast_channel_iterator_destroy(iter);
Modified: team/eliel/data_api_providers_gsoc2010/main/data.c
URL: http://svnview.digium.com/svn/asterisk/team/eliel/data_api_providers_gsoc2010/main/data.c?view=diff&rev=260562&r1=260561&r2=260562
==============================================================================
--- team/eliel/data_api_providers_gsoc2010/main/data.c (original)
+++ team/eliel/data_api_providers_gsoc2010/main/data.c Sun May 2 02:41:00 2010
@@ -58,8 +58,6 @@
</manager>
***/
-static struct ast_data *data_result_find_child(struct ast_data *root, const char *name);
-
#define NUM_DATA_NODE_BUCKETS 59
#define NUM_DATA_RESULT_BUCKETS 59
#define NUM_DATA_SEARCH_BUCKETS 59
@@ -983,6 +981,409 @@
return current;
}
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current string value.
+ * .search = "somename=somestring"
+ * name = "somename"
+ * value is the current value of something and will be evaluated against "somestring".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] value The value to compare.
+ * \returns The strcmp return value.
+ */
+static int data_search_cmp_string(const struct ast_data_search *root, const char *name,
+ char *value)
+{
+ struct ast_data_search *child;
+ enum data_search_comparison cmp_type;
+ int ret;
+
+ child = data_search_get_node(root, name);
+ if (!child) {
+ return 0;
+ }
+
+ ret = strcmp(value, child->value);
+ cmp_type = child->cmp_type;
+
+ ao2_ref(child, -1);
+
+ return data_search_comparison_result(ret, cmp_type);
+}
+
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current pointer address value.
+ * .search = "something=0x32323232"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "0x32323232".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] ptr The pointer address to compare.
+ * \returns The (value - current_value) result.
+ */
+static int data_search_cmp_ptr(const struct ast_data_search *root, const char *name,
+ void *ptr)
+{
+ struct ast_data_search *child;
+ enum data_search_comparison cmp_type;
+ void *node_ptr;
+
+ child = data_search_get_node(root, name);
+ if (!child) {
+ return 0;
+ }
+
+ cmp_type = child->cmp_type;
+
+ if (sscanf(child->value, "%p", &node_ptr) <= 0) {
+ return 1;
+ }
+
+ ao2_ref(child, -1);
+
+ return data_search_comparison_result((node_ptr - ptr), cmp_type);
+}
+
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current ipv4 address value.
+ * .search = "something=192.168.2.2"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "192.168.2.2".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] addr The ipv4 address value to compare.
+ * \returns The (value - current_value) result.
+ */
+static int data_search_cmp_ipaddr(const struct ast_data_search *root, const char *name,
+ struct in_addr addr)
+{
+ struct ast_data_search *child;
+ enum data_search_comparison cmp_type;
+ struct in_addr node_addr;
+
+ child = data_search_get_node(root, name);
+ if (!child) {
+ return 0;
+ }
+ cmp_type = child->cmp_type;
+
+ inet_aton(child->value, &node_addr);
+
+ ao2_ref(child, -1);
+
+ return data_search_comparison_result((node_addr.s_addr - addr.s_addr), cmp_type);
+}
+
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current boolean value.
+ * .search = "something=true"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "true".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] value The boolean value to compare.
+ * \returns The (value - current_value) result.
+ */
+static int data_search_cmp_bool(const struct ast_data_search *root, const char *name,
+ unsigned int value)
+{
+ struct ast_data_search *child;
+ unsigned int node_value;
+ enum data_search_comparison cmp_type;
+
+ child = data_search_get_node(root, name);
+ if (!child) {
+ return 0;
+ }
+
+ node_value = abs(ast_true(child->value));
+ cmp_type = child->cmp_type;
+
+ ao2_ref(child, -1);
+
+ return data_search_comparison_result(value - node_value, cmp_type);
+}
+
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current double value.
+ * .search = "something=222"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "222".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] value The double value to compare.
+ * \returns The (value - current_value) result.
+ */
+static int data_search_cmp_dbl(const struct ast_data_search *root, const char *name,
+ double value)
+{
+ struct ast_data_search *child;
+ double node_value;
+ enum data_search_comparison cmp_type;
+
+ child = data_search_get_node(root, name);
+ if (!child) {
+ return 0;
+ }
+
+ node_value = strtod(child->value, NULL);
+ cmp_type = child->cmp_type;
+
+ ao2_ref(child, -1);
+
+ return data_search_comparison_result(value - node_value, cmp_type);
+}
+
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current unsigned integer value.
+ * .search = "something=10"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "10".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] value The unsigned value to compare.
+ * \returns The strcmp return value.
+ */
+static int data_search_cmp_uint(const struct ast_data_search *root, const char *name,
+ unsigned int value)
+{
+ struct ast_data_search *child;
+ unsigned int node_value;
+ enum data_search_comparison cmp_type;
+
+ child = data_search_get_node(root, name);
+ if (!child) {
+ return 0;
+ }
+
+ node_value = atoi(child->value);
+ cmp_type = child->cmp_type;
+
+ ao2_ref(child, -1);
+
+ return data_search_comparison_result(value - node_value, cmp_type);
+}
+
+/*!
+ * \internal
+ * \brief Based on a search tree, evaluate the specified 'name' inside the tree with the
+ * current signed integer value.
+ * .search = "something=10"
+ * name = "something"
+ * value is the current value of something and will be evaluated against "10".
+ * \param[in] root The root node pointer of the search tree.
+ * \param[in] name The name of the specific.
+ * \param[in] value The value to compare.
+ * \returns The strcmp return value.
+ */
+static int data_search_cmp_int(const struct ast_data_search *root, const char *name,
+ int value)
+{
+ struct ast_data_search *child;
+ int node_value;
+ enum data_search_comparison cmp_type;
+
+ child = data_search_get_node(root, name);
+ if (!child) {
+ return 0;
+ }
+
+ node_value = atoi(child->value);
+ cmp_type = child->cmp_type;
+
+ ao2_ref(child, -1);
+
+ return data_search_comparison_result(value - node_value, cmp_type);
+}
+
+/*!
+ * \internal
+ * \brief Get the member pointer, from a mapping structure, based on its name.
+ * \XXX We will need to improve performance here!!.
+ * \retval <0 if the member was not found.
+ * \retval >=0 The member position in the mapping structure.
+ */
+static inline int data_search_mapping_find(const struct ast_data_mapping_structure *map,
+ size_t mapping_len,
+ const char *member_name)
+{
+ int i;
+
+ for (i = 0; i < mapping_len; i++) {
+ if (!strcmp(map[i].name, member_name)) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int __ast_data_search_cmp_structure(const struct ast_data_search *search,
+ const struct ast_data_mapping_structure *mapping, size_t mapping_len,
+ void *structure, const char *structure_name)
+{
+ struct ao2_iterator i;
+ struct ast_data_search *node, *struct_children;
+ int member, notmatch = 0;
+
+ if (!search) {
+ return 0;
+ }
+
+ struct_children = data_search_get_node(search, structure_name);
+ if (!struct_children) {
+ return 0;
+ }
+
+ i = ao2_iterator_init(struct_children->children, 0);
+ while ((node = ao2_iterator_next(&i))) {
+ member = data_search_mapping_find(mapping, mapping_len, node->name);
+ if (member < 0) {
+ /* the structure member name doesn't match! */
+ ao2_ref(node, -1);
+ ao2_ref(struct_children, -1);
+ ao2_iterator_destroy(&i);
+ return 0;
+ }
+
+ notmatch = 0;
+ switch (mapping[member].type) {
+ case AST_DATA_STRING:
+ notmatch = data_search_cmp_string(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_STRING(structure));
+ break;
+ case AST_DATA_INTEGER:
+ notmatch = data_search_cmp_int(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_INTEGER(structure));
+ break;
+ case AST_DATA_BOOLEAN:
+ notmatch = data_search_cmp_bool(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_BOOLEAN(structure));
+ break;
+ case AST_DATA_UNSIGNED_INTEGER:
+ notmatch = data_search_cmp_uint(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_UNSIGNED_INTEGER(structure));
+ break;
+ case AST_DATA_DOUBLE:
+ notmatch = data_search_cmp_dbl(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_DOUBLE(structure));
+ break;
+ case AST_DATA_IPADDR:
+ notmatch = data_search_cmp_ipaddr(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_IPADDR(structure));
+ break;
+ case AST_DATA_POINTER:
+ notmatch = data_search_cmp_ptr(struct_children,
+ node->name,
+ mapping[member].get.AST_DATA_POINTER(structure));
+ break;
+ case AST_DATA_CONTAINER:
+ break;
+ }
+
+ ao2_ref(node, -1);
+ }
+ ao2_iterator_destroy(&i);
+
+ ao2_ref(struct_children, -1);
+
+ return notmatch;
+}
+
+/*!
+ * \internal
+ * \brief Release the memory allocated by a call to ao2_alloc.
+ */
+static void data_result_destructor(void *obj)
+{
+ struct ast_data *root = obj;
+
+ switch (root->type) {
+ case AST_DATA_POINTER:
+ case AST_DATA_STRING:
+ ast_free(root->payload.ptr);
+ case AST_DATA_CONTAINER:
+ case AST_DATA_INTEGER:
+ case AST_DATA_UNSIGNED_INTEGER:
+ case AST_DATA_DOUBLE:
+ case AST_DATA_BOOLEAN:
+ case AST_DATA_IPADDR:
+ ao2_ref(root->children, -1);
+ break;
+ }
+}
+
+static struct ast_data *data_result_create(const char *name)
+{
+ struct ast_data *res;
+ size_t namelen;
+
+ namelen = ast_strlen_zero(name) ? 1 : strlen(name) + 1;
+
+ res = ao2_alloc(sizeof(*res) + namelen, data_result_destructor);
+ if (!res) {
+ return NULL;
+ }
+
+ strcpy(res->name, namelen ? name : "");
+
+ /* 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;
+ }
+
+ /* set this node as a container. */
+ res->type = AST_DATA_CONTAINER;
+
+ return res;
+}
+
+/*!
+ * \internal
+ * \brief Find a child node, based on its name.
+ * \param[in] root The starting point.
+ * \param[in] name The child name.
+ * \retval NULL if the node wasn't found.
+ * \retval non-NULL the node we were looking for.
+ */
+static struct ast_data *data_result_find_child(struct ast_data *root, const char *name)
+{
+ struct ast_data *found, *find_node;
+
+ find_node = data_result_create(name);
+ if (!find_node) {
+ return NULL;
+ }
+
+ found = ao2_find(root->children, find_node, OBJ_POINTER);
+
+ /* release the temporary created node used for searching. */
+ ao2_ref(find_node, -1);
+
+ return found;
+}
+
int ast_data_search_match(const struct ast_data_search *search, struct ast_data *data)
{
struct ao2_iterator i, ii;
@@ -997,6 +1398,7 @@
s_child = data_search_find(search->children, data->name);
if (!s_child) {
/* nothing to compare */
+ ao2_ref(s_child, -1);
return 1;
}
@@ -1013,31 +1415,31 @@
switch (d_child->type) {
case AST_DATA_STRING:
- notmatch = ast_data_search_cmp_string(s_child, d_child->name,
+ notmatch = data_search_cmp_string(s_child, d_child->name,
d_child->payload.str);
break;
case AST_DATA_INTEGER:
- notmatch = ast_data_search_cmp_int(s_child, d_child->name,
+ notmatch = data_search_cmp_int(s_child, d_child->name,
d_child->payload.sint);
break;
case AST_DATA_BOOLEAN:
- notmatch = ast_data_search_cmp_bool(s_child, d_child->name,
+ notmatch = data_search_cmp_bool(s_child, d_child->name,
d_child->payload.boolean);
break;
case AST_DATA_UNSIGNED_INTEGER:
- notmatch = ast_data_search_cmp_uint(s_child, d_child->name,
+ notmatch = data_search_cmp_uint(s_child, d_child->name,
d_child->payload.uint);
break;
case AST_DATA_DOUBLE:
- notmatch = ast_data_search_cmp_dbl(s_child, d_child->name,
+ notmatch = data_search_cmp_dbl(s_child, d_child->name,
d_child->payload.dbl);
break;
case AST_DATA_IPADDR:
- notmatch = ast_data_search_cmp_ipaddr(s_child, d_child->name,
+ notmatch = data_search_cmp_ipaddr(s_child, d_child->name,
d_child->payload.ipaddr);
break;
case AST_DATA_POINTER:
- notmatch = ast_data_search_cmp_ptr(s_child, d_child->name,
+ notmatch = data_search_cmp_ptr(s_child, d_child->name,
d_child->payload.ptr);
break;
case AST_DATA_CONTAINER:
@@ -1068,341 +1470,9 @@
}
ao2_iterator_destroy(&i);
+ ao2_ref(s_child, -1);
+
return !notmatch;
-}
-
-int ast_data_search_cmp_string(const struct ast_data_search *root, const char *name,
- char *value)
-{
- struct ast_data_search *child;
- enum data_search_comparison cmp_type;
- int ret;
-
- child = data_search_get_node(root, name);
- if (!child) {
- return 0;
- }
-
- ret = strcmp(value, child->value);
- cmp_type = child->cmp_type;
-
- ao2_ref(child, -1);
-
- return data_search_comparison_result(ret, cmp_type);
-}
-
-int ast_data_search_cmp_ptr(const struct ast_data_search *root, const char *name,
- void *ptr)
-{
- struct ast_data_search *child;
- enum data_search_comparison cmp_type;
- void *node_ptr;
-
- child = data_search_get_node(root, name);
- if (!child) {
- return 0;
- }
-
- cmp_type = child->cmp_type;
-
- if (sscanf(child->value, "%p", &node_ptr) <= 0) {
- return 1;
- }
-
- ao2_ref(child, -1);
-
- return data_search_comparison_result((node_ptr - ptr), cmp_type);
-}
-
-int ast_data_search_cmp_ipaddr(const struct ast_data_search *root, const char *name,
- struct in_addr addr)
-{
- struct ast_data_search *child;
- enum data_search_comparison cmp_type;
- struct in_addr node_addr;
-
- child = data_search_get_node(root, name);
- if (!child) {
- return 0;
- }
- cmp_type = child->cmp_type;
-
- inet_aton(child->value, &node_addr);
-
- ao2_ref(child, -1);
-
- return data_search_comparison_result((node_addr.s_addr - addr.s_addr), cmp_type);
-}
-
-int ast_data_search_cmp_bool(const struct ast_data_search *root, const char *name,
- unsigned int value)
-{
- struct ast_data_search *child;
- unsigned int node_value;
- enum data_search_comparison cmp_type;
-
- child = data_search_get_node(root, name);
- if (!child) {
- return 0;
- }
-
- node_value = abs(ast_true(child->value));
- cmp_type = child->cmp_type;
-
- ao2_ref(child, -1);
-
- return data_search_comparison_result(value - node_value, cmp_type);
-}
-
-int ast_data_search_cmp_dbl(const struct ast_data_search *root, const char *name,
- double value)
-{
- struct ast_data_search *child;
- double node_value;
- enum data_search_comparison cmp_type;
-
- child = data_search_get_node(root, name);
- if (!child) {
- return 0;
- }
-
- node_value = strtod(child->value, NULL);
- cmp_type = child->cmp_type;
-
- ao2_ref(child, -1);
-
- return data_search_comparison_result(value - node_value, cmp_type);
-}
-
-int ast_data_search_cmp_uint(const struct ast_data_search *root, const char *name,
- unsigned int value)
-{
- struct ast_data_search *child;
- unsigned int node_value;
- enum data_search_comparison cmp_type;
-
- child = data_search_get_node(root, name);
- if (!child) {
- return 0;
- }
-
- node_value = atoi(child->value);
- cmp_type = child->cmp_type;
-
- ao2_ref(child, -1);
-
- return data_search_comparison_result(value - node_value, cmp_type);
-}
-
-int ast_data_search_cmp_int(const struct ast_data_search *root, const char *name,
- int value)
-{
- struct ast_data_search *child;
- int node_value;
- enum data_search_comparison cmp_type;
-
- child = data_search_get_node(root, name);
- if (!child) {
- return 0;
- }
-
- node_value = atoi(child->value);
- cmp_type = child->cmp_type;
-
- ao2_ref(child, -1);
-
- return data_search_comparison_result(value - node_value, cmp_type);
-}
-
-/*!
- * \internal
- * \brief Get the member pointer, from a mapping structure, based on its name.
- * \XXX We will need to improve performance here!!.
- * \retval <0 if the member was not found.
- * \retval >=0 The member position in the mapping structure.
- */
-static inline int data_search_mapping_find(const struct ast_data_mapping_structure *map,
- size_t mapping_len,
- const char *member_name)
-{
- int i;
-
- for (i = 0; i < mapping_len; i++) {
- if (!strcmp(map[i].name, member_name)) {
- return i;
- }
- }
-
- return -1;
-}
-
-int ast_data_search_has_condition(const struct ast_data_search *search,
- const char *compare_condition)
-{
- struct ast_data_search *child;
-
- child = data_search_get_node(search, compare_condition);
- if (!child) {
- return 0;
- }
-
- ao2_ref(child, -1);
-
- return 1;
-}
-
-int __ast_data_search_cmp_structure(const struct ast_data_search *search,
- const struct ast_data_mapping_structure *mapping, size_t mapping_len,
- void *structure, const char *structure_name)
-{
- struct ao2_iterator i;
- struct ast_data_search *node, *struct_children;
- int member, notmatch = 0;
-
- if (!search) {
- return 0;
- }
-
- struct_children = data_search_get_node(search, structure_name);
- if (!struct_children) {
- return 0;
- }
-
- i = ao2_iterator_init(struct_children->children, 0);
- while ((node = ao2_iterator_next(&i))) {
- member = data_search_mapping_find(mapping, mapping_len, node->name);
- if (member < 0) {
- /* the structure member name doesn't match! */
- ao2_ref(node, -1);
- ao2_ref(struct_children, -1);
- ao2_iterator_destroy(&i);
- return 0;
- }
-
- notmatch = 0;
- switch (mapping[member].type) {
- case AST_DATA_STRING:
- notmatch = ast_data_search_cmp_string(struct_children,
- node->name,
- mapping[member].get.AST_DATA_STRING(structure));
- break;
- case AST_DATA_INTEGER:
- notmatch = ast_data_search_cmp_int(struct_children,
- node->name,
- mapping[member].get.AST_DATA_INTEGER(structure));
- break;
- case AST_DATA_BOOLEAN:
- notmatch = ast_data_search_cmp_bool(struct_children,
- node->name,
- mapping[member].get.AST_DATA_BOOLEAN(structure));
- break;
- case AST_DATA_UNSIGNED_INTEGER:
- notmatch = ast_data_search_cmp_uint(struct_children,
- node->name,
- mapping[member].get.AST_DATA_UNSIGNED_INTEGER(structure));
- break;
- case AST_DATA_DOUBLE:
- notmatch = ast_data_search_cmp_dbl(struct_children,
- node->name,
- mapping[member].get.AST_DATA_DOUBLE(structure));
- break;
- case AST_DATA_IPADDR:
- notmatch = ast_data_search_cmp_ipaddr(struct_children,
- node->name,
- mapping[member].get.AST_DATA_IPADDR(structure));
- break;
- case AST_DATA_POINTER:
- notmatch = ast_data_search_cmp_ptr(struct_children,
- node->name,
- mapping[member].get.AST_DATA_POINTER(structure));
- break;
- case AST_DATA_CONTAINER:
- break;
- }
-
- ao2_ref(node, -1);
- }
- ao2_iterator_destroy(&i);
-
- ao2_ref(struct_children, -1);
-
- return notmatch;
-}
-
-/*!
- * \internal
- * \brief Release the memory allocated by a call to ao2_alloc.
- */
-static void data_result_destructor(void *obj)
-{
- struct ast_data *root = obj;
-
- switch (root->type) {
- case AST_DATA_POINTER:
- case AST_DATA_STRING:
- ast_free(root->payload.ptr);
- case AST_DATA_CONTAINER:
- case AST_DATA_INTEGER:
- case AST_DATA_UNSIGNED_INTEGER:
- case AST_DATA_DOUBLE:
- case AST_DATA_BOOLEAN:
- case AST_DATA_IPADDR:
- ao2_ref(root->children, -1);
- break;
- }
-}
-
-static struct ast_data *data_result_create(const char *name)
-{
- struct ast_data *res;
- size_t namelen;
-
- namelen = ast_strlen_zero(name) ? 1 : strlen(name) + 1;
-
- res = ao2_alloc(sizeof(*res) + namelen, data_result_destructor);
- if (!res) {
- return NULL;
- }
-
- strcpy(res->name, namelen ? name : "");
-
- /* 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;
- }
-
- /* set this node as a container. */
- res->type = AST_DATA_CONTAINER;
-
- return res;
-}
-
-/*!
- * \internal
- * \brief Find a child node, based on its name.
- * \param[in] root The starting point.
- * \param[in] name The child name.
- * \retval NULL if the node wasn't found.
- * \retval non-NULL the node we were looking for.
- */
-static struct ast_data *data_result_find_child(struct ast_data *root, const char *name)
-{
- struct ast_data *found, *find_node;
-
- find_node = data_result_create(name);
- if (!find_node) {
- return NULL;
- }
-
- found = ao2_find(root->children, find_node, OBJ_POINTER);
-
- /* release the temporary created node used for searching. */
- ao2_ref(find_node, -1);
-
- return found;
}
/*!
@@ -2843,10 +2913,6 @@
.a_uint = 20
};
- if (ast_data_search_cmp_structure(search, test_structure, &local_test_structure, "test_structure")) {
- return 0;
- }
-
test_structure = ast_data_add_node(root, "test_structure");
if (!test_structure) {
ast_debug(1, "Internal data api error\n");
@@ -2855,6 +2921,10 @@
/* add the complete structure. */
ast_data_add_structure(test_structure, test_structure, &local_test_structure);
+
+ if (!ast_data_search_match(search, test_structure)) {
+ ast_data_remove_node(root, test_structure);
+ }
return 0;
}
More information about the asterisk-commits
mailing list