ReactOS 0.4.16-dev-2207-geb15453
dict.c
Go to the documentation of this file.
1/*
2 * dict.c: dictionary of reusable strings, just used to avoid allocation
3 * and freeing operations.
4 *
5 * Copyright (C) 2003-2012 Daniel Veillard.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 * Author: daniel@veillard.com
17 */
18
19#define IN_LIBXML
20#include "libxml.h"
21
22#include <limits.h>
23#include <string.h>
24#include <time.h>
25
26#include "private/dict.h"
27#include "private/threads.h"
28
29#include <libxml/parser.h>
30#include <libxml/dict.h>
31#include <libxml/xmlmemory.h>
32#include <libxml/xmlstring.h>
33
34#ifndef SIZE_MAX
35 #define SIZE_MAX ((size_t) -1)
36#endif
37
38#define MAX_FILL_NUM 7
39#define MAX_FILL_DENOM 8
40#define MIN_HASH_SIZE 8
41#define MAX_HASH_SIZE (1u << 31)
42
49 size_t size;
50 size_t nbStrings;
52};
53
55
56/*
57 * The entire dictionary
58 */
59struct _xmlDict {
61
63 size_t size;
64 unsigned int nbElems;
66
68 /* used for randomization */
69 unsigned seed;
70 /* used to impose a limit on size */
71 size_t limit;
72};
73
74/*
75 * A mutex for modifying the reference counter for shared
76 * dictionaries.
77 */
79
87int
90 return(0);
91}
92
98void
101}
102
111void
113}
114
120void
123}
124
125/*
126 * xmlDictAddString:
127 * @dict: the dictionary
128 * @name: the name of the userdata
129 * @len: the length of the name
130 *
131 * Add the string to the array[s]
132 *
133 * Returns the pointer of the local string, or NULL in case of error.
134 */
135static const xmlChar *
136xmlDictAddString(xmlDictPtr dict, const xmlChar *name, unsigned int namelen) {
138 const xmlChar *ret;
139 size_t size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
140 size_t limit = 0;
141
142 pool = dict->strings;
143 while (pool != NULL) {
144 if ((size_t)(pool->end - pool->free) > namelen)
145 goto found_pool;
146 if (pool->size > size) size = pool->size;
147 limit += pool->size;
148 pool = pool->next;
149 }
150 /*
151 * Not found, need to allocate
152 */
153 if (pool == NULL) {
154 if ((dict->limit > 0) && (limit > dict->limit)) {
155 return(NULL);
156 }
157
158 if (size == 0) {
159 size = 1000;
160 } else {
161 if (size < (SIZE_MAX - sizeof(xmlDictStrings)) / 4)
162 size *= 4; /* exponential growth */
163 else
164 size = SIZE_MAX - sizeof(xmlDictStrings);
165 }
166 if (size / 4 < namelen) {
167 if ((size_t) namelen + 0 < (SIZE_MAX - sizeof(xmlDictStrings)) / 4)
168 size = 4 * (size_t) namelen; /* just in case ! */
169 else
170 return(NULL);
171 }
173 if (pool == NULL)
174 return(NULL);
175 pool->size = size;
176 pool->nbStrings = 0;
177 pool->free = &pool->array[0];
178 pool->end = &pool->array[size];
179 pool->next = dict->strings;
180 dict->strings = pool;
181 }
182found_pool:
183 ret = pool->free;
184 memcpy(pool->free, name, namelen);
185 pool->free += namelen;
186 *(pool->free++) = 0;
187 pool->nbStrings++;
188 return(ret);
189}
190
191/*
192 * xmlDictAddQString:
193 * @dict: the dictionary
194 * @prefix: the prefix of the userdata
195 * @plen: the prefix length
196 * @name: the name of the userdata
197 * @len: the length of the name
198 *
199 * Add the QName to the array[s]
200 *
201 * Returns the pointer of the local string, or NULL in case of error.
202 */
203static const xmlChar *
204xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, unsigned int plen,
205 const xmlChar *name, unsigned int namelen)
206{
208 const xmlChar *ret;
209 size_t size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
210 size_t limit = 0;
211
212 pool = dict->strings;
213 while (pool != NULL) {
214 if ((size_t)(pool->end - pool->free) > namelen + plen + 1)
215 goto found_pool;
216 if (pool->size > size) size = pool->size;
217 limit += pool->size;
218 pool = pool->next;
219 }
220 /*
221 * Not found, need to allocate
222 */
223 if (pool == NULL) {
224 if ((dict->limit > 0) && (limit > dict->limit)) {
225 return(NULL);
226 }
227
228 if (size == 0) size = 1000;
229 else size *= 4; /* exponential growth */
230 if (size < 4 * (namelen + plen + 1))
231 size = 4 * (namelen + plen + 1); /* just in case ! */
233 if (pool == NULL)
234 return(NULL);
235 pool->size = size;
236 pool->nbStrings = 0;
237 pool->free = &pool->array[0];
238 pool->end = &pool->array[size];
239 pool->next = dict->strings;
240 dict->strings = pool;
241 }
242found_pool:
243 ret = pool->free;
244 memcpy(pool->free, prefix, plen);
245 pool->free += plen;
246 *(pool->free++) = ':';
247 memcpy(pool->free, name, namelen);
248 pool->free += namelen;
249 *(pool->free++) = 0;
250 pool->nbStrings++;
251 return(ret);
252}
253
263 xmlDictPtr dict;
264
266
267 dict = xmlMalloc(sizeof(xmlDict));
268 if (dict == NULL)
269 return(NULL);
270 dict->ref_counter = 1;
271 dict->limit = 0;
272
273 dict->size = 0;
274 dict->nbElems = 0;
275 dict->table = NULL;
276 dict->strings = NULL;
277 dict->subdict = NULL;
278 dict->seed = xmlRandom();
279#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
280 dict->seed = 0;
281#endif
282 return(dict);
283}
284
298 xmlDictPtr dict = xmlDictCreate();
299
300 if ((dict != NULL) && (sub != NULL)) {
301 dict->seed = sub->seed;
302 dict->subdict = sub;
304 }
305 return(dict);
306}
307
316int
318 if (dict == NULL) return -1;
320 dict->ref_counter++;
322 return(0);
323}
324
332void
334 xmlDictStringsPtr pool, nextp;
335
336 if (dict == NULL)
337 return;
338
339 /* decrement the counter, it may be shared by a parser and docs */
341 dict->ref_counter--;
342 if (dict->ref_counter > 0) {
344 return;
345 }
346
348
349 if (dict->subdict != NULL) {
350 xmlDictFree(dict->subdict);
351 }
352
353 if (dict->table) {
354 xmlFree(dict->table);
355 }
356 pool = dict->strings;
357 while (pool != NULL) {
358 nextp = pool->next;
359 xmlFree(pool);
360 pool = nextp;
361 }
362 xmlFree(dict);
363}
364
375int
378
379 if ((dict == NULL) || (str == NULL))
380 return(-1);
381 pool = dict->strings;
382 while (pool != NULL) {
383 if ((str >= &pool->array[0]) && (str <= pool->free))
384 return(1);
385 pool = pool->next;
386 }
387 if (dict->subdict)
388 return(xmlDictOwns(dict->subdict, str));
389 return(0);
390}
391
401int
403 if (dict == NULL)
404 return(-1);
405 if (dict->subdict)
406 return(dict->nbElems + dict->subdict->nbElems);
407 return(dict->nbElems);
408}
409
420size_t
422 size_t ret;
423
424 if (dict == NULL)
425 return(0);
426 ret = dict->limit;
427 dict->limit = limit;
428 return(ret);
429}
430
440size_t
443 size_t limit = 0;
444
445 if (dict == NULL)
446 return(0);
447 pool = dict->strings;
448 while (pool != NULL) {
449 limit += pool->size;
450 pool = pool->next;
451 }
452 return(limit);
453}
454
455/*****************************************************************
456 *
457 * The code below was rewritten and is additionally licensed under
458 * the main license in file 'Copyright'.
459 *
460 *****************************************************************/
461
463static unsigned
464xmlDictHashName(unsigned seed, const xmlChar* data, size_t maxLen,
465 size_t *plen) {
466 unsigned h1, h2;
467 size_t i;
468
469 HASH_INIT(h1, h2, seed);
470
471 for (i = 0; i < maxLen && data[i]; i++) {
472 HASH_UPDATE(h1, h2, data[i]);
473 }
474
475 HASH_FINISH(h1, h2);
476
477 *plen = i;
478 return(h2 | MAX_HASH_SIZE);
479}
480
482static unsigned
484 size_t *pplen, size_t *plen) {
485 unsigned h1, h2;
486 size_t i;
487
488 HASH_INIT(h1, h2, seed);
489
490 for (i = 0; prefix[i] != 0; i++) {
491 HASH_UPDATE(h1, h2, prefix[i]);
492 }
493 *pplen = i;
494
495 HASH_UPDATE(h1, h2, ':');
496
497 for (i = 0; name[i] != 0; i++) {
498 HASH_UPDATE(h1, h2, name[i]);
499 }
500 *plen = i;
501
502 HASH_FINISH(h1, h2);
503
504 /*
505 * Always set the upper bit of hash values since 0 means an unoccupied
506 * bucket.
507 */
508 return(h2 | MAX_HASH_SIZE);
509}
510
511unsigned
512xmlDictComputeHash(const xmlDict *dict, const xmlChar *string) {
513 size_t len;
514 return(xmlDictHashName(dict->seed, string, SIZE_MAX, &len));
515}
516
517#define HASH_ROL31(x,n) ((x) << (n) | ((x) & 0x7FFFFFFF) >> (31 - (n)))
518
520unsigned
521xmlDictCombineHash(unsigned v1, unsigned v2) {
522 /*
523 * The upper bit of hash values is always set, so we have to operate on
524 * 31-bit hashes here.
525 */
526 v1 ^= v2;
527 v1 += HASH_ROL31(v2, 5);
528
529 return((v1 & 0xFFFFFFFF) | 0x80000000);
530}
531
546static xmlDictEntry *
548 const xmlChar *name, int len, unsigned hashValue,
549 int *pfound) {
551 unsigned mask, pos, displ;
552 int found = 0;
553
554 mask = dict->size - 1;
555 pos = hashValue & mask;
556 entry = &dict->table[pos];
557
558 if (entry->hashValue != 0) {
559 /*
560 * Robin hood hashing: abort if the displacement of the entry
561 * is smaller than the displacement of the key we look for.
562 * This also stops at the correct position when inserting.
563 */
564 displ = 0;
565
566 do {
567 if (entry->hashValue == hashValue) {
568 if (prefix == NULL) {
569 /*
570 * name is not necessarily null-terminated.
571 */
572 if ((strncmp((const char *) entry->name,
573 (const char *) name, len) == 0) &&
574 (entry->name[len] == 0)) {
575 found = 1;
576 break;
577 }
578 } else {
579 if (xmlStrQEqual(prefix, name, entry->name)) {
580 found = 1;
581 break;
582 }
583 }
584 }
585
586 displ++;
587 pos++;
588 entry++;
589 if ((pos & mask) == 0)
590 entry = dict->table;
591 } while ((entry->hashValue != 0) &&
592 (((pos - entry->hashValue) & mask) >= displ));
593 }
594
595 *pfound = found;
596 return(entry);
597}
598
608static int
609xmlDictGrow(xmlDictPtr dict, unsigned size) {
610 const xmlDictEntry *oldentry, *oldend, *end;
612 unsigned oldsize, i;
613
614 /* Add 0 to avoid spurious -Wtype-limits warning on 64-bit GCC */
615 if ((size_t) size + 0 > SIZE_MAX / sizeof(table[0]))
616 return(-1);
617 table = xmlMalloc(size * sizeof(table[0]));
618 if (table == NULL)
619 return(-1);
620 memset(table, 0, size * sizeof(table[0]));
621
622 oldsize = dict->size;
623 if (oldsize == 0)
624 goto done;
625
626 oldend = &dict->table[oldsize];
627 end = &table[size];
628
629 /*
630 * Robin Hood sorting order is maintained if we
631 *
632 * - compute dict indices with modulo
633 * - resize by an integer factor
634 * - start to copy from the beginning of a probe sequence
635 */
636 oldentry = dict->table;
637 while (oldentry->hashValue != 0) {
638 if (++oldentry >= oldend)
639 oldentry = dict->table;
640 }
641
642 for (i = 0; i < oldsize; i++) {
643 if (oldentry->hashValue != 0) {
644 xmlDictEntry *entry = &table[oldentry->hashValue & (size - 1)];
645
646 while (entry->hashValue != 0) {
647 if (++entry >= end)
648 entry = table;
649 }
650 *entry = *oldentry;
651 }
652
653 if (++oldentry >= oldend)
654 oldentry = dict->table;
655 }
656
657 xmlFree(dict->table);
658
659done:
660 dict->table = table;
661 dict->size = size;
662
663 return(0);
664}
665
677static const xmlDictEntry *
679 const xmlChar *name, int maybeLen, int update) {
681 const xmlChar *ret;
682 unsigned hashValue;
683 size_t maxLen, len, plen, klen;
684 int found = 0;
685
686 if ((dict == NULL) || (name == NULL))
687 return(NULL);
688
689 maxLen = (maybeLen < 0) ? SIZE_MAX : (size_t) maybeLen;
690
691 if (prefix == NULL) {
692 hashValue = xmlDictHashName(dict->seed, name, maxLen, &len);
693 if (len > INT_MAX / 2)
694 return(NULL);
695 klen = len;
696 } else {
697 hashValue = xmlDictHashQName(dict->seed, prefix, name, &plen, &len);
698 if ((len > INT_MAX / 2) || (plen >= INT_MAX / 2 - len))
699 return(NULL);
700 klen = plen + 1 + len;
701 }
702
703 if ((dict->limit > 0) && (klen >= dict->limit))
704 return(NULL);
705
706 /*
707 * Check for an existing entry
708 */
709 if (dict->size > 0)
710 entry = xmlDictFindEntry(dict, prefix, name, klen, hashValue, &found);
711 if (found)
712 return(entry);
713
714 if ((dict->subdict != NULL) && (dict->subdict->size > 0)) {
715 xmlDictEntry *subEntry;
716 unsigned subHashValue;
717
718 if (prefix == NULL)
719 subHashValue = xmlDictHashName(dict->subdict->seed, name, len,
720 &len);
721 else
722 subHashValue = xmlDictHashQName(dict->subdict->seed, prefix, name,
723 &plen, &len);
724 subEntry = xmlDictFindEntry(dict->subdict, prefix, name, klen,
725 subHashValue, &found);
726 if (found)
727 return(subEntry);
728 }
729
730 if (!update)
731 return(NULL);
732
733 /*
734 * Grow the hash table if needed
735 */
736 if (dict->nbElems + 1 > dict->size / MAX_FILL_DENOM * MAX_FILL_NUM) {
737 unsigned newSize, mask, displ, pos;
738
739 if (dict->size == 0) {
740 newSize = MIN_HASH_SIZE;
741 } else {
742 if (dict->size >= MAX_HASH_SIZE)
743 return(NULL);
744 newSize = dict->size * 2;
745 }
746 if (xmlDictGrow(dict, newSize) != 0)
747 return(NULL);
748
749 /*
750 * Find new entry
751 */
752 mask = dict->size - 1;
753 displ = 0;
754 pos = hashValue & mask;
755 entry = &dict->table[pos];
756
757 while ((entry->hashValue != 0) &&
758 ((pos - entry->hashValue) & mask) >= displ) {
759 displ++;
760 pos++;
761 entry++;
762 if ((pos & mask) == 0)
763 entry = dict->table;
764 }
765 }
766
767 if (prefix == NULL)
768 ret = xmlDictAddString(dict, name, len);
769 else
770 ret = xmlDictAddQString(dict, prefix, plen, name, len);
771 if (ret == NULL)
772 return(NULL);
773
774 /*
775 * Shift the remainder of the probe sequence to the right
776 */
777 if (entry->hashValue != 0) {
778 const xmlDictEntry *end = &dict->table[dict->size];
779 const xmlDictEntry *cur = entry;
780
781 do {
782 cur++;
783 if (cur >= end)
784 cur = dict->table;
785 } while (cur->hashValue != 0);
786
787 if (cur < entry) {
788 /*
789 * If we traversed the end of the buffer, handle the part
790 * at the start of the buffer.
791 */
792 memmove(&dict->table[1], dict->table,
793 (char *) cur - (char *) dict->table);
794 cur = end - 1;
795 dict->table[0] = *cur;
796 }
797
798 memmove(&entry[1], entry, (char *) cur - (char *) entry);
799 }
800
801 /*
802 * Populate entry
803 */
804 entry->hashValue = hashValue;
805 entry->name = ret;
806
807 dict->nbElems++;
808
809 return(entry);
810}
811
823const xmlChar *
825 const xmlDictEntry *entry;
826
828 if (entry == NULL)
829 return(NULL);
830 return(entry->name);
831}
832
846 const xmlDictEntry *entry;
848
850
851 if (entry == NULL) {
852 ret.name = NULL;
853 ret.hashValue = 0;
854 } else {
855 ret = *entry;
856 }
857
858 return(ret);
859}
860
871const xmlChar *
873 const xmlDictEntry *entry;
874
876 if (entry == NULL)
877 return(NULL);
878 return(entry->name);
879}
880
893const xmlChar *
895 const xmlDictEntry *entry;
896
897 entry = xmlDictLookupInternal(dict, prefix, name, -1, 1);
898 if (entry == NULL)
899 return(NULL);
900 return(entry->name);
901}
902
903/*
904 * Pseudo-random generator
905 */
906
908
909static unsigned globalRngState[2];
910
911#ifdef XML_THREAD_LOCAL
912static XML_THREAD_LOCAL int localRngInitialized = 0;
913static XML_THREAD_LOCAL unsigned localRngState[2];
914#endif
915
917void
919 int var;
920
922
923 /* TODO: Get seed values from system PRNG */
924
926 HASH_ROL((unsigned) (size_t) &xmlInitRandom, 8);
927 globalRngState[1] = HASH_ROL((unsigned) (size_t) &xmlRngMutex, 16) ^
928 HASH_ROL((unsigned) (size_t) &var, 24);
929}
930
931void
934}
935
937static unsigned
938xoroshiro64ss(unsigned *s) {
939 unsigned s0 = s[0];
940 unsigned s1 = s[1];
941 unsigned result = HASH_ROL(s0 * 0x9E3779BB, 5) * 5;
942
943 s1 ^= s0;
944 s[0] = HASH_ROL(s0, 26) ^ s1 ^ (s1 << 9);
945 s[1] = HASH_ROL(s1, 13);
946
947 return(result & 0xFFFFFFFF);
948}
949
950unsigned
952#ifdef XML_THREAD_LOCAL
953 if (!localRngInitialized) {
955 localRngState[0] = xoroshiro64ss(globalRngState);
956 localRngState[1] = xoroshiro64ss(globalRngState);
957 localRngInitialized = 1;
959 }
960
961 return(xoroshiro64ss(localRngState));
962#else
963 unsigned ret;
964
968
969 return(ret);
970#endif
971}
#define free
Definition: debug_ros.c:5
#define NULL
Definition: types.h:112
#define INT_MAX
Definition: limits.h:26
_ACRTIMP int __cdecl strncmp(const char *, const char *, size_t)
Definition: string.c:3330
return ret
Definition: mutex.c:146
FxCollectionEntry * cur
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLint namelen
Definition: glext.h:7232
GLenum GLint GLuint mask
Definition: glext.h:6028
GLint limit
Definition: glext.h:10326
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLsizei len
Definition: glext.h:6722
GLfloat GLfloat v1
Definition: glext.h:6062
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
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
uint32_t entry
Definition: isohybrid.c:63
XMLPUBFUN void xmlMutexLock(xmlMutexPtr tok)
Definition: threads.c:201
XMLPUBFUN void xmlMutexUnlock(xmlMutexPtr tok)
Definition: threads.c:225
#define ATTRIBUTE_NO_SANITIZE_INTEGER
Definition: libxml.h:67
struct S1 s1
__u16 time
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
const char * var
Definition: shader.c:5666
static unsigned(__cdecl *hash_bstr)(bstr_t s)
XML_HIDDEN void xmlCleanupMutex(xmlMutexPtr mutex)
Definition: threads.c:166
XML_HIDDEN void xmlInitMutex(xmlMutexPtr mutex)
Definition: threads.c:128
const WCHAR * str
xmlHashedString xmlDictLookupHashed(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:845
static const xmlChar * xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, unsigned int plen, const xmlChar *name, unsigned int namelen)
Definition: dict.c:204
unsigned xmlDictComputeHash(const xmlDict *dict, const xmlChar *string)
Definition: dict.c:512
void xmlDictFree(xmlDictPtr dict)
Definition: dict.c:333
static xmlMutex xmlDictMutex
Definition: dict.c:78
const xmlChar * xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:872
xmlDictPtr xmlDictCreateSub(xmlDictPtr sub)
Definition: dict.c:297
#define SIZE_MAX
Definition: dict.c:35
#define MIN_HASH_SIZE
Definition: dict.c:40
ATTRIBUTE_NO_SANITIZE_INTEGER void xmlInitRandom(void)
Definition: dict.c:918
static ATTRIBUTE_NO_SANITIZE_INTEGER unsigned xmlDictHashQName(unsigned seed, const xmlChar *prefix, const xmlChar *name, size_t *pplen, size_t *plen)
Definition: dict.c:483
int xmlDictOwns(xmlDictPtr dict, const xmlChar *str)
Definition: dict.c:376
struct _xmlDictStrings xmlDictStrings
Definition: dict.c:43
void xmlCleanupDictInternal(void)
Definition: dict.c:121
xmlDictStrings * xmlDictStringsPtr
Definition: dict.c:44
ATTRIBUTE_NO_SANITIZE_INTEGER unsigned xmlDictCombineHash(unsigned v1, unsigned v2)
Definition: dict.c:521
size_t xmlDictGetUsage(xmlDictPtr dict)
Definition: dict.c:441
void xmlDictCleanup(void)
Definition: dict.c:112
size_t xmlDictSetLimit(xmlDictPtr dict, size_t limit)
Definition: dict.c:421
static ATTRIBUTE_NO_SANITIZE_INTEGER unsigned xoroshiro64ss(unsigned *s)
Definition: dict.c:938
static ATTRIBUTE_NO_SANITIZE_INTEGER const xmlDictEntry * xmlDictLookupInternal(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name, int maybeLen, int update)
Definition: dict.c:678
static ATTRIBUTE_NO_SANITIZE_INTEGER unsigned xmlDictHashName(unsigned seed, const xmlChar *data, size_t maxLen, size_t *plen)
Definition: dict.c:464
int xmlDictReference(xmlDictPtr dict)
Definition: dict.c:317
static xmlMutex xmlRngMutex
Definition: dict.c:907
#define MAX_FILL_DENOM
Definition: dict.c:39
static int xmlDictGrow(xmlDictPtr dict, unsigned size)
Definition: dict.c:609
unsigned xmlRandom(void)
Definition: dict.c:951
#define HASH_ROL31(x, n)
Definition: dict.c:517
const xmlChar * xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name)
Definition: dict.c:894
void xmlCleanupRandom(void)
Definition: dict.c:932
static unsigned globalRngState[2]
Definition: dict.c:909
int xmlDictSize(xmlDictPtr dict)
Definition: dict.c:402
static const xmlChar * xmlDictAddString(xmlDictPtr dict, const xmlChar *name, unsigned int namelen)
Definition: dict.c:136
int xmlInitializeDict(void)
Definition: dict.c:88
void xmlInitDictInternal(void)
Definition: dict.c:99
xmlDictPtr xmlDictCreate(void)
Definition: dict.c:262
#define MAX_HASH_SIZE
Definition: dict.c:41
const xmlChar * xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:824
xmlHashedString xmlDictEntry
Definition: dict.c:54
static ATTRIBUTE_NO_SANITIZE_INTEGER xmlDictEntry * xmlDictFindEntry(const xmlDict *dict, const xmlChar *prefix, const xmlChar *name, int len, unsigned hashValue, int *pfound)
Definition: dict.c:547
#define MAX_FILL_NUM
Definition: dict.c:38
xmlFreeFunc xmlFree
Definition: globals.c:184
xmlMallocFunc xmlMalloc
Definition: globals.c:193
XML_GLOBALS_PARSER XMLPUBFUN void xmlInitParser(void)
Definition: threads.c:569
#define HASH_UPDATE(h1, h2, ch)
Definition: dict.h:28
#define HASH_ROL(x, n)
Definition: dict.h:12
#define HASH_FINISH(h1, h2)
Definition: dict.h:38
#define HASH_INIT(h1, h2, seed)
Definition: dict.h:22
#define memset(x, y, z)
Definition: compat.h:39
xmlChar * end
Definition: dict.c:48
size_t size
Definition: dict.c:49
xmlDictStringsPtr next
Definition: dict.c:46
xmlChar * free
Definition: dict.c:47
size_t nbStrings
Definition: dict.c:50
Definition: dict.c:59
unsigned seed
Definition: dict.c:69
size_t limit
Definition: dict.c:71
xmlDictStringsPtr strings
Definition: dict.c:65
struct _xmlDict * subdict
Definition: dict.c:67
int ref_counter
Definition: dict.c:60
unsigned int nbElems
Definition: dict.c:64
size_t size
Definition: dict.c:63
xmlDictEntry * table
Definition: dict.c:62
Definition: undname.c:54
Definition: name.c:39
unsigned hashValue
Definition: dict.h:49
Character const *const prefix
Definition: tempnam.cpp:195
XMLPUBFUN int xmlStrQEqual(const xmlChar *pref, const xmlChar *name, const xmlChar *str)
Definition: xmlstring.c:188
unsigned char xmlChar
Definition: xmlstring.h:28