Added Unicode ctype support.
[wine] / include / wine / unicode.h
1 /*
2  * Wine internal Unicode definitions
3  *
4  * Copyright 2000 Alexandre Julliard
5  */
6
7 #ifndef __WINE_UNICODE_H
8 #define __WINE_UNICODE_H
9
10 #include "windef.h"
11
12 /* code page info common to SBCS and DBCS */
13 struct cp_info
14 {
15     unsigned int          codepage;          /* codepage id */
16     unsigned int          char_size;         /* char size (1 or 2 bytes) */
17     WCHAR                 def_char;          /* default char value (can be double-byte) */
18     WCHAR                 def_unicode_char;  /* default Unicode char value */
19     const char           *name;              /* code page name */
20 };
21
22 struct sbcs_table
23 {
24     struct cp_info        info;
25     const WCHAR          *cp2uni;            /* code page -> Unicode map */
26     const unsigned char  *uni2cp_low;        /* Unicode -> code page map */
27     const unsigned short *uni2cp_high;
28 };
29
30 struct dbcs_table
31 {
32     struct cp_info        info;
33     const WCHAR          *cp2uni;            /* code page -> Unicode map */
34     const unsigned char  *cp2uni_leadbytes;
35     const unsigned short *uni2cp_low;        /* Unicode -> code page map */
36     const unsigned short *uni2cp_high;
37     unsigned char         lead_bytes[12];    /* lead bytes ranges */
38 };
39
40 union cptable
41 {
42     struct cp_info    info;
43     struct sbcs_table sbcs;
44     struct dbcs_table dbcs;
45 };
46
47 extern const union cptable *cp_get_table( unsigned int codepage );
48 extern const union cptable *cp_enum_table( unsigned int index );
49
50 extern int cp_mbstowcs( const union cptable *table, int flags,
51                         const char *src, int srclen,
52                         WCHAR *dst, int dstlen );
53 extern int cp_wcstombs( const union cptable *table, int flags,
54                         const WCHAR *src, int srclen,
55                         char *dst, int dstlen, const char *defchar, int *used );
56 extern int utf8_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen );
57 extern int utf8_mbstowcs( int flags, const char *src, int srclen, WCHAR *dst, int dstlen );
58
59 static inline int is_dbcs_leadbyte( const union cptable *table, unsigned char ch )
60 {
61     return (table->info.char_size == 2) && (table->dbcs.cp2uni_leadbytes[ch]);
62 }
63
64 static inline WCHAR tolowerW( WCHAR ch )
65 {
66     extern WCHAR casemap_lower[];
67     return ch + casemap_lower[casemap_lower[ch >> 8] + (ch & 0xff)];
68 }
69
70 static inline WCHAR toupperW( WCHAR ch )
71 {
72     extern WCHAR casemap_upper[];
73     return ch + casemap_upper[casemap_upper[ch >> 8] + (ch & 0xff)];
74 }
75
76 /* the character type contains the C1_* flags in the low 12 bits */
77 /* and the C2_* type in the high 4 bits */
78 static inline unsigned short get_char_typeW( WCHAR ch )
79 {
80     extern unsigned short wctype_table[];
81     return wctype_table[wctype_table[ch >> 8] + (ch & 0xff)];
82 }
83
84 /* some useful string manipulation routines */
85
86 static inline unsigned int strlenW( const WCHAR *str )
87 {
88 #if defined(__i386__) && defined(__GNUC__)
89     int dummy, res;
90     __asm__( "cld\n\t"
91              "repne\n\t"
92              "scasw\n\t"
93              "notl %0"
94              : "=c" (res), "=&D" (dummy)
95              : "0" (0xffffffff), "1" (str), "a" (0) );
96     return res - 1;
97 #else
98     const WCHAR *s = str;
99     while (*s) s++;
100     return s - str;
101 #endif
102 }
103
104 static inline WCHAR *strcpyW( WCHAR *dst, const WCHAR *src ) 
105 {
106 #if defined(__i386__) && defined(__GNUC__)
107     int dummy1, dummy2, dummy3;
108     __asm__ __volatile__( "cld\n"
109                           "1:\tlodsw\n\t"
110                           "stosw\n\t"
111                           "testw %%ax,%%ax\n\t"
112                           "jne 1b"
113                           : "=&S" (dummy1), "=&D" (dummy2), "=&a" (dummy3)
114                           : "0" (src), "1" (dst)
115                           : "memory" );
116 #else
117     WCHAR *p = dst;
118     while ((*p++ = *src++));
119 #endif
120     return dst;
121 }
122
123 static inline int strcmpW( const WCHAR *str1, const WCHAR *str2 ) 
124 {
125     while (*str1 && (*str1 == *str2)) { str1++; str2++; }
126     return *str1 - *str2;
127 }
128
129 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
130 {
131     if (n <= 0) return 0;
132     while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
133     return *str1 - *str2;
134 }
135
136 static inline WCHAR *strcatW( WCHAR *dst, const WCHAR *src )
137 {
138     strcpyW( dst + strlenW(dst), src );
139     return dst;
140 }
141
142 static inline WCHAR *strchrW( const WCHAR *str, WCHAR ch )
143 {
144     for ( ; *str; str++) if (*str == ch) return (WCHAR *)str;
145     return NULL;
146 }
147  
148 static inline WCHAR *strrchrW( const WCHAR *str, WCHAR ch )
149 {
150     WCHAR *ret = NULL;
151     for ( ; *str; str++) if (*str == ch) ret = (WCHAR *)str;
152     return ret;
153 }               
154
155 static inline WCHAR *strlwrW( WCHAR *str )
156 {
157     WCHAR *ret = str;
158     while ((*str = tolowerW(*str))) str++;
159     return ret;
160 }
161
162 static inline WCHAR *struprW( WCHAR *str )
163 {
164     WCHAR *ret = str;
165     while ((*str = toupperW(*str))) str++;
166     return ret;
167 }
168
169 extern int strcmpiW( const WCHAR *str1, const WCHAR *str2 );
170 extern int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n );
171 extern WCHAR *strstrW( const WCHAR *str, const WCHAR *sub );
172
173 #endif  /* __WINE_UNICODE_H */