/**
 * Runs the @p for_each_func function on each entry in the given hash.
 * @param   hash          The given hash.
 * @param   for_each_func The function that each entry is passed to.
 * @param		user_data			a pointer passed to calls of for_each_func
 * @return  TRUE on success, FALSE otherwise.
 * @ingroup Ecore_Data_Hash_ADT_Traverse_Group
 */
EAPI int
ecore_hash_for_each_node(Ecore_Hash *hash,
                         Ecore_For_Each for_each_func,
                         void *user_data)
{
   unsigned int i = 0;

   CHECK_PARAM_POINTER_RETURN("hash",          hash,          FALSE);
   CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE);

   while (i < ecore_prime_table[hash->size])
     {
        if (hash->buckets[i])
          {
             Ecore_Hash_Node *node;

             for (node = hash->buckets[i]; node; node = node->next)
               {
                  for_each_func(node, user_data);
               }
          }

        i++;
     }

   return TRUE;
}
Пример #2
0
/**
 * Write the transformed xml document out to a file descriptor.
 * @param   xml The xml document
 * @param  xsl The xml stylesheet
 * @param  params The transform parameters
 * @param   fd The source xml input descriptor
 * @return	@c TRUE if successful, @c FALSE if an error occurs.
 * @ingroup EXML_XSLT_Group
 */
int exml_transform_fd_write( EXML *xml, EXML_XSL *xsl, const char *params[],
                             int fd )
{
	int ret;
	xmlDocPtr res, doc;

	CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE);
	CHECK_PARAM_POINTER_RETURN("xsl", xsl, FALSE);
	
	exml_doc_write(xml, &doc);

	res = xsltApplyStylesheet(xsl->cur, doc, params);

	xmlFreeDoc(doc);

	if( !res ) {
		return FALSE;
	}

	ret = xsltSaveResultToFd(fd, res, xsl->cur);

	xmlFreeDoc(res);

	xsltCleanupGlobals();

	if( ret < 0 )
		return FALSE;

	return TRUE;
}
Пример #3
0
/**
 * Place a node in the tree.
 * @param tree The tree to add @a node.
 * @param node The node to add to @a tree.
 * @return TRUE on a successful add, FALSE otherwise.
 */
EAPI int edata_tree_node_add(Edata_Tree *tree, Edata_Tree_Node *node)
{
	Edata_Tree_Node *travel = NULL;

	CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
	CHECK_PARAM_POINTER_RETURN("node", node, FALSE);

	/* Find where to put this new node. */
	if (!tree->tree)
		tree->tree = node;
	else
	{
		travel = tree_node_find_parent(tree, node->key);
		node->parent = travel;

		/* The node is less than travel */
		if (tree->compare_func(node->key, travel->key) < 0)
		{
			travel->right_child = node;
			travel->max_left = 1;
			/* The node is greater than travel */
		}
		else
		{
			travel->left_child = node;
			travel->max_right = 1;
		}
	}

	return TRUE;
}
/*
 * @brief Add the node to the hash table
 * @param hash: the hash table to add the key
 * @param node: the node to add to the hash table
 * @return Returns FALSE on error, TRUE on success
 */
static int
_ecore_hash_node_add(Ecore_Hash *hash, Ecore_Hash_Node *node)
{
   unsigned long hash_val;

   CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);
   CHECK_PARAM_POINTER_RETURN("node", node, FALSE);

   /* Check to see if the hash needs to be resized */
   if (ECORE_HASH_INCREASE(hash))
      _ecore_hash_increase(hash);

   /* Compute the position in the table */
   if (!hash->hash_func)
      hash_val = (unsigned long)node->key % ecore_prime_table[hash->size];
   else
      hash_val = ECORE_COMPUTE_HASH(hash, node->key);

   /* Prepend the node to the list at the index position */
   node->next = hash->buckets[hash_val];
   hash->buckets[hash_val] = node;
   hash->nodes++;

   return TRUE;
}
/**
 * Retrieves the first value that matches
 * table.
 * @param   hash The given hash table.
 * @param   key  The key to search for.
 * @return  The value corresponding to key on success, @c NULL otherwise.
 * @ingroup Ecore_Data_Hash_ADT_Data_Group
 */
EAPI void *
ecore_hash_find(Ecore_Hash *hash, Ecore_Compare_Cb compare, const void *value)
{
   unsigned int i = 0;

   CHECK_PARAM_POINTER_RETURN("hash",    hash,    NULL);
   CHECK_PARAM_POINTER_RETURN("compare", compare, NULL);
   CHECK_PARAM_POINTER_RETURN("value",   value,   NULL);

   while (i < ecore_prime_table[hash->size])
     {
        if (hash->buckets[i])
          {
             Ecore_Hash_Node *node;

             for (node = hash->buckets[i]; node; node = node->next)
               {
                  if (!compare(node->value, value))
                     return node->value;
               }
          }

        i++;
     }

   return NULL;
}
Пример #6
0
/**
 * @brief Execute the function for each node in the tree
 * @param tree: the tree to traverse
 * @param for_each_func: the function to execute for each node
 * @param user_data: data passed to each for_each_func call
 * @return Returns TRUE on success, FALSE on failure.
 */
EAPI int edata_tree_for_each_node(Edata_Tree *tree,
		Edata_For_Each for_each_func, void *user_data)
{
	CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);
	CHECK_PARAM_POINTER_RETURN("for_each_func", for_each_func, FALSE);

	if (!tree->tree)
		return FALSE;

	return tree_for_each_node(tree->tree, for_each_func, user_data);
}
Пример #7
0
/**
 * Set the current tag name
 * @param   xml The xml document to modify
 * @param   tag The new tag name
 * @return  @c TRUE if successful, @c FALSE if an error occurs.
 * @ingroup EXML_Modfiy_Element_Group
 */
int exml_tag_set(EXML *xml, char *tag)
{
	CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE);
	CHECK_PARAM_POINTER_RETURN("tag", tag, FALSE);

	IF_FREE(xml->current->tag);

	xml->current->tag = strdup( tag );
	if (!xml->current->tag)
		return FALSE;

	return TRUE;
}
Пример #8
0
/**
 * Set the current tag value
 * @param   xml The xml document to modify
 * @param   value The new value name
 * @return  @c TRUE if successful, @c FALSE if an error occurs.
 * @ingroup EXML_Modfiy_Element_Group
 */
int exml_value_set(EXML *xml, char *value)
{
	CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE);
	CHECK_PARAM_POINTER_RETURN("value", value, FALSE);

	IF_FREE(xml->current->value);

	xml->current->value = strdup( value );
	if (!xml->current->value)
		return FALSE;

	return TRUE;
}
Пример #9
0
/**
 * Create a new child tag for the current node level, and sets it to current
 * @param   xml The xml document to add the tag to
 * @return  @c TRUE if successful, @c FALSE if an error occurs.
 * @ingroup EXML_Create_Element_Group
 */
int exml_start(EXML *xml)
{
	EXML_Node *node;

	CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE);

	if (xml->current == NULL && xml->top)
		return FALSE;

	node = exml_node_new();
	if (!node)
		return FALSE;

	node->parent = xml->current;

	/* no sanity check on xml->current pointer */

	if (xml->top == NULL)
		xml->current = xml->top = node;
	else {
		ecore_list_append( xml->current->children, node );
		xml->current = node;
	}

	return TRUE;
}
/**
 * Counts the number of nodes in a hash table.
 * @param   hash The hash table to count current nodes.
 * @return  The number of nodes in the hash.
 * @ingroup Ecore_Data_Hash_ADT_Destruction_Group
 */
EAPI int
ecore_hash_count(Ecore_Hash *hash)
{
   CHECK_PARAM_POINTER_RETURN("hash", hash, 0);

   return hash->nodes;
}
/**
 * Sets a key-value pair in the given hash table.
 * @param   hash    The given hash table.
 * @param   key     The key.
 * @param   value   The value.
 * @return  @c TRUE if successful, @c FALSE if not.
 * @ingroup Ecore_Data_Hash_ADT_Data_Group
 */
EAPI int
ecore_hash_set(Ecore_Hash *hash, void *key, void *value)
{
   int ret = FALSE;
   Ecore_Hash_Node *node;

   CHECK_PARAM_POINTER_RETURN("hash", hash, FALSE);

   node = _ecore_hash_node_get(hash, key);
   if (node)
     {
        if (hash->free_key)
           hash->free_key(key);

        if (node->value && hash->free_value)
           hash->free_value(node->value);

        node->value = value;
        ret = TRUE;
     }
   else
     {
        node = _ecore_hash_node_new(key, value);
        if (node)
           ret = _ecore_hash_node_add(hash, node);
     }

   return ret;
}
Пример #12
0
/* The tree is overbalanced to the right, so we rotate nodes to the left */
static int tree_node_rotate_left(Edata_Tree *tree, Edata_Tree_Node *top_node)
{
	Edata_Tree_Node *temp;

	CHECK_PARAM_POINTER_RETURN("top_node", top_node, FALSE);

	/*
	 * The right branch's left branch becomes the nodes right branch,
	 * the right branch becomes the top node, and the node becomes the
	 * left branch.
	 */
	temp = top_node->left_child;
	top_node->left_child = temp->right_child;
	temp->right_child = top_node;

	/* Make sure the nodes know who their new parents are. */
	temp->parent = top_node->parent;
	if (temp->parent == NULL)
		tree->tree = temp;
	else
	{
		if (temp->parent->left_child == top_node)
			temp->parent->left_child = temp;
		else
			temp->parent->right_child = temp;
	}
	top_node->parent = temp;

	/* And recalculate node heights */
	tree_node_balance(tree, top_node);
	tree_node_balance(tree, temp);

	return TRUE;
}
Пример #13
0
/* Balance the tree with respect to node */
static int tree_node_balance(Edata_Tree *tree, Edata_Tree_Node *top_node)
{
	int balance;

	CHECK_PARAM_POINTER_RETURN("top_node", top_node, FALSE);

	/* Get the height of the left branch. */
	if (top_node->right_child)
		top_node->max_left = MAX_HEIGHT(top_node->right_child) + 1;
	else
		top_node->max_left = 0;

	/* Get the height of the right branch. */
	if (top_node->left_child)
		top_node->max_right = MAX_HEIGHT(top_node->left_child) + 1;
	else
		top_node->max_right = 0;

	/* Determine which side has a larger height. */
	balance = top_node->max_right - top_node->max_left;

	/* if the left side has a height advantage >1 rotate right */
	if (balance < -1)
		tree_node_rotate_right(tree, top_node);
	/* else if the left side has a height advantage >1 rotate left */
	else if (balance > 1)
		tree_node_rotate_left(tree, top_node);

	return TRUE;
}
Пример #14
0
/* Search for the node with a specified key */
static Edata_Tree_Node * tree_node_find(Edata_Tree *tree, const void *key)
{
	int compare;
	Edata_Tree_Node *node;

	CHECK_PARAM_POINTER_RETURN("tree", tree, NULL);

	node = tree->tree;
	while (node && (compare = tree->compare_func(key, node->key)) != 0)
	{

		if (compare < 0)
		{
			if (!node->right_child)
				return NULL;

			node = node->right_child;
		}
		else
		{
			if (!node->left_child)
				return NULL;

			node = node->left_child;
		}
	}

	return node;
}
Пример #15
0
/* Find the parent for the key */
static Edata_Tree_Node * tree_node_find_parent(Edata_Tree *tree,
		const void *key)
{
	Edata_Tree_Node *parent, *travel;

	CHECK_PARAM_POINTER_RETURN("tree", tree, NULL);

	parent = tree_node_find(tree, key);
	if (parent)
		parent = parent->parent;

	travel = tree->tree;
	if (!travel)
		return NULL;

	while (!parent)
	{
		int compare;

		if ((compare = tree->compare_func(key, travel->key)) < 0)
		{
			if (!travel->right_child)
				parent = travel;
			travel = travel->right_child;
		}
		else
		{
			if (!travel->left_child)
				parent = travel;
			travel = travel->left_child;
		}
	}

	return parent;
}
/*
 * @brief Retrieve the node associated with key
 * @param hash: the hash table to search for the key
 * @param key: the key to search for in the hash table
 * @return Returns NULL on error, node corresponding to key on success
 */
static Ecore_Hash_Node *
_ecore_hash_node_get(Ecore_Hash *hash, const void *key)
{
   unsigned long hash_val;
   Ecore_Hash_Node *node = NULL;

   CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);

   if (!hash->buckets)
      return NULL;

   /* Compute the position in the table */
   if (!hash->hash_func)
      hash_val = (unsigned long)key % ecore_prime_table[hash->size];
   else
      hash_val = ECORE_COMPUTE_HASH(hash, key);

   /* Grab the bucket at the specified position */
   if (hash->buckets[hash_val])
     {
        node = _ecore_hash_bucket_get(hash, hash->buckets[hash_val], key);
        /*
         * Move matched node to the front of the list as it's likely
         * to be searched for again soon.
         */
        if (node && node != hash->buckets[hash_val])
          {
             node->next = hash->buckets[hash_val];
             hash->buckets[hash_val] = node;
          }
     }

   return node;
}
/**
 * Retrieves an ecore_list of all keys in the given hash.
 * @param   hash          The given hash.
 * @return  new ecore_list on success, NULL otherwise
 * @ingroup Ecore_Data_Hash_ADT_Traverse_Group
 */
EAPI Ecore_List *
ecore_hash_keys(Ecore_Hash *hash)
{
   unsigned int i = 0;
   Ecore_List *keys;

   CHECK_PARAM_POINTER_RETURN("hash", hash, NULL);

   keys = ecore_list_new();
   while (i < ecore_prime_table[hash->size])
     {
        if (hash->buckets[i])
          {
             Ecore_Hash_Node *node;

             for (node = hash->buckets[i]; node; node = node->next)
               {
                  ecore_list_append(keys, node->key);
               }
          }

        i++;
     }
   ecore_list_first_goto(keys);

   return keys;
}
Пример #18
0
/**
 * Set the value associated with key to @a value.
 * @param  tree  The tree that contains the key/value pair.
 * @param  key   The key to identify which node to set a value.
 * @param  value Value to set the found node.
 * @return TRUE if successful, FALSE if not.
 */
EAPI int edata_tree_set(Edata_Tree *tree, void *key, void *value)
{
	Edata_Tree_Node *node = NULL;

	CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);

	node = tree_node_find(tree, key);
	if (!node)
	{
		node = edata_tree_node_new();
		edata_tree_node_key_set(node, key);
		if (!edata_tree_node_add(tree, node))
			return FALSE;
	}
	else
	{
		if (tree->free_key)
			tree->free_key(key);
		if (node->value && tree->free_value)
			tree->free_value(node->value);
	}

	edata_tree_node_value_set(node, value);

	for (; node; node = node->parent)
		tree_node_balance(tree, node);

	return TRUE;
}
Пример #19
0
/**
 * Move the current xml document pointer to the indicated node
 * @param   xml The xml document
 * @param   node The position within the document to move to
 * @return  The current xml tag name
 * @ingroup EXML_Traversal_Group
 */
char *exml_goto_node(EXML *xml, EXML_Node *node)
{
	Ecore_List *stack;
	EXML_Node *n, *l;

	CHECK_PARAM_POINTER_RETURN("xml", xml, NULL);

	stack = ecore_list_new();
	n = node;

	while( n->parent != NULL ) {
		ecore_list_prepend(stack, n);
		n = n->parent;
	}

	l = xml->top;

	if (n != l)
		return NULL;

	while( (n = ecore_list_first_remove(stack)) ) {
		l = ecore_list_goto(l->children, n);

		if (!l)
			return NULL;
	}

	xml->current = node;

	return xml->current ? xml->current->tag : NULL;
}
Пример #20
0
/**
 * Move the current xml to its next sibling, return NULL and move to parent
 * at the end of the list
 * @param   xml The xml document
 * @return  The current xml tag name or NULL
 * @ingroup EXML_Traversal_Group
 */
char *exml_next_nomove(EXML *xml)
{
	Ecore_List *p_list;
	EXML_Node *parent, *cur;

	CHECK_PARAM_POINTER_RETURN("xml", xml, NULL);

	if (xml->current) {
		cur = xml->current;
		parent = cur->parent;

		if (parent) {
			p_list = parent->children;

			ecore_list_goto( p_list, xml->current );
			ecore_list_next( p_list );
			if ((xml->current = ecore_list_current(p_list)) == NULL) {
				xml->current = cur;
				return NULL;
			}
		} else
			xml->current = NULL;
	}

	return xml->current ? xml->current->tag : NULL;
}
Пример #21
0
/**
 * Remove the current node from the document
 * @param   xml The xml document to modify
 * @return  @c TRUE if successful, @c FALSE if an error occurs.
 * @ingroup EXML_Modfiy_Element_Group
 */
int exml_tag_remove(EXML *xml)
{
	EXML_Node *n_cur;

	CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE);

	n_cur = xml->current;
	if (!n_cur)
		return FALSE;

	n_cur = n_cur->parent;

	if (n_cur) {
		EXML_Node *c_parent = n_cur;
		Ecore_List *c_list = c_parent->children;

		ecore_list_goto( c_list, xml->current );
		ecore_list_remove_destroy( c_list );
		if ((n_cur = ecore_list_current( c_list )) == NULL)
			if ((n_cur = ecore_list_last_goto( c_list )) == NULL)
				n_cur = c_parent;
	} else {
		/* we're removing the top level node */
		xml->top = NULL;
		_exml_node_destroy( xml->current );
	}

	xml->current = n_cur;
	return TRUE;
}
Пример #22
0
/**
 * Move the current xml document pointer to the toplevel
 * @param   xml The xml document
 * @return  The current xml tag name
 * @ingroup EXML_Traversal_Group
 */
char *exml_goto_top(EXML *xml)
{
	CHECK_PARAM_POINTER_RETURN("xml", xml, NULL);

	xml->current = xml->top;

	return xml->current ? xml->current->tag : NULL;
}
Пример #23
0
/*
 * @brief Add a function to be called at node destroy time
 * @param tree: the tree that will use this function when nodes are destroyed
 * @param free_key: the function that will be passed the node being freed
 * @return Returns TRUE on successful set, FALSE otherwise.
 */
EAPI int edata_tree_free_key_cb_set(Edata_Tree *tree, Edata_Free_Cb free_key)
{
	CHECK_PARAM_POINTER_RETURN("tree", tree, FALSE);

	tree->free_key = free_key;

	return TRUE;
}
Пример #24
0
/**
 * Set an attribute for this tag
 * @param   xml The xml document to modify
 * @param   attr The attribute to set
 * @param   value The value to set this attribute to
 * @return  @c TRUE if successful, @c FALSE if an error occurs.
 * @ingroup EXML_Modfiy_Element_Group
 */
int exml_attribute_set(EXML *xml, char *attr, char *value)
{
	char *oldvalue;

	CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE);
	CHECK_PARAM_POINTER_RETURN("attr", attr, FALSE);

	oldvalue = ecore_hash_get( xml->current->attributes, attr );
	IF_FREE(oldvalue);

	if (value)
		value = strdup(value);

	ecore_hash_set( xml->current->attributes, strdup( attr ), value );

	return TRUE;
}
Пример #25
0
/*
 * @brief Set the value of the node's key  to key
 * @param node: the node to be set
 * @param key: the value to set it's key to.
 * @return Returns TRUE if the node is set successfully, FALSE if not.
 */
EAPI int edata_tree_node_key_set(Edata_Tree_Node *node, void *key)
{
	CHECK_PARAM_POINTER_RETURN("node", node, FALSE);

	node->key = key;

	return TRUE;
}
Пример #26
0
/**
 * Set the function for freeing data.
 * @param  heap      The heap that will use this function when nodes are
 *                   destroyed.
 * @param  free_func The function that will free the key data.
 * @return @c TRUE on successful set, @c FALSE otherwise.
 */
EAPI int edata_sheap_free_cb_set(Edata_Sheap *heap, Edata_Free_Cb free_func)
{
	CHECK_PARAM_POINTER_RETURN("heap", heap, FALSE);

	heap->free_func = free_func;

	return TRUE;
}
Пример #27
0
/*
 * @brief Set the value of the node to value
 * @param node: the node to be set
 * @param value: the value to set the node to.
 * @return Returns TRUE if the node is set successfully, FALSE if not.
 */
EAPI int edata_tree_node_value_set(Edata_Tree_Node *node, void *value)
{
	CHECK_PARAM_POINTER_RETURN("node", node, FALSE);

	node->value = value;

	return TRUE;
}
Пример #28
0
/**
 * Check for children in the current node
 * @param   xml The xml document
 * @return  @c TRUE if children are present, @c FALSE if not.
 */
int exml_has_children(EXML *xml)
{
	CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE);
	
	if (xml->current && xml->current->children)
		return !ecore_list_empty_is(xml->current->children);

	return FALSE;
}
Пример #29
0
/**
 * Move the current xml to its parent
 * @param   xml The xml document
 * @return  The current xml tag name
 * @ingroup EXML_Traversal_Group
 */
char *exml_up(EXML *xml)
{
	CHECK_PARAM_POINTER_RETURN("xml", xml, NULL);

	if (xml->current)
		xml->current = xml->current->parent;

	return xml->current ? xml->current->tag : NULL;
}
Пример #30
0
/**
 * Initialize an xml document structure to some sane starting values.
 * @param   xml The xml to initialize.
 * @return  @c TRUE if successful, @c FALSE if an error occurs.
 * @ingroup EXML_Creation_Group
 */
int exml_init(EXML *xml)
{
	CHECK_PARAM_POINTER_RETURN("xml", xml, FALSE);

	xml->buffers = ecore_hash_new(ecore_direct_hash, ecore_direct_compare);
	ecore_hash_free_value_cb_set(xml->buffers, ECORE_FREE_CB(xmlBufferFree));

	return TRUE;
}