source: trunk/src/kernel32/unicode.cpp@ 3461

Last change on this file since 3461 was 3461, checked in by sandervl, 25 years ago

init changes, export for installation program, create additional directories & registry keys, added lvl2 debug log feature, override for windows dir re-added

File size: 12.1 KB
Line 
1/* $Id: unicode.cpp,v 1.23 2000-04-29 18:26:59 sandervl Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 * Unicode functions
6 * Copyright 1998 Joel Troster
7 * Copyright 1999 Patrick haller
8 * Copyright 1999 Achim Hasenmueller
9 * Copyright 1999 Christoph Bratschi
10 *
11 * Read comments about the implementation before using these functions
12 * Attention: length values include terminating 0
13 */
14#include <os2win.h>
15#include <winnls.h>
16#include <stdlib.h>
17#include <string.h>
18#include "misc.h"
19#include "codepage.h"
20#include <unicode.h>
21
22#define DBG_LOCALLOG DBG_unicode
23#include "dbglocal.h"
24
25/*static UconvObject uconv_object = NULL;*/
26/*
27BOOL getUconvObject( void )
28{
29 int rc;
30 BOOL ret;
31 if ( uconv_object )
32 ret = TRUE;
33 else
34 {
35 rc = UniCreateUconvObject( (UniChar*)L"", &uconv_object );
36 if ( rc == ULS_SUCCESS )
37 ret = TRUE;
38 else
39 {
40 uconv_object = NULL; // to make sure
41 return FALSE;
42 }
43 dprintf(("UniCreateUconvObject(%d)\n", rc ));
44 }
45 return ret;
46}
47*/
48/***********************************************************************
49 * MultiByteToWideChar (KERNEL32.534)
50 *
51 * PARAMS
52 * page [in] Codepage character set to convert from
53 * flags [in] Character mapping flags
54 * src [in] Source string buffer
55 * srclen [in] Length of source string buffer
56 * dst [in] Destination buffer
57 * dstlen [in] Length of destination buffer
58 *
59 * NOTES
60 * The returned length includes the null terminator character.
61 *
62 * RETURNS
63 * Success: If dstlen > 0, number of characters written to destination
64 * buffer. If dstlen == 0, number of characters needed to do
65 * conversion.
66 * Failure: 0. Occurs if not enough space is available.
67 *
68 * ERRORS
69 * ERROR_INSUFFICIENT_BUFFER
70 * ERROR_INVALID_FLAGS (not yet implemented)
71 * ERROR_INVALID_PARAMETER (not yet implemented)
72 *
73 * BUGS
74 * Does not properly handle codepage conversions.
75 * Does not properly handle flags.
76 *
77 */
78INT WINAPI MultiByteToWideChar(UINT page, DWORD flags,
79 LPCSTR src, INT srclen,
80 LPWSTR dst, INT dstlen)
81{
82 int ret;
83
84 dprintf2(("MultiByteToWideChar: %d %x (%s %d) (%x %d)", page, flags, src, srclen, dst, dstlen));
85 if (srclen == -1)
86 srclen = lstrlenA(src)+1;
87 if (!dstlen || !dst)
88 return srclen;
89
90 ret = srclen;
91 while (srclen && dstlen) {
92 *dst = (WCHAR)(unsigned char)*src;
93 dst++; src++;
94 dstlen--; srclen--;
95 }
96 if (!dstlen && srclen) {
97 SetLastError(ERROR_INSUFFICIENT_BUFFER);
98 return 0;
99 }
100 return ret;
101}
102
103/***********************************************************************
104 * WideCharToMultiByte (KERNEL32.727)
105 *
106 * PARAMS
107 * page [in] Codepage character set to convert to
108 * flags [in] Character mapping flags
109 * src [in] Source string buffer
110 * srclen [in] Length of source string buffer
111 * dst [in] Destination buffer
112 * dstlen [in] Length of destination buffer
113 * defchar [in] Default character to use for conversion if no exact
114 * conversion can be made
115 * used [out] Set if default character was used in the conversion
116 *
117 * NOTES
118 * The returned length includes the null terminator character.
119 *
120 * RETURNS
121 * Success: If dstlen > 0, number of characters written to destination
122 * buffer. If dstlen == 0, number of characters needed to do
123 * conversion.
124 * Failure: 0. Occurs if not enough space is available.
125 *
126 * ERRORS
127 * ERROR_INSUFFICIENT_BUFFER
128 * ERROR_INVALID_FLAGS (not yet implemented)
129 *
130 * BUGS
131 * Does not properly handle codepage conversions.
132 * Does not properly handle flags.
133 *
134 */
135INT WIN32API WideCharToMultiByte(UINT page, DWORD flags, LPCWSTR src,
136 INT srclen,LPSTR dst, INT dstlen,
137 LPCSTR defchar, BOOL *used)
138{
139 int count = 0;
140 int eos = 0;
141 int care_for_eos=0;
142 int dont_copy= (dstlen==0);
143
144 dprintf2(("WideCharToMultiByte: %d %x (%x %d) (%x %d)", page, flags, src, srclen, dst, dstlen));
145
146 if ((!src) || ((!dst) && (!dont_copy)) )
147 {
148 SetLastError(ERROR_INVALID_PARAMETER);
149 return 0;
150 }
151
152 if (page!=GetACP() && page!=CP_OEMCP && page!=CP_ACP)
153 dprintf(("WideCharToMultiByte, Conversion in CP %d not supported\n",page));
154#if 0
155 if (flags)
156 dprintf(("WideCharToMultiByte, flags %lx not supported\n",flags));
157#endif
158 if(used)
159 *used=0;
160 if (srclen == -1)
161 {
162 srclen = lstrlenW(src)+1;
163 care_for_eos=1;
164 }
165 while(srclen && (dont_copy || dstlen))
166 {
167 if(!dont_copy){
168 if(*src<256)
169 *dst = *src;
170 else
171 {
172 /* ??? The WC_DEFAULTCHAR flag only gets used in
173 * combination with the WC_COMPOSITECHECK flag or at
174 * least this is what it seems from using the function
175 * on NT4.0 in combination with reading the documentation.
176 */
177 *dst = defchar ? *defchar : '?';
178 if(used)*used=1;
179 }
180 dstlen--;
181 dst++;
182 }
183 count++;
184 srclen--;
185 if((!*src) && care_for_eos) {
186 eos = 1;
187 break;
188 }
189 src++;
190 }
191 if (dont_copy)
192 return count;
193
194 if (!eos && srclen > 0) {
195 SetLastError(ERROR_INSUFFICIENT_BUFFER);
196 return 0;
197 }
198 return count;
199}
200//******************************************************************************
201//******************************************************************************
202BOOL WIN32API GetCPInfo(UINT uCodePage, CPINFO *lpCPInfo)
203{
204 dprintf(("GetCPInfo (%d), not correctly implemented\n", uCodePage));
205 memset(lpCPInfo, 0, sizeof(CPINFO));
206 lpCPInfo->MaxCharSize = 1;
207 lpCPInfo->DefaultChar[0] = 'a';
208
209 return(TRUE);
210}
211
212//******************************************************************************
213// unilen: length of astring buffer (including 0 terminator)
214// returns string length
215//******************************************************************************
216int UnicodeToCodepageN(LPCWSTR ustring, char *astring, int unilen, UconvObject uconv_object)
217{
218 int i;
219 int rc, length;
220 size_t uni_chars_left;
221 size_t out_bytes_left;
222 size_t num_subs;
223 UniChar * in_buf;
224 char * out_buf;
225
226 if (ustring == NULL)
227 {
228 if (astring != NULL && unilen > 0) astring[0] = 0;
229 return 0;
230 }
231
232 if (astring == NULL || unilen <= 0) return 0;
233
234// dprintf(("KERNEL32: UnicodeToAsciiN\n"));
235
236// length = UniStrlen(ustring)+1;
237// unilen = min(length, unilen);
238
239 if (uconv_object)
240 {
241 if (unilen == 1)
242 {
243 astring[0] = 0;
244 return 0; //no data
245 }
246
247 uni_chars_left = unilen-1; //elements
248 out_bytes_left = uni_chars_left; //size in bytes == elements
249 in_buf = (UniChar*)ustring;
250 out_buf = astring;
251 rc = UniUconvFromUcs(uconv_object,
252 &in_buf, &uni_chars_left,
253 (void**)&out_buf, &out_bytes_left,
254 &num_subs);
255
256 unilen -= 1+out_bytes_left; //end + left bytes
257 astring[unilen] = 0; //terminate
258
259 return unilen;
260
261// dprintf(("KERNEL32: UnicodeToAsciiN(%d) '%s'\n", rc, astring ));
262 } else
263 {
264 /* idiots unicode conversion :) */
265 for (i = 0; i < unilen-1; i++)
266 {
267 astring[i] = (ustring[i] > 255) ? (char)20 : (char)ustring[i]; //CB: handle invalid characters as space
268 if (ustring[i] == 0) return i; //asta la vista, baby
269 }
270
271 astring[unilen-1] = 0; // @@@PH: 1999/06/09 fix - always terminate string
272
273 return(unilen-1);
274 }
275}
276
277int WIN32API UnicodeToAsciiN(LPCWSTR ustring, char *astring, int unilen)
278{
279 return UnicodeToCodepageN(ustring, astring, unilen, GetWindowsUconvObject());
280}
281
282//******************************************************************************
283// Converts unicode string to ascii string
284// returns length of ascii string
285//******************************************************************************
286int WIN32API UnicodeToAscii(LPCWSTR ustring, char *astring)
287{
288 /* forward to function with len parameter */
289 return UnicodeToAsciiN(ustring, astring, UniStrlen((UniChar*)ustring)+1); //end included
290}
291//******************************************************************************
292// Converts unicode string to ascii string
293// returns pointer to ascii string
294//******************************************************************************
295char * WIN32API UnicodeToAsciiString(LPCWSTR ustring)
296{
297 char *astring;
298
299 if(ustring == NULL) return(NULL);
300
301 astring = (char *)malloc( 1 + UniStrlen((UniChar*)ustring) );
302 UnicodeToAscii( ustring, astring );
303 return(astring);
304}
305//******************************************************************************
306// length = characters to convert
307//******************************************************************************
308char * WIN32API UnicodeToAsciiStringN(LPCWSTR ustring, ULONG length)
309{
310 char *astring;
311
312 if(ustring == NULL) return(NULL);
313
314 astring = (char *)malloc( 1 + length );
315 UnicodeToAsciiN( ustring, astring, length+1 ); //terminating 0 always added
316 return(astring);
317}
318//******************************************************************************
319// Converts ascii string to unicode string
320// returns pointer to unicode string
321//******************************************************************************
322WCHAR * WIN32API AsciiToUnicodeString(const char *astring)
323{
324 WCHAR *ustring;
325
326 if(astring == NULL)
327 return(NULL);
328
329 ustring = (WCHAR *)malloc( 1 + strlen(astring) << 1 );
330 AsciiToUnicode( astring, ustring );
331 return(ustring);
332}
333
334//******************************************************************************
335//SvL: 24-6-'97 - Added
336//******************************************************************************
337void WIN32API FreeAsciiString(char *astring)
338{
339 if( astring )
340 free( astring );
341}
342//******************************************************************************
343// asciilen: max length of unicode buffer (including end 0)
344//******************************************************************************
345void CodepageToUnicodeN(const char *ascii, WCHAR *unicode, int asciilen, UconvObject uconv_object)
346{
347 int rc;
348 int i;
349 size_t uni_chars_left;
350 size_t in_bytes_left;
351 size_t num_subs;
352 UniChar * out_buf;
353 const char * in_buf;
354
355
356 dprintf(("KERNEL32: AsciiToUnicodeN(%s,%08xh)\n",
357 ascii,
358 unicode));
359
360 //CB: no input, set at least terminator
361 if (ascii == NULL)
362 {
363 if (unicode != NULL && asciilen > 0) unicode[0] = 0;
364 return;
365 }
366
367 if (unicode == NULL || asciilen <= 0) return; //nothing to do
368
369// dprintf(("KERNEL32: AsciiToUnicodeN %s\n", ascii));
370 if (uconv_object)
371 {
372 if (asciilen == 1)
373 {
374 unicode[0] = 0;
375 return;
376 }
377
378 in_buf = ascii;
379 in_bytes_left = asciilen-1; //buffer size in bytes
380 out_buf = (UniChar*)unicode;
381
382 uni_chars_left = in_bytes_left; //elements
383 dprintf2(("KERNEL32: AsciiToUnicode %d\n", in_bytes_left));
384
385 rc = UniUconvToUcs( uconv_object,
386 (void**)&in_buf, &in_bytes_left,
387 &out_buf, &uni_chars_left,
388 &num_subs );
389
390 unicode[asciilen-1-in_bytes_left] = 0;
391
392 //if (rc != ULS_SUCCESS && in_bytes_left > 0) //CB: never the case during my tests
393 // dprintf(("KERNEL32: AsciiToUnicode failed, %d bytes left!\n",in_bytes_left));
394
395 } else
396 { //poor man's conversion
397
398 for(i = 0;i < asciilen-1;i++)
399 {
400 unicode[i] = ascii[i];
401 if (ascii[i] == 0) return; //work done
402 }
403
404 unicode[asciilen-1] = 0;
405 }
406}
407
408void WIN32API AsciiToUnicodeN(const char *ascii, WCHAR *unicode, int asciilen)
409{
410 CodepageToUnicodeN(ascii, unicode, asciilen, GetWindowsUconvObject());
411}
412
413
414//******************************************************************************
415// Copies the full string from ascii to unicode
416//******************************************************************************
417void WIN32API AsciiToUnicode(const char *ascii, WCHAR *unicode)
418{
419 /* achimha for security, strlen might trap if garbage in */
420 /* @@@PH 98/06/07 */
421 if (ascii == NULL)
422 {
423 if (unicode != NULL) unicode[0] = 0; //CB: set at least end
424 return;
425 }
426
427 if (unicode == NULL) return; /* garbage in, garbage out ! */
428
429 /* forward to call with length parameter */
430 AsciiToUnicodeN(ascii, unicode, strlen(ascii)+1); //end included
431}
432
433
434
435
436
Note: See TracBrowser for help on using the repository browser.