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