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 }