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

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

Unicode changes

File size: 8.4 KB
Line 
1/* $Id: unicode.cpp,v 1.10 1999-06-30 13:25:01 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; //elements
143 out_bytes_left = unilen; //size in bytes
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// dprintf(("KERNEL32: UnicodeToAsciiN(%d) '%s'\n", rc, astring ));
152 } else
153 {
154 /* idiots unicode conversion :) */
155 for(i = 0; i < unilen-1; i++)
156 {
157 astring[i] = (ustring[i] > 255) ? (char)20 : (char)ustring[i]; //CB: handle invalid characters as space
158 if (ustring[i] == 0) return i; //asta la vista, baby
159 }
160 }
161
162 astring[unilen-1] = 0; // @@@PH: 1999/06/09 fix - always terminate string
163
164 return(unilen-1);
165}
166//******************************************************************************
167// Converts unicode string to ascii string
168// returns length of ascii string
169//******************************************************************************
170int WIN32API UnicodeToAscii(WCHAR *ustring, char *astring)
171{
172 /* forward to function with len parameter */
173 return UnicodeToAsciiN(ustring, astring, UniStrlen((UniChar*)ustring)+1); //end included
174}
175//******************************************************************************
176// Converts unicode string to ascii string
177// returns pointer to ascii string
178//******************************************************************************
179char * WIN32API UnicodeToAsciiString(WCHAR *ustring)
180{
181 char *astring;
182
183 if(ustring == NULL) return(NULL);
184
185 astring = (char *)malloc( 1 + UniStrlen((UniChar*)ustring) );
186 UnicodeToAscii( ustring, astring );
187 return(astring);
188}
189//******************************************************************************
190//SvL: 24-6-'97 - Added
191//******************************************************************************
192void WIN32API FreeAsciiString(char *astring)
193{
194 if( astring )
195 free( astring );
196}
197//******************************************************************************
198// asciilen: max length of unicode buffer (including end 0)
199//******************************************************************************
200void WIN32API AsciiToUnicodeN(char *ascii, WCHAR *unicode, int asciilen)
201{
202 int rc;
203 int i;
204 size_t uni_chars_left;
205 size_t in_bytes_left;
206 size_t num_subs;
207 UniChar * out_buf;
208 char * in_buf;
209
210
211 dprintf(("KERNEL32: AsciiToUnicodeN(%s,%08xh)\n",
212 ascii,
213 unicode));
214
215 //CB: no input, set at least terminator
216 if (ascii == NULL)
217 {
218 if (unicode != NULL && asciilen > 0) unicode[0] = 0;
219 return;
220 }
221
222 if (unicode == NULL || asciilen <= 0) return; //nothing to do
223
224// dprintf(("KERNEL32: AsciiToUnicodeN %s\n", ascii));
225 if (getUconvObject())
226 {
227 if (asciilen == 1)
228 {
229 unicode[0] = 0;
230 return;
231 }
232
233 in_buf = ascii;
234 in_bytes_left = asciilen; //buffer size in bytes
235 out_buf = (UniChar*)unicode;
236
237 uni_chars_left = asciilen; //elements
238 dprintf(("KERNEL32: AsciiToUnicode %d\n", in_bytes_left));
239
240 rc = UniUconvToUcs( uconv_object,
241 (void**)&in_buf, &in_bytes_left,
242 &out_buf, &uni_chars_left,
243 &num_subs );
244
245 //if (rc != ULS_SUCCESS && in_bytes_left > 0) //CB: never the case during my tests
246 // dprintf(("KERNEL32: AsciiToUnicode failed, %d bytes left!\n",in_bytes_left));
247
248 } else
249 { //poor man's conversion
250
251 for(i = 0;i < asciilen-1;i++)
252 {
253 unicode[i] = ascii[i];
254 if (ascii[i] == 0) return; //work done
255 }
256 }
257
258 unicode[asciilen-1] = 0;
259}
260//******************************************************************************
261// Copies the full string from ascii to unicode
262//******************************************************************************
263void WIN32API AsciiToUnicode(char *ascii, WCHAR *unicode)
264{
265 /* achimha for security, strlen might trap if garbage in */
266 /* @@@PH 98/06/07 */
267 if (ascii == NULL)
268 {
269 if (unicode != NULL) unicode[0] = 0; //CB: set at least end
270 return;
271 }
272
273 if (unicode == NULL) return; /* garbage in, garbage out ! */
274
275 /* forward to call with length parameter */
276 AsciiToUnicodeN(ascii, unicode, strlen(ascii)+1); //end included
277}
278
279
280
Note: See TracBrowser for help on using the repository browser.