1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * Wine internal Unicode definitions
3*c2c66affSColin Finck *
4*c2c66affSColin Finck * Copyright 2000 Alexandre Julliard
5*c2c66affSColin Finck *
6*c2c66affSColin Finck * This library is free software; you can redistribute it and/or
7*c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
8*c2c66affSColin Finck * License as published by the Free Software Foundation; either
9*c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
10*c2c66affSColin Finck *
11*c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
12*c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14*c2c66affSColin Finck * Lesser General Public License for more details.
15*c2c66affSColin Finck *
16*c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
17*c2c66affSColin Finck * License along with this library; if not, write to the Free Software
18*c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19*c2c66affSColin Finck */
20*c2c66affSColin Finck
21*c2c66affSColin Finck #ifndef __WINE_WINE_UNICODE_H
22*c2c66affSColin Finck #define __WINE_WINE_UNICODE_H
23*c2c66affSColin Finck
24*c2c66affSColin Finck #include <ctype.h>
25*c2c66affSColin Finck #include <stdarg.h>
26*c2c66affSColin Finck #include <string.h>
27*c2c66affSColin Finck #include <typedefs.h>
28*c2c66affSColin Finck
29*c2c66affSColin Finck // Definitions copied from <winnls.h>
30*c2c66affSColin Finck // We only want to include host headers, so we define them manually
31*c2c66affSColin Finck #define C1_UPPER 1
32*c2c66affSColin Finck #define C1_LOWER 2
33*c2c66affSColin Finck #define C1_DIGIT 4
34*c2c66affSColin Finck #define C1_SPACE 8
35*c2c66affSColin Finck #define C1_PUNCT 16
36*c2c66affSColin Finck #define C1_CNTRL 32
37*c2c66affSColin Finck #define C1_BLANK 64
38*c2c66affSColin Finck #define C1_XDIGIT 128
39*c2c66affSColin Finck #define C1_ALPHA 256
40*c2c66affSColin Finck #define MB_COMPOSITE 2
41*c2c66affSColin Finck #define MB_ERR_INVALID_CHARS 8
42*c2c66affSColin Finck #define MB_USEGLYPHCHARS 0x04
43*c2c66affSColin Finck #define WC_COMPOSITECHECK 512
44*c2c66affSColin Finck #define WC_DISCARDNS 16
45*c2c66affSColin Finck #define WC_DEFAULTCHAR 64
46*c2c66affSColin Finck #define WC_NO_BEST_FIT_CHARS 1024
47*c2c66affSColin Finck #define WC_ERR_INVALID_CHARS 0x0080
48*c2c66affSColin Finck
49*c2c66affSColin Finck #ifdef __WINE_WINE_TEST_H
50*c2c66affSColin Finck #error This file should not be used in Wine tests
51*c2c66affSColin Finck #endif
52*c2c66affSColin Finck
53*c2c66affSColin Finck #ifdef __cplusplus
54*c2c66affSColin Finck extern "C" {
55*c2c66affSColin Finck #endif
56*c2c66affSColin Finck
57*c2c66affSColin Finck #ifndef WINE_UNICODE_API
58*c2c66affSColin Finck #define WINE_UNICODE_API
59*c2c66affSColin Finck #endif
60*c2c66affSColin Finck
61*c2c66affSColin Finck #ifndef WINE_UNICODE_INLINE
62*c2c66affSColin Finck #define WINE_UNICODE_INLINE static inline
63*c2c66affSColin Finck #endif
64*c2c66affSColin Finck
65*c2c66affSColin Finck /* code page info common to SBCS and DBCS */
66*c2c66affSColin Finck struct cp_info
67*c2c66affSColin Finck {
68*c2c66affSColin Finck unsigned int codepage; /* codepage id */
69*c2c66affSColin Finck unsigned int char_size; /* char size (1 or 2 bytes) */
70*c2c66affSColin Finck WCHAR def_char; /* default char value (can be double-byte) */
71*c2c66affSColin Finck WCHAR def_unicode_char; /* default Unicode char value */
72*c2c66affSColin Finck const char *name; /* code page name */
73*c2c66affSColin Finck };
74*c2c66affSColin Finck
75*c2c66affSColin Finck struct sbcs_table
76*c2c66affSColin Finck {
77*c2c66affSColin Finck struct cp_info info;
78*c2c66affSColin Finck const WCHAR *cp2uni; /* code page -> Unicode map */
79*c2c66affSColin Finck const WCHAR *cp2uni_glyphs; /* code page -> Unicode map with glyph chars */
80*c2c66affSColin Finck const unsigned char *uni2cp_low; /* Unicode -> code page map */
81*c2c66affSColin Finck const unsigned short *uni2cp_high;
82*c2c66affSColin Finck };
83*c2c66affSColin Finck
84*c2c66affSColin Finck struct dbcs_table
85*c2c66affSColin Finck {
86*c2c66affSColin Finck struct cp_info info;
87*c2c66affSColin Finck const WCHAR *cp2uni; /* code page -> Unicode map */
88*c2c66affSColin Finck const unsigned char *cp2uni_leadbytes;
89*c2c66affSColin Finck const unsigned short *uni2cp_low; /* Unicode -> code page map */
90*c2c66affSColin Finck const unsigned short *uni2cp_high;
91*c2c66affSColin Finck unsigned char lead_bytes[12]; /* lead bytes ranges */
92*c2c66affSColin Finck };
93*c2c66affSColin Finck
94*c2c66affSColin Finck union cptable
95*c2c66affSColin Finck {
96*c2c66affSColin Finck struct cp_info info;
97*c2c66affSColin Finck struct sbcs_table sbcs;
98*c2c66affSColin Finck struct dbcs_table dbcs;
99*c2c66affSColin Finck };
100*c2c66affSColin Finck
101*c2c66affSColin Finck extern const union cptable *wine_cp_get_table( unsigned int codepage );
102*c2c66affSColin Finck extern const union cptable *wine_cp_enum_table( unsigned int index );
103*c2c66affSColin Finck
104*c2c66affSColin Finck extern int wine_cp_mbstowcs( const union cptable *table, int flags,
105*c2c66affSColin Finck const char *src, int srclen,
106*c2c66affSColin Finck WCHAR *dst, int dstlen );
107*c2c66affSColin Finck extern int wine_cp_wcstombs( const union cptable *table, int flags,
108*c2c66affSColin Finck const WCHAR *src, int srclen,
109*c2c66affSColin Finck char *dst, int dstlen, const char *defchar, int *used );
110*c2c66affSColin Finck extern int wine_cpsymbol_mbstowcs( const char *src, int srclen, WCHAR *dst, int dstlen );
111*c2c66affSColin Finck extern int wine_cpsymbol_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen );
112*c2c66affSColin Finck extern int wine_utf8_mbstowcs( int flags, const char *src, int srclen, WCHAR *dst, int dstlen );
113*c2c66affSColin Finck extern int wine_utf8_wcstombs( int flags, const WCHAR *src, int srclen, char *dst, int dstlen );
114*c2c66affSColin Finck
115*c2c66affSColin Finck extern int wine_compare_string( int flags, const WCHAR *str1, int len1, const WCHAR *str2, int len2 );
116*c2c66affSColin Finck extern int wine_get_sortkey( int flags, const WCHAR *src, int srclen, char *dst, int dstlen );
117*c2c66affSColin Finck extern int wine_fold_string( int flags, const WCHAR *src, int srclen , WCHAR *dst, int dstlen );
118*c2c66affSColin Finck
119*c2c66affSColin Finck extern int strcmpiW( const WCHAR *str1, const WCHAR *str2 );
120*c2c66affSColin Finck extern int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n );
121*c2c66affSColin Finck extern int memicmpW( const WCHAR *str1, const WCHAR *str2, int n );
122*c2c66affSColin Finck extern WCHAR *strstrW( const WCHAR *str, const WCHAR *sub );
123*c2c66affSColin Finck extern long int strtolW( const WCHAR *nptr, WCHAR **endptr, int base );
124*c2c66affSColin Finck extern unsigned long int strtoulW( const WCHAR *nptr, WCHAR **endptr, int base );
125*c2c66affSColin Finck extern int sprintfW( WCHAR *str, const WCHAR *format, ... );
126*c2c66affSColin Finck extern int snprintfW( WCHAR *str, size_t len, const WCHAR *format, ... );
127*c2c66affSColin Finck extern int vsprintfW( WCHAR *str, const WCHAR *format, va_list valist );
128*c2c66affSColin Finck extern int vsnprintfW( WCHAR *str, size_t len, const WCHAR *format, va_list valist );
129*c2c66affSColin Finck
wine_is_dbcs_leadbyte(const union cptable * table,unsigned char ch)130*c2c66affSColin Finck WINE_UNICODE_INLINE int wine_is_dbcs_leadbyte( const union cptable *table, unsigned char ch )
131*c2c66affSColin Finck {
132*c2c66affSColin Finck return (table->info.char_size == 2) && (table->dbcs.cp2uni_leadbytes[ch]);
133*c2c66affSColin Finck }
134*c2c66affSColin Finck
tolowerW(WCHAR ch)135*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR tolowerW( WCHAR ch )
136*c2c66affSColin Finck {
137*c2c66affSColin Finck extern WINE_UNICODE_API const WCHAR wine_casemap_lower[];
138*c2c66affSColin Finck return ch + wine_casemap_lower[wine_casemap_lower[ch >> 8] + (ch & 0xff)];
139*c2c66affSColin Finck }
140*c2c66affSColin Finck
toupperW(WCHAR ch)141*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR toupperW( WCHAR ch )
142*c2c66affSColin Finck {
143*c2c66affSColin Finck extern WINE_UNICODE_API const WCHAR wine_casemap_upper[];
144*c2c66affSColin Finck return ch + wine_casemap_upper[wine_casemap_upper[ch >> 8] + (ch & 0xff)];
145*c2c66affSColin Finck }
146*c2c66affSColin Finck
147*c2c66affSColin Finck /* the character type contains the C1_* flags in the low 12 bits */
148*c2c66affSColin Finck /* and the C2_* type in the high 4 bits */
get_char_typeW(WCHAR ch)149*c2c66affSColin Finck WINE_UNICODE_INLINE unsigned short get_char_typeW( WCHAR ch )
150*c2c66affSColin Finck {
151*c2c66affSColin Finck extern WINE_UNICODE_API const unsigned short wine_wctype_table[];
152*c2c66affSColin Finck return wine_wctype_table[wine_wctype_table[ch >> 8] + (ch & 0xff)];
153*c2c66affSColin Finck }
154*c2c66affSColin Finck
iscntrlW(WCHAR wc)155*c2c66affSColin Finck WINE_UNICODE_INLINE int iscntrlW( WCHAR wc )
156*c2c66affSColin Finck {
157*c2c66affSColin Finck return get_char_typeW(wc) & C1_CNTRL;
158*c2c66affSColin Finck }
159*c2c66affSColin Finck
ispunctW(WCHAR wc)160*c2c66affSColin Finck WINE_UNICODE_INLINE int ispunctW( WCHAR wc )
161*c2c66affSColin Finck {
162*c2c66affSColin Finck return get_char_typeW(wc) & C1_PUNCT;
163*c2c66affSColin Finck }
164*c2c66affSColin Finck
isspaceW(WCHAR wc)165*c2c66affSColin Finck WINE_UNICODE_INLINE int isspaceW( WCHAR wc )
166*c2c66affSColin Finck {
167*c2c66affSColin Finck return get_char_typeW(wc) & C1_SPACE;
168*c2c66affSColin Finck }
169*c2c66affSColin Finck
isdigitW(WCHAR wc)170*c2c66affSColin Finck WINE_UNICODE_INLINE int isdigitW( WCHAR wc )
171*c2c66affSColin Finck {
172*c2c66affSColin Finck return get_char_typeW(wc) & C1_DIGIT;
173*c2c66affSColin Finck }
174*c2c66affSColin Finck
isxdigitW(WCHAR wc)175*c2c66affSColin Finck WINE_UNICODE_INLINE int isxdigitW( WCHAR wc )
176*c2c66affSColin Finck {
177*c2c66affSColin Finck return get_char_typeW(wc) & C1_XDIGIT;
178*c2c66affSColin Finck }
179*c2c66affSColin Finck
islowerW(WCHAR wc)180*c2c66affSColin Finck WINE_UNICODE_INLINE int islowerW( WCHAR wc )
181*c2c66affSColin Finck {
182*c2c66affSColin Finck return get_char_typeW(wc) & C1_LOWER;
183*c2c66affSColin Finck }
184*c2c66affSColin Finck
isupperW(WCHAR wc)185*c2c66affSColin Finck WINE_UNICODE_INLINE int isupperW( WCHAR wc )
186*c2c66affSColin Finck {
187*c2c66affSColin Finck return get_char_typeW(wc) & C1_UPPER;
188*c2c66affSColin Finck }
189*c2c66affSColin Finck
isalnumW(WCHAR wc)190*c2c66affSColin Finck WINE_UNICODE_INLINE int isalnumW( WCHAR wc )
191*c2c66affSColin Finck {
192*c2c66affSColin Finck return get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT|C1_LOWER|C1_UPPER);
193*c2c66affSColin Finck }
194*c2c66affSColin Finck
isalphaW(WCHAR wc)195*c2c66affSColin Finck WINE_UNICODE_INLINE int isalphaW( WCHAR wc )
196*c2c66affSColin Finck {
197*c2c66affSColin Finck return get_char_typeW(wc) & (C1_ALPHA|C1_LOWER|C1_UPPER);
198*c2c66affSColin Finck }
199*c2c66affSColin Finck
isgraphW(WCHAR wc)200*c2c66affSColin Finck WINE_UNICODE_INLINE int isgraphW( WCHAR wc )
201*c2c66affSColin Finck {
202*c2c66affSColin Finck return get_char_typeW(wc) & (C1_ALPHA|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER);
203*c2c66affSColin Finck }
204*c2c66affSColin Finck
isprintW(WCHAR wc)205*c2c66affSColin Finck WINE_UNICODE_INLINE int isprintW( WCHAR wc )
206*c2c66affSColin Finck {
207*c2c66affSColin Finck return get_char_typeW(wc) & (C1_ALPHA|C1_BLANK|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER);
208*c2c66affSColin Finck }
209*c2c66affSColin Finck
210*c2c66affSColin Finck /* some useful string manipulation routines */
211*c2c66affSColin Finck
strlenW(const WCHAR * str)212*c2c66affSColin Finck WINE_UNICODE_INLINE unsigned int strlenW( const WCHAR *str )
213*c2c66affSColin Finck {
214*c2c66affSColin Finck const WCHAR *s = str;
215*c2c66affSColin Finck while (*s) s++;
216*c2c66affSColin Finck return (unsigned int)(s - str);
217*c2c66affSColin Finck }
218*c2c66affSColin Finck
strcpyW(WCHAR * dst,const WCHAR * src)219*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR *strcpyW( WCHAR *dst, const WCHAR *src )
220*c2c66affSColin Finck {
221*c2c66affSColin Finck WCHAR *p = dst;
222*c2c66affSColin Finck while ((*p++ = *src++));
223*c2c66affSColin Finck return dst;
224*c2c66affSColin Finck }
225*c2c66affSColin Finck
226*c2c66affSColin Finck /* strncpy doesn't do what you think, don't use it */
227*c2c66affSColin Finck #define strncpyW(d,s,n) error do_not_use_strncpyW_use_lstrcpynW_or_memcpy_instead
228*c2c66affSColin Finck
strcmpW(const WCHAR * str1,const WCHAR * str2)229*c2c66affSColin Finck WINE_UNICODE_INLINE int strcmpW( const WCHAR *str1, const WCHAR *str2 )
230*c2c66affSColin Finck {
231*c2c66affSColin Finck while (*str1 && (*str1 == *str2)) { str1++; str2++; }
232*c2c66affSColin Finck return *str1 - *str2;
233*c2c66affSColin Finck }
234*c2c66affSColin Finck
strncmpW(const WCHAR * str1,const WCHAR * str2,int n)235*c2c66affSColin Finck WINE_UNICODE_INLINE int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
236*c2c66affSColin Finck {
237*c2c66affSColin Finck if (n <= 0) return 0;
238*c2c66affSColin Finck while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
239*c2c66affSColin Finck return *str1 - *str2;
240*c2c66affSColin Finck }
241*c2c66affSColin Finck
strcatW(WCHAR * dst,const WCHAR * src)242*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR *strcatW( WCHAR *dst, const WCHAR *src )
243*c2c66affSColin Finck {
244*c2c66affSColin Finck strcpyW( dst + strlenW(dst), src );
245*c2c66affSColin Finck return dst;
246*c2c66affSColin Finck }
247*c2c66affSColin Finck
strchrW(const WCHAR * str,WCHAR ch)248*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR *strchrW( const WCHAR *str, WCHAR ch )
249*c2c66affSColin Finck {
250*c2c66affSColin Finck do { if (*str == ch) return (WCHAR *)(ULONG_PTR)str; } while (*str++);
251*c2c66affSColin Finck return NULL;
252*c2c66affSColin Finck }
253*c2c66affSColin Finck
strrchrW(const WCHAR * str,WCHAR ch)254*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR *strrchrW( const WCHAR *str, WCHAR ch )
255*c2c66affSColin Finck {
256*c2c66affSColin Finck WCHAR *ret = NULL;
257*c2c66affSColin Finck do { if (*str == ch) ret = (WCHAR *)(ULONG_PTR)str; } while (*str++);
258*c2c66affSColin Finck return ret;
259*c2c66affSColin Finck }
260*c2c66affSColin Finck
strpbrkW(const WCHAR * str,const WCHAR * accept)261*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR *strpbrkW( const WCHAR *str, const WCHAR *accept )
262*c2c66affSColin Finck {
263*c2c66affSColin Finck for ( ; *str; str++) if (strchrW( accept, *str )) return (WCHAR *)(ULONG_PTR)str;
264*c2c66affSColin Finck return NULL;
265*c2c66affSColin Finck }
266*c2c66affSColin Finck
strspnW(const WCHAR * str,const WCHAR * accept)267*c2c66affSColin Finck WINE_UNICODE_INLINE size_t strspnW( const WCHAR *str, const WCHAR *accept )
268*c2c66affSColin Finck {
269*c2c66affSColin Finck const WCHAR *ptr;
270*c2c66affSColin Finck for (ptr = str; *ptr; ptr++) if (!strchrW( accept, *ptr )) break;
271*c2c66affSColin Finck return ptr - str;
272*c2c66affSColin Finck }
273*c2c66affSColin Finck
strcspnW(const WCHAR * str,const WCHAR * reject)274*c2c66affSColin Finck WINE_UNICODE_INLINE size_t strcspnW( const WCHAR *str, const WCHAR *reject )
275*c2c66affSColin Finck {
276*c2c66affSColin Finck const WCHAR *ptr;
277*c2c66affSColin Finck for (ptr = str; *ptr; ptr++) if (strchrW( reject, *ptr )) break;
278*c2c66affSColin Finck return ptr - str;
279*c2c66affSColin Finck }
280*c2c66affSColin Finck
strlwrW(WCHAR * str)281*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR *strlwrW( WCHAR *str )
282*c2c66affSColin Finck {
283*c2c66affSColin Finck WCHAR *ret = str;
284*c2c66affSColin Finck while ((*str = tolowerW(*str))) str++;
285*c2c66affSColin Finck return ret;
286*c2c66affSColin Finck }
287*c2c66affSColin Finck
struprW(WCHAR * str)288*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR *struprW( WCHAR *str )
289*c2c66affSColin Finck {
290*c2c66affSColin Finck WCHAR *ret = str;
291*c2c66affSColin Finck while ((*str = toupperW(*str))) str++;
292*c2c66affSColin Finck return ret;
293*c2c66affSColin Finck }
294*c2c66affSColin Finck
memchrW(const WCHAR * ptr,WCHAR ch,size_t n)295*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR *memchrW( const WCHAR *ptr, WCHAR ch, size_t n )
296*c2c66affSColin Finck {
297*c2c66affSColin Finck const WCHAR *end;
298*c2c66affSColin Finck for (end = ptr + n; ptr < end; ptr++) if (*ptr == ch) return (WCHAR *)(ULONG_PTR)ptr;
299*c2c66affSColin Finck return NULL;
300*c2c66affSColin Finck }
301*c2c66affSColin Finck
memrchrW(const WCHAR * ptr,WCHAR ch,size_t n)302*c2c66affSColin Finck WINE_UNICODE_INLINE WCHAR *memrchrW( const WCHAR *ptr, WCHAR ch, size_t n )
303*c2c66affSColin Finck {
304*c2c66affSColin Finck const WCHAR *end;
305*c2c66affSColin Finck WCHAR *ret = NULL;
306*c2c66affSColin Finck for (end = ptr + n; ptr < end; ptr++) if (*ptr == ch) ret = (WCHAR *)(ULONG_PTR)ptr;
307*c2c66affSColin Finck return ret;
308*c2c66affSColin Finck }
309*c2c66affSColin Finck
atolW(const WCHAR * str)310*c2c66affSColin Finck WINE_UNICODE_INLINE long int atolW( const WCHAR *str )
311*c2c66affSColin Finck {
312*c2c66affSColin Finck return strtolW( str, (WCHAR **)0, 10 );
313*c2c66affSColin Finck }
314*c2c66affSColin Finck
atoiW(const WCHAR * str)315*c2c66affSColin Finck WINE_UNICODE_INLINE int atoiW( const WCHAR *str )
316*c2c66affSColin Finck {
317*c2c66affSColin Finck return (int)atolW( str );
318*c2c66affSColin Finck }
319*c2c66affSColin Finck
320*c2c66affSColin Finck #undef WINE_UNICODE_INLINE
321*c2c66affSColin Finck
322*c2c66affSColin Finck #ifdef __cplusplus
323*c2c66affSColin Finck }
324*c2c66affSColin Finck #endif
325*c2c66affSColin Finck
326*c2c66affSColin Finck #endif /* __WINE_WINE_UNICODE_H */
327