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 28extern BOOL 29 30BSTRToUTF8 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 122exit: 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 144extern BOOL 145 146UTF8ToBSTR 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 210exit: 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 232BOOL 233 234ByteArrayToVariant 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 276exit: 277 278 279 280 return ok; 281 282} 283 284 285 286 287 288extern BOOL 289 290VariantToByteArray 291 ( 292 VARIANT * inVariant, 293 std::vector< BYTE > & outArray 294 ) 295{ 296 BOOL ok = TRUE; 297 298 if ( V_VT( inVariant ) == VT_BSTR ) 299 { 300 BSTR bstr = V_BSTR( inVariant ); 301 std::string utf8; 302 303 BSTRToUTF8( bstr, utf8 ); 304 305 outArray.reserve( utf8.size() ); 306 outArray.assign( utf8.begin(), utf8.end() ); 307 } 308 else if ( V_VT( inVariant ) == VT_ARRAY ) 309 { 310 SAFEARRAY * psa = NULL; 311 BYTE * pData = NULL; 312 ULONG cElements = 0; 313 HRESULT hr; 314 315 psa = V_ARRAY( inVariant ); 316 317 require_action( psa, exit, ok = FALSE ); 318 319 require_action( SafeArrayGetDim( psa ) == 1, exit, ok = FALSE ); 320 321 hr = SafeArrayAccessData( psa, ( LPVOID* )&pData ); 322 323 require_action( hr == S_OK, exit, ok = FALSE ); 324 325 cElements = psa->rgsabound[0].cElements; 326 327 outArray.reserve( cElements ); 328 329 outArray.assign( cElements, 0 ); 330 331 memcpy( &outArray[ 0 ], pData, cElements ); 332 333 SafeArrayUnaccessData( psa ); 334 } 335 else 336 { 337 ok = FALSE; 338 } 339 340exit: 341 342 return ok; 343 344}