• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }