#define USE_XML_ATTR_DATA
#include <xml/attrdata.h>
#include <xml/attrlist.h>
#include <xml/attrnode.h>
#include <string.h>

#define ___ {
#define ____ }

/* the node->attributes is a sorted list, sorted by ->data->name */
void    xml_node_attribute_remove_all (xml_GNode* node)
{
    if (! node) return;
    xml_attr_list_free (node->attributes);
    node->attributes = 0;
}
/* if the key already exists in the attribute-list then its current
   value replaced with the new value. The old values get destroyed
   then and  the new key too (since that memory is probably just
   allocated and its better to release it back early).
 */
void     xml_node_attribute_insert (xml_GNode* node,
				      gchar* key, gchar* value)
{
    /* g_hash_table_insert (node->attributes,  key, value); */
    if (! key) return;
    ___ xml_AttrList* list = node->attributes;
    if (! list)
    
{
	node->attributes = xml_attr_list_new0 (key, value);
	return;
    }
next: ___ int cmp = strcmp (list->data->name, key); if (cmp < 0)
{
	if (list->next) 
{ list = list->next; goto next; }
list->next = xml_attr_list_new0 (key, value); list->next->prev = list; return; }
if (cmp == 0)
{   /* replace value, release key */
	g_free (key);
	g_free (list->data->value);
	list->data->value = value;
	return;
    }
____; /* cmp > 0 */ node->attributes = xml_attr_list_insert_before (node->attributes, list, xml_attr_data_new0 (key, value)); ____; }
#if 0 /* this would be faster ! */
List* lookup_node (xml_GNode* node, const gchar* key)
{
    if (! key) return 0;
    ___ xml_AttrList* link = node->attributes;
    if (! link) return 0;

    for (; link ; link = link->next)
    
{
	int cmp= strcmp (link->data->name, key);
	if (cmp < 0) continue;
	if (cmp == 0) break;
	link = 0; break;
    }
return link; ____; }
#endif
gboolean xml_node_attribute_remove (xml_GNode* node, const gchar* key)
{
    xml_AttrList* link = xml_attr_list_find_name (node->attributes, key);
    if (! link) return FALSE; 
    node->attributes = xml_attr_list_remove_link (node->attributes, link);
    xml_attr_list_free_1 (link);
    return TRUE;
}
gboolean xml_node_attribute_steal (xml_GNode* node, const gchar* key)
{
    if (! node) return FALSE;
    ___ xml_AttrList* link = xml_attr_list_find_name (node->attributes, key);
    if (! link) return FALSE;
    node->attributes = xml_attr_list_remove_link (node->attributes, link);
    g_free (link->data); /* keep "key" and "value" */
    xml_attr_list_free_link_1 (link);
    return TRUE;
    ____;
}
gchar*   xml_node_attribute_lookup (xml_GNode* node, const gchar* key)
{
    if (! node) return 0;
    ___ xml_AttrList* link = xml_attr_list_find_name (node->attributes, key);
    if (! link) return 0;
    return link->data->value;
    ____;
}
guint   xml_node_attribute_count (xml_GNode* node)
{
    /* return  g_hash_table_size (node->attributes); */
    if (! node) return 0;
    return xml_node_attribute_count_ (node);
}
# if 0 /* deleted */
void     xml_node_attribute_foreach (xml_GNode* node,
				     xml_GHFunc func,
				     gpointer user_data)
{
    if (! node || ! func) return;
    ___ xml_AttrList* list = node->attributes;
    for (; list ; list = list->next)
    
{
	func (list->data->name, list->data->value, user_data);
    }
____; }
guint   xml_node_attribute_foreach_remove (xml_GNode* node,
					     xml_GHRFunc func,
					     gpointer user_data)
{ 
    if (! node || ! func) return 0;
    ___ xml_AttrList* link = node->attributes; guint count = 0;
    ___ xml_AttrList* next; 
    for (; link ; link = next)
    
{
	next = link->next;
	if (func (link->data->name, link->data->value, user_data))
	
{
	    node->attributes = 
		xml_attr_list_remove_link (node->attributes, link);
	    xml_attr_list_free_1 (link);
	    count ++;
	}
}
____; return count; ____; }
guint   xml_node_attribute_foreach_steal (xml_GNode* node,
					  xml_GHRFunc func,
					  gpointer user_data)
{
    if (! node || ! func) return 0;
    ___ xml_AttrList* link = node->attributes; guint count = 0;
    ___ xml_AttrList* next;
    for (; link ; link = next)
    
{
	next = link->next;
	if (func (link->data->name, link->data->value, user_data))
	
{
	    node->attributes = 
		xml_attr_list_remove_link (node->attributes, link);
	    g_free (link->data); /* keep "key" and "value" */
	    xml_attr_list_free_link_1 (link);
	    count++;
	}
}
____; return count; ____; }
# endif /* deleted */
/* 
   Local variables:
   c-file-style: "stroustrup"
   End:
 */