/* * xmlDictAddQString: * @dict: the dictionary * @prefix: the prefix of the userdata * @plen: the prefix length * @name: the name of the userdata * @len: the length of the name * * Add the QName to the array[s] * * Returns the pointer of the local string, or NULL in case of error. */ static const xmlChar * xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, unsigned int plen, const xmlChar *name, unsigned int namelen) { xmlDictStringsPtr pool; const xmlChar *ret; size_t size = 0; /* + sizeof(_xmlDictStrings) == 1024 */ size_t limit = 0; if (prefix == NULL) return(xmlDictAddString(dict, name, namelen)); #ifdef DICT_DEBUG_PATTERNS fprintf(stderr, "="); #endif pool = dict->strings; while (pool != NULL) { if (pool->end - pool->free > namelen + plen + 1) goto found_pool; if (pool->size > size) size = pool->size; limit += pool->size; pool = pool->next; } /* * Not found, need to allocate */ if (pool == NULL) { if ((dict->limit > 0) && (limit > dict->limit)) { return(NULL); } if (size == 0) size = 1000; else size *= 4; /* exponential growth */ if (size < 4 * (namelen + plen + 1)) size = 4 * (namelen + plen + 1); /* just in case ! */ pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size); if (pool == NULL) return(NULL); pool->size = size; pool->nbStrings = 0; pool->free = &pool->array[0]; pool->end = &pool->array[size]; pool->next = dict->strings; dict->strings = pool; #ifdef DICT_DEBUG_PATTERNS fprintf(stderr, "+"); #endif } found_pool: ret = pool->free; memcpy(pool->free, prefix, plen); pool->free += plen; *(pool->free++) = ':'; memcpy(pool->free, name, namelen); pool->free += namelen; *(pool->free++) = 0; pool->nbStrings++; return(ret); }
/* * xmlDictAddQString: * @param dict the dictionnary * @param prefix the prefix of the userdata * @param name the name of the userdata * @param len the length of the name, if -1 it is recomputed * * Add the QName to the array[s] * * Returns the pointer of the local string, or NULL in case of error. */ static const xmlChar * xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name, int namelen) { xmlDictStringsPtr pool; const xmlChar *ret; int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */ int plen; if (!prefix) return(xmlDictAddString(dict, name, namelen)); plen = xmlStrlen(prefix); pool = dict->strings; while (pool) { if (pool->end - pool->free > namelen) goto found_pool; if (pool->size > size) size = pool->size; pool = pool->next; } /* * Not found, need to allocate */ if (!pool) { if (size == 0) size = 1000; else size *= 4; /* exponential growth */ if (size < 4 * namelen) size = 4 * namelen; /* just in case ! */ pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size); if (!pool) return(NULL); pool->size = size; pool->nbStrings = 0; pool->free = &pool->array[0]; pool->end = &pool->array[size]; pool->next = dict->strings; dict->strings = pool; } found_pool: ret = pool->free; memcpy(pool->free, prefix, plen); pool->free += plen; *(pool->free++) = ':'; namelen -= plen + 1; memcpy(pool->free, name, namelen); pool->free += namelen; *(pool->free++) = 0; return(ret); }
static const xmlChar * xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, int plen, const xmlChar *name, int namelen) { xmlDictStringsPtr pool; const xmlChar *ret; int size = 0; if (prefix == NULL) return(xmlDictAddString(dict, name, namelen)); #ifdef DICT_DEBUG_PATTERNS fprintf(stderr, "="); #endif pool = dict->strings; while (pool != NULL) { if (pool->end - pool->free > namelen + plen + 1) goto found_pool; if (pool->size > size) size = pool->size; pool = pool->next; } if (pool == NULL) { if (size == 0) size = 1000; else size *= 4; if (size < 4 * (namelen + plen + 1)) size = 4 * (namelen + plen + 1); pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size); if (pool == NULL) return(NULL); pool->size = size; pool->nbStrings = 0; pool->free = &pool->array[0]; pool->end = &pool->array[size]; pool->next = dict->strings; dict->strings = pool; #ifdef DICT_DEBUG_PATTERNS fprintf(stderr, "+"); #endif } found_pool: ret = pool->free; memcpy(pool->free, prefix, plen); pool->free += plen; *(pool->free++) = ':'; memcpy(pool->free, name, namelen); pool->free += namelen; *(pool->free++) = 0; pool->nbStrings++; return(ret); }
/** * xmlDictLookup: * @param dict the dictionnary * @param name the name of the userdata * @param len the length of the name, if -1 it is recomputed * * Add the name to the hash dict if not present. * * Returns the internal copy of the name or NULL in case of internal error * * OOM: possible --> returns NULL and OOM flag is set */ XMLPUBFUNEXPORT 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 || !name) 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; 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 } // if (dict->subdict->dict[key].valid != 0) key = okey % dict->size; } // if (dict->subdict) ret = xmlDictAddString(dict, name, len); // may set OOM flag if (!ret) return(NULL); if (!insert) { entry = &(dict->dict[key]); } else { entry = (xmlDictEntryPtr)xmlMalloc(sizeof(xmlDictEntry)); if (!entry) return(NULL); //OOM } entry->name = ret; entry->len = len; entry->next = NULL; entry->valid = 1; if (insert) 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); if(OOM_FLAG) return NULL; } /* Note that entry may have been freed at this point by xmlDictGrow */ return(ret); }
/** * xmlDictLookup: * @dict: the dictionary * @name: the name of the userdata * @len: the length of the name, if -1 it is recomputed * * Add the @name to the dictionary @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; unsigned int l; if ((dict == NULL) || (name == NULL)) return(NULL); if (len < 0) l = strlen((const char *) name); else l = len; if (((dict->limit > 0) && (l >= dict->limit)) || (l > INT_MAX / 2)) return(NULL); /* * Check for duplicate and insertion location. */ okey = xmlDictComputeKey(dict, name, l); 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->okey == okey) && (insert->len == l)) { if (!memcmp(insert->name, name, l)) return(insert->name); } #else if ((insert->okey == okey) && (insert->len == l) && (!xmlStrncmp(insert->name, name, l))) return(insert->name); #endif nbi++; } #ifdef __GNUC__ if ((insert->okey == okey) && (insert->len == l)) { if (!memcmp(insert->name, name, l)) return(insert->name); } #else if ((insert->okey == okey) && (insert->len == l) && (!xmlStrncmp(insert->name, name, l))) return(insert->name); #endif } if (dict->subdict) { unsigned long skey; /* we cannot always reuse the same okey for the subdict */ if (((dict->size == MIN_DICT_SIZE) && (dict->subdict->size != MIN_DICT_SIZE)) || ((dict->size != MIN_DICT_SIZE) && (dict->subdict->size == MIN_DICT_SIZE))) skey = xmlDictComputeKey(dict->subdict, name, l); else skey = okey; key = skey % 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->okey == skey) && (tmp->len == l)) { if (!memcmp(tmp->name, name, l)) return(tmp->name); } #else if ((tmp->okey == skey) && (tmp->len == l) && (!xmlStrncmp(tmp->name, name, l))) return(tmp->name); #endif nbi++; } #ifdef __GNUC__ if ((tmp->okey == skey) && (tmp->len == l)) { if (!memcmp(tmp->name, name, l)) return(tmp->name); } #else if ((tmp->okey == skey) && (tmp->len == l) && (!xmlStrncmp(tmp->name, name, l))) return(tmp->name); #endif } key = okey % dict->size; } ret = xmlDictAddString(dict, name, l); 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 = l; entry->next = NULL; entry->valid = 1; entry->okey = okey; if (insert != NULL) insert->next = entry; dict->nbElems++; if ((nbi > MAX_HASH_LEN) && (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN))) { if (xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size) != 0) return(NULL); } /* Note that entry may have been freed at this point by xmlDictGrow */ return(ret); }
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 = strlen((const char *) name); okey = xmlDictComputeKey(dict, 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->okey == okey) && (insert->len == len)) { if (!memcmp(insert->name, name, len)) return(insert->name); } #else if ((insert->okey == okey) && (insert->len == len) && (!xmlStrncmp(insert->name, name, len))) return(insert->name); #endif nbi++; } #ifdef __GNUC__ if ((insert->okey == okey) && (insert->len == len)) { if (!memcmp(insert->name, name, len)) return(insert->name); } #else if ((insert->okey == okey) && (insert->len == len) && (!xmlStrncmp(insert->name, name, len))) return(insert->name); #endif } if (dict->subdict) { unsigned long skey; if (((dict->size == MIN_DICT_SIZE) && (dict->subdict->size != MIN_DICT_SIZE)) || ((dict->size != MIN_DICT_SIZE) && (dict->subdict->size == MIN_DICT_SIZE))) skey = xmlDictComputeKey(dict->subdict, name, len); else skey = okey; key = skey % 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->okey == skey) && (tmp->len == len)) { if (!memcmp(tmp->name, name, len)) return(tmp->name); } #else if ((tmp->okey == skey) && (tmp->len == len) && (!xmlStrncmp(tmp->name, name, len))) return(tmp->name); #endif nbi++; } #ifdef __GNUC__ if ((tmp->okey == skey) && (tmp->len == len)) { if (!memcmp(tmp->name, name, len)) return(tmp->name); } #else if ((tmp->okey == skey) && (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; entry->okey = okey; if (insert != NULL) insert->next = entry; dict->nbElems++; if ((nbi > MAX_HASH_LEN) && (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN))) { if (xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size) != 0) return(NULL); } return(ret); }