📄 dict.c
字号:
while (iter) {
next = iter->next;
/*
* put back the entry in the new dict
*/
key = xmlDictComputeKey(iter->name, iter->len) % dict->size;
if (dict->dict[key].valid == 0) {
memcpy(&(dict->dict[key]), iter, sizeof(xmlDictEntry));
dict->dict[key].next = NULL;
dict->dict[key].valid = 1;
xmlFree(iter);
} else {
iter->next = dict->dict[key].next;
dict->dict[key].next = iter;
}
#ifdef DEBUG_GROW
nbElem++;
#endif
iter = next;
}
}
xmlFree(olddict);
#ifdef DEBUG_GROW
xmlGenericError(xmlGenericErrorContext,
"xmlDictGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
#endif
return(0);
}
/**
* xmlDictFree:
* @dict: the dictionnary
*
* Free the hash @dict and its contents. The userdata is
* deallocated with @f if provided.
*/
void
xmlDictFree(xmlDictPtr dict) {
int i;
xmlDictEntryPtr iter;
xmlDictEntryPtr next;
int inside_dict = 0;
xmlDictStringsPtr pool, nextp;
if (dict == NULL)
return;
if (!xmlDictInitialized)
if (!xmlInitializeDict())
return;
/* decrement the counter, it may be shared by a parser and docs */
xmlRMutexLock(xmlDictMutex);
dict->ref_counter--;
if (dict->ref_counter > 0) {
xmlRMutexUnlock(xmlDictMutex);
return;
}
xmlRMutexUnlock(xmlDictMutex);
if (dict->subdict != NULL) {
xmlDictFree(dict->subdict);
}
if (dict->dict) {
for(i = 0; ((i < dict->size) && (dict->nbElems > 0)); i++) {
iter = &(dict->dict[i]);
if (iter->valid == 0)
continue;
inside_dict = 1;
while (iter) {
next = iter->next;
if (!inside_dict)
xmlFree(iter);
dict->nbElems--;
inside_dict = 0;
iter = next;
}
inside_dict = 0;
}
xmlFree(dict->dict);
}
pool = dict->strings;
while (pool != NULL) {
nextp = pool->next;
xmlFree(pool);
pool = nextp;
}
xmlFreeRMutex(dict->mutex);
xmlFree(dict);
}
/**
* xmlDictLookup:
* @dict: the dictionnary
* @name: the name of the userdata
* @len: the length of the name, if -1 it is recomputed
*
* Add the @name to the dictionnary @dict if not present.
*
* Returns the internal copy of the name or NULL in case of internal error
*/
const xmlChar *
xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
unsigned long key, okey, nbi = 0;
xmlDictEntryPtr entry;
xmlDictEntryPtr insert;
const xmlChar *ret;
if ((dict == NULL) || (name == NULL))
return(NULL);
if (len < 0)
len = xmlStrlen(name);
/*
* Check for duplicate and insertion location.
*/
okey = xmlDictComputeKey(name, len);
key = okey % dict->size;
if (dict->dict[key].valid == 0) {
insert = NULL;
} else {
for (insert = &(dict->dict[key]); insert->next != NULL;
insert = insert->next) {
#ifdef __GNUC__
if (insert->len == len) {
if (!memcmp(insert->name, name, len))
return(insert->name);
}
#else
if ((insert->len == len) &&
(!xmlStrncmp(insert->name, name, len)))
return(insert->name);
#endif
nbi++;
}
#ifdef __GNUC__
if (insert->len == len) {
if (!memcmp(insert->name, name, len))
return(insert->name);
}
#else
if ((insert->len == len) &&
(!xmlStrncmp(insert->name, name, len)))
return(insert->name);
#endif
}
if (dict->subdict) {
key = okey % dict->subdict->size;
if (dict->subdict->dict[key].valid != 0) {
xmlDictEntryPtr tmp;
for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
tmp = tmp->next) {
#ifdef __GNUC__
if (tmp->len == len) {
if (!memcmp(tmp->name, name, len))
return(tmp->name);
}
#else
if ((tmp->len == len) &&
(!xmlStrncmp(tmp->name, name, len)))
return(tmp->name);
#endif
nbi++;
}
#ifdef __GNUC__
if (tmp->len == len) {
if (!memcmp(tmp->name, name, len))
return(tmp->name);
}
#else
if ((tmp->len == len) &&
(!xmlStrncmp(tmp->name, name, len)))
return(tmp->name);
#endif
}
key = okey % dict->size;
}
ret = xmlDictAddString(dict, name, len);
if (ret == NULL)
return(NULL);
if (insert == NULL) {
entry = &(dict->dict[key]);
} else {
entry = xmlMalloc(sizeof(xmlDictEntry));
if (entry == NULL)
return(NULL);
}
entry->name = ret;
entry->len = len;
entry->next = NULL;
entry->valid = 1;
if (insert != NULL)
insert->next = entry;
dict->nbElems++;
if ((nbi > MAX_HASH_LEN) &&
(dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN)))
xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size);
/* Note that entry may have been freed at this point by xmlDictGrow */
return(ret);
}
/**
* xmlDictExists:
* @dict: the dictionnary
* @name: the name of the userdata
* @len: the length of the name, if -1 it is recomputed
*
* Check if the @name exists in the dictionnary @dict.
*
* Returns the internal copy of the name or NULL if not found.
*/
const xmlChar *
xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
unsigned long key, okey, nbi = 0;
xmlDictEntryPtr insert;
if ((dict == NULL) || (name == NULL))
return(NULL);
if (len < 0)
len = xmlStrlen(name);
/*
* Check for duplicate and insertion location.
*/
okey = xmlDictComputeKey(name, len);
key = okey % dict->size;
if (dict->dict[key].valid == 0) {
insert = NULL;
} else {
for (insert = &(dict->dict[key]); insert->next != NULL;
insert = insert->next) {
#ifdef __GNUC__
if (insert->len == len) {
if (!memcmp(insert->name, name, len))
return(insert->name);
}
#else
if ((insert->len == len) &&
(!xmlStrncmp(insert->name, name, len)))
return(insert->name);
#endif
nbi++;
}
#ifdef __GNUC__
if (insert->len == len) {
if (!memcmp(insert->name, name, len))
return(insert->name);
}
#else
if ((insert->len == len) &&
(!xmlStrncmp(insert->name, name, len)))
return(insert->name);
#endif
}
if (dict->subdict) {
key = okey % dict->subdict->size;
if (dict->subdict->dict[key].valid != 0) {
xmlDictEntryPtr tmp;
for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
tmp = tmp->next) {
#ifdef __GNUC__
if (tmp->len == len) {
if (!memcmp(tmp->name, name, len))
return(tmp->name);
}
#else
if ((tmp->len == len) &&
(!xmlStrncmp(tmp->name, name, len)))
return(tmp->name);
#endif
nbi++;
}
#ifdef __GNUC__
if (tmp->len == len) {
if (!memcmp(tmp->name, name, len))
return(tmp->name);
}
#else
if ((tmp->len == len) &&
(!xmlStrncmp(tmp->name, name, len)))
return(tmp->name);
#endif
}
key = okey % dict->size;
}
/* not found */
return(NULL);
}
/**
* xmlDictQLookup:
* @dict: the dictionnary
* @prefix: the prefix
* @name: the name
*
* Add the QName @prefix:@name to the hash @dict if not present.
*
* Returns the internal copy of the QName or NULL in case of internal error
*/
const xmlChar *
xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) {
unsigned long okey, key, nbi = 0;
xmlDictEntryPtr entry;
xmlDictEntryPtr insert;
const xmlChar *ret;
int len;
if ((dict == NULL) || (name == NULL))
return(NULL);
len = xmlStrlen(name);
if (prefix != NULL)
len += 1 + xmlStrlen(prefix);
/*
* Check for duplicate and insertion location.
*/
okey = xmlDictComputeQKey(prefix, name, len);
key = okey % dict->size;
if (dict->dict[key].valid == 0) {
insert = NULL;
} else {
for (insert = &(dict->dict[key]); insert->next != NULL;
insert = insert->next) {
if ((insert->len == len) &&
(xmlStrQEqual(prefix, name, insert->name)))
return(insert->name);
nbi++;
}
if ((insert->len == len) &&
(xmlStrQEqual(prefix, name, insert->name)))
return(insert->name);
}
if (dict->subdict) {
key = okey % dict->subdict->size;
if (dict->subdict->dict[key].valid != 0) {
xmlDictEntryPtr tmp;
for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
tmp = tmp->next) {
if ((tmp->len == len) &&
(xmlStrQEqual(prefix, name, tmp->name)))
return(tmp->name);
nbi++;
}
if ((tmp->len == len) &&
(xmlStrQEqual(prefix, name, tmp->name)))
return(tmp->name);
}
key = okey % dict->size;
}
ret = xmlDictAddQString(dict, prefix, name, len);
if (ret == NULL)
return(NULL);
if (insert == NULL) {
entry = &(dict->dict[key]);
} else {
entry = xmlMalloc(sizeof(xmlDictEntry));
if (entry == NULL)
return(NULL);
}
entry->name = ret;
entry->len = len;
entry->next = NULL;
entry->valid = 1;
if (insert != NULL)
insert->next = entry;
dict->nbElems++;
if ((nbi > MAX_HASH_LEN) &&
(dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN)))
xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size);
/* Note that entry may have been freed at this point by xmlDictGrow */
return(ret);
}
/**
* xmlDictOwns:
* @dict: the dictionnary
* @str: the string
*
* check if a string is owned by the disctionary
*
* Returns 1 if true, 0 if false and -1 in case of error
* -1 in case of error
*/
int
xmlDictOwns(xmlDictPtr dict, const xmlChar *str) {
xmlDictStringsPtr pool;
if ((dict == NULL) || (str == NULL))
return(-1);
pool = dict->strings;
while (pool != NULL) {
if ((str >= &pool->array[0]) && (str <= pool->free))
return(1);
pool = pool->next;
}
if (dict->subdict)
return(xmlDictOwns(dict->subdict, str));
return(0);
}
/**
* xmlDictSize:
* @dict: the dictionnary
*
* Query the number of elements installed in the hash @dict.
*
* Returns the number of elements in the dictionnary or
* -1 in case of error
*/
int
xmlDictSize(xmlDictPtr dict) {
if (dict == NULL)
return(-1);
if (dict->subdict)
return(dict->nbElems + dict->subdict->nbElems);
return(dict->nbElems);
}
#define bottom_dict
#include "elfgcchack.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -