15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * dict.c: dictionary of reusable strings, just used to avoid allocation 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and freeing operations. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2003 Daniel Veillard. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission to use, copy, modify, and distribute this software for any 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * purpose with or without fee is hereby granted, provided that the above 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copyright notice and this permission notice appear in all copies. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author: daniel@veillard.com 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXML 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_STDINT_H 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdint.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_INTTYPES_H 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <inttypes.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(WIN32) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef unsigned __int32 uint32_t; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h> 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/dict.h> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlmemory.h> 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlerror.h> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/globals.h> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_GROW */ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DICT_DEBUG_PATTERNS */ 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_HASH_LEN 3 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MIN_DICT_SIZE 128 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_DICT_HASH 8 * 2048 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WITH_BIG_KEY 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_BIG_KEY 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define xmlDictComputeKey(dict, name, len) \ 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (((dict)->size == MIN_DICT_SIZE) ? \ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictComputeFastKey(name, len) : \ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictComputeBigKey(name, len)) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define xmlDictComputeQKey(dict, prefix, plen, name, len) \ 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (((prefix) == NULL) ? \ 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlDictComputeKey(dict, name, len)) : \ 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (((dict)->size == MIN_DICT_SIZE) ? \ 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictComputeFastQKey(prefix, plen, name, len) : \ 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictComputeBigQKey(prefix, plen, name, len))) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* !WITH_BIG_KEY */ 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define xmlDictComputeKey(dict, name, len) \ 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictComputeFastKey(name, len) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define xmlDictComputeQKey(dict, prefix, plen, name, len) \ 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictComputeFastQKey(prefix, plen, name, len) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* WITH_BIG_KEY */ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * An entry in the dictionnary 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlDictEntry xmlDictEntry; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlDictEntry *xmlDictEntryPtr; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlDictEntry { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct _xmlDictEntry *next; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *name; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int valid; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long okey; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xmlDictStrings xmlDictStrings; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xmlDictStrings *xmlDictStringsPtr; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlDictStrings { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictStringsPtr next; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *free; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *end; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbStrings; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar array[1]; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The entire dictionnary 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xmlDict { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ref_counter; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct _xmlDictEntry *dict; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbElems; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictStringsPtr strings; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct _xmlDict *subdict; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A mutex for modifying the reference counter for shared 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * dictionaries. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlRMutexPtr xmlDictMutex = NULL; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Whether the dictionary mutex was initialized. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlDictInitialized = 0; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlInitializeDict: 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Do the dictionary mutex initialization. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * this function is not thread safe, initialization should 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * preferably be done once at startup 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int xmlInitializeDict(void) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlDictInitialized) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((xmlDictMutex = xmlNewRMutex()) == NULL) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictInitialized = 1; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictCleanup: 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free the dictionary mutex. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictCleanup(void) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlDictInitialized) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeRMutex(xmlDictMutex); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictInitialized = 0; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictAddString: 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: the dictionnary 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: the name of the userdata 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the length of the name, if -1 it is recomputed 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add the string to the array[s] 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the pointer of the local string, or NULL in case of error. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const xmlChar * 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictAddString(xmlDictPtr dict, const xmlChar *name, int namelen) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictStringsPtr pool; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *ret; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */ 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DICT_DEBUG_PATTERNS 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "-"); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool = dict->strings; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pool != NULL) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool->end - pool->free > namelen) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto found_pool; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool->size > size) size = pool->size; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool = pool->next; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Not found, need to allocate 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool == NULL) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size == 0) size = 1000; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else size *= 4; /* exponential growth */ 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size < 4 * namelen) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = 4 * namelen; /* just in case ! */ 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool == NULL) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->size = size; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->nbStrings = 0; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->free = &pool->array[0]; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->end = &pool->array[size]; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->next = dict->strings; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->strings = pool; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DICT_DEBUG_PATTERNS 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "+"); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)found_pool: 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = pool->free; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(pool->free, name, namelen); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->free += namelen; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(pool->free++) = 0; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->nbStrings++; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictAddQString: 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: the dictionnary 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @prefix: the prefix of the userdata 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @plen: the prefix length 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: the name of the userdata 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the length of the name, if -1 it is recomputed 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add the QName to the array[s] 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the pointer of the local string, or NULL in case of error. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const xmlChar * 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, int plen, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *name, int namelen) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictStringsPtr pool; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *ret; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */ 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefix == NULL) return(xmlDictAddString(dict, name, namelen)); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DICT_DEBUG_PATTERNS 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "="); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool = dict->strings; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pool != NULL) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool->end - pool->free > namelen + plen + 1) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto found_pool; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool->size > size) size = pool->size; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool = pool->next; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Not found, need to allocate 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool == NULL) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size == 0) size = 1000; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else size *= 4; /* exponential growth */ 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size < 4 * (namelen + plen + 1)) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = 4 * (namelen + plen + 1); /* just in case ! */ 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool == NULL) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->size = size; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->nbStrings = 0; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->free = &pool->array[0]; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->end = &pool->array[size]; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->next = dict->strings; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->strings = pool; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DICT_DEBUG_PATTERNS 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "+"); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)found_pool: 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = pool->free; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(pool->free, prefix, plen); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->free += plen; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(pool->free++) = ':'; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(pool->free, name, namelen); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->free += namelen; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(pool->free++) = 0; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->nbStrings++; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_BIG_KEY 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictComputeBigKey: 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Calculate a hash key using a good hash function that works well for 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * larger hash table sizes. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Hash function by "One-at-a-Time Hash" see 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://burtleburtle.net/bob/hash/doobs.html 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static uint32_t 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictComputeBigKey(const xmlChar* data, int namelen) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t hash; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (namelen <= 0 || data == NULL) return(0); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash = 0; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < namelen; i++) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += data[i]; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += (hash << 10); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash ^= (hash >> 6); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += (hash << 3); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash ^= (hash >> 11); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += (hash << 15); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hash; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictComputeBigQKey: 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Calculate a hash key for two strings using a good hash function 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that works well for larger hash table sizes. 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Hash function by "One-at-a-Time Hash" see 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://burtleburtle.net/bob/hash/doobs.html 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Neither of the two strings must be NULL. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned long 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictComputeBigQKey(const xmlChar *prefix, int plen, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *name, int len) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t hash; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash = 0; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < plen; i++) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += prefix[i]; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += (hash << 10); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash ^= (hash >> 6); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += ':'; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += (hash << 10); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash ^= (hash >> 6); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < len; i++) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += name[i]; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += (hash << 10); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash ^= (hash >> 6); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += (hash << 3); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash ^= (hash >> 11); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash += (hash << 15); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hash; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* WITH_BIG_KEY */ 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictComputeFastKey: 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Calculate a hash key using a fast hash function that works well 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for low hash table fill. 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned long 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictComputeFastKey(const xmlChar *name, int namelen) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long value = 0L; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name == NULL) return(0); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = *name; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value <<= 5; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (namelen > 10) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value += name[namelen - 1]; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) namelen = 10; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (namelen) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 10: value += name[9]; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 9: value += name[8]; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: value += name[7]; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 7: value += name[6]; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 6: value += name[5]; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 5: value += name[4]; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: value += name[3]; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: value += name[2]; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: value += name[1]; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: break; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(value); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictComputeFastQKey: 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Calculate a hash key for two strings using a fast hash function 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * that works well for low hash table fill. 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Neither of the two strings must be NULL. 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned long 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictComputeFastQKey(const xmlChar *prefix, int plen, 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *name, int len) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long value = 0L; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plen == 0) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value += 30 * (unsigned long) ':'; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value += 30 * (*prefix); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len > 10) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value += name[len - (plen + 1 + 1)]; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = 10; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (plen > 10) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plen = 10; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (plen) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 10: value += prefix[9]; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 9: value += prefix[8]; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: value += prefix[7]; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 7: value += prefix[6]; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 6: value += prefix[5]; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 5: value += prefix[4]; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: value += prefix[3]; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: value += prefix[2]; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: value += prefix[1]; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: value += prefix[0]; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: break; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len -= plen; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len > 0) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value += (unsigned long) ':'; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len--; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (len) { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 10: value += name[9]; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 9: value += name[8]; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 8: value += name[7]; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 7: value += name[6]; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 6: value += name[5]; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 5: value += name[4]; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 4: value += name[3]; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: value += name[2]; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: value += name[1]; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: value += name[0]; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: break; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(value); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictCreate: 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new dictionary 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created dictionnary, or NULL if an error occured. 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictPtr 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictCreate(void) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictPtr dict; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlDictInitialized) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlInitializeDict()) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DICT_DEBUG_PATTERNS 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "C"); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict = xmlMalloc(sizeof(xmlDict)); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->ref_counter = 1; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->size = MIN_DICT_SIZE; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->nbElems = 0; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->dict = xmlMalloc(MIN_DICT_SIZE * sizeof(xmlDictEntry)); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->strings = NULL; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->subdict = NULL; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->dict) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry)); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(dict); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(dict); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictCreateSub: 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @sub: an existing dictionnary 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new dictionary, inheriting strings from the read-only 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * dictionnary @sub. On lookup, strings are first searched in the 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * new dictionnary, then in @sub, and if not found are created in the 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * new dictionnary. 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created dictionnary, or NULL if an error occured. 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictPtr 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictCreateSub(xmlDictPtr sub) { 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictPtr dict = xmlDictCreate(); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((dict != NULL) && (sub != NULL)) { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DICT_DEBUG_PATTERNS 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "R"); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->subdict = sub; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictReference(dict->subdict); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(dict); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictReference: 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: the dictionnary 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Increment the reference counter of a dictionary 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 0 in case of success and -1 in case of error 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictReference(xmlDictPtr dict) { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlDictInitialized) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlInitializeDict()) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict == NULL) return -1; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRMutexLock(xmlDictMutex); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->ref_counter++; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRMutexUnlock(xmlDictMutex); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictGrow: 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: the dictionnary 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @size: the new size of the dictionnary 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * resize the dictionnary 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 0 in case of success, -1 in case of failure 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictGrow(xmlDictPtr dict, int size) { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long key, okey; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int oldsize, i; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr iter, next; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct _xmlDictEntry *olddict; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_GROW 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long nbElem = 0; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int keep_keys = 1; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict == NULL) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size < 8) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size > 8 * 2048) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DICT_DEBUG_PATTERNS 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "*"); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldsize = dict->size; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) olddict = dict->dict; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (olddict == NULL) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (oldsize == MIN_DICT_SIZE) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keep_keys = 0; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->dict = xmlMalloc(size * sizeof(xmlDictEntry)); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->dict == NULL) { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->dict = olddict; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(dict->dict, 0, size * sizeof(xmlDictEntry)); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->size = size; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* If the two loops are merged, there would be situations where 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a new entry needs to allocated and data copied into it from 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the main dict. It is nicer to run through the array twice, first 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) copying all the elements in the main array (less probability of 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocate) and then the rest, so we only free in the second loop. 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < oldsize; i++) { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (olddict[i].valid == 0) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (keep_keys) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) okey = olddict[i].okey; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) okey = xmlDictComputeKey(dict, olddict[i].name, olddict[i].len); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = okey % dict->size; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->dict[key].valid == 0) { 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&(dict->dict[key]), &(olddict[i]), sizeof(xmlDictEntry)); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->dict[key].next = NULL; 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->dict[key].okey = okey; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr entry; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry = xmlMalloc(sizeof(xmlDictEntry)); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry != NULL) { 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->name = olddict[i].name; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->len = olddict[i].len; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->okey = okey; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->next = dict->dict[key].next; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->valid = 1; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->dict[key].next = entry; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * we don't have much ways to alert from herei 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * result is loosing an entry and unicity garantee 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = -1; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_GROW 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbElem++; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < oldsize; i++) { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = olddict[i].next; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (iter) { 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter->next; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * put back the entry in the new dict 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (keep_keys) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) okey = iter->okey; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) okey = xmlDictComputeKey(dict, iter->name, iter->len); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = okey % dict->size; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->dict[key].valid == 0) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&(dict->dict[key]), iter, sizeof(xmlDictEntry)); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->dict[key].next = NULL; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->dict[key].valid = 1; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->dict[key].okey = okey; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(iter); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->next = dict->dict[key].next; 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->okey = okey; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->dict[key].next = iter; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_GROW 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbElem++; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = next; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(olddict); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_GROW 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlGenericError(xmlGenericErrorContext, 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xmlDictGrow : from %d to %d, %d elems\n", oldsize, size, nbElem); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictFree: 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: the dictionnary 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free the hash @dict and its contents. The userdata is 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * deallocated with @f if provided. 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictFree(xmlDictPtr dict) { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr iter; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr next; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int inside_dict = 0; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictStringsPtr pool, nextp; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict == NULL) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlDictInitialized) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlInitializeDict()) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* decrement the counter, it may be shared by a parser and docs */ 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRMutexLock(xmlDictMutex); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->ref_counter--; 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->ref_counter > 0) { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRMutexUnlock(xmlDictMutex); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlRMutexUnlock(xmlDictMutex); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->subdict != NULL) { 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictFree(dict->subdict); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->dict) { 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i = 0; ((i < dict->size) && (dict->nbElems > 0)); i++) { 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = &(dict->dict[i]); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter->valid == 0) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inside_dict = 1; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (iter) { 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter->next; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!inside_dict) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(iter); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->nbElems--; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inside_dict = 0; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = next; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(dict->dict); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool = dict->strings; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pool != NULL) { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nextp = pool->next; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(pool); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool = nextp; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(dict); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictLookup: 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: the dictionnary 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: the name of the userdata 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the length of the name, if -1 it is recomputed 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add the @name to the dictionnary @dict if not present. 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the internal copy of the name or NULL in case of internal error 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const xmlChar * 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) { 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long key, okey, nbi = 0; 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr entry; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr insert; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *ret; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((dict == NULL) || (name == NULL)) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len < 0) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = strlen((const char *) name); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check for duplicate and insertion location. 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) okey = xmlDictComputeKey(dict, name, len); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = okey % dict->size; 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->dict[key].valid == 0) { 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert = NULL; 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (insert = &(dict->dict[key]); insert->next != NULL; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert = insert->next) { 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __GNUC__ 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->okey == okey) && (insert->len == len)) { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!memcmp(insert->name, name, len)) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert->name); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->okey == okey) && (insert->len == len) && 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!xmlStrncmp(insert->name, name, len))) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert->name); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbi++; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __GNUC__ 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->okey == okey) && (insert->len == len)) { 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!memcmp(insert->name, name, len)) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert->name); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->okey == okey) && (insert->len == len) && 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!xmlStrncmp(insert->name, name, len))) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert->name); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->subdict) { 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long skey; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* we cannot always reuse the same okey for the subdict */ 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((dict->size == MIN_DICT_SIZE) && 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (dict->subdict->size != MIN_DICT_SIZE)) || 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((dict->size != MIN_DICT_SIZE) && 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (dict->subdict->size == MIN_DICT_SIZE))) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skey = xmlDictComputeKey(dict->subdict, name, len); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skey = okey; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = skey % dict->subdict->size; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->subdict->dict[key].valid != 0) { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr tmp; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = tmp->next) { 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __GNUC__ 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp->okey == skey) && (tmp->len == len)) { 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!memcmp(tmp->name, name, len)) 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp->name); 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp->okey == skey) && (tmp->len == len) && 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!xmlStrncmp(tmp->name, name, len))) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp->name); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbi++; 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __GNUC__ 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp->okey == skey) && (tmp->len == len)) { 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!memcmp(tmp->name, name, len)) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp->name); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp->okey == skey) && (tmp->len == len) && 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!xmlStrncmp(tmp->name, name, len))) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp->name); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = okey % dict->size; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlDictAddString(dict, name, len); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (insert == NULL) { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry = &(dict->dict[key]); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry = xmlMalloc(sizeof(xmlDictEntry)); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry == NULL) 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->name = ret; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->len = len; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->next = NULL; 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->valid = 1; 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->okey = okey; 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (insert != NULL) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert->next = entry; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->nbElems++; 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((nbi > MAX_HASH_LEN) && 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN))) { 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size) != 0) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Note that entry may have been freed at this point by xmlDictGrow */ 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictExists: 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: the dictionnary 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: the name of the userdata 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @len: the length of the name, if -1 it is recomputed 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check if the @name exists in the dictionnary @dict. 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the internal copy of the name or NULL if not found. 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const xmlChar * 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) { 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long key, okey, nbi = 0; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr insert; 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((dict == NULL) || (name == NULL)) 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len < 0) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = strlen((const char *) name); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check for duplicate and insertion location. 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) okey = xmlDictComputeKey(dict, name, len); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = okey % dict->size; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->dict[key].valid == 0) { 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert = NULL; 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (insert = &(dict->dict[key]); insert->next != NULL; 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert = insert->next) { 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __GNUC__ 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->okey == okey) && (insert->len == len)) { 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!memcmp(insert->name, name, len)) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert->name); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->okey == okey) && (insert->len == len) && 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!xmlStrncmp(insert->name, name, len))) 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert->name); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbi++; 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __GNUC__ 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->okey == okey) && (insert->len == len)) { 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!memcmp(insert->name, name, len)) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert->name); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->okey == okey) && (insert->len == len) && 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!xmlStrncmp(insert->name, name, len))) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert->name); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->subdict) { 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long skey; 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* we cannot always reuse the same okey for the subdict */ 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((dict->size == MIN_DICT_SIZE) && 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (dict->subdict->size != MIN_DICT_SIZE)) || 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((dict->size != MIN_DICT_SIZE) && 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (dict->subdict->size == MIN_DICT_SIZE))) 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skey = xmlDictComputeKey(dict->subdict, name, len); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skey = okey; 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = skey % dict->subdict->size; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->subdict->dict[key].valid != 0) { 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr tmp; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL; 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = tmp->next) { 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __GNUC__ 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp->okey == skey) && (tmp->len == len)) { 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!memcmp(tmp->name, name, len)) 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp->name); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp->okey == skey) && (tmp->len == len) && 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!xmlStrncmp(tmp->name, name, len))) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp->name); 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbi++; 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef __GNUC__ 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp->okey == skey) && (tmp->len == len)) { 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!memcmp(tmp->name, name, len)) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp->name); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp->okey == skey) && (tmp->len == len) && 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!xmlStrncmp(tmp->name, name, len))) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp->name); 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* not found */ 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictQLookup: 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: the dictionnary 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @prefix: the prefix 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: the name 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add the QName @prefix:@name to the hash @dict if not present. 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the internal copy of the QName or NULL in case of internal error 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const xmlChar * 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) { 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long okey, key, nbi = 0; 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr entry; 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr insert; 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *ret; 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len, plen, l; 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((dict == NULL) || (name == NULL)) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefix == NULL) 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlDictLookup(dict, name, -1)); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l = len = strlen((const char *) name); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) plen = strlen((const char *) prefix); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len += 1 + plen; 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check for duplicate and insertion location. 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) okey = xmlDictComputeQKey(dict, prefix, plen, name, l); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = okey % dict->size; 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->dict[key].valid == 0) { 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert = NULL; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (insert = &(dict->dict[key]); insert->next != NULL; 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert = insert->next) { 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->okey == okey) && (insert->len == len) && 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrQEqual(prefix, name, insert->name))) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert->name); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbi++; 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((insert->okey == okey) && (insert->len == len) && 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrQEqual(prefix, name, insert->name))) 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(insert->name); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->subdict) { 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long skey; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* we cannot always reuse the same okey for the subdict */ 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((dict->size == MIN_DICT_SIZE) && 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (dict->subdict->size != MIN_DICT_SIZE)) || 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((dict->size != MIN_DICT_SIZE) && 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (dict->subdict->size == MIN_DICT_SIZE))) 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skey = xmlDictComputeQKey(dict->subdict, prefix, plen, name, l); 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skey = okey; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = skey % dict->subdict->size; 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->subdict->dict[key].valid != 0) { 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictEntryPtr tmp; 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL; 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = tmp->next) { 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp->okey == skey) && (tmp->len == len) && 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrQEqual(prefix, name, tmp->name))) 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp->name); 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbi++; 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmp->okey == skey) && (tmp->len == len) && 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrQEqual(prefix, name, tmp->name))) 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(tmp->name); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = okey % dict->size; 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlDictAddQString(dict, prefix, plen, name, l); 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (insert == NULL) { 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry = &(dict->dict[key]); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry = xmlMalloc(sizeof(xmlDictEntry)); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry == NULL) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->name = ret; 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->len = len; 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->next = NULL; 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->valid = 1; 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry->okey = okey; 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (insert != NULL) 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) insert->next = entry; 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->nbElems++; 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((nbi > MAX_HASH_LEN) && 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN))) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size); 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Note that entry may have been freed at this point by xmlDictGrow */ 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictOwns: 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: the dictionnary 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @str: the string 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * check if a string is owned by the disctionary 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if true, 0 if false and -1 in case of error 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -1 in case of error 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictOwns(xmlDictPtr dict, const xmlChar *str) { 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDictStringsPtr pool; 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((dict == NULL) || (str == NULL)) 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool = dict->strings; 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pool != NULL) { 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((str >= &pool->array[0]) && (str <= pool->free)) 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool = pool->next; 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->subdict) 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xmlDictOwns(dict->subdict, str)); 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlDictSize: 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @dict: the dictionnary 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Query the number of elements installed in the hash @dict. 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of elements in the dictionnary or 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -1 in case of error 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlDictSize(xmlDictPtr dict) { 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict == NULL) 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dict->subdict) 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(dict->nbElems + dict->subdict->nbElems); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(dict->nbElems); 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define bottom_dict 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "elfgcchack.h" 1101