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

Last change on this file since 2803 was 2803, checked in by sandervl, 26 years ago

Added new logging feature

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