From 19161bab1592a44f4b1b0068007e9dd59a94146b Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Mon, 25 Sep 2023 14:00:48 +0200 Subject: [PATCH] dict: Internal API to look up hash values --- CMakeLists.txt | 2 +- configure.ac | 2 +- dict.c | 73 ++++++++++++++++++++++++++++++++++-------- include/private/dict.h | 12 +++++++ 4 files changed, 73 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0b691bb..a257ef4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -430,7 +430,7 @@ endif() if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU") # These compiler flags can break the checks above so keep them here. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wall -Wextra -Wshadow \ --Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return \ +-Wpointer-arith -Wcast-align -Wwrite-strings \ -Wstrict-prototypes -Wmissing-prototypes \ -Wno-long-long -Wno-format-extra-args") diff --git a/configure.ac b/configure.ac index c3071b7c..4fac7b27 100644 --- a/configure.ac +++ b/configure.ac @@ -519,7 +519,7 @@ else fi # warnings we'd like to see - AM_CFLAGS="${AM_CFLAGS} -pedantic -Wall -Wextra -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes" + AM_CFLAGS="${AM_CFLAGS} -pedantic -Wall -Wextra -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes" # warnings we'd like to suppress AM_CFLAGS="${AM_CFLAGS} -Wno-long-long -Wno-format-extra-args" case "${host}" in diff --git a/dict.c b/dict.c index 70f00121..8bfc9f15 100644 --- a/dict.c +++ b/dict.c @@ -40,12 +40,6 @@ #define MIN_HASH_SIZE 8 #define MAX_HASH_SIZE (1u << 31) -typedef struct { - unsigned hashValue; - const xmlChar *name; -} xmlDictEntry; -typedef xmlDictEntry *xmlDictEntryPtr; - typedef struct _xmlDictStrings xmlDictStrings; typedef xmlDictStrings *xmlDictStringsPtr; struct _xmlDictStrings { @@ -57,6 +51,8 @@ struct _xmlDictStrings { xmlChar array[1]; }; +typedef xmlHashedString xmlDictEntry; + /* * The entire dictionary */ @@ -496,6 +492,12 @@ xmlDictHashQName(unsigned seed, const xmlChar *prefix, const xmlChar *name, return(h2 | MAX_HASH_SIZE); } +unsigned +xmlDictComputeHash(const xmlDict *dict, const xmlChar *string) { + size_t len; + return(xmlDictHashName(dict->seed, string, SIZE_MAX, &len)); +} + /** * xmlDictFindEntry: * @dict: dict @@ -640,10 +642,10 @@ done: * Internal lookup and update function. */ ATTRIBUTE_NO_SANITIZE_INTEGER -static const xmlChar * +static const xmlDictEntry * xmlDictLookupInternal(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name, int maybeLen, int update) { - xmlDictEntryPtr entry = NULL; + xmlDictEntry *entry = NULL; const xmlChar *ret; unsigned hashValue; size_t maxLen, len, plen, klen; @@ -675,7 +677,7 @@ xmlDictLookupInternal(xmlDictPtr dict, const xmlChar *prefix, if (dict->size > 0) entry = xmlDictFindEntry(dict, prefix, name, klen, hashValue, &found); if (found) - return(entry->name); + return(entry); if (dict->subdict != NULL) { xmlDictEntry *subEntry; @@ -690,7 +692,7 @@ xmlDictLookupInternal(xmlDictPtr dict, const xmlChar *prefix, subEntry = xmlDictFindEntry(dict->subdict, prefix, name, klen, subHashValue, &found); if (found) - return(subEntry->name); + return(subEntry); } if (!update) @@ -772,7 +774,7 @@ xmlDictLookupInternal(xmlDictPtr dict, const xmlChar *prefix, dict->nbElems++; - return(ret); + return(entry); } /** @@ -788,7 +790,40 @@ xmlDictLookupInternal(xmlDictPtr dict, const xmlChar *prefix, */ const xmlChar * xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) { - return(xmlDictLookupInternal(dict, NULL, name, len, 1)); + const xmlDictEntry *entry; + + entry = xmlDictLookupInternal(dict, NULL, name, len, 1); + if (entry == NULL) + return(NULL); + return(entry->name); +} + +/** + * xmlDictLookupHashed: + * @dict: dictionary + * @name: string key + * @len: length of the key, if -1 it is recomputed + * + * Lookup a dictionary entry and add the string to the dictionary if + * it wasn't found. + * + * Returns the dictionary entry. + */ +xmlHashedString +xmlDictLookupHashed(xmlDictPtr dict, const xmlChar *name, int len) { + const xmlDictEntry *entry; + xmlHashedString ret; + + entry = xmlDictLookupInternal(dict, NULL, name, len, 1); + + if (entry == NULL) { + ret.name = NULL; + ret.hashValue = 0; + } else { + ret = *entry; + } + + return(ret); } /** @@ -803,7 +838,12 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) { */ const xmlChar * xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) { - return(xmlDictLookupInternal(dict, NULL, name, len, 0)); + const xmlDictEntry *entry; + + entry = xmlDictLookupInternal(dict, NULL, name, len, 0); + if (entry == NULL) + return(NULL); + return(entry->name); } /** @@ -820,7 +860,12 @@ xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) { */ const xmlChar * xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) { - return(xmlDictLookupInternal(dict, prefix, name, -1, 1)); + const xmlDictEntry *entry; + + entry = xmlDictLookupInternal(dict, prefix, name, -1, 1); + if (entry == NULL) + return(NULL); + return(entry->name); } /* diff --git a/include/private/dict.h b/include/private/dict.h index d2791d2b..21084a7d 100644 --- a/include/private/dict.h +++ b/include/private/dict.h @@ -1,6 +1,8 @@ #ifndef XML_DICT_H_PRIVATE__ #define XML_DICT_H_PRIVATE__ +#include + /* * Values are ANDed with 0xFFFFFFFF to support platforms where * unsigned is larger than 32 bits. With 32-bit unsigned values, @@ -43,11 +45,21 @@ h2 &= 0xFFFFFFFF; \ } while (0) +typedef struct { + unsigned hashValue; + const xmlChar *name; +} xmlHashedString; + XML_HIDDEN void xmlInitDictInternal(void); XML_HIDDEN void xmlCleanupDictInternal(void); +unsigned +xmlDictComputeHash(const xmlDict *dict, const xmlChar *string); +xmlHashedString +xmlDictLookupHashed(xmlDictPtr dict, const xmlChar *name, int len); + XML_HIDDEN void xmlInitRandom(void); XML_HIDDEN void