Home | History | Annotate | Download | only in DLLX
      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 
     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 
    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 
    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 
    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 }