Alexandre Julliard : winebuild: Store length of Unicode strings explicitly.

Alexandre Julliard julliard at winehq.org
Tue Feb 8 16:11:45 CST 2022


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Feb  8 17:44:58 2022 +0100

winebuild: Store length of Unicode strings explicitly.

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

---

 tools/winebuild/res32.c | 82 ++++++++++++++++++++++++-------------------------
 1 file changed, 41 insertions(+), 41 deletions(-)

diff --git a/tools/winebuild/res32.c b/tools/winebuild/res32.c
index a0209ad6f2a..80890f55458 100644
--- a/tools/winebuild/res32.c
+++ b/tools/winebuild/res32.c
@@ -35,6 +35,7 @@ typedef unsigned short WCHAR;
 struct string_id
 {
     WCHAR *str;  /* ptr to Unicode string */
+    unsigned int len;    /* len in characters */
     unsigned short id;   /* integer id if str is NULL */
 };
 
@@ -92,19 +93,6 @@ static inline struct resource *add_resource( DLLSPEC *spec )
     return &spec->resources[spec->nb_resources++];
 }
 
-static inline unsigned int strlenW( const WCHAR *str )
-{
-    const WCHAR *s = str;
-    while (*s) s++;
-    return s - str;
-}
-
-static inline int strcmpW( const WCHAR *str1, const WCHAR *str2 )
-{
-    while (*str1 && (*str1 == *str2)) { str1++; str2++; }
-    return *str1 - *str2;
-}
-
 static struct res_name *add_name( struct res_type *type, struct resource *res )
 {
     struct res_name *name;
@@ -132,8 +120,11 @@ static struct res_type *add_type( struct res_tree *tree, struct resource *res )
 /* get a string from the current resource file */
 static void get_string( struct string_id *str )
 {
+    unsigned int i = 0;
+    size_t start_pos = input_buffer_pos;
     WCHAR wc = get_word();
 
+    str->len = 0;
     if (wc == 0xffff)
     {
         str->str = NULL;
@@ -141,10 +132,11 @@ static void get_string( struct string_id *str )
     }
     else
     {
-        WCHAR *p = xmalloc( (strlenW( (const WCHAR *)(input_buffer + input_buffer_pos) - 1) + 1) * sizeof(WCHAR) );
-        str->str = p;
-        str->id  = 0;
-        if ((*p++ = wc)) while ((*p++ = get_word()));
+        input_buffer_pos = start_pos;
+        while (get_word()) str->len++;
+        str->str = xmalloc( str->len * sizeof(WCHAR) );
+        input_buffer_pos = start_pos;
+        while ((wc = get_word())) str->str[i++] = wc;
     }
 }
 
@@ -153,8 +145,8 @@ static void put_string( const struct string_id *str )
 {
     if (str->str)
     {
-        const WCHAR *p = str->str;
-        while (*p) put_word( *p++ );
+        unsigned int i;
+        for (i = 0; i < str->len; i++) put_word( str->str[i] );
         put_word( 0 );
     }
     else
@@ -253,13 +245,18 @@ int load_res32_file( const char *name, DLLSPEC *spec )
 /* compare two unicode strings/ids */
 static int cmp_string( const struct string_id *str1, const struct string_id *str2 )
 {
+    unsigned int i;
+
     if (!str1->str)
     {
         if (!str2->str) return str1->id - str2->id;
         return 1;  /* an id compares larger than a string */
     }
     if (!str2->str) return -1;
-    return strcmpW( str1->str, str2->str );
+
+    for (i = 0; i < str1->len && i < str2->len; i++)
+        if (str1->str[i] != str2->str[i]) return str1->str[i] - str2->str[i];
+    return str1->len - str2->len;
 }
 
 /* compare two resources for sorting the resource directory */
@@ -278,11 +275,13 @@ static int cmp_res( const void *ptr1, const void *ptr2 )
 
 static char *format_res_string( const struct string_id *str )
 {
-    int i, len = str->str ? strlenW(str->str) + 1 : 5;
-    char *ret = xmalloc( len );
+    unsigned int i;
+    char *ret;
 
-    if (!str->str) sprintf( ret, "%04x", str->id );
-    else for (i = 0; i < len; i++) ret[i] = str->str[i];  /* dumb W->A conversion */
+    if (!str->str) return strmake( "#%04x", str->id );
+    ret = xmalloc( str->len + 1 );
+    for (i = 0; i < str->len; i++) ret[i] = str->str[i];  /* dumb W->A conversion */
+    ret[i] = 0;
     return ret;
 }
 
@@ -365,7 +364,7 @@ static struct res_tree *build_resource_tree( DLLSPEC *spec, unsigned int *dir_si
         if (type->type->str)
         {
             type->name_offset = offset | 0x80000000;
-            offset += (strlenW(type->type->str)+1) * sizeof(WCHAR);
+            offset += (type->type->len + 1) * sizeof(WCHAR);
         }
         else type->name_offset = type->type->id;
 
@@ -374,7 +373,7 @@ static struct res_tree *build_resource_tree( DLLSPEC *spec, unsigned int *dir_si
             if (name->name->str)
             {
                 name->name_offset = offset | 0x80000000;
-                offset += (strlenW(name->name->str)+1) * sizeof(WCHAR);
+                offset += (name->name->len + 1) * sizeof(WCHAR);
             }
             else name->name_offset = name->name->id;
             for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
@@ -399,13 +398,13 @@ static void free_resource_tree( struct res_tree *tree )
 }
 
 /* output a Unicode string */
-static void output_string( const WCHAR *name )
+static void output_string( const struct string_id *str )
 {
-    int i, len = strlenW(name);
-    output( "\t.short 0x%04x", len );
-    for (i = 0; i < len; i++) output( ",0x%04x", name[i] );
+    unsigned int i;
+    output( "\t.short 0x%04x", str->len );
+    for (i = 0; i < str->len; i++) output( ",0x%04x", str->str[i] );
     output( " /* " );
-    for (i = 0; i < len; i++) output( "%c", isprint((char)name[i]) ? (char)name[i] : '?' );
+    for (i = 0; i < str->len; i++) output( "%c", isprint((char)str->str[i]) ? (char)str->str[i] : '?' );
     output( " */\n" );
 }
 
@@ -480,9 +479,9 @@ void output_resources( DLLSPEC *spec )
 
     for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
     {
-        if (type->type->str) output_string( type->type->str );
+        if (type->type->str) output_string( type->type );
         for (n = 0, name = type->names; n < type->nb_names; n++, name++)
-            if (name->name->str) output_string( name->name->str );
+            if (name->name->str) output_string( name->name );
     }
 
     /* resource data */
@@ -503,11 +502,12 @@ void output_resources( DLLSPEC *spec )
 }
 
 /* output a Unicode string in binary format */
-static void output_bin_string( const WCHAR *name )
+static void output_bin_string( const struct string_id *str )
 {
-    int i, len = strlenW(name);
-    put_word( len );
-    for (i = 0; i < len; i++) put_word( name[i] );
+    unsigned int i;
+
+    put_word( str->len );
+    for (i = 0; i < str->len; i++) put_word( str->str[i] );
 }
 
 /* output a resource directory in binary format */
@@ -588,9 +588,9 @@ void output_bin_resources( DLLSPEC *spec, unsigned int start_rva )
 
     for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
     {
-        if (type->type->str) output_bin_string( type->type->str );
+        if (type->type->str) output_bin_string( type->type );
         for (n = 0, name = type->names; n < type->nb_names; n++, name++)
-            if (name->name->str) output_bin_string( name->name->str );
+            if (name->name->str) output_bin_string( name->name );
     }
 
     /* resource data */
@@ -610,10 +610,10 @@ static unsigned int get_resource_header_size( const struct resource *res )
     unsigned int size  = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short);
 
     if (!res->type.str) size += 2 * sizeof(unsigned short);
-    else size += (strlenW(res->type.str) + 1) * sizeof(WCHAR);
+    else size += (res->type.len + 1) * sizeof(WCHAR);
 
     if (!res->name.str) size += 2 * sizeof(unsigned short);
-    else size += (strlenW(res->name.str) + 1) * sizeof(WCHAR);
+    else size += (res->name.len + 1) * sizeof(WCHAR);
 
     return size;
 }




More information about the wine-cvs mailing list