VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/libWine/mbtowc.c@ 30585

Last change on this file since 30585 was 22496, checked in by vboxsync, 15 years ago

crOpenGL: update wine to 1.1.27 and better fix for depthstencil surface refcounting

  • Property svn:eol-style set to native
File size: 10.6 KB
Line 
1/*
2 * MultiByteToWideChar implementation
3 *
4 * Copyright 2000 Alexandre Julliard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21/*
22 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
23 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
24 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
25 * a choice of LGPL license versions is made available with the language indicating
26 * that LGPLv2 or any later version may be used, or where a choice of which version
27 * of the LGPL is applied is otherwise unspecified.
28 */
29
30#include "config.h"
31#include "wine/port.h"
32
33#include <string.h>
34
35#include "wine/unicode.h"
36
37/* get the decomposition of a Unicode char */
38static int get_decomposition( WCHAR src, WCHAR *dst, unsigned int dstlen )
39{
40 extern const WCHAR unicode_decompose_table[];
41 const WCHAR *ptr = unicode_decompose_table;
42 int res;
43
44 *dst = src;
45 ptr = unicode_decompose_table + ptr[src >> 8];
46 ptr = unicode_decompose_table + ptr[(src >> 4) & 0x0f] + 2 * (src & 0x0f);
47 if (!*ptr) return 1;
48 if (dstlen <= 1) return 0;
49 /* apply the decomposition recursively to the first char */
50 if ((res = get_decomposition( *ptr, dst, dstlen-1 ))) dst[res++] = ptr[1];
51 return res;
52}
53
54/* check src string for invalid chars; return non-zero if invalid char found */
55static inline int check_invalid_chars_sbcs( const struct sbcs_table *table, int flags,
56 const unsigned char *src, unsigned int srclen )
57{
58 const WCHAR * const cp2uni = (flags & MB_USEGLYPHCHARS) ? table->cp2uni_glyphs : table->cp2uni;
59 const WCHAR def_unicode_char = table->info.def_unicode_char;
60 const unsigned char def_char = table->uni2cp_low[table->uni2cp_high[def_unicode_char >> 8]
61 + (def_unicode_char & 0xff)];
62 while (srclen)
63 {
64 if (cp2uni[*src] == def_unicode_char && *src != def_char) break;
65 src++;
66 srclen--;
67 }
68 return srclen;
69}
70
71/* mbstowcs for single-byte code page */
72/* all lengths are in characters, not bytes */
73static inline int mbstowcs_sbcs( const struct sbcs_table *table, int flags,
74 const unsigned char *src, unsigned int srclen,
75 WCHAR *dst, unsigned int dstlen )
76{
77 const WCHAR * const cp2uni = (flags & MB_USEGLYPHCHARS) ? table->cp2uni_glyphs : table->cp2uni;
78 int ret = srclen;
79
80 if (dstlen < srclen)
81 {
82 /* buffer too small: fill it up to dstlen and return error */
83 srclen = dstlen;
84 ret = -1;
85 }
86
87 for (;;)
88 {
89 switch(srclen)
90 {
91 default:
92 case 16: dst[15] = cp2uni[src[15]];
93 case 15: dst[14] = cp2uni[src[14]];
94 case 14: dst[13] = cp2uni[src[13]];
95 case 13: dst[12] = cp2uni[src[12]];
96 case 12: dst[11] = cp2uni[src[11]];
97 case 11: dst[10] = cp2uni[src[10]];
98 case 10: dst[9] = cp2uni[src[9]];
99 case 9: dst[8] = cp2uni[src[8]];
100 case 8: dst[7] = cp2uni[src[7]];
101 case 7: dst[6] = cp2uni[src[6]];
102 case 6: dst[5] = cp2uni[src[5]];
103 case 5: dst[4] = cp2uni[src[4]];
104 case 4: dst[3] = cp2uni[src[3]];
105 case 3: dst[2] = cp2uni[src[2]];
106 case 2: dst[1] = cp2uni[src[1]];
107 case 1: dst[0] = cp2uni[src[0]];
108 case 0: break;
109 }
110 if (srclen < 16) return ret;
111 dst += 16;
112 src += 16;
113 srclen -= 16;
114 }
115}
116
117/* mbstowcs for single-byte code page with char decomposition */
118static int mbstowcs_sbcs_decompose( const struct sbcs_table *table, int flags,
119 const unsigned char *src, unsigned int srclen,
120 WCHAR *dst, unsigned int dstlen )
121{
122 const WCHAR * const cp2uni = (flags & MB_USEGLYPHCHARS) ? table->cp2uni_glyphs : table->cp2uni;
123 unsigned int len;
124
125 if (!dstlen) /* compute length */
126 {
127 WCHAR dummy[4]; /* no decomposition is larger than 4 chars */
128 for (len = 0; srclen; srclen--, src++)
129 len += get_decomposition( cp2uni[*src], dummy, 4 );
130 return len;
131 }
132
133 for (len = dstlen; srclen && len; srclen--, src++)
134 {
135 int res = get_decomposition( cp2uni[*src], dst, len );
136 if (!res) break;
137 len -= res;
138 dst += res;
139 }
140 if (srclen) return -1; /* overflow */
141 return dstlen - len;
142}
143
144/* query necessary dst length for src string */
145static inline int get_length_dbcs( const struct dbcs_table *table,
146 const unsigned char *src, unsigned int srclen )
147{
148 const unsigned char * const cp2uni_lb = table->cp2uni_leadbytes;
149 int len;
150
151 for (len = 0; srclen; srclen--, src++, len++)
152 {
153 if (cp2uni_lb[*src])
154 {
155 if (!--srclen) break; /* partial char, ignore it */
156 src++;
157 }
158 }
159 return len;
160}
161
162/* check src string for invalid chars; return non-zero if invalid char found */
163static inline int check_invalid_chars_dbcs( const struct dbcs_table *table,
164 const unsigned char *src, unsigned int srclen )
165{
166 const WCHAR * const cp2uni = table->cp2uni;
167 const unsigned char * const cp2uni_lb = table->cp2uni_leadbytes;
168 const WCHAR def_unicode_char = table->info.def_unicode_char;
169 const unsigned short def_char = table->uni2cp_low[table->uni2cp_high[def_unicode_char >> 8]
170 + (def_unicode_char & 0xff)];
171 while (srclen)
172 {
173 unsigned char off = cp2uni_lb[*src];
174 if (off) /* multi-byte char */
175 {
176 if (srclen == 1) break; /* partial char, error */
177 if (cp2uni[(off << 8) + src[1]] == def_unicode_char &&
178 ((src[0] << 8) | src[1]) != def_char) break;
179 src++;
180 srclen--;
181 }
182 else if (cp2uni[*src] == def_unicode_char && *src != def_char) break;
183 src++;
184 srclen--;
185 }
186 return srclen;
187}
188
189/* mbstowcs for double-byte code page */
190/* all lengths are in characters, not bytes */
191static inline int mbstowcs_dbcs( const struct dbcs_table *table,
192 const unsigned char *src, unsigned int srclen,
193 WCHAR *dst, unsigned int dstlen )
194{
195 const WCHAR * const cp2uni = table->cp2uni;
196 const unsigned char * const cp2uni_lb = table->cp2uni_leadbytes;
197 unsigned int len;
198
199 if (!dstlen) return get_length_dbcs( table, src, srclen );
200
201 for (len = dstlen; srclen && len; len--, srclen--, src++, dst++)
202 {
203 unsigned char off = cp2uni_lb[*src];
204 if (off)
205 {
206 if (!--srclen) break; /* partial char, ignore it */
207 src++;
208 *dst = cp2uni[(off << 8) + *src];
209 }
210 else *dst = cp2uni[*src];
211 }
212 if (srclen) return -1; /* overflow */
213 return dstlen - len;
214}
215
216
217/* mbstowcs for double-byte code page with character decomposition */
218static int mbstowcs_dbcs_decompose( const struct dbcs_table *table,
219 const unsigned char *src, unsigned int srclen,
220 WCHAR *dst, unsigned int dstlen )
221{
222 const WCHAR * const cp2uni = table->cp2uni;
223 const unsigned char * const cp2uni_lb = table->cp2uni_leadbytes;
224 unsigned int len;
225 WCHAR ch;
226 int res;
227
228 if (!dstlen) /* compute length */
229 {
230 WCHAR dummy[4]; /* no decomposition is larger than 4 chars */
231 for (len = 0; srclen; srclen--, src++)
232 {
233 unsigned char off = cp2uni_lb[*src];
234 if (off)
235 {
236 if (!--srclen) break; /* partial char, ignore it */
237 src++;
238 ch = cp2uni[(off << 8) + *src];
239 }
240 else ch = cp2uni[*src];
241 len += get_decomposition( ch, dummy, 4 );
242 }
243 return len;
244 }
245
246 for (len = dstlen; srclen && len; srclen--, src++)
247 {
248 unsigned char off = cp2uni_lb[*src];
249 if (off)
250 {
251 if (!--srclen) break; /* partial char, ignore it */
252 src++;
253 ch = cp2uni[(off << 8) + *src];
254 }
255 else ch = cp2uni[*src];
256 if (!(res = get_decomposition( ch, dst, len ))) break;
257 dst += res;
258 len -= res;
259 }
260 if (srclen) return -1; /* overflow */
261 return dstlen - len;
262}
263
264
265/* return -1 on dst buffer overflow, -2 on invalid input char */
266int wine_cp_mbstowcs( const union cptable *table, int flags,
267 const char *s, int srclen,
268 WCHAR *dst, int dstlen )
269{
270 const unsigned char *src = (const unsigned char*) s;
271
272 if (table->info.char_size == 1)
273 {
274 if (flags & MB_ERR_INVALID_CHARS)
275 {
276 if (check_invalid_chars_sbcs( &table->sbcs, flags, src, srclen )) return -2;
277 }
278 if (!(flags & MB_COMPOSITE))
279 {
280 if (!dstlen) return srclen;
281 return mbstowcs_sbcs( &table->sbcs, flags, src, srclen, dst, dstlen );
282 }
283 return mbstowcs_sbcs_decompose( &table->sbcs, flags, src, srclen, dst, dstlen );
284 }
285 else /* mbcs */
286 {
287 if (flags & MB_ERR_INVALID_CHARS)
288 {
289 if (check_invalid_chars_dbcs( &table->dbcs, src, srclen )) return -2;
290 }
291 if (!(flags & MB_COMPOSITE))
292 return mbstowcs_dbcs( &table->dbcs, src, srclen, dst, dstlen );
293 else
294 return mbstowcs_dbcs_decompose( &table->dbcs, src, srclen, dst, dstlen );
295 }
296}
297
298/* CP_SYMBOL implementation */
299/* return -1 on dst buffer overflow */
300int wine_cpsymbol_mbstowcs( const char *src, int srclen, WCHAR *dst, int dstlen)
301{
302 int len, i;
303 if( dstlen == 0) return srclen;
304 len = dstlen > srclen ? srclen : dstlen;
305 for( i = 0; i < len; i++)
306 {
307 unsigned char c = src [ i ];
308 if( c < 0x20 )
309 dst[i] = c;
310 else
311 dst[i] = c + 0xf000;
312 }
313 if( srclen > len) return -1;
314 return len;
315}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette