1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19
20 #include "StringServices.h"
21
22 #include <DebugServices.h>
23
24
25
26
27
28 extern BOOL
29
BSTRToUTF8(BSTR inString,std::string & outString)30 BSTRToUTF8
31
32 (
33
34 BSTR inString,
35
36 std::string & outString
37
38 )
39
40 {
41
42 USES_CONVERSION;
43
44
45
46 char * utf8String = NULL;
47
48 OSStatus err = kNoErr;
49
50
51
52 outString = "";
53
54 if ( inString )
55
56 {
57 TCHAR * utf16String = NULL;
58 size_t size = 0;
59
60
61 utf16String = OLE2T( inString );
62
63 require_action( utf16String != NULL, exit, err = kUnknownErr );
64
65
66
67 if ( wcslen( utf16String ) > 0 )
68
69 {
70
71 size = (size_t) WideCharToMultiByte( CP_UTF8, 0, utf16String, ( int ) wcslen( utf16String ), NULL, 0, NULL, NULL );
72
73 err = translate_errno( size != 0, GetLastError(), kUnknownErr );
74
75 require_noerr( err, exit );
76
77
78
79 try
80
81 {
82
83 utf8String = new char[ size + 1 ];
84
85 }
86
87 catch ( ... )
88
89 {
90
91 utf8String = NULL;
92
93 }
94
95
96
97 require_action( utf8String != NULL, exit, err = kNoMemoryErr );
98
99 size = (size_t) WideCharToMultiByte( CP_UTF8, 0, utf16String, ( int ) wcslen( utf16String ), utf8String, (int) size, NULL, NULL);
100
101 err = translate_errno( size != 0, GetLastError(), kUnknownErr );
102
103 require_noerr( err, exit );
104
105
106
107 // have to add the trailing 0 because WideCharToMultiByte doesn't do it,
108
109 // although it does return the correct size
110
111
112
113 utf8String[size] = '\0';
114
115 outString = utf8String;
116
117 }
118 }
119
120
121
122 exit:
123
124
125
126 if ( utf8String != NULL )
127
128 {
129
130 delete [] utf8String;
131
132 }
133
134
135
136 return ( !err ) ? TRUE : FALSE;
137
138 }
139
140
141
142
143
144 extern BOOL
145
UTF8ToBSTR(const char * inString,CComBSTR & outString)146 UTF8ToBSTR
147
148 (
149
150 const char * inString,
151
152 CComBSTR & outString
153
154 )
155
156 {
157
158 wchar_t * unicode = NULL;
159
160 OSStatus err = 0;
161
162
163
164 if ( inString )
165
166 {
167 int n;
168
169 n = MultiByteToWideChar( CP_UTF8, 0, inString, -1, NULL, 0 );
170
171
172
173 if ( n > 0 )
174
175 {
176
177 try
178
179 {
180
181 unicode = new wchar_t[ n ];
182
183 }
184
185 catch ( ... )
186
187 {
188
189 unicode = NULL;
190
191 }
192
193
194
195 require_action( unicode, exit, err = ERROR_INSUFFICIENT_BUFFER );
196
197
198
199 n = MultiByteToWideChar( CP_UTF8, 0, inString, -1, unicode, n );
200
201 }
202
203
204
205 outString = unicode;
206
207 }
208
209
210 exit:
211
212
213
214 if ( unicode != NULL )
215
216 {
217
218 delete [] unicode;
219
220 }
221
222
223
224 return ( !err ) ? TRUE : FALSE;
225
226 }
227
228
229
230
231
232 BOOL
233
ByteArrayToVariant(const void * inArray,size_t inArrayLen,VARIANT * outVariant)234 ByteArrayToVariant
235
236 (
237
238 const void * inArray,
239
240 size_t inArrayLen,
241
242 VARIANT * outVariant
243
244 )
245
246 {
247
248 LPBYTE buf = NULL;
249
250 HRESULT hr = 0;
251
252 BOOL ok = TRUE;
253
254
255
256 VariantClear( outVariant );
257
258 outVariant->vt = VT_ARRAY|VT_UI1;
259
260 outVariant->parray = SafeArrayCreateVector( VT_UI1, 0, ( ULONG ) inArrayLen );
261
262 require_action( outVariant->parray, exit, ok = FALSE );
263
264 hr = SafeArrayAccessData( outVariant->parray, (LPVOID *)&buf );
265
266 require_action( hr == S_OK, exit, ok = FALSE );
267
268 memcpy( buf, inArray, inArrayLen );
269
270 hr = SafeArrayUnaccessData( outVariant->parray );
271
272 require_action( hr == S_OK, exit, ok = FALSE );
273
274
275
276 exit:
277
278
279
280 return ok;
281
282 }
283
284
285
286
287
288 extern BOOL
289
VariantToByteArray(VARIANT * inVariant,std::vector<BYTE> & outArray)290 VariantToByteArray
291
292 (
293
294 VARIANT * inVariant,
295
296 std::vector< BYTE > & outArray
297
298 )
299
300 {
301
302 SAFEARRAY * psa = NULL;
303
304 BYTE * pData = NULL;
305
306 ULONG cElements = 0;
307
308 HRESULT hr;
309
310 BOOL ok = TRUE;
311
312
313
314 require_action( V_VT( inVariant ) == ( VT_ARRAY|VT_UI1 ), exit, ok = FALSE );
315
316 psa = V_ARRAY( inVariant );
317
318 require_action( psa, exit, ok = FALSE );
319
320 require_action( SafeArrayGetDim( psa ) == 1, exit, ok = FALSE );
321
322 hr = SafeArrayAccessData( psa, ( LPVOID* )&pData );
323
324 require_action( hr == S_OK, exit, ok = FALSE );
325
326 cElements = psa->rgsabound[0].cElements;
327
328 outArray.reserve( cElements );
329
330 outArray.assign( cElements, 0 );
331
332 memcpy( &outArray[ 0 ], pData, cElements );
333
334 SafeArrayUnaccessData( psa );
335
336
337
338 exit:
339
340
341
342 return ok;
343
344 }