summaryrefslogtreecommitdiff
path: root/source3/lib/util_unistr.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/util_unistr.c')
-rw-r--r--source3/lib/util_unistr.c139
1 files changed, 70 insertions, 69 deletions
diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c
index 1054eab6e1..a0e1b88eb8 100644
--- a/source3/lib/util_unistr.c
+++ b/source3/lib/util_unistr.c
@@ -25,6 +25,53 @@
#define MAXUNI 1024
#endif
+/* these 3 tables define the unicode case handling. They are loaded
+ at startup either via mmap() or read() from the lib directory */
+static smb_ucs2_t *upcase_table;
+static smb_ucs2_t *lowcase_table;
+static uint8 *valid_table;
+
+/*******************************************************************
+load the case handling tables
+********************************************************************/
+void load_case_tables(void)
+{
+ static int initialised;
+ int i;
+
+ if (initialised) return;
+ initialised = 1;
+
+ upcase_table = map_file(lib_path("upcase.dat"), 0x20000);
+ lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000);
+ valid_table = map_file(lib_path("valid.dat"), 0x10000);
+
+ /* we would like Samba to limp along even if these tables are
+ not available */
+ if (!upcase_table) {
+ DEBUG(1,("creating lame upcase table\n"));
+ upcase_table = malloc(0x20000);
+ for (i=0;i<256;i++) upcase_table[i] = islower(i)?toupper(i):i;
+ for (;i<0x10000;i++) upcase_table[i] = i;
+ }
+
+ if (!lowcase_table) {
+ DEBUG(1,("creating lame lowcase table\n"));
+ lowcase_table = malloc(0x20000);
+ for (i=0;i<256;i++) lowcase_table[i] = isupper(i)?tolower(i):i;
+ for (;i<0x10000;i++) lowcase_table[i] = i;
+ }
+
+ if (!valid_table) {
+ DEBUG(1,("creating lame valid table\n"));
+ valid_table = malloc(0x10000);
+ for (i=0;i<256;i++) valid_table[i] =
+ isalnum(i) && !strchr("*\\/?<>|\":", i);
+ for (;i<0x10000;i++) valid_table[i] = 0;
+ }
+}
+
+
/*******************************************************************
Write a string in (little-endian) unicode format. src is in
the current DOS codepage. len is the length in bytes of the
@@ -129,94 +176,46 @@ uint32 buffer2_to_uint32(BUFFER2 *str)
}
/*******************************************************************
- Mapping tables for UNICODE character. Allows toupper/tolower and
- isXXX functions to work.
-
- tridge: split into 2 pieces. This saves us 5/6 of the memory
- with a small speed penalty
- The magic constants are the lower/upper range of the tables two
- parts
+ Convert a wchar to upper case.
********************************************************************/
-typedef struct {
- smb_ucs2_t lower;
- smb_ucs2_t upper;
- unsigned char flags;
-} smb_unicode_table_t;
-
-#define TABLE1_BOUNDARY 9450
-#define TABLE2_BOUNDARY 64256
-
-static smb_unicode_table_t map_table1[] = {
-#include "unicode_map_table1.h"
-};
-
-static smb_unicode_table_t map_table2[] = {
-#include "unicode_map_table2.h"
-};
-
-static unsigned char map_table_flags(smb_ucs2_t v)
-{
- v = SVAL(&v,0);
- if (v < TABLE1_BOUNDARY) return map_table1[v].flags;
- if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].flags;
- return 0;
-}
-
-static smb_ucs2_t map_table_lower(smb_ucs2_t v)
-{
- v = SVAL(&v,0);
- if (v < TABLE1_BOUNDARY) return map_table1[v].lower;
- if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].lower;
- return v;
-}
-
-static smb_ucs2_t map_table_upper(smb_ucs2_t v)
+smb_ucs2_t toupper_w(smb_ucs2_t val)
{
- v = SVAL(&v,0);
- if (v < TABLE1_BOUNDARY) return map_table1[v].upper;
- if (v >= TABLE2_BOUNDARY) return map_table2[v - TABLE2_BOUNDARY].upper;
- return v;
+ return upcase_table[val];
}
/*******************************************************************
- Is an upper case wchar.
+ Convert a wchar to lower case.
********************************************************************/
-int isupper_w( smb_ucs2_t val)
+smb_ucs2_t tolower_w( smb_ucs2_t val )
{
- return (map_table_flags(val) & UNI_UPPER);
+ return lowcase_table[val];
}
/*******************************************************************
- Is a lower case wchar.
+determine if a character is lowercase
********************************************************************/
-
-int islower_w( smb_ucs2_t val)
+BOOL islower_w(smb_ucs2_t c)
{
- return (map_table_flags(val) & UNI_LOWER);
+ return upcase_table[c] != c;
}
/*******************************************************************
- Convert a wchar to upper case.
+determine if a character is uppercase
********************************************************************/
-
-smb_ucs2_t toupper_w( smb_ucs2_t val )
+BOOL isupper_w(smb_ucs2_t c)
{
- val = map_table_upper(val);
- val = SVAL(&val,0);
- return val;
+ return lowcase_table[c] != c;
}
+
/*******************************************************************
- Convert a wchar to lower case.
+determine if a character is valid in a 8.3 name
********************************************************************/
-
-smb_ucs2_t tolower_w( smb_ucs2_t val )
+BOOL isvalid83_w(smb_ucs2_t c)
{
- val = map_table_lower(val);
- val = SVAL(&val,0);
- return val;
+ return valid_table[c] != 0;
}
/*******************************************************************
@@ -252,8 +251,9 @@ BOOL strlower_w(smb_ucs2_t *s)
{
BOOL ret = False;
while (*s) {
- if (isupper_w(*s)) {
- *s = tolower_w(*s);
+ smb_ucs2_t v = tolower_w(*s);
+ if (v != *s) {
+ *s = v;
ret = True;
}
s++;
@@ -269,8 +269,9 @@ BOOL strupper_w(smb_ucs2_t *s)
{
BOOL ret = False;
while (*s) {
- if (islower_w(*s)) {
- *s = toupper_w(*s);
+ smb_ucs2_t v = toupper_w(*s);
+ if (v != *s) {
+ *s = v;
ret = True;
}
s++;
@@ -283,7 +284,7 @@ case insensitive string comparison
********************************************************************/
int strcasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b)
{
- while (*b && tolower_w(*a) == tolower_w(*b)) { a++; b++; }
+ while (*b && toupper_w(*a) == toupper_w(*b)) { a++; b++; }
return (tolower_w(*a) - tolower_w(*b));
}