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

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

Fix for MultibyteToWideChar

File size: 9.5 KB
Line 
1/* $Id: unicode.cpp,v 1.14 1999-09-13 09:06:05 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 <unicode.h>
20
21static UconvObject uconv_object = NULL;
22BOOL getUconvObject( void )
23{
24 int rc;
25 BOOL ret;
26 if ( uconv_object )
27 ret = TRUE;
28 else
29 {
30 rc = UniCreateUconvObject( (UniChar*)L"", &uconv_object );
31 if ( rc == ULS_SUCCESS )
32 ret = TRUE;
33 else
34 {
35 uconv_object = NULL; // to make sure
36 return FALSE;
37 }
38 dprintf(("UniCreateUconvObject(%d)\n", rc ));
39 }
40 return ret;
41}
42
43//******************************************************************************
44//Not identical, but close enough
45//******************************************************************************
46int WIN32API MultiByteToWideChar(UINT uCodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
47 int cchMultiByte, LPWSTR lpWideCharStr, int cchWideChar)
48{
49 int i, len;
50
51// dprintf(("MultiByteToWideChar %s\n", lpMultiByteStr));
52
53 if((int)lpMultiByteStr == (int)lpWideCharStr) {//not allowed
54 SetLastError(ERROR_INVALID_PARAMETER);
55 return(FALSE);
56 }
57 if(cchWideChar == 0) {//return space required for conversion
58 if(cchMultiByte == -1)
59 cchMultiByte = strlen(lpMultiByteStr) + 1;
60 return(cchMultiByte); //return length in wide chars
61 }
62 if(cchMultiByte == -1)
63 cchMultiByte = strlen(lpMultiByteStr) + 1;
64
65 len = min(cchWideChar, cchMultiByte);
66 for(i=0;i<=len;i++) { //including 0 terminator
67 lpWideCharStr[i] = lpMultiByteStr[i];
68 }
69 return(len);
70}
71//******************************************************************************
72//******************************************************************************
73//Not identical, close enough
74//Forget about characters that can't be mapped; just do it
75//******************************************************************************
76int WIN32API WideCharToMultiByte(UINT uCodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
77 int cchWideChar, LPSTR lpMultiByteStr,
78 int cchMultiByte, LPCSTR lpDefaultChar,
79 LPBOOL lpfUsedDefaultChar)
80{
81 int i, len;
82
83// dprintf(("WideCharToMultiByte\n"));
84
85 if((int)lpMultiByteStr == (int)lpWideCharStr) {//not allowed
86 SetLastError(ERROR_INVALID_PARAMETER);
87 return(FALSE);
88 }
89 if(cchMultiByte == 0) {//return space required for conversion
90 if(cchWideChar == -1) cchWideChar = UniStrlen((UniChar *)lpWideCharStr);
91 return(cchWideChar);
92 }
93 if(cchWideChar == -1)
94 cchWideChar = UniStrlen((UniChar*)lpWideCharStr);
95
96 len = min(cchWideChar, cchMultiByte);
97 for(i=0;i<=len;i++) { //including 0 terminator
98 lpMultiByteStr[i] = (UCHAR)lpWideCharStr[i];
99 }
100 return(len);
101}
102//******************************************************************************
103//******************************************************************************
104BOOL WIN32API GetCPInfo(UINT uCodePage, CPINFO *lpCPInfo)
105{
106 dprintf(("GetCPInfo (%d), not correctly implemented\n", uCodePage));
107 memset(lpCPInfo, 0, sizeof(CPINFO));
108 lpCPInfo->MaxCharSize = 1;
109 lpCPInfo->DefaultChar[0] = 'a';
110
111 return(TRUE);
112}
113//******************************************************************************
114// unilen: length of astring buffer (including 0 terminator)
115// returns string length
116//******************************************************************************
117int WIN32API UnicodeToAsciiN(WCHAR *ustring, char *astring, int unilen)
118{
119 int i;
120 int rc;
121 size_t uni_chars_left;
122 size_t out_bytes_left;
123 size_t num_subs;
124 UniChar * in_buf;
125 char * out_buf;
126
127 if (ustring == NULL)
128 {
129 if (astring != NULL && unilen > 0) astring[0] = 0;
130 return 0;
131 }
132
133 if (astring == NULL || unilen <= 0) return 0;
134
135// dprintf(("KERNEL32: UnicodeToAsciiN\n"));
136 if (getUconvObject())
137 {
138 if (unilen == 1)
139 {
140 astring[0] = 0;
141 return 0; //no data
142 }
143
144 uni_chars_left = unilen-1; //elements
145 out_bytes_left = uni_chars_left; //size in bytes == elements
146 in_buf = (UniChar*)ustring;
147 out_buf = astring;
148 rc = UniUconvFromUcs(uconv_object,
149 &in_buf, &uni_chars_left,
150 (void**)&out_buf, &out_bytes_left,
151 &num_subs);
152
153 unilen -= 1+out_bytes_left; //end + left bytes
154 astring[unilen] = 0; //terminate
155
156 return unilen;
157
158// dprintf(("KERNEL32: UnicodeToAsciiN(%d) '%s'\n", rc, astring ));
159 } else
160 {
161 /* idiots unicode conversion :) */
162 for (i = 0; i < unilen-1; i++)
163 {
164 astring[i] = (ustring[i] > 255) ? (char)20 : (char)ustring[i]; //CB: handle invalid characters as space
165 if (ustring[i] == 0) return i; //asta la vista, baby
166 }
167
168 astring[unilen-1] = 0; // @@@PH: 1999/06/09 fix - always terminate string
169
170 return(unilen-1);
171 }
172}
173//******************************************************************************
174// Converts unicode string to ascii string
175// returns length of ascii string
176//******************************************************************************
177int WIN32API UnicodeToAscii(WCHAR *ustring, char *astring)
178{
179 /* forward to function with len parameter */
180 return UnicodeToAsciiN(ustring, astring, UniStrlen((UniChar*)ustring)+1); //end included
181}
182//******************************************************************************
183// Converts unicode string to ascii string
184// returns pointer to ascii string
185//******************************************************************************
186char * WIN32API UnicodeToAsciiString(WCHAR *ustring)
187{
188 char *astring;
189
190 if(ustring == NULL) return(NULL);
191
192 astring = (char *)malloc( 1 + UniStrlen((UniChar*)ustring) );
193 UnicodeToAscii( ustring, astring );
194 return(astring);
195}
196//******************************************************************************
197//******************************************************************************
198char * WIN32API UnicodeToAsciiStringN(WCHAR *ustring, ULONG length)
199{
200 char *astring;
201
202 if(ustring == NULL) return(NULL);
203
204 astring = (char *)malloc( 1 + length );
205 UnicodeToAscii( ustring, astring );
206 return(astring);
207}
208//******************************************************************************
209// Converts ascii string to unicode string
210// returns pointer to unicode string
211//******************************************************************************
212WCHAR * WIN32API AsciiToUnicodeString(char *astring)
213{
214 WCHAR *ustring;
215
216 if(astring == NULL)
217 return(NULL);
218
219 ustring = (WCHAR *)malloc( 1 + strlen(astring) << 1 );
220 AsciiToUnicode( astring, ustring );
221 return(ustring);
222}
223
224//******************************************************************************
225//SvL: 24-6-'97 - Added
226//******************************************************************************
227void WIN32API FreeAsciiString(char *astring)
228{
229 if( astring )
230 free( astring );
231}
232//******************************************************************************
233// asciilen: max length of unicode buffer (including end 0)
234//******************************************************************************
235void WIN32API AsciiToUnicodeN(char *ascii, WCHAR *unicode, int asciilen)
236{
237 int rc;
238 int i;
239 size_t uni_chars_left;
240 size_t in_bytes_left;
241 size_t num_subs;
242 UniChar * out_buf;
243 char * in_buf;
244
245
246 dprintf(("KERNEL32: AsciiToUnicodeN(%s,%08xh)\n",
247 ascii,
248 unicode));
249
250 //CB: no input, set at least terminator
251 if (ascii == NULL)
252 {
253 if (unicode != NULL && asciilen > 0) unicode[0] = 0;
254 return;
255 }
256
257 if (unicode == NULL || asciilen <= 0) return; //nothing to do
258
259// dprintf(("KERNEL32: AsciiToUnicodeN %s\n", ascii));
260 if (getUconvObject())
261 {
262 if (asciilen == 1)
263 {
264 unicode[0] = 0;
265 return;
266 }
267
268 in_buf = ascii;
269 in_bytes_left = asciilen-1; //buffer size in bytes
270 out_buf = (UniChar*)unicode;
271
272 uni_chars_left = in_bytes_left; //elements
273 dprintf(("KERNEL32: AsciiToUnicode %d\n", in_bytes_left));
274
275 rc = UniUconvToUcs( uconv_object,
276 (void**)&in_buf, &in_bytes_left,
277 &out_buf, &uni_chars_left,
278 &num_subs );
279
280 unicode[asciilen-1-in_bytes_left] = 0;
281
282 //if (rc != ULS_SUCCESS && in_bytes_left > 0) //CB: never the case during my tests
283 // dprintf(("KERNEL32: AsciiToUnicode failed, %d bytes left!\n",in_bytes_left));
284
285 } else
286 { //poor man's conversion
287
288 for(i = 0;i < asciilen-1;i++)
289 {
290 unicode[i] = ascii[i];
291 if (ascii[i] == 0) return; //work done
292 }
293
294 unicode[asciilen-1] = 0;
295 }
296}
297//******************************************************************************
298// Copies the full string from ascii to unicode
299//******************************************************************************
300void WIN32API AsciiToUnicode(char *ascii, WCHAR *unicode)
301{
302 /* achimha for security, strlen might trap if garbage in */
303 /* @@@PH 98/06/07 */
304 if (ascii == NULL)
305 {
306 if (unicode != NULL) unicode[0] = 0; //CB: set at least end
307 return;
308 }
309
310 if (unicode == NULL) return; /* garbage in, garbage out ! */
311
312 /* forward to call with length parameter */
313 AsciiToUnicodeN(ascii, unicode, strlen(ascii)+1); //end included
314}
315
316
317
318
Note: See TracBrowser for help on using the repository browser.