From 261e25786073840d341ffdd5c36a08b0b9e46504 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 26 Jun 2021 14:54:37 -0700 Subject: [PATCH] stringi-set: New functions for not necessarily null terminated strings. --- src/libpspp/stringi-set.c | 36 ++++++++++++++++++++++++++++++++---- src/libpspp/stringi-set.h | 7 ++++++- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/libpspp/stringi-set.c b/src/libpspp/stringi-set.c index b442a41567..a609150d99 100644 --- a/src/libpspp/stringi-set.c +++ b/src/libpspp/stringi-set.c @@ -32,6 +32,8 @@ static struct stringi_set_node *stringi_set_find_node__ ( const struct stringi_set *, const char *, unsigned int hash); +static struct stringi_set_node *stringi_set_find_node_len__ ( + const struct stringi_set *, const char *, size_t length, unsigned int hash); static void stringi_set_insert__ (struct stringi_set *, char *, unsigned int hash); static bool stringi_set_delete__ (struct stringi_set *, const char *, @@ -81,7 +83,16 @@ stringi_set_destroy (struct stringi_set *set) bool stringi_set_contains (const struct stringi_set *set, const char *s) { - return stringi_set_find_node (set, s) != NULL; + return stringi_set_contains_len (set, s, strlen (s)); +} + +/* Returns true if SET contains S with the given LENGTH (or a similar string + with different case), false otherwise. */ +bool +stringi_set_contains_len (const struct stringi_set *set, const char *s, + size_t length) +{ + return stringi_set_find_node_len (set, s, length) != NULL; } /* Returns the node in SET that contains S, or a null pointer if SET does not @@ -89,7 +100,17 @@ stringi_set_contains (const struct stringi_set *set, const char *s) struct stringi_set_node * stringi_set_find_node (const struct stringi_set *set, const char *s) { - return stringi_set_find_node__ (set, s, utf8_hash_case_string (s, 0)); + return stringi_set_find_node_len (set, s, strlen (s)); +} + +/* Returns the node in SET that contains S with the given LENGTH, or a null + pointer if SET does not contain S. */ +struct stringi_set_node * +stringi_set_find_node_len (const struct stringi_set *set, const char *s, + size_t length) +{ + return stringi_set_find_node_len__ (set, s, length, + utf8_hash_case_bytes (s, length, 0)); } /* Inserts a copy of S into SET. Returns true if successful, false if SET @@ -281,13 +302,20 @@ stringi_set_get_sorted_array (const struct stringi_set *set) static struct stringi_set_node * stringi_set_find_node__ (const struct stringi_set *set, const char *s, - unsigned int hash) + unsigned int hash) +{ + return stringi_set_find_node_len__ (set, s, strlen (s), hash); +} + +static struct stringi_set_node * +stringi_set_find_node_len__ (const struct stringi_set *set, const char *s, + size_t length, unsigned int hash) { struct stringi_set_node *node; HMAP_FOR_EACH_WITH_HASH (node, struct stringi_set_node, hmap_node, hash, &set->hmap) - if (!utf8_strcasecmp (s, node->string)) + if (!utf8_strncasecmp (s, length, node->string, strlen (node->string))) return node; return NULL; diff --git a/src/libpspp/stringi-set.h b/src/libpspp/stringi-set.h index 2a000889ec..ea4fad6bcf 100644 --- a/src/libpspp/stringi-set.h +++ b/src/libpspp/stringi-set.h @@ -60,8 +60,13 @@ static inline size_t stringi_set_count (const struct stringi_set *); static inline bool stringi_set_is_empty (const struct stringi_set *); bool stringi_set_contains (const struct stringi_set *, const char *); +bool stringi_set_contains_len (const struct stringi_set *, const char *, + size_t length); struct stringi_set_node *stringi_set_find_node (const struct stringi_set *, - const char *); + const char *); +struct stringi_set_node *stringi_set_find_node_len (const struct stringi_set *, + const char *, + size_t length); bool stringi_set_insert (struct stringi_set *, const char *); bool stringi_set_insert_nocopy (struct stringi_set *, char *); -- 2.30.2