Alexandre Julliard : server: Add a helper function for hashing a Unicode string.

Alexandre Julliard julliard at winehq.org
Tue Mar 24 15:28:16 CDT 2020


Module: wine
Branch: master
Commit: 6db1232567018bc0312767246ff566c35f11a537
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=6db1232567018bc0312767246ff566c35f11a537

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Mar 24 12:48:26 2020 +0100

server: Add a helper function for hashing a Unicode string.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 server/atom.c    | 16 ++++------------
 server/object.c  | 12 ++----------
 server/unicode.c |  8 ++++++++
 server/unicode.h |  1 +
 4 files changed, 15 insertions(+), 22 deletions(-)

diff --git a/server/atom.c b/server/atom.c
index 11f4b46ffb..57aff7b891 100644
--- a/server/atom.c
+++ b/server/atom.c
@@ -163,15 +163,6 @@ static atom_t add_atom_entry( struct atom_table *table, struct atom_entry *entry
     return entry->atom;
 }
 
-/* compute the hash code for a string */
-static unsigned short atom_hash( struct atom_table *table, const struct unicode_str *str )
-{
-    unsigned int i;
-    unsigned short hash = 0;
-    for (i = 0; i < str->len / sizeof(WCHAR); i++) hash ^= toupperW(str->str[i]) + i;
-    return hash % table->entries_count;
-}
-
 /* dump an atom table */
 static void atom_table_dump( struct object *obj, int verbose )
 {
@@ -224,7 +215,7 @@ static struct atom_entry *find_atom_entry( struct atom_table *table, const struc
 static atom_t add_atom( struct atom_table *table, const struct unicode_str *str )
 {
     struct atom_entry *entry;
-    unsigned short hash = atom_hash( table, str );
+    unsigned short hash = hash_strW( str->str, str->len, table->entries_count );
     atom_t atom = 0;
 
     if (!str->len)
@@ -293,7 +284,8 @@ static atom_t find_atom( struct atom_table *table, const struct unicode_str *str
         set_error( STATUS_INVALID_PARAMETER );
         return 0;
     }
-    if (table && (entry = find_atom_entry( table, str, atom_hash(table, str) )))
+    if (table && (entry = find_atom_entry( table, str,
+                                           hash_strW( str->str, str->len, table->entries_count ))))
         return entry->atom;
     set_error( STATUS_OBJECT_NAME_NOT_FOUND );
     return 0;
@@ -350,7 +342,7 @@ atom_t find_global_atom( struct winstation *winstation, const struct unicode_str
     struct atom_entry *entry;
 
     if (!str->len || str->len > MAX_ATOM_LEN || !table) return 0;
-    if ((entry = find_atom_entry( table, str, atom_hash(table, str) )))
+    if ((entry = find_atom_entry( table, str, hash_strW( str->str, str->len, table->entries_count ))))
         return entry->atom;
     return 0;
 }
diff --git a/server/object.c b/server/object.c
index 0cac62ca6d..dacfe1d71a 100644
--- a/server/object.c
+++ b/server/object.c
@@ -127,17 +127,9 @@ void *memdup( const void *data, size_t len )
 
 /*****************************************************************/
 
-static int get_name_hash( const struct namespace *namespace, const WCHAR *name, data_size_t len )
-{
-    WCHAR hash = 0;
-    len /= sizeof(WCHAR);
-    while (len--) hash ^= tolowerW(*name++);
-    return hash % namespace->hash_size;
-}
-
 void namespace_add( struct namespace *namespace, struct object_name *ptr )
 {
-    int hash = get_name_hash( namespace, ptr->name, ptr->len );
+    unsigned int hash = hash_strW( ptr->name, ptr->len, namespace->hash_size );
 
     list_add_head( &namespace->names[hash], &ptr->entry );
 }
@@ -450,7 +442,7 @@ struct object *find_object( const struct namespace *namespace, const struct unic
 
     if (!name || !name->len) return NULL;
 
-    list = &namespace->names[ get_name_hash( namespace, name->str, name->len ) ];
+    list = &namespace->names[ hash_strW( name->str, name->len, namespace->hash_size ) ];
     LIST_FOR_EACH( p, list )
     {
         const struct object_name *ptr = LIST_ENTRY( p, struct object_name, entry );
diff --git a/server/unicode.c b/server/unicode.c
index eb06284c56..8d6c411cb6 100644
--- a/server/unicode.c
+++ b/server/unicode.c
@@ -66,6 +66,14 @@ int memicmp_strW( const WCHAR *str1, const WCHAR *str2, data_size_t len )
     return ret;
 }
 
+unsigned int hash_strW( const WCHAR *str, data_size_t len, unsigned int hash_size )
+{
+    unsigned int i, hash = 0;
+
+    for (i = 0; i < len / sizeof(WCHAR); i++) hash = hash * 65599 + to_lower( str[i] );
+    return hash % hash_size;
+}
+
 WCHAR *ascii_to_unicode_str( const char *str, struct unicode_str *ret )
 {
     data_size_t i, len = strlen(str);
diff --git a/server/unicode.h b/server/unicode.h
index 99f248bd68..cfeceb88b9 100644
--- a/server/unicode.h
+++ b/server/unicode.h
@@ -28,6 +28,7 @@
 #include "object.h"
 
 extern int memicmp_strW( const WCHAR *str1, const WCHAR *str2, data_size_t len );
+extern unsigned int hash_strW( const WCHAR *str, data_size_t len, unsigned int hash_size );
 extern WCHAR *ascii_to_unicode_str( const char *str, struct unicode_str *ret );
 extern int parse_strW( WCHAR *buffer, data_size_t *len, const char *src, char endchar );
 extern int dump_strW( const WCHAR *str, data_size_t len, FILE *f, const char escape[2] );




More information about the wine-cvs mailing list