コード例 #1
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Free an XML node.
 *
 * This is the user-visible routine that can succeed only if the node is
 * not part of a tree structure.
 */
void
xnode_free(xnode_t *xn)
{
	etree_t t;

	xnode_check(xn);
	etree_init_root(&t, xn, TRUE, offsetof(xnode_t, node));
	g_assert(etree_is_standalone(&t, xn));

	switch (xn->type) {
	case XNODE_T_COMMENT:
		HFREE_NULL(xn->u.c.text);
		break;
	case XNODE_T_TEXT:
		HFREE_NULL(xn->u.t.text);
		break;
	case XNODE_T_PI:
		atom_str_free_null(&xn->u.pi.name);
		HFREE_NULL(xn->u.pi.target);
		break;
	case XNODE_T_ELEMENT:
		atom_str_free_null(&xn->u.e.name);
		atom_str_free_null(&xn->u.e.ns_uri);
		nv_table_free_null(&xn->u.e.ns);
		xattr_table_free_null(&xn->u.e.attrs);
		break;
	case XNODE_T_MAX:
		g_assert_not_reached();
	}

	xn->magic = 0;
	WFREE(xn);
}
コード例 #2
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Make sure node is orphan.
 */
static void
xnode_orphan_check(const xnode_t * const xn)
{
	etree_t t;

	xnode_check(xn);
	etree_init_root(&t, xn, TRUE, offsetof(xnode_t, node));
	g_assert(etree_is_orphan(&t, xn));
}
コード例 #3
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * @return last child node, or NULL if the node has no children (leaf node).
 */
xnode_t *
xnode_last_child(const xnode_t *xn)
{
	etree_t t;

	xnode_check(xn);
	etree_init_root(&t, xn, TRUE, offsetof(xnode_t, node));
	return etree_last_child(&t, xn);
}
コード例 #4
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * @return next sibbling node, or NULL if the node has no more siblings.
 */
xnode_t *
xnode_next_sibling(const xnode_t *xn)
{
	etree_t t;

	xnode_check(xn);
	etree_init_root(&t, xn, TRUE, offsetof(xnode_t, node));
	return etree_next_sibling(&t, xn);
}
コード例 #5
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Recursively apply function on each node, in depth-first mode.
 *
 * Traversal is done in such a way that the applied function can safely
 * free up the local node.
 */
void
xnode_tree_foreach(xnode_t *root, data_fn_t func, void *data)
{
	etree_t t;

	xnode_check(root);

	etree_init_root(&t, root, TRUE, offsetof(xnode_t, node));
	etree_foreach(&t, func, data);
}
コード例 #6
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Detach node and all its sub-tree from a tree, making it the new root of
 * a smaller tree.
 */
void
xnode_detach(xnode_t *xn)
{
	etree_t t;

	xnode_check(xn);

	etree_init_root(&t, xn, TRUE, offsetof(xnode_t, node));
	etree_detach(&t, xn);
}
コード例 #7
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Free an XML tree, recursively.
 */
void
xnode_tree_free(xnode_t *root)
{
	etree_t t;

	xnode_check(root);

	etree_init_root(&t, root, TRUE, offsetof(xnode_t, node));
	etree_free(&t, xnode_item_free);
}
コード例 #8
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Recursively apply matching function on each node, in depth-first order,
 * until it returns TRUE, at which time we return the matching node.
 *
 * @return the first matching node in the traversal path, NULL if none matched.
 */
xnode_t *
xnode_tree_find(xnode_t *root, match_fn_t func, void *data)
{
	etree_t t;

	xnode_check(root);

	etree_init_root(&t, root, TRUE, offsetof(xnode_t, node));
	return etree_find(&t, func, data);
}
コード例 #9
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Add orphan node as right-sibling of previous node (cannot be the root node).
 */
void
xnode_add_sibling(xnode_t *previous, xnode_t *node)
{
	etree_t t;

	xnode_check(previous);
	xnode_orphan_check(node);

	etree_init_root(&t, previous, TRUE, offsetof(xnode_t, node));
	etree_add_right_sibling(&t, previous, node);
}
コード例 #10
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Add parentless node under parent as first child.
 */
void
xnode_add_first_child(xnode_t *parent, xnode_t *node)
{
	etree_t t;

	xnode_check(parent);
	xnode_orphan_check(node);

	etree_init_root(&t, parent, TRUE, offsetof(xnode_t, node));
	etree_prepend_child(&t, parent, node);
}
コード例 #11
0
ファイル: etree.c プロジェクト: qgewfg/gtk-gnutella
/**
 * Free sub-tree, destroying all its items and removing the reference in
 * the parent node, if any.
 *
 * @param tree		the tree descriptor
 * @param item		root item of sub-tree to remove
 * @param fcb		free routine for each item
 */
void
etree_sub_free(etree_t *tree, void *item, free_fn_t fcb)
{
	etree_t dtree;

	etree_check(tree);

	etree_detach(tree, item);
	etree_init_root(&dtree, item, etree_is_extended(tree), tree->offset);
	etree_free(&dtree, fcb);
}
コード例 #12
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Recursively apply two functions on each node, in depth-first mode.
 *
 * The first function "enter" is called when we enter a node and the
 * second "leave" is called when all the children have been processed,
 * before returning.
 *
 * Traversal is done in such a way that the "leave" function can safely
 * free up the local node.
 *
 * Traversal of a branch is aborted when "enter" returns FALSE, i.e. the
 * children of the node are not traversed and the "leave" callback is not
 * called since we did not enter...
 */
void
xnode_tree_enter_leave(xnode_t *root,
	match_fn_t enter, data_fn_t leave, void *data)
{
	etree_t t;

	xnode_check(root);

	etree_init_root(&t, root, TRUE, offsetof(xnode_t, node));
	etree_traverse(&t, ETREE_TRAVERSE_ALL | ETREE_CALL_AFTER,
		0, ETREE_MAX_DEPTH, enter, leave, data);
}
コード例 #13
0
ファイル: xnode.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Same as xnode_tree_find() but limit search to specified depth: 0 means
 * the root node only, 1 corresponds to the immediate children of the root,
 * and so on.
 *
 * @return the first matching node in the traversal path, NULL if none matched.
 */
xnode_t *
xnode_tree_find_depth(xnode_t *root, unsigned depth,
	match_fn_t func, void *data)
{
	etree_t t;

	xnode_check(root);
	g_assert(uint_is_non_negative(depth));

	etree_init_root(&t, root, TRUE, offsetof(xnode_t, node));
	return etree_find_depth(&t, depth, func, data);
}