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

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

MultiByteToWideChar & lstrcpynA bugfixes; added cdaudio system.ini section

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