2001-02-23 17:55:21 +00:00
/*
* hash . c : chained hash tables
*
* Reference : Your favorite introductory book on algorithms
*
* Copyright ( C ) 2000 Bjorn Reese and Daniel Veillard .
*
* Permission to use , copy , modify , and distribute this software for any
* purpose with or without fee is hereby granted , provided that the above
* copyright notice and this permission notice appear in all copies .
*
* THIS SOFTWARE IS PROVIDED ` ` AS IS ' ' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES , INCLUDING , WITHOUT LIMITATION , THE IMPLIED WARRANTIES OF
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE . THE AUTHORS AND
* CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER .
*
2001-04-21 16:57:29 +00:00
* Author : breese @ users . sourceforge . net
2001-02-23 17:55:21 +00:00
*/
2001-04-21 16:57:29 +00:00
# include "libxml.h"
2001-02-23 17:55:21 +00:00
# include <string.h>
# include <libxml/hash.h>
# include <libxml/xmlmemory.h>
# include <libxml/parser.h>
2001-04-18 13:09:01 +00:00
# include <libxml/xmlerror.h>
2001-10-17 15:58:35 +00:00
# include <libxml/globals.h>
2001-04-18 13:09:01 +00:00
# define MAX_HASH_LEN 8
/* #define DEBUG_GROW */
2001-02-23 17:55:21 +00:00
/*
* A single entry in the hash table
*/
typedef struct _xmlHashEntry xmlHashEntry ;
typedef xmlHashEntry * xmlHashEntryPtr ;
struct _xmlHashEntry {
struct _xmlHashEntry * next ;
xmlChar * name ;
xmlChar * name2 ;
xmlChar * name3 ;
void * payload ;
} ;
/*
* The entire hash table
*/
struct _xmlHashTable {
struct _xmlHashEntry * * table ;
int size ;
int nbElems ;
} ;
/*
* xmlHashComputeKey :
* Calculate the hash key
*/
static unsigned long
2001-04-18 13:09:01 +00:00
xmlHashComputeKey ( xmlHashTablePtr table , const xmlChar * name ,
const xmlChar * name2 , const xmlChar * name3 ) {
2001-02-23 17:55:21 +00:00
unsigned long value = 0L ;
char ch ;
2001-04-18 13:09:01 +00:00
if ( name ! = NULL ) {
value + = 30 * ( * name ) ;
while ( ( ch = * name + + ) ! = 0 ) {
/* value *= 31; */
value + = ( unsigned long ) ch ;
}
}
if ( name2 ! = NULL ) {
while ( ( ch = * name2 + + ) ! = 0 ) {
/* value *= 31; */
value + = ( unsigned long ) ch ;
}
}
if ( name3 ! = NULL ) {
while ( ( ch = * name3 + + ) ! = 0 ) {
/* value *= 31; */
value + = ( unsigned long ) ch ;
}
2001-02-23 17:55:21 +00:00
}
return ( value % table - > size ) ;
}
/**
* xmlHashCreate :
* @ size : the size of the hash table
*
* Create a new xmlHashTablePtr .
*
* Returns the newly created object , or NULL if an error occured .
*/
xmlHashTablePtr
xmlHashCreate ( int size ) {
xmlHashTablePtr table ;
if ( size < = 0 )
size = 256 ;
table = xmlMalloc ( sizeof ( xmlHashTable ) ) ;
if ( table ) {
table - > size = size ;
table - > nbElems = 0 ;
table - > table = xmlMalloc ( size * sizeof ( xmlHashEntry ) ) ;
if ( table - > table ) {
memset ( table - > table , 0 , size * sizeof ( xmlHashEntry ) ) ;
return ( table ) ;
}
xmlFree ( table ) ;
}
return ( NULL ) ;
}
2001-04-18 13:09:01 +00:00
/**
* xmlHashGrow :
* @ table : the hash table
* @ size : the new size of the hash table
*
* resize the hash table
*
* Returns 0 in case of success , - 1 in case of failure
*/
2001-04-20 13:03:48 +00:00
static int
2001-04-18 13:09:01 +00:00
xmlHashGrow ( xmlHashTablePtr table , int size ) {
unsigned long key ;
int oldsize , i ;
xmlHashEntryPtr iter , next ;
struct _xmlHashEntry * * oldtable ;
# ifdef DEBUG_GROW
unsigned long nbElem = 0 ;
# endif
if ( table = = NULL )
return ( - 1 ) ;
if ( size < 8 )
return ( - 1 ) ;
if ( size > 8 * 2048 )
return ( - 1 ) ;
oldsize = table - > size ;
oldtable = table - > table ;
if ( oldtable = = NULL )
return ( - 1 ) ;
table - > table = xmlMalloc ( size * sizeof ( xmlHashEntry ) ) ;
if ( table - > table = = NULL ) {
table - > table = oldtable ;
return ( - 1 ) ;
}
memset ( table - > table , 0 , size * sizeof ( xmlHashEntry ) ) ;
table - > size = size ;
for ( i = 0 ; i < oldsize ; i + + ) {
iter = oldtable [ i ] ;
while ( iter ) {
next = iter - > next ;
/*
* put back the entry in the new table
*/
key = xmlHashComputeKey ( table , iter - > name , iter - > name2 ,
iter - > name3 ) ;
iter - > next = table - > table [ key ] ;
table - > table [ key ] = iter ;
# ifdef DEBUG_GROW
nbElem + + ;
# endif
iter = next ;
}
}
xmlFree ( oldtable ) ;
# ifdef DEBUG_GROW
xmlGenericError ( xmlGenericErrorContext ,
" xmlHashGrow : from %d to %d, %d elems \n " , oldsize , size , nbElem ) ;
# endif
return ( 0 ) ;
}
2001-02-23 17:55:21 +00:00
/**
* xmlHashFree :
* @ table : the hash table
* @ f : the deallocator function for items in the hash
*
2001-12-31 16:16:02 +00:00
* Free the hash @ table and its contents . The userdata is
* deallocated with @ f if provided .
2001-02-23 17:55:21 +00:00
*/
void
xmlHashFree ( xmlHashTablePtr table , xmlHashDeallocator f ) {
int i ;
xmlHashEntryPtr iter ;
xmlHashEntryPtr next ;
if ( table = = NULL )
return ;
if ( table - > table ) {
for ( i = 0 ; i < table - > size ; i + + ) {
iter = table - > table [ i ] ;
while ( iter ) {
next = iter - > next ;
2001-04-18 13:09:01 +00:00
if ( f )
f ( iter - > payload , iter - > name ) ;
2001-02-23 17:55:21 +00:00
if ( iter - > name )
xmlFree ( iter - > name ) ;
if ( iter - > name2 )
xmlFree ( iter - > name2 ) ;
if ( iter - > name3 )
xmlFree ( iter - > name3 ) ;
iter - > payload = NULL ;
xmlFree ( iter ) ;
iter = next ;
}
table - > table [ i ] = NULL ;
}
xmlFree ( table - > table ) ;
}
xmlFree ( table ) ;
}
/**
* xmlHashAddEntry :
* @ table : the hash table
* @ name : the name of the userdata
* @ userdata : a pointer to the userdata
*
2001-12-31 16:16:02 +00:00
* Add the @ userdata to the hash @ table . This can later be retrieved
* by using the @ name . Duplicate names generate errors .
2001-02-23 17:55:21 +00:00
*
* Returns 0 the addition succeeded and - 1 in case of error .
*/
int
xmlHashAddEntry ( xmlHashTablePtr table , const xmlChar * name , void * userdata ) {
return ( xmlHashAddEntry3 ( table , name , NULL , NULL , userdata ) ) ;
}
/**
* xmlHashAddEntry2 :
* @ table : the hash table
* @ name : the name of the userdata
* @ name2 : a second name of the userdata
* @ userdata : a pointer to the userdata
*
2001-12-31 16:16:02 +00:00
* Add the @ userdata to the hash @ table . This can later be retrieved
* by using the ( @ name , @ name2 ) tuple . Duplicate tuples generate errors .
2001-02-23 17:55:21 +00:00
*
* Returns 0 the addition succeeded and - 1 in case of error .
*/
int
xmlHashAddEntry2 ( xmlHashTablePtr table , const xmlChar * name ,
const xmlChar * name2 , void * userdata ) {
return ( xmlHashAddEntry3 ( table , name , name2 , NULL , userdata ) ) ;
}
/**
* xmlHashUpdateEntry :
* @ table : the hash table
* @ name : the name of the userdata
* @ userdata : a pointer to the userdata
* @ f : the deallocator function for replaced item ( if any )
*
2001-12-31 16:16:02 +00:00
* Add the @ userdata to the hash @ table . This can later be retrieved
* by using the @ name . Existing entry for this @ name will be removed
2001-02-23 17:55:21 +00:00
* and freed with @ f if found .
*
* Returns 0 the addition succeeded and - 1 in case of error .
*/
int
xmlHashUpdateEntry ( xmlHashTablePtr table , const xmlChar * name ,
void * userdata , xmlHashDeallocator f ) {
return ( xmlHashUpdateEntry3 ( table , name , NULL , NULL , userdata , f ) ) ;
}
/**
* xmlHashUpdateEntry2 :
* @ table : the hash table
* @ name : the name of the userdata
* @ name2 : a second name of the userdata
* @ userdata : a pointer to the userdata
* @ f : the deallocator function for replaced item ( if any )
*
2001-12-31 16:16:02 +00:00
* Add the @ userdata to the hash @ table . This can later be retrieved
* by using the ( @ name , @ name2 ) tuple . Existing entry for this tuple will
2001-02-23 17:55:21 +00:00
* be removed and freed with @ f if found .
*
* Returns 0 the addition succeeded and - 1 in case of error .
*/
int
xmlHashUpdateEntry2 ( xmlHashTablePtr table , const xmlChar * name ,
const xmlChar * name2 , void * userdata ,
xmlHashDeallocator f ) {
return ( xmlHashUpdateEntry3 ( table , name , name2 , NULL , userdata , f ) ) ;
}
/**
* xmlHashLookup :
* @ table : the hash table
* @ name : the name of the userdata
*
2001-12-31 16:16:02 +00:00
* Find the userdata specified by the @ name .
2001-02-23 17:55:21 +00:00
*
2001-07-18 19:30:27 +00:00
* Returns the pointer to the userdata
2001-02-23 17:55:21 +00:00
*/
void *
xmlHashLookup ( xmlHashTablePtr table , const xmlChar * name ) {
return ( xmlHashLookup3 ( table , name , NULL , NULL ) ) ;
}
/**
* xmlHashLookup2 :
* @ table : the hash table
* @ name : the name of the userdata
* @ name2 : a second name of the userdata
*
2001-12-31 16:16:02 +00:00
* Find the userdata specified by the ( @ name , @ name2 ) tuple .
2001-02-23 17:55:21 +00:00
*
2001-07-18 19:30:27 +00:00
* Returns the pointer to the userdata
2001-02-23 17:55:21 +00:00
*/
void *
xmlHashLookup2 ( xmlHashTablePtr table , const xmlChar * name ,
const xmlChar * name2 ) {
return ( xmlHashLookup3 ( table , name , name2 , NULL ) ) ;
}
/**
* xmlHashAddEntry3 :
* @ table : the hash table
* @ name : the name of the userdata
* @ name2 : a second name of the userdata
* @ name3 : a third name of the userdata
* @ userdata : a pointer to the userdata
*
2001-12-31 16:16:02 +00:00
* Add the @ userdata to the hash @ table . This can later be retrieved
* by using the tuple ( @ name , @ name2 , @ name3 ) . Duplicate entries generate
2001-02-23 17:55:21 +00:00
* errors .
*
* Returns 0 the addition succeeded and - 1 in case of error .
*/
int
xmlHashAddEntry3 ( xmlHashTablePtr table , const xmlChar * name ,
const xmlChar * name2 , const xmlChar * name3 ,
void * userdata ) {
2001-04-18 13:09:01 +00:00
unsigned long key , len = 0 ;
2001-02-23 17:55:21 +00:00
xmlHashEntryPtr entry ;
xmlHashEntryPtr insert ;
if ( ( table = = NULL ) | | name = = NULL )
return ( - 1 ) ;
/*
* Check for duplicate and insertion location .
*/
2001-04-18 13:09:01 +00:00
key = xmlHashComputeKey ( table , name , name2 , name3 ) ;
2001-02-23 17:55:21 +00:00
if ( table - > table [ key ] = = NULL ) {
insert = NULL ;
} else {
for ( insert = table - > table [ key ] ; insert - > next ! = NULL ;
insert = insert - > next ) {
if ( ( xmlStrEqual ( insert - > name , name ) ) & &
( xmlStrEqual ( insert - > name2 , name2 ) ) & &
( xmlStrEqual ( insert - > name3 , name3 ) ) )
return ( - 1 ) ;
2001-04-18 13:09:01 +00:00
len + + ;
2001-02-23 17:55:21 +00:00
}
if ( ( xmlStrEqual ( insert - > name , name ) ) & &
( xmlStrEqual ( insert - > name2 , name2 ) ) & &
( xmlStrEqual ( insert - > name3 , name3 ) ) )
return ( - 1 ) ;
}
entry = xmlMalloc ( sizeof ( xmlHashEntry ) ) ;
if ( entry = = NULL )
return ( - 1 ) ;
entry - > name = xmlStrdup ( name ) ;
entry - > name2 = xmlStrdup ( name2 ) ;
entry - > name3 = xmlStrdup ( name3 ) ;
entry - > payload = userdata ;
entry - > next = NULL ;
if ( insert = = NULL ) {
table - > table [ key ] = entry ;
} else {
insert - > next = entry ;
}
table - > nbElems + + ;
2001-04-18 13:09:01 +00:00
if ( len > MAX_HASH_LEN )
xmlHashGrow ( table , MAX_HASH_LEN * table - > size ) ;
2001-02-23 17:55:21 +00:00
return ( 0 ) ;
}
/**
* xmlHashUpdateEntry3 :
* @ table : the hash table
* @ name : the name of the userdata
* @ name2 : a second name of the userdata
* @ name3 : a third name of the userdata
* @ userdata : a pointer to the userdata
* @ f : the deallocator function for replaced item ( if any )
*
2001-12-31 16:16:02 +00:00
* Add the @ userdata to the hash @ table . This can later be retrieved
* by using the tuple ( @ name , @ name2 , @ name3 ) . Existing entry for this tuple
2001-02-23 17:55:21 +00:00
* will be removed and freed with @ f if found .
*
* Returns 0 the addition succeeded and - 1 in case of error .
*/
int
xmlHashUpdateEntry3 ( xmlHashTablePtr table , const xmlChar * name ,
const xmlChar * name2 , const xmlChar * name3 ,
void * userdata , xmlHashDeallocator f ) {
unsigned long key ;
xmlHashEntryPtr entry ;
xmlHashEntryPtr insert ;
if ( ( table = = NULL ) | | name = = NULL )
return ( - 1 ) ;
/*
* Check for duplicate and insertion location .
*/
2001-04-18 13:09:01 +00:00
key = xmlHashComputeKey ( table , name , name2 , name3 ) ;
2001-02-23 17:55:21 +00:00
if ( table - > table [ key ] = = NULL ) {
insert = NULL ;
} else {
for ( insert = table - > table [ key ] ; insert - > next ! = NULL ;
insert = insert - > next ) {
if ( ( xmlStrEqual ( insert - > name , name ) ) & &
( xmlStrEqual ( insert - > name2 , name2 ) ) & &
( xmlStrEqual ( insert - > name3 , name3 ) ) ) {
if ( f )
f ( insert - > payload , insert - > name ) ;
insert - > payload = userdata ;
return ( 0 ) ;
}
}
if ( ( xmlStrEqual ( insert - > name , name ) ) & &
( xmlStrEqual ( insert - > name2 , name2 ) ) & &
( xmlStrEqual ( insert - > name3 , name3 ) ) ) {
if ( f )
f ( insert - > payload , insert - > name ) ;
insert - > payload = userdata ;
return ( 0 ) ;
}
}
entry = xmlMalloc ( sizeof ( xmlHashEntry ) ) ;
if ( entry = = NULL )
return ( - 1 ) ;
entry - > name = xmlStrdup ( name ) ;
entry - > name2 = xmlStrdup ( name2 ) ;
entry - > name3 = xmlStrdup ( name3 ) ;
entry - > payload = userdata ;
entry - > next = NULL ;
table - > nbElems + + ;
if ( insert = = NULL ) {
table - > table [ key ] = entry ;
} else {
insert - > next = entry ;
}
return ( 0 ) ;
}
/**
2001-07-18 19:30:27 +00:00
* xmlHashLookup3 :
2001-02-23 17:55:21 +00:00
* @ table : the hash table
* @ name : the name of the userdata
* @ name2 : a second name of the userdata
* @ name3 : a third name of the userdata
*
2001-12-31 16:16:02 +00:00
* Find the userdata specified by the ( @ name , @ name2 , @ name3 ) tuple .
2001-02-23 17:55:21 +00:00
*
* Returns the a pointer to the userdata
*/
void *
xmlHashLookup3 ( xmlHashTablePtr table , const xmlChar * name ,
const xmlChar * name2 , const xmlChar * name3 ) {
unsigned long key ;
xmlHashEntryPtr entry ;
if ( table = = NULL )
return ( NULL ) ;
if ( name = = NULL )
return ( NULL ) ;
2001-04-18 13:09:01 +00:00
key = xmlHashComputeKey ( table , name , name2 , name3 ) ;
2001-02-23 17:55:21 +00:00
for ( entry = table - > table [ key ] ; entry ! = NULL ; entry = entry - > next ) {
if ( ( xmlStrEqual ( entry - > name , name ) ) & &
( xmlStrEqual ( entry - > name2 , name2 ) ) & &
( xmlStrEqual ( entry - > name3 , name3 ) ) )
return ( entry - > payload ) ;
}
return ( NULL ) ;
}
/**
* xmlHashScan :
* @ table : the hash table
* @ f : the scanner function for items in the hash
* @ data : extra data passed to f
*
2001-12-31 16:16:02 +00:00
* Scan the hash @ table and applied @ f to each value .
2001-02-23 17:55:21 +00:00
*/
void
xmlHashScan ( xmlHashTablePtr table , xmlHashScanner f , void * data ) {
2001-07-22 03:54:15 +00:00
xmlHashScanFull ( table , ( xmlHashScannerFull ) f , data ) ;
}
/**
* xmlHashScanFull :
* @ table : the hash table
* @ f : the scanner function for items in the hash
* @ data : extra data passed to f
*
2001-12-31 16:16:02 +00:00
* Scan the hash @ table and applied @ f to each value .
2001-07-22 03:54:15 +00:00
*/
void
xmlHashScanFull ( xmlHashTablePtr table , xmlHashScannerFull f , void * data ) {
2001-02-23 17:55:21 +00:00
int i ;
xmlHashEntryPtr iter ;
xmlHashEntryPtr next ;
if ( table = = NULL )
return ;
if ( f = = NULL )
return ;
if ( table - > table ) {
for ( i = 0 ; i < table - > size ; i + + ) {
iter = table - > table [ i ] ;
while ( iter ) {
next = iter - > next ;
if ( f )
2001-07-22 03:54:15 +00:00
f ( iter - > payload , data , iter - > name ,
iter - > name2 , iter - > name3 ) ;
2001-02-23 17:55:21 +00:00
iter = next ;
}
}
}
}
/**
* xmlHashScan3 :
* @ table : the hash table
* @ name : the name of the userdata or NULL
* @ name2 : a second name of the userdata or NULL
* @ name3 : a third name of the userdata or NULL
* @ f : the scanner function for items in the hash
* @ data : extra data passed to f
*
2001-12-31 16:16:02 +00:00
* Scan the hash @ table and applied @ f to each value matching
* ( @ name , @ name2 , @ name3 ) tuple . If one of the names is null ,
2001-02-23 17:55:21 +00:00
* the comparison is considered to match .
*/
void
xmlHashScan3 ( xmlHashTablePtr table , const xmlChar * name ,
const xmlChar * name2 , const xmlChar * name3 ,
xmlHashScanner f , void * data ) {
2001-07-22 03:54:15 +00:00
xmlHashScanFull3 ( table , name , name2 , name3 ,
( xmlHashScannerFull ) f , data ) ;
}
/**
* xmlHashScanFull3 :
* @ table : the hash table
* @ name : the name of the userdata or NULL
* @ name2 : a second name of the userdata or NULL
* @ name3 : a third name of the userdata or NULL
* @ f : the scanner function for items in the hash
* @ data : extra data passed to f
*
2001-12-31 16:16:02 +00:00
* Scan the hash @ table and applied @ f to each value matching
* ( @ name , @ name2 , @ name3 ) tuple . If one of the names is null ,
2001-07-22 03:54:15 +00:00
* the comparison is considered to match .
*/
void
xmlHashScanFull3 ( xmlHashTablePtr table , const xmlChar * name ,
const xmlChar * name2 , const xmlChar * name3 ,
xmlHashScannerFull f , void * data ) {
2001-02-23 17:55:21 +00:00
int i ;
xmlHashEntryPtr iter ;
xmlHashEntryPtr next ;
if ( table = = NULL )
return ;
if ( f = = NULL )
return ;
if ( table - > table ) {
for ( i = 0 ; i < table - > size ; i + + ) {
iter = table - > table [ i ] ;
while ( iter ) {
next = iter - > next ;
if ( ( ( name = = NULL ) | | ( xmlStrEqual ( name , iter - > name ) ) ) & &
( ( name2 = = NULL ) | | ( xmlStrEqual ( name2 , iter - > name2 ) ) ) & &
( ( name3 = = NULL ) | | ( xmlStrEqual ( name3 , iter - > name3 ) ) ) ) {
2001-07-22 03:54:15 +00:00
f ( iter - > payload , data , iter - > name ,
iter - > name2 , iter - > name3 ) ;
2001-02-23 17:55:21 +00:00
}
iter = next ;
}
}
}
}
/**
* xmlHashCopy :
* @ table : the hash table
* @ f : the copier function for items in the hash
*
2001-12-31 16:16:02 +00:00
* Scan the hash @ table and applied @ f to each value .
2001-02-23 17:55:21 +00:00
*
* Returns the new table or NULL in case of error .
*/
xmlHashTablePtr
xmlHashCopy ( xmlHashTablePtr table , xmlHashCopier f ) {
int i ;
xmlHashEntryPtr iter ;
xmlHashEntryPtr next ;
xmlHashTablePtr ret ;
if ( table = = NULL )
return ( NULL ) ;
if ( f = = NULL )
return ( NULL ) ;
ret = xmlHashCreate ( table - > size ) ;
if ( table - > table ) {
for ( i = 0 ; i < table - > size ; i + + ) {
iter = table - > table [ i ] ;
while ( iter ) {
next = iter - > next ;
xmlHashAddEntry3 ( ret , iter - > name , iter - > name2 ,
iter - > name3 , f ( iter - > payload , iter - > name ) ) ;
iter = next ;
}
}
}
ret - > nbElems = table - > nbElems ;
return ( ret ) ;
}
/**
* xmlHashSize :
* @ table : the hash table
*
2001-12-31 16:16:02 +00:00
* Query the number of elements installed in the hash @ table .
2001-07-18 19:30:27 +00:00
*
2001-02-23 17:55:21 +00:00
* Returns the number of elements in the hash table or
* - 1 in case of error
*/
int
xmlHashSize ( xmlHashTablePtr table ) {
if ( table = = NULL )
return ( - 1 ) ;
return ( table - > nbElems ) ;
}
/**
2001-05-19 13:24:56 +00:00
* xmlHashRemoveEntry :
2001-02-23 17:55:21 +00:00
* @ table : the hash table
* @ name : the name of the userdata
* @ f : the deallocator function for removed item ( if any )
*
2001-12-31 16:16:02 +00:00
* Find the userdata specified by the @ name and remove
* it from the hash @ table . Existing userdata for this tuple will be removed
2001-02-23 17:55:21 +00:00
* and freed with @ f .
*
* Returns 0 if the removal succeeded and - 1 in case of error or not found .
*/
int xmlHashRemoveEntry ( xmlHashTablePtr table , const xmlChar * name ,
2001-04-18 13:09:01 +00:00
xmlHashDeallocator f ) {
return ( xmlHashRemoveEntry3 ( table , name , NULL , NULL , f ) ) ;
2001-02-23 17:55:21 +00:00
}
/**
2001-05-19 13:24:56 +00:00
* xmlHashRemoveEntry2 :
2001-02-23 17:55:21 +00:00
* @ table : the hash table
* @ name : the name of the userdata
* @ name2 : a second name of the userdata
* @ f : the deallocator function for removed item ( if any )
*
2001-12-31 16:16:02 +00:00
* Find the userdata specified by the ( @ name , @ name2 ) tuple and remove
* it from the hash @ table . Existing userdata for this tuple will be removed
2001-02-23 17:55:21 +00:00
* and freed with @ f .
*
* Returns 0 if the removal succeeded and - 1 in case of error or not found .
*/
int xmlHashRemoveEntry2 ( xmlHashTablePtr table , const xmlChar * name ,
2001-04-18 13:09:01 +00:00
const xmlChar * name2 , xmlHashDeallocator f ) {
return ( xmlHashRemoveEntry3 ( table , name , name2 , NULL , f ) ) ;
2001-02-23 17:55:21 +00:00
}
/**
2001-05-19 13:24:56 +00:00
* xmlHashRemoveEntry3
2001-02-23 17:55:21 +00:00
* @ table : the hash table
* @ name : the name of the userdata
* @ name2 : a second name of the userdata
* @ name3 : a third name of the userdata
* @ f : the deallocator function for removed item ( if any )
*
2001-12-31 16:16:02 +00:00
* Find the userdata specified by the ( @ name , @ name2 , @ name3 ) tuple and remove
* it from the hash @ table . Existing userdata for this tuple will be removed
2001-02-23 17:55:21 +00:00
* and freed with @ f .
*
* Returns 0 if the removal succeeded and - 1 in case of error or not found .
*/
int xmlHashRemoveEntry3 ( xmlHashTablePtr table , const xmlChar * name ,
2001-04-18 13:09:01 +00:00
const xmlChar * name2 , const xmlChar * name3 , xmlHashDeallocator f ) {
unsigned long key ;
xmlHashEntryPtr entry ;
xmlHashEntryPtr prev = NULL ;
2001-02-23 17:55:21 +00:00
2001-04-18 13:09:01 +00:00
if ( table = = NULL | | name = = NULL )
return ( - 1 ) ;
2001-02-23 17:55:21 +00:00
2001-04-18 13:09:01 +00:00
key = xmlHashComputeKey ( table , name , name2 , name3 ) ;
if ( table - > table [ key ] = = NULL ) {
return ( - 1 ) ;
} else {
for ( entry = table - > table [ key ] ; entry ! = NULL ; entry = entry - > next ) {
if ( xmlStrEqual ( entry - > name , name ) & &
xmlStrEqual ( entry - > name2 , name2 ) & &
xmlStrEqual ( entry - > name3 , name3 ) ) {
if ( f )
f ( entry - > payload , entry - > name ) ;
entry - > payload = NULL ;
if ( entry - > name )
xmlFree ( entry - > name ) ;
if ( entry - > name2 )
xmlFree ( entry - > name2 ) ;
if ( entry - > name3 )
xmlFree ( entry - > name3 ) ;
if ( prev )
prev - > next = entry - > next ;
else
table - > table [ key ] = entry - > next ;
xmlFree ( entry ) ;
table - > nbElems - - ;
return ( 0 ) ;
}
prev = entry ;
}
return ( - 1 ) ;
}
2001-03-18 23:17:47 +00:00
}