[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