ReactOS 0.4.16-dev-2208-g6350669
hash.c File Reference
#include "libxml.h"
#include <string.h>
#include <limits.h>
#include <libxml/parser.h>
#include <libxml/hash.h>
#include <libxml/dict.h>
#include <libxml/xmlmemory.h>
#include <libxml/xmlstring.h>
#include "private/dict.h"
Include dependency graph for hash.c:

Go to the source code of this file.

Classes

struct  xmlHashEntry
 
struct  _xmlHashTable
 
struct  stubData
 

Macros

#define IN_LIBXML
 
#define SIZE_MAX   ((size_t) -1)
 
#define MAX_FILL_NUM   7
 
#define MAX_FILL_DENOM   8
 
#define MIN_HASH_SIZE   8
 
#define MAX_HASH_SIZE   (1u << 31)
 

Functions

static int xmlHashGrow (xmlHashTablePtr hash, unsigned size)
 
static ATTRIBUTE_NO_SANITIZE_INTEGER unsigned xmlHashValue (unsigned seed, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, size_t *lengths)
 
static ATTRIBUTE_NO_SANITIZE_INTEGER unsigned xmlHashQNameValue (unsigned seed, const xmlChar *prefix, const xmlChar *name, const xmlChar *prefix2, const xmlChar *name2, const xmlChar *prefix3, const xmlChar *name3)
 
xmlHashTablePtr xmlHashCreate (int size)
 
xmlHashTablePtr xmlHashCreateDict (int size, xmlDictPtr dict)
 
void xmlHashFree (xmlHashTablePtr hash, xmlHashDeallocator dealloc)
 
static int xmlFastStrEqual (const xmlChar *s1, const xmlChar *s2)
 
static ATTRIBUTE_NO_SANITIZE_INTEGER xmlHashEntryxmlHashFindEntry (const xmlHashTable *hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, unsigned hashValue, int *pfound)
 
static ATTRIBUTE_NO_SANITIZE_INTEGER int xmlHashUpdateInternal (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, void *payload, xmlHashDeallocator dealloc, int update)
 
void xmlHashDefaultDeallocator (void *entry, const xmlChar *key ATTRIBUTE_UNUSED)
 
int xmlHashAddEntry (xmlHashTablePtr hash, const xmlChar *key, void *payload)
 
int xmlHashAddEntry2 (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, void *payload)
 
int xmlHashAddEntry3 (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, void *payload)
 
int xmlHashUpdateEntry (xmlHashTablePtr hash, const xmlChar *key, void *payload, xmlHashDeallocator dealloc)
 
int xmlHashUpdateEntry2 (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, void *payload, xmlHashDeallocator dealloc)
 
int xmlHashUpdateEntry3 (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, void *payload, xmlHashDeallocator dealloc)
 
voidxmlHashLookup (xmlHashTablePtr hash, const xmlChar *key)
 
voidxmlHashLookup2 (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2)
 
or @name.

Returns a pointer to the payload or NULL if no entry was found.

voidxmlHashQLookup (xmlHashTablePtr hash, const xmlChar *prefix, const xmlChar *name)
 
2: second local name

@prefix3: third prefix

voidxmlHashQLookup2 (xmlHashTablePtr hash, const xmlChar *prefix, const xmlChar *name, const xmlChar *prefix2, const xmlChar *name2)
 
voidxmlHashLookup3 (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3)
 
3: third local name

Find the payload specified by the QNames tuple.

Returns a pointer to the payload or NULL if no entry was found.

ATTRIBUTE_NO_SANITIZE_INTEGER voidxmlHashQLookup3 (xmlHashTablePtr hash, const xmlChar *prefix, const xmlChar *name, const xmlChar *prefix2, const xmlChar *name2, const xmlChar *prefix3, const xmlChar *name3)
 
static void stubHashScannerFull (void *payload, void *data, const xmlChar *key, const xmlChar *key2 ATTRIBUTE_UNUSED, const xmlChar *key3 ATTRIBUTE_UNUSED)
 
void xmlHashScan (xmlHashTablePtr hash, xmlHashScanner scan, void *data)
 
void xmlHashScanFull (xmlHashTablePtr hash, xmlHashScannerFull scan, void *data)
 
void xmlHashScan3 (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, xmlHashScanner scan, void *data)
 
void xmlHashScanFull3 (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, xmlHashScannerFull scan, void *data)
 
xmlHashTablePtr xmlHashCopy (xmlHashTablePtr hash, xmlHashCopier copy)
 
int xmlHashSize (xmlHashTablePtr hash)
 
int xmlHashRemoveEntry (xmlHashTablePtr hash, const xmlChar *key, xmlHashDeallocator dealloc)
 
int xmlHashRemoveEntry2 (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, xmlHashDeallocator dealloc)
 
ATTRIBUTE_NO_SANITIZE_INTEGER int xmlHashRemoveEntry3 (xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, xmlHashDeallocator dealloc)
 

Macro Definition Documentation

◆ IN_LIBXML

#define IN_LIBXML

Definition at line 10 of file hash.c.

◆ MAX_FILL_DENOM

#define MAX_FILL_DENOM   8

Definition at line 29 of file hash.c.

◆ MAX_FILL_NUM

#define MAX_FILL_NUM   7

Definition at line 28 of file hash.c.

◆ MAX_HASH_SIZE

#define MAX_HASH_SIZE   (1u << 31)

Definition at line 31 of file hash.c.

◆ MIN_HASH_SIZE

#define MIN_HASH_SIZE   8

Definition at line 30 of file hash.c.

◆ SIZE_MAX

#define SIZE_MAX   ((size_t) -1)

Definition at line 25 of file hash.c.

Function Documentation

◆ stubHashScannerFull()

static void stubHashScannerFull ( void payload,
void data,
const xmlChar key,
const xmlChar *key2  ATTRIBUTE_UNUSED,
const xmlChar *key3  ATTRIBUTE_UNUSED 
)
static

Definition at line 882 of file hash.c.

884 {
886 sdata->scan(payload, sdata->data, key);
887}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
Definition: copy.c:22
Definition: hash.c:876
static uint8 * sdata
Definition: svgawin.c:77

Referenced by xmlHashScan(), and xmlHashScan3().

◆ xmlFastStrEqual()

static int xmlFastStrEqual ( const xmlChar s1,
const xmlChar s2 
)
static

xmlFastStrEqual: @s1: string @s2: string

Compare two strings for equality, allowing NULL values.

Definition at line 269 of file hash.c.

269 {
270 if (s1 == NULL)
271 return(s2 == NULL);
272 else
273 return((s2 != NULL) &&
274 (strcmp((const char *) s1, (const char *) s2) == 0));
275}
#define NULL
Definition: types.h:112
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
struct S1 s1
PCWSTR s2
Definition: shell32_main.h:38

Referenced by xmlHashFindEntry(), and xmlHashScanFull3().

◆ xmlHashAddEntry()

int xmlHashAddEntry ( xmlHashTablePtr  hash,
const xmlChar key,
void payload 
)

xmlHashAddEntry: @hash: hash table @key: string key @payload: pointer to the payload

Add a hash table entry. If an entry with this key already exists, payload will not be updated and -1 is returned. This return value can't be distinguished from out-of-memory errors, so this function should be used with care.

Returns 0 on success and -1 in case of error.

Definition at line 621 of file hash.c.

621 {
622 return(xmlHashUpdateInternal(hash, key, NULL, NULL, payload, NULL, 0));
623}
static ATTRIBUTE_NO_SANITIZE_INTEGER int xmlHashUpdateInternal(xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, void *payload, xmlHashDeallocator dealloc, int update)
Definition: hash.c:425
Definition: _hash_fun.h:40

Referenced by cache_add_entry(), xmlAddID(), xmlAddNotationDecl(), xmlAddRef(), xsltGetExtData(), xsltInitCtxtExt(), xsltInitCtxtKey(), xsltNamespaceAlias(), xsltRegisterExtModuleFull(), and xsltStyleInitializeStylesheetModule().

◆ xmlHashAddEntry2()

int xmlHashAddEntry2 ( xmlHashTablePtr  hash,
const xmlChar key,
const xmlChar key2,
void payload 
)

xmlHashAddEntry2: @hash: hash table @key: first string key @key2: second string key @payload: pointer to the payload

Add a hash table entry with two strings as key.

See xmlHashAddEntry.

Returns 0 on success and -1 in case of error.

Definition at line 639 of file hash.c.

640 {
641 return(xmlHashUpdateInternal(hash, key, key2, NULL, payload, NULL, 0));
642}

Referenced by xmlAddElementDecl(), xmlAddSpecialAttr(), xmlGetDtdElementDesc2(), xsltAddTemplate(), xsltDocumentElem(), xsltEvalGlobalVariables(), xsltParseStylesheetAttributeSet(), xsltParseStylesheetOutput(), xsltParseStylesheetPreserveSpace(), xsltParseStylesheetStripSpace(), xsltProcessUserParamInternal(), xsltRegisterExtElement(), xsltRegisterExtFunction(), and xsltResolveSASCallback().

◆ xmlHashAddEntry3()

int xmlHashAddEntry3 ( xmlHashTablePtr  hash,
const xmlChar key,
const xmlChar key2,
const xmlChar key3,
void payload 
)

xmlHashAddEntry3: @hash: hash table @key: first string key @key2: second string key @key3: third string key @payload: pointer to the payload

Add a hash table entry with three strings as key.

See xmlHashAddEntry.

Returns 0 on success and -1 in case of error.

Definition at line 659 of file hash.c.

661 {
662 return(xmlHashUpdateInternal(hash, key, key2, key3, payload, NULL, 0));
663}

Referenced by xmlAddAttributeDecl(), xmlHashCopy(), and xsltAddTemplate().

◆ xmlHashCopy()

xmlHashTablePtr xmlHashCopy ( xmlHashTablePtr  hash,
xmlHashCopier  copy 
)

xmlHashCopy: @hash: hash table @copy: copier function for items in the hash

Copy the hash @table using @copy to copy payloads.

Returns the new table or NULL if a memory allocation failed.

Definition at line 1050 of file hash.c.

1050 {
1051 const xmlHashEntry *entry, *end;
1053
1054 if ((hash == NULL) || (copy == NULL))
1055 return(NULL);
1056
1057 ret = xmlHashCreate(hash->size);
1058 if (ret == NULL)
1059 return(NULL);
1060
1061 if (hash->size == 0)
1062 return(ret);
1063
1064 end = &hash->table[hash->size];
1065
1066 for (entry = hash->table; entry < end; entry++) {
1067 if (entry->hashValue != 0)
1068 xmlHashAddEntry3(ret, entry->key, entry->key2, entry->key3,
1069 copy(entry->payload, entry->key));
1070 }
1071
1072 return(ret);
1073}
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
return ret
Definition: mutex.c:146
GLuint GLuint end
Definition: gl.h:1545
uint32_t entry
Definition: isohybrid.c:63
xmlHashTablePtr xmlHashCreate(int size)
Definition: hash.c:160
int xmlHashAddEntry3(xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, void *payload)
Definition: hash.c:659

◆ xmlHashCreate()

xmlHashTablePtr xmlHashCreate ( int  size)

xmlHashCreate: @size: initial size of the hash table

Create a new hash table. Set size to zero if the number of entries can't be estimated.

Returns the newly created object, or NULL if a memory allocation failed.

Definition at line 160 of file hash.c.

160 {
162
164
165 hash = xmlMalloc(sizeof(*hash));
166 if (hash == NULL)
167 return(NULL);
168 hash->dict = NULL;
169 hash->size = 0;
170 hash->table = NULL;
171 hash->nbElems = 0;
172 hash->randomSeed = xmlRandom();
173#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
174 hash->randomSeed = 0;
175#endif
176
177 /*
178 * Unless a larger size is passed, the backing table is created
179 * lazily with MIN_HASH_SIZE capacity. In practice, there are many
180 * hash tables which are never filled.
181 */
182 if (size > MIN_HASH_SIZE) {
183 unsigned newSize = MIN_HASH_SIZE * 2;
184
185 while ((newSize < (unsigned) size) && (newSize < MAX_HASH_SIZE))
186 newSize *= 2;
187
188 if (xmlHashGrow(hash, newSize) != 0) {
189 xmlFree(hash);
190 return(NULL);
191 }
192 }
193
194 return(hash);
195}
GLsizeiptr size
Definition: glext.h:5919
unsigned xmlRandom(void)
Definition: dict.c:951
xmlFreeFunc xmlFree
Definition: globals.c:184
xmlMallocFunc xmlMalloc
Definition: globals.c:193
#define MIN_HASH_SIZE
Definition: hash.c:30
static int xmlHashGrow(xmlHashTablePtr hash, unsigned size)
Definition: hash.c:354
#define MAX_HASH_SIZE
Definition: hash.c:31
XML_GLOBALS_PARSER XMLPUBFUN void xmlInitParser(void)
Definition: threads.c:569

Referenced by SchemaCache_create(), xmlHashCopy(), xmlHashCreateDict(), xsltAddTemplate(), xsltApplyStylesheetInternal(), xsltDocumentElem(), xsltGatherNamespaces(), xsltGetExtData(), xsltInitCtxtExt(), xsltNamespaceAlias(), xsltNewKeyTable(), xsltParseStylesheetAttributeSet(), xsltParseStylesheetOutput(), xsltParseStylesheetPreserveSpace(), xsltParseStylesheetStripSpace(), xsltProcessUserParamInternal(), xsltRegisterExtElement(), xsltRegisterExtFunction(), xsltRegisterExtModuleElement(), xsltRegisterExtModuleFull(), xsltRegisterExtModuleFunction(), xsltRegisterExtModuleTopLevel(), xsltResolveStylesheetAttributeSet(), and xsltStyleInitializeStylesheetModule().

◆ xmlHashCreateDict()

xmlHashTablePtr xmlHashCreateDict ( int  size,
xmlDictPtr  dict 
)

xmlHashCreateDict: @size: the size of the hash table @dict: a dictionary to use for the hash

Create a new hash table backed by a dictionary. This can reduce resource usage considerably if most keys passed to API functions originate from this dictionary.

Returns the newly created object, or NULL if a memory allocation failed.

Definition at line 209 of file hash.c.

209 {
211
213 if (hash != NULL) {
214 hash->dict = dict;
215 xmlDictReference(dict);
216 }
217 return(hash);
218}
int xmlDictReference(xmlDictPtr dict)
Definition: dict.c:317

Referenced by xmlAddAttributeDecl(), xmlAddDefAttrs(), xmlAddElementDecl(), xmlAddID(), xmlAddNotationDecl(), xmlAddRef(), xmlAddSpecialAttr(), and xmlGetDtdElementDesc2().

◆ xmlHashDefaultDeallocator()

void xmlHashDefaultDeallocator ( void entry,
const xmlChar *key  ATTRIBUTE_UNUSED 
)

xmlHashDefaultDeallocator: @entry: hash table entry @key: the entry's string key

Free a hash table entry with xmlFree.

Definition at line 603 of file hash.c.

603 {
604 xmlFree(entry);
605}

Referenced by xmlCtxtReset(), and xmlFreeParserCtxt().

◆ xmlHashFindEntry()

static ATTRIBUTE_NO_SANITIZE_INTEGER xmlHashEntry * xmlHashFindEntry ( const xmlHashTable hash,
const xmlChar key,
const xmlChar key2,
const xmlChar key3,
unsigned  hashValue,
int pfound 
)
static

xmlHashFindEntry: @hash: hash table, non-NULL, size > 0 @key: first string key, non-NULL @key2: second string key @key3: third string key @hashValue: valid hash value of keys @pfound: result of search

Try to find a matching hash table entry. If an entry was found, set @found to 1 and return the entry. Otherwise, set @found to 0 and return the location where a new entry should be inserted.

Definition at line 292 of file hash.c.

294 {
296 unsigned mask, pos, displ;
297 int found = 0;
298
299 mask = hash->size - 1;
300 pos = hashValue & mask;
301 entry = &hash->table[pos];
302
303 if (entry->hashValue != 0) {
304 /*
305 * Robin hood hashing: abort if the displacement of the entry
306 * is smaller than the displacement of the key we look for.
307 * This also stops at the correct position when inserting.
308 */
309 displ = 0;
310 hashValue |= MAX_HASH_SIZE;
311
312 do {
313 if (entry->hashValue == hashValue) {
314 if (hash->dict) {
315 if ((entry->key == key) &&
316 (entry->key2 == key2) &&
317 (entry->key3 == key3)) {
318 found = 1;
319 break;
320 }
321 }
322 if ((strcmp((const char *) entry->key,
323 (const char *) key) == 0) &&
324 (xmlFastStrEqual(entry->key2, key2)) &&
325 (xmlFastStrEqual(entry->key3, key3))) {
326 found = 1;
327 break;
328 }
329 }
330
331 displ++;
332 pos++;
333 entry++;
334 if ((pos & mask) == 0)
335 entry = hash->table;
336 } while ((entry->hashValue != 0) &&
337 (((pos - entry->hashValue) & mask) >= displ));
338 }
339
340 *pfound = found;
341 return(entry);
342}
GLenum GLint GLuint mask
Definition: glext.h:6028
static int xmlFastStrEqual(const xmlChar *s1, const xmlChar *s2)
Definition: hash.c:269

Referenced by xmlHashLookup3(), xmlHashRemoveEntry3(), and xmlHashUpdateInternal().

◆ xmlHashFree()

void xmlHashFree ( xmlHashTablePtr  hash,
xmlHashDeallocator  dealloc 
)

xmlHashFree: @hash: hash table @dealloc: deallocator function or NULL

Free the hash and its contents. The payload is deallocated with @dealloc if provided.

Definition at line 229 of file hash.c.

229 {
230 if (hash == NULL)
231 return;
232
233 if (hash->table) {
234 const xmlHashEntry *end = &hash->table[hash->size];
235 const xmlHashEntry *entry;
236
237 for (entry = hash->table; entry < end; entry++) {
238 if (entry->hashValue == 0)
239 continue;
240 if ((dealloc != NULL) && (entry->payload != NULL))
241 dealloc(entry->payload, entry->key);
242 if (hash->dict == NULL) {
243 if (entry->key)
244 xmlFree(entry->key);
245 if (entry->key2)
246 xmlFree(entry->key2);
247 if (entry->key3)
248 xmlFree(entry->key3);
249 }
250 }
251
252 xmlFree(hash->table);
253 }
254
255 if (hash->dict)
256 xmlDictFree(hash->dict);
257
258 xmlFree(hash);
259}
void dealloc(int i, int no_throw)
Definition: ehthrow.cxx:33
void xmlDictFree(xmlDictPtr dict)
Definition: dict.c:333

Referenced by schema_cache_Release(), xmlCleanSpecialAttr(), xmlCtxtReset(), xmlFreeAttributeTable(), xmlFreeElementTable(), xmlFreeIDTable(), xmlFreeNotationTable(), xmlFreeParserCtxt(), xmlFreeRefTable(), xsltCleanupGlobals(), xsltFreeAttributeSetsHashes(), xsltFreeCtxtExts(), xsltFreeGlobalVariables(), xsltFreeKeyTable(), xsltFreeNamespaceAliasHashes(), xsltFreeStylesheet(), xsltFreeTemplateHashes(), xsltResolveStylesheetAttributeSet(), xsltShutdownCtxtExts(), xsltShutdownExts(), xsltUnregisterAllExtModuleElement(), xsltUnregisterAllExtModuleFunction(), xsltUnregisterAllExtModules(), and xsltUnregisterAllExtModuleTopLevel().

◆ xmlHashGrow()

static int xmlHashGrow ( xmlHashTablePtr  hash,
unsigned  size 
)
static

xmlHashGrow: @hash: hash table @size: new size of the hash table

Resize the hash table.

Returns 0 in case of success, -1 if a memory allocation failed.

Definition at line 354 of file hash.c.

354 {
355 const xmlHashEntry *oldentry, *oldend, *end;
357 unsigned oldsize, i;
358
359 /* Add 0 to avoid spurious -Wtype-limits warning on 64-bit GCC */
360 if ((size_t) size + 0 > SIZE_MAX / sizeof(table[0]))
361 return(-1);
362 table = xmlMalloc(size * sizeof(table[0]));
363 if (table == NULL)
364 return(-1);
365 memset(table, 0, size * sizeof(table[0]));
366
367 oldsize = hash->size;
368 if (oldsize == 0)
369 goto done;
370
371 oldend = &hash->table[oldsize];
372 end = &table[size];
373
374 /*
375 * Robin Hood sorting order is maintained if we
376 *
377 * - compute hash indices with modulo
378 * - resize by an integer factor
379 * - start to copy from the beginning of a probe sequence
380 */
381 oldentry = hash->table;
382 while (oldentry->hashValue != 0) {
383 if (++oldentry >= oldend)
384 oldentry = hash->table;
385 }
386
387 for (i = 0; i < oldsize; i++) {
388 if (oldentry->hashValue != 0) {
389 xmlHashEntry *entry = &table[oldentry->hashValue & (size - 1)];
390
391 while (entry->hashValue != 0) {
392 if (++entry >= end)
393 entry = table;
394 }
395 *entry = *oldentry;
396 }
397
398 if (++oldentry >= oldend)
399 oldentry = hash->table;
400 }
401
402 xmlFree(hash->table);
403
404done:
405 hash->table = table;
406 hash->size = size;
407
408 return(0);
409}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SIZE_MAX
Definition: hash.c:25
#define memset(x, y, z)
Definition: compat.h:39
unsigned hashValue
Definition: hash.c:37

Referenced by xmlHashCreate(), and xmlHashUpdateInternal().

◆ xmlHashLookup()

void * xmlHashLookup ( xmlHashTablePtr  hash,
const xmlChar key 
)

xmlHashLookup: @hash: hash table @key: string key

Find the entry specified by @key.

Returns a pointer to the payload or NULL if no entry was found.

Definition at line 739 of file hash.c.

739 {
740 return(xmlHashLookup3(hash, key, NULL, NULL));
741}
void * xmlHashLookup3(xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3)
Definition: hash.c:806

Referenced by cache_copy(), get_entry(), lookup_schema_elemDecl(), schema_cache_get(), xmlAddRef(), xmlGetDtdNotationDesc(), xmlGetID(), xmlGetRefs(), xmlRemoveID(), xmlRemoveRef(), xsltApplySequenceConstructor(), xsltCheckInstructionElement(), xsltCheckParentElement(), xsltCopyNamespaceList(), xsltGatherNamespaces(), xsltGetExtData(), xsltGetExtInfo(), xsltGetKey(), xsltGetNamespace(), xsltInitCtxtExt(), xsltInitCtxtKey(), xsltRegisterExtModuleFull(), xsltRegisterExtPrefix(), xsltStyleGetExtData(), and xsltStyleInitializeStylesheetModule().

◆ xmlHashLookup2()

◆ xmlHashLookup3()

void * xmlHashLookup3 ( xmlHashTablePtr  hash,
const xmlChar key,
const xmlChar key2,
const xmlChar key3 
)

xmlHashLookup3: @hash: hash table @key: first string key @key2: second string key @key3: third string key

Find the payload specified by the (@key, @key2, @key3) tuple.

Returns a pointer to the payload or NULL if no entry was found.

Definition at line 806 of file hash.c.

807 {
808 const xmlHashEntry *entry;
809 unsigned hashValue;
810 int found;
811
812 if ((hash == NULL) || (hash->size == 0) || (key == NULL))
813 return(NULL);
814 hashValue = xmlHashValue(hash->randomSeed, key, key2, key3, NULL);
815 entry = xmlHashFindEntry(hash, key, key2, key3, hashValue, &found);
816 if (found)
817 return(entry->payload);
818 return(NULL);
819}
static ATTRIBUTE_NO_SANITIZE_INTEGER xmlHashEntry * xmlHashFindEntry(const xmlHashTable *hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, unsigned hashValue, int *pfound)
Definition: hash.c:292
static ATTRIBUTE_NO_SANITIZE_INTEGER unsigned xmlHashValue(unsigned seed, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, size_t *lengths)
Definition: hash.c:61

Referenced by xmlAddAttributeDecl(), xmlGetDtdAttrDesc(), xmlGetDtdQAttrDesc(), xmlHashLookup(), xmlHashLookup2(), xsltAddTemplate(), and xsltGetTemplate().

◆ xmlHashQLookup()

void * xmlHashQLookup ( xmlHashTablePtr  hash,
const xmlChar prefix,
const xmlChar name 
)

Definition at line 770 of file hash.c.

771 {
773}
ATTRIBUTE_NO_SANITIZE_INTEGER void * xmlHashQLookup3(xmlHashTablePtr hash, const xmlChar *prefix, const xmlChar *name, const xmlChar *prefix2, const xmlChar *name2, const xmlChar *prefix3, const xmlChar *name3)
Definition: hash.c:837
Definition: name.c:39
Character const *const prefix
Definition: tempnam.cpp:195

◆ xmlHashQLookup2()

void * xmlHashQLookup2 ( xmlHashTablePtr  hash,
const xmlChar prefix,
const xmlChar name,
const xmlChar prefix2,
const xmlChar name2 
)

Definition at line 788 of file hash.c.

790 {
791 return(xmlHashQLookup3(hash, prefix, name, prefix2, name2, NULL, NULL));
792}
static WCHAR name2[]
Definition: record.c:35

Referenced by xmlParseAttribute2().

◆ xmlHashQLookup3()

ATTRIBUTE_NO_SANITIZE_INTEGER void * xmlHashQLookup3 ( xmlHashTablePtr  hash,
const xmlChar prefix,
const xmlChar name,
const xmlChar prefix2,
const xmlChar name2,
const xmlChar prefix3,
const xmlChar name3 
)

Definition at line 837 of file hash.c.

840 {
841 const xmlHashEntry *entry;
842 unsigned hashValue, mask, pos, displ;
843
844 if ((hash == NULL) || (hash->size == 0) || (name == NULL))
845 return(NULL);
846
847 hashValue = xmlHashQNameValue(hash->randomSeed, prefix, name, prefix2,
848 name2, prefix3, name3);
849 mask = hash->size - 1;
850 pos = hashValue & mask;
851 entry = &hash->table[pos];
852
853 if (entry->hashValue != 0) {
854 displ = 0;
855 hashValue |= MAX_HASH_SIZE;
856
857 do {
858 if ((hashValue == entry->hashValue) &&
859 (xmlStrQEqual(prefix, name, entry->key)) &&
860 (xmlStrQEqual(prefix2, name2, entry->key2)) &&
861 (xmlStrQEqual(prefix3, name3, entry->key3)))
862 return(entry->payload);
863
864 displ++;
865 pos++;
866 entry++;
867 if ((pos & mask) == 0)
868 entry = hash->table;
869 } while ((entry->hashValue != 0) &&
870 (((pos - entry->hashValue) & mask) >= displ));
871 }
872
873 return(NULL);
874}
static const WCHAR name3[]
Definition: db.c:2839
static ATTRIBUTE_NO_SANITIZE_INTEGER unsigned xmlHashQNameValue(unsigned seed, const xmlChar *prefix, const xmlChar *name, const xmlChar *prefix2, const xmlChar *name2, const xmlChar *prefix3, const xmlChar *name3)
Definition: hash.c:101
XMLPUBFUN int xmlStrQEqual(const xmlChar *pref, const xmlChar *name, const xmlChar *str)
Definition: xmlstring.c:188

Referenced by xmlHashQLookup(), and xmlHashQLookup2().

◆ xmlHashQNameValue()

static ATTRIBUTE_NO_SANITIZE_INTEGER unsigned xmlHashQNameValue ( unsigned  seed,
const xmlChar prefix,
const xmlChar name,
const xmlChar prefix2,
const xmlChar name2,
const xmlChar prefix3,
const xmlChar name3 
)
static

Definition at line 101 of file hash.c.

104 {
105 unsigned h1, h2, ch;
106
107 HASH_INIT(h1, h2, seed);
108
109 if (prefix != NULL) {
110 while ((ch = *prefix++) != 0) {
111 HASH_UPDATE(h1, h2, ch);
112 }
113 HASH_UPDATE(h1, h2, ':');
114 }
115 if (name != NULL) {
116 while ((ch = *name++) != 0) {
117 HASH_UPDATE(h1, h2, ch);
118 }
119 }
120 HASH_UPDATE(h1, h2, 0);
121 if (prefix2 != NULL) {
122 while ((ch = *prefix2++) != 0) {
123 HASH_UPDATE(h1, h2, ch);
124 }
125 HASH_UPDATE(h1, h2, ':');
126 }
127 if (name2 != NULL) {
128 while ((ch = *name2++) != 0) {
129 HASH_UPDATE(h1, h2, ch);
130 }
131 }
132 HASH_UPDATE(h1, h2, 0);
133 if (prefix3 != NULL) {
134 while ((ch = *prefix3++) != 0) {
135 HASH_UPDATE(h1, h2, ch);
136 }
137 HASH_UPDATE(h1, h2, ':');
138 }
139 if (name3 != NULL) {
140 while ((ch = *name3++) != 0) {
141 HASH_UPDATE(h1, h2, ch);
142 }
143 }
144
145 HASH_FINISH(h1, h2);
146
147 return(h2);
148}
unsigned char ch[4][2]
Definition: console.c:118
#define HASH_UPDATE(h1, h2, ch)
Definition: dict.h:28
#define HASH_FINISH(h1, h2)
Definition: dict.h:38
#define HASH_INIT(h1, h2, seed)
Definition: dict.h:22

Referenced by xmlHashQLookup3().

◆ xmlHashRemoveEntry()

int xmlHashRemoveEntry ( xmlHashTablePtr  hash,
const xmlChar key,
xmlHashDeallocator  dealloc 
)

xmlHashRemoveEntry: @hash: hash table @key: string key @dealloc: deallocator function for removed item or NULL

Find the entry specified by the @key and remove it from the hash table. Payload will be freed with @dealloc.

Returns 0 on success and -1 if no entry was found.

Definition at line 1102 of file hash.c.

1103 {
1105}
ATTRIBUTE_NO_SANITIZE_INTEGER int xmlHashRemoveEntry3(xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, xmlHashDeallocator dealloc)
Definition: hash.c:1142

Referenced by cache_add_entry(), cache_remove_entry(), xmlRemoveID(), and xsltUnregisterExtModule().

◆ xmlHashRemoveEntry2()

int xmlHashRemoveEntry2 ( xmlHashTablePtr  hash,
const xmlChar key,
const xmlChar key2,
xmlHashDeallocator  dealloc 
)

xmlHashRemoveEntry2: @hash: hash table @key: first string key @key2: second string key @dealloc: deallocator function for removed item or NULL

Remove an entry with two strings as key.

See xmlHashRemoveEntry.

Returns 0 on success and -1 in case of error.

Definition at line 1121 of file hash.c.

1122 {
1123 return(xmlHashRemoveEntry3(hash, key, key2, NULL, dealloc));
1124}

Referenced by xmlAddElementDecl(), xmlCleanSpecialAttrCallback(), xsltResolveAttrSet(), xsltUnregisterExtModuleElement(), xsltUnregisterExtModuleFunction(), and xsltUnregisterExtModuleTopLevel().

◆ xmlHashRemoveEntry3()

ATTRIBUTE_NO_SANITIZE_INTEGER int xmlHashRemoveEntry3 ( xmlHashTablePtr  hash,
const xmlChar key,
const xmlChar key2,
const xmlChar key3,
xmlHashDeallocator  dealloc 
)

xmlHashRemoveEntry3: @hash: hash table @key: first string key @key2: second string key @key3: third string key @dealloc: deallocator function for removed item or NULL

Remove an entry with three strings as key.

See xmlHashRemoveEntry.

Returns 0 on success and -1 in case of error.

Definition at line 1142 of file hash.c.

1144 {
1146 unsigned hashValue, mask, pos, nextpos;
1147 int found;
1148
1149 if ((hash == NULL) || (hash->size == 0) || (key == NULL))
1150 return(-1);
1151
1152 hashValue = xmlHashValue(hash->randomSeed, key, key2, key3, NULL);
1153 entry = xmlHashFindEntry(hash, key, key2, key3, hashValue, &found);
1154 if (!found)
1155 return(-1);
1156
1157 if ((dealloc != NULL) && (entry->payload != NULL))
1158 dealloc(entry->payload, entry->key);
1159 if (hash->dict == NULL) {
1160 if (entry->key)
1161 xmlFree(entry->key);
1162 if (entry->key2)
1163 xmlFree(entry->key2);
1164 if (entry->key3)
1165 xmlFree(entry->key3);
1166 }
1167
1168 /*
1169 * Find end of probe sequence. Entries at their initial probe
1170 * position start a new sequence.
1171 */
1172 mask = hash->size - 1;
1173 pos = entry - hash->table;
1174 cur = entry;
1175
1176 while (1) {
1177 nextpos = pos + 1;
1178 next = cur + 1;
1179 if ((nextpos & mask) == 0)
1180 next = hash->table;
1181
1182 if ((next->hashValue == 0) ||
1183 (((next->hashValue - nextpos) & mask) == 0))
1184 break;
1185
1186 cur = next;
1187 pos = nextpos;
1188 }
1189
1190 /*
1191 * Backward shift
1192 */
1193 next = entry + 1;
1194
1195 if (cur < entry) {
1196 xmlHashEntry *end = &hash->table[hash->size];
1197
1198 memmove(entry, next, (char *) end - (char *) next);
1199 entry = hash->table;
1200 end[-1] = *entry;
1201 next = entry + 1;
1202 }
1203
1204 memmove(entry, next, (char *) cur - (char *) entry);
1205
1206 /*
1207 * Update entry
1208 */
1209 cur->hashValue = 0;
1210
1211 hash->nbElems--;
1212
1213 return(0);
1214}
FxCollectionEntry * cur
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static unsigned __int64 next
Definition: rand_nt.c:6

Referenced by xmlHashRemoveEntry(), and xmlHashRemoveEntry2().

◆ xmlHashScan()

void xmlHashScan ( xmlHashTablePtr  hash,
xmlHashScanner  scan,
void data 
)

xmlHashScan: @hash: hash table @scan: scanner function for items in the hash @data: extra data passed to @scan

Scan the hash @table and apply @scan to each value.

Definition at line 898 of file hash.c.

898 {
900 sdata.data = data;
901 sdata.scan = scan;
903}
static void stubHashScannerFull(void *payload, void *data, const xmlChar *key, const xmlChar *key2 ATTRIBUTE_UNUSED, const xmlChar *key3 ATTRIBUTE_UNUSED)
Definition: hash.c:882
void xmlHashScanFull(xmlHashTablePtr hash, xmlHashScannerFull scan, void *data)
Definition: hash.c:914

Referenced by schema_cache_addCollection(), xsltCleanupGlobals(), xsltEvalGlobalVariables(), xsltFixImportedCompSteps(), xsltInitCtxtExts(), xsltShutdownCtxtExts(), and xsltShutdownExts().

◆ xmlHashScan3()

void xmlHashScan3 ( xmlHashTablePtr  hash,
const xmlChar key,
const xmlChar key2,
const xmlChar key3,
xmlHashScanner  scan,
void data 
)

xmlHashScan3: @hash: hash table @key: first string key or NULL @key2: second string key or NULL @key3: third string key or NULL @scan: scanner function for items in the hash @data: extra data passed to @scan

Scan the hash @table and apply @scan to each value matching (@key, @key2, @key3) tuple. If one of the keys is null, the comparison is considered to match.

Definition at line 969 of file hash.c.

971 {
973 sdata.data = data;
974 sdata.scan = scan;
976}
void xmlHashScanFull3(xmlHashTablePtr hash, const xmlChar *key, const xmlChar *key2, const xmlChar *key3, xmlHashScannerFull scan, void *data)
Definition: hash.c:992

◆ xmlHashScanFull()

void xmlHashScanFull ( xmlHashTablePtr  hash,
xmlHashScannerFull  scan,
void data 
)

xmlHashScanFull: @hash: hash table @scan: scanner function for items in the hash @data: extra data passed to @scan

Scan the hash @table and apply @scan to each value.

Definition at line 914 of file hash.c.

914 {
915 const xmlHashEntry *entry, *end;
916 xmlHashEntry old;
917 unsigned i;
918
919 if ((hash == NULL) || (hash->size == 0) || (scan == NULL))
920 return;
921
922 /*
923 * We must handle the case that a scanned entry is removed when executing
924 * the callback (xmlCleanSpecialAttr and possibly other places).
925 *
926 * Find the start of a probe sequence to avoid scanning entries twice if
927 * a deletion happens.
928 */
929 entry = hash->table;
930 end = &hash->table[hash->size];
931 while (entry->hashValue != 0) {
932 if (++entry >= end)
933 entry = hash->table;
934 }
935
936 for (i = 0; i < hash->size; i++) {
937 if ((entry->hashValue != 0) && (entry->payload != NULL)) {
938 /*
939 * Make sure to rescan after a possible deletion.
940 */
941 do {
942 old = *entry;
943 scan(entry->payload, data, entry->key, entry->key2, entry->key3);
944 } while ((entry->hashValue != 0) &&
945 (entry->payload != NULL) &&
946 ((entry->key != old.key) ||
947 (entry->key2 != old.key2) ||
948 (entry->key3 != old.key3)));
949 }
950 if (++entry >= end)
951 entry = hash->table;
952 }
953}
xmlChar * key
Definition: hash.c:39
xmlChar * key3
Definition: hash.c:41
xmlChar * key2
Definition: hash.c:40

Referenced by xmlCleanSpecialAttr(), xmlHashScan(), xsltDebugDumpExtensions(), and xsltResolveStylesheetAttributeSet().

◆ xmlHashScanFull3()

void xmlHashScanFull3 ( xmlHashTablePtr  hash,
const xmlChar key,
const xmlChar key2,
const xmlChar key3,
xmlHashScannerFull  scan,
void data 
)

xmlHashScanFull3: @hash: hash table @key: first string key or NULL @key2: second string key or NULL @key3: third string key or NULL @scan: scanner function for items in the hash @data: extra data passed to @scan

Scan the hash @table and apply @scan to each value matching (@key, @key2, @key3) tuple. If one of the keys is null, the comparison is considered to match.

Definition at line 992 of file hash.c.

994 {
995 const xmlHashEntry *entry, *end;
996 xmlHashEntry old;
997 unsigned i;
998
999 if ((hash == NULL) || (hash->size == 0) || (scan == NULL))
1000 return;
1001
1002 /*
1003 * We must handle the case that a scanned entry is removed when executing
1004 * the callback (xmlCleanSpecialAttr and possibly other places).
1005 *
1006 * Find the start of a probe sequence to avoid scanning entries twice if
1007 * a deletion happens.
1008 */
1009 entry = hash->table;
1010 end = &hash->table[hash->size];
1011 while (entry->hashValue != 0) {
1012 if (++entry >= end)
1013 entry = hash->table;
1014 }
1015
1016 for (i = 0; i < hash->size; i++) {
1017 if ((entry->hashValue != 0) && (entry->payload != NULL)) {
1018 /*
1019 * Make sure to rescan after a possible deletion.
1020 */
1021 do {
1022 if (((key != NULL) && (strcmp((const char *) key,
1023 (const char *) entry->key) != 0)) ||
1024 ((key2 != NULL) && (!xmlFastStrEqual(key2, entry->key2))) ||
1025 ((key3 != NULL) && (!xmlFastStrEqual(key3, entry->key3))))
1026 break;
1027 old = *entry;
1028 scan(entry->payload, data, entry->key, entry->key2, entry->key3);
1029 } while ((entry->hashValue != 0) &&
1030 (entry->payload != NULL) &&
1031 ((entry->key != old.key) ||
1032 (entry->key2 != old.key2) ||
1033 (entry->key3 != old.key3)));
1034 }
1035 if (++entry >= end)
1036 entry = hash->table;
1037 }
1038}

Referenced by xmlHashScan3().

◆ xmlHashSize()

int xmlHashSize ( xmlHashTablePtr  hash)

xmlHashSize: @hash: hash table

Query the number of elements in the hash table.

Returns the number of elements in the hash table or -1 in case of error.

Definition at line 1085 of file hash.c.

1085 {
1086 if (hash == NULL)
1087 return(-1);
1088 return(hash->nbElems);
1089}

Referenced by lookup_schema_elemDecl(), and xmlCleanSpecialAttr().

◆ xmlHashUpdateEntry()

int xmlHashUpdateEntry ( xmlHashTablePtr  hash,
const xmlChar key,
void payload,
xmlHashDeallocator  dealloc 
)

xmlHashUpdateEntry: @hash: hash table @key: string key @payload: pointer to the payload @dealloc: deallocator function for replaced item or NULL

Add a hash table entry. If an entry with this key already exists, the old payload will be freed and updated with the new value.

Returns 0 in case of success, -1 if a memory allocation failed.

Definition at line 678 of file hash.c.

679 {
680 return(xmlHashUpdateInternal(hash, key, NULL, NULL, payload,
681 dealloc, 1));
682}

Referenced by xmlRemoveRef(), and xsltGatherNamespaces().

◆ xmlHashUpdateEntry2()

int xmlHashUpdateEntry2 ( xmlHashTablePtr  hash,
const xmlChar key,
const xmlChar key2,
void payload,
xmlHashDeallocator  dealloc 
)

xmlHashUpdateEntry2: @hash: hash table @key: first string key @key2: second string key @payload: pointer to the payload @dealloc: deallocator function for replaced item or NULL

Add a hash table entry with two strings as key.

See xmlHashUpdateEntry.

Returns 0 on success and -1 in case of error.

Definition at line 699 of file hash.c.

701 {
702 return(xmlHashUpdateInternal(hash, key, key2, NULL, payload,
703 dealloc, 1));
704}

Referenced by xmlAddDefAttrs(), xsltRegisterExtModuleElement(), xsltRegisterExtModuleFunction(), and xsltRegisterExtModuleTopLevel().

◆ xmlHashUpdateEntry3()

int xmlHashUpdateEntry3 ( xmlHashTablePtr  hash,
const xmlChar key,
const xmlChar key2,
const xmlChar key3,
void payload,
xmlHashDeallocator  dealloc 
)

xmlHashUpdateEntry3: @hash: hash table @key: first string key @key2: second string key @key3: third string key @payload: pointer to the payload @dealloc: deallocator function for replaced item or NULL

Add a hash table entry with three strings as key.

See xmlHashUpdateEntry.

Returns 0 on success and -1 in case of error.

Definition at line 722 of file hash.c.

724 {
725 return(xmlHashUpdateInternal(hash, key, key2, key3, payload,
726 dealloc, 1));
727}

Referenced by xsltAddTemplate().

◆ xmlHashUpdateInternal()

static ATTRIBUTE_NO_SANITIZE_INTEGER int xmlHashUpdateInternal ( xmlHashTablePtr  hash,
const xmlChar key,
const xmlChar key2,
const xmlChar key3,
void payload,
xmlHashDeallocator  dealloc,
int  update 
)
static

xmlHashUpdateInternal: @hash: hash table @key: first string key @key2: second string key @key3: third string key @payload: pointer to the payload @dealloc: deallocator function for replaced item or NULL @update: whether existing entries should be updated

Internal function to add or update hash entries.

Definition at line 425 of file hash.c.

427 {
428 xmlChar *copy, *copy2, *copy3;
430 size_t lengths[3];
431 unsigned hashValue;
432 int found = 0;
433
434 if ((hash == NULL) || (key == NULL))
435 return(-1);
436
437 /*
438 * Check for an existing entry
439 */
440 hashValue = xmlHashValue(hash->randomSeed, key, key2, key3, lengths);
441 if (hash->size > 0)
442 entry = xmlHashFindEntry(hash, key, key2, key3, hashValue, &found);
443 if (found) {
444 if (update) {
445 if (dealloc)
446 dealloc(entry->payload, entry->key);
447 entry->payload = payload;
448 return(0);
449 } else {
450 /*
451 * xmlHashAddEntry found an existing entry.
452 *
453 * TODO: We should return a different error code here to
454 * distinguish from malloc failures.
455 */
456 return(-1);
457 }
458 }
459
460 /*
461 * Grow the hash table if needed
462 */
463 if (hash->nbElems + 1 > hash->size / MAX_FILL_DENOM * MAX_FILL_NUM) {
464 unsigned newSize, mask, displ, pos;
465
466 if (hash->size == 0) {
467 newSize = MIN_HASH_SIZE;
468 } else {
469 /* This guarantees that nbElems < INT_MAX */
470 if (hash->size >= MAX_HASH_SIZE)
471 return(-1);
472 newSize = hash->size * 2;
473 }
474 if (xmlHashGrow(hash, newSize) != 0)
475 return(-1);
476
477 /*
478 * Find new entry
479 */
480 mask = hash->size - 1;
481 displ = 0;
482 pos = hashValue & mask;
483 entry = &hash->table[pos];
484
485 if (entry->hashValue != 0) {
486 do {
487 displ++;
488 pos++;
489 entry++;
490 if ((pos & mask) == 0)
491 entry = hash->table;
492 } while ((entry->hashValue != 0) &&
493 ((pos - entry->hashValue) & mask) >= displ);
494 }
495 }
496
497 /*
498 * Copy keys
499 */
500 if (hash->dict != NULL) {
501 if (xmlDictOwns(hash->dict, key)) {
502 copy = (xmlChar *) key;
503 } else {
504 copy = (xmlChar *) xmlDictLookup(hash->dict, key, -1);
505 if (copy == NULL)
506 return(-1);
507 }
508
509 if ((key2 == NULL) || (xmlDictOwns(hash->dict, key2))) {
510 copy2 = (xmlChar *) key2;
511 } else {
512 copy2 = (xmlChar *) xmlDictLookup(hash->dict, key2, -1);
513 if (copy2 == NULL)
514 return(-1);
515 }
516 if ((key3 == NULL) || (xmlDictOwns(hash->dict, key3))) {
517 copy3 = (xmlChar *) key3;
518 } else {
519 copy3 = (xmlChar *) xmlDictLookup(hash->dict, key3, -1);
520 if (copy3 == NULL)
521 return(-1);
522 }
523 } else {
524 copy = xmlMalloc(lengths[0] + 1);
525 if (copy == NULL)
526 return(-1);
527 memcpy(copy, key, lengths[0] + 1);
528
529 if (key2 != NULL) {
530 copy2 = xmlMalloc(lengths[1] + 1);
531 if (copy2 == NULL) {
532 xmlFree(copy);
533 return(-1);
534 }
535 memcpy(copy2, key2, lengths[1] + 1);
536 } else {
537 copy2 = NULL;
538 }
539
540 if (key3 != NULL) {
541 copy3 = xmlMalloc(lengths[2] + 1);
542 if (copy3 == NULL) {
543 xmlFree(copy);
544 xmlFree(copy2);
545 return(-1);
546 }
547 memcpy(copy3, key3, lengths[2] + 1);
548 } else {
549 copy3 = NULL;
550 }
551 }
552
553 /*
554 * Shift the remainder of the probe sequence to the right
555 */
556 if (entry->hashValue != 0) {
557 const xmlHashEntry *end = &hash->table[hash->size];
558 const xmlHashEntry *cur = entry;
559
560 do {
561 cur++;
562 if (cur >= end)
563 cur = hash->table;
564 } while (cur->hashValue != 0);
565
566 if (cur < entry) {
567 /*
568 * If we traversed the end of the buffer, handle the part
569 * at the start of the buffer.
570 */
571 memmove(&hash->table[1], hash->table,
572 (char *) cur - (char *) hash->table);
573 cur = end - 1;
574 hash->table[0] = *cur;
575 }
576
577 memmove(&entry[1], entry, (char *) cur - (char *) entry);
578 }
579
580 /*
581 * Populate entry
582 */
583 entry->key = copy;
584 entry->key2 = copy2;
585 entry->key3 = copy3;
586 entry->payload = payload;
587 /* OR with MAX_HASH_SIZE to make sure that the value is non-zero */
588 entry->hashValue = hashValue | MAX_HASH_SIZE;
589
590 hash->nbElems++;
591
592 return(0);
593}
GLsizei GLenum GLenum GLuint GLenum GLsizei * lengths
Definition: glext.h:7753
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int xmlDictOwns(xmlDictPtr dict, const xmlChar *str)
Definition: dict.c:376
const xmlChar * xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:824
#define MAX_FILL_DENOM
Definition: hash.c:29
#define MAX_FILL_NUM
Definition: hash.c:28
unsigned char xmlChar
Definition: xmlstring.h:28

Referenced by xmlHashAddEntry(), xmlHashAddEntry2(), xmlHashAddEntry3(), xmlHashUpdateEntry(), xmlHashUpdateEntry2(), and xmlHashUpdateEntry3().

◆ xmlHashValue()

static ATTRIBUTE_NO_SANITIZE_INTEGER unsigned xmlHashValue ( unsigned  seed,
const xmlChar key,
const xmlChar key2,
const xmlChar key3,
size_t lengths 
)
static

Definition at line 61 of file hash.c.

62 {
63 unsigned h1, h2;
64 size_t i;
65
66 HASH_INIT(h1, h2, seed);
67
68 for (i = 0; key[i] != 0; i++) {
69 HASH_UPDATE(h1, h2, key[i]);
70 }
71 if (lengths)
72 lengths[0] = i;
73
74 HASH_UPDATE(h1, h2, 0);
75
76 if (key2 != NULL) {
77 for (i = 0; key2[i] != 0; i++) {
78 HASH_UPDATE(h1, h2, key2[i]);
79 }
80 if (lengths)
81 lengths[1] = i;
82 }
83
84 HASH_UPDATE(h1, h2, 0);
85
86 if (key3 != NULL) {
87 for (i = 0; key3[i] != 0; i++) {
88 HASH_UPDATE(h1, h2, key3[i]);
89 }
90 if (lengths)
91 lengths[2] = i;
92 }
93
94 HASH_FINISH(h1, h2);
95
96 return(h2);
97}

Referenced by xmlHashLookup3(), xmlHashRemoveEntry3(), and xmlHashUpdateInternal().