Merge from 3_0: Build a lookup table of valid DOS characters just
authorMartin Pool <mbp@samba.org>
Tue, 8 Apr 2003 03:01:02 +0000 (03:01 +0000)
committerMartin Pool <mbp@samba.org>
Tue, 8 Apr 2003 03:01:02 +0000 (03:01 +0000)
once, when init_iconv is first called.  Use this in check_dos_char
rather than doing the conversion every time.  Much faster.

source/lib/charcnv.c
source/lib/util_unistr.c

index f025e937186f00e204a8ae7a2e03927a16ae43ae..d727628e415e460aedd9076265961046003f0cbd 100644 (file)
@@ -59,7 +59,7 @@ static const char *charset_name(charset_t ch)
        return ret;
 }
 
-static void lazy_initialize_conv(void)
+void lazy_initialize_conv(void)
 {
        static int initialized = False;
 
@@ -67,14 +67,16 @@ static void lazy_initialize_conv(void)
                initialized = True;
                load_case_tables();
                init_iconv();
-               init_valid_table();
        }
 }
 
 /**
- Initialize iconv conversion descriptors.
-**/
-
+ * Initialize iconv conversion descriptors.
+ *
+ * This is called the first time it is needed, and also called again
+ * every time the configuration is reloaded, because the charset or
+ * codepage might have changed.
+ **/
 void init_iconv(void)
 {
        int c1, c2;
@@ -112,6 +114,10 @@ void init_iconv(void)
        }
 
        if (did_reload) {
+               /* XXX: Does this really get called every time the dos
+                * codepage changes? */
+               /* XXX: Is the did_reload test too strict? */
+               init_doschar_table();
                init_valid_table();
        }
 }
index c666155f9fdfe85e0f5b3f6797cd240957661db5..812859000a9f73eeb98212b57c39e0b507e90c16 100644 (file)
@@ -31,6 +31,14 @@ static smb_ucs2_t *upcase_table;
 static smb_ucs2_t *lowcase_table;
 static uint8 *valid_table;
 
+/**
+ * This table says which Unicode characters are valid dos
+ * characters.
+ *
+ * Each value is just a single bit.
+ **/
+static uint8 doschar_table[8192]; /* 65536 characters / 8 bits/byte */
+
 
 /*******************************************************************
 load the case handling tables
@@ -84,6 +92,21 @@ void load_case_tables(void)
   and mapped back to the same character in ucs2
 */
 static int check_dos_char(smb_ucs2_t c)
+{
+       static int initialized = False;
+
+       if (!initialized) {
+               initialized = True;
+               init_doschar_table();
+       }
+       
+       /* Find the right byte, and right bit within the byte; return
+        * 1 or 0 */
+       return (doschar_table[(c & 0xffff) / 8] & (1 << (c & 7))) != 0;
+}
+
+
+static int check_dos_char_slowly(smb_ucs2_t c)
 {
        char buf[10];
        smb_ucs2_t c2 = 0;
@@ -95,6 +118,31 @@ static int check_dos_char(smb_ucs2_t c)
        return (c == c2);
 }
 
+
+/**
+ * Fill out doschar table the hard way, by examining each character
+ **/
+void init_doschar_table(void)
+{
+       int i, j, byteval;
+
+       /* For each byte of packed table */
+       
+       for (i = 0; i <= 0xffff; i += 8) {
+               byteval = 0;
+               for (j = 0; j <= 7; j++) {
+                       smb_ucs2_t c;
+
+                       c = i + j;
+                       
+                       if (check_dos_char_slowly(c))
+                               byteval |= 1 << j;
+               }
+               doschar_table[i/8] = byteval;
+       }
+}
+
+
 /**
  * Load the valid character map table from <tt>valid.dat</tt> or
  * create from the configured codepage.