[asterisk-commits] bbryant: branch group/data_api_gsoc2009 r202750 - in /team/group/data_api_gso...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jun 23 14:22:14 CDT 2009
Author: bbryant
Date: Tue Jun 23 14:22:10 2009
New Revision: 202750
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=202750
Log:
Add the initial implementation with astobj2 for adding children into the result tree structure.
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=202750&r1=202749&r2=202750
==============================================================================
--- team/group/data_api_gsoc2009/include/asterisk/data.h (original)
+++ team/group/data_api_gsoc2009/include/asterisk/data.h Tue Jun 23 14:22:10 2009
@@ -81,6 +81,7 @@
AST_DATA_INTEGER,
AST_DATA_UNSIGNED_INTEGER,
AST_DATA_DOUBLE,
+ AST_DATA_BOOLEAN,
AST_DATA_STRING,
AST_DATA_IPADDR,
AST_DATA_POINTER
@@ -202,11 +203,11 @@
struct ast_data *ast_data_get(const struct ast_data_query *query);
/*!
- * \brief Release the allocated memory of a returned subtree.
- * \param[in] res The sub-tree pointer returned by a call to ast_data_get.
+ * \brief Release the allocated memory of a tree.
+ * \param[in] obj The sub-tree pointer returned by a call to ast_data_get.
* \see ast_data_get
*/
-void ast_data_free(struct ast_data *res);
+void ast_data_free(void *obj);
/*!
* \brief Allocate a 'data' node structure.
@@ -226,27 +227,63 @@
/*!
* \brief Add a container child.
- * \TODO: Complete docs
+ * \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);
/*!
* \brief Add an integer node type.
- * \TODO: Complete docs
- */
-struct ast_data *ast_data_add_integer(struct ast_data *root, const char *childname, int value);
+ * \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, int value);
+
+/*!
+ * \brief Add an unsigned integer node type.
+ * \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, unsigned int value);
+
+/*!
+ * \brief Add a floating point node type.
+ * \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, double dbl);
+
/*!
* \brief Add a string node type.
- * \TODO: Complete docs
- */
-struct ast_data *ast_data_add_string(struct ast_data *root, const char *childname, const char *string);
+ * \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, const char *string);
/*!
* \brief Add a boolean node type.
- * \TODO: Complete docs
- */
-struct ast_data *ast_data_add_boolean(struct ast_data *root, const char *childname, unsigned int boolean);
+ * \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, unsigned int boolean);
/*!
* \brief Initialize an iterator.
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=202750&r1=202749&r2=202750
==============================================================================
--- team/group/data_api_gsoc2009/main/data.c (original)
+++ team/group/data_api_gsoc2009/main/data.c Tue Jun 23 14:22:10 2009
@@ -35,7 +35,7 @@
#define NUM_DATA_NODE_BUCKETS 60
/*! \brief The data tree to be returned by the callbacks and
- managed by functions local to this file. */
+ managed by functions local to this file. */
struct ast_data {
enum ast_data_type type;
@@ -86,7 +86,6 @@
static int data_provider_hash(const void *obj, const int flags)
{
const struct data_provider *node = obj;
-
return ast_str_hash(node->name);
}
@@ -95,12 +94,32 @@
* \brief Compare two data_provider's.
* \see ast_data_init
*/
-static int data_provider_cmp(void *obj, void *arg, int flags)
-{
- struct data_provider *node1 = obj, *node2 = arg;
-
+static int data_provider_cmp(void *obj1, void *obj2, int flags)
+{
+ struct data_provider *node1 = obj1, *node2 = obj2;
return strcasecmp(node1->name, node2->name) ? 0 : CMP_MATCH;
}
+
+/*!
+ * \internal
+ * \brief Common string hash function for data nodes
+ */
+static int data_result_hash(const void *obj, const int flags)
+{
+ const struct ast_data *node = obj;
+ return ast_str_hash(node->name);
+}
+
+/*!
+ * \internal
+ * \brief Common string comparison function
+ */
+static int data_result_cmp(void *obj, void *arg, int flags)
+{
+ struct ast_data *node1 = obj, *node2 = arg;
+ return strcasecmp(node1->name, node2->name) ? 0 : CMP_MATCH;
+}
+
/*!
* \internal
@@ -565,6 +584,7 @@
* \retval NULL on error.
* \retval non-NULL The generated result tree.
*/
+#if 0 /* XXX: Discuss with eliel, remove for now so that it will compile in dev-mode */
static struct ast_data *data_result_generate_node(struct data_provider *root_provider,
const char *parent_node_name)
{
@@ -600,6 +620,7 @@
return node;
}
+#endif
/*!
* \internal
@@ -642,40 +663,101 @@
return internal->type;
}
-struct ast_data *ast_data_add_node(struct ast_data *root, const char *childname)
-{
- /* TODO: implement this. */
- /* adds a container type. */
- return NULL;
-}
-
-struct ast_data *ast_data_add_integer(struct ast_data *root, const char *childname,
- int value)
-{
- /* TODO: implement this. */
- /* adds an integer node. */
- return NULL;
-}
-
-struct ast_data *ast_data_add_string(struct ast_data *root, const char *childname,
- const char *value)
-{
- /* TODO: implement this. */
- /* adds a string node. */
- return NULL;
-}
-
-struct ast_data *ast_data_add_boolean(struct ast_data *root, const char *childname,
+/*!
+ * \internal
+ * \brief Allocate the memory for a data node that will be
+ * created and allocated in response to issuing the
+ * callback
+ * \param root
+ * \param name
+ * \param type
+ * \param ptr
+ */
+static struct ast_data *__ast_data_add(struct ast_data *root, const char *name,
+ enum ast_data_type type, void *ptr) {
+ 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))) {
+ return NULL;
+ }
+
+ if (namelen > 1) {
+ strcpy(node->name, name);
+ } else {
+ node->name[0] = '\0';
+ }
+
+ switch (type) {
+ case AST_DATA_INTEGER:
+ case AST_DATA_UNSIGNED_INTEGER:
+ node->payload.sint = *(int *)ptr;
+ break;
+
+ case AST_DATA_DOUBLE:
+ node->payload.dbl = *(double *)ptr;
+ break;
+
+ case AST_DATA_STRING:
+ case AST_DATA_POINTER:
+ node->payload.ptr = ptr;
+ break;
+
+ case AST_DATA_IPADDR:
+ node->payload.ipaddr = *(struct in_addr *)ptr;
+ break;
+
+ default: break;
+ }
+
+ data_result_add_child(root, node);
+
+ 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, 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, 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,
unsigned int boolean)
{
- /* TODO: implement this. */
- /* adds a boolean node inside another node. */
- return NULL;
+ return __ast_data_add(root, childname, AST_DATA_BOOLEAN, &boolean);
+}
+
+struct ast_data *ast_data_add_str(struct ast_data *root, const char *childname, const char *value)
+{
+ char *name;
+
+ if (!(name = ast_malloc(1 + (ast_strlen_zero(value) ? 0 : strlen(value)))))
+ return NULL;
+
+ strcpy(name, value);
+ return __ast_data_add(root, childname, AST_DATA_STRING, name);
}
struct ast_data *ast_data_create(const char *name)
{
- if (!name) {
+ if (ast_strlen_zero(name)) {
ast_log(LOG_ERROR, "You must specify a root node name in order to create "
"a data result tree\n");
return NULL;
@@ -684,19 +766,34 @@
return data_result_create(name);
}
-void ast_data_free(struct ast_data *root)
-{
+/*!
+ * \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 *node;
-
- /* Free internal nodes too. */
- i = ao2_iterator_init(root->children, 0);
- while ((node = ao2_iterator_next(&i))) {
- ast_data_free(node);
- ao2_unlink(root->children, node);
- }
-
- ao2_ref(root, -1);
+ 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);
}
/* XXX: test callback */
More information about the asterisk-commits
mailing list