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

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

Fixes for unicode apps

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