| /* -*- Mode: C; tab-width: 4 -*- |
| * |
| * Copyright (c) 2009 Apple Computer, Inc. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| |
| #include "StringServices.h" |
| |
| #include <DebugServices.h> |
| |
| |
| |
| |
| |
| extern BOOL |
| |
| BSTRToUTF8 |
| |
| ( |
| |
| BSTR inString, |
| |
| std::string & outString |
| |
| ) |
| |
| { |
| |
| USES_CONVERSION; |
| |
| |
| |
| char * utf8String = NULL; |
| |
| OSStatus err = kNoErr; |
| |
| |
| |
| outString = ""; |
| |
| if ( inString ) |
| |
| { |
| TCHAR * utf16String = NULL; |
| size_t size = 0; |
| |
| |
| utf16String = OLE2T( inString ); |
| |
| require_action( utf16String != NULL, exit, err = kUnknownErr ); |
| |
| |
| |
| if ( wcslen( utf16String ) > 0 ) |
| |
| { |
| |
| size = (size_t) WideCharToMultiByte( CP_UTF8, 0, utf16String, ( int ) wcslen( utf16String ), NULL, 0, NULL, NULL ); |
| |
| err = translate_errno( size != 0, GetLastError(), kUnknownErr ); |
| |
| require_noerr( err, exit ); |
| |
| |
| |
| try |
| |
| { |
| |
| utf8String = new char[ size + 1 ]; |
| |
| } |
| |
| catch ( ... ) |
| |
| { |
| |
| utf8String = NULL; |
| |
| } |
| |
| |
| |
| require_action( utf8String != NULL, exit, err = kNoMemoryErr ); |
| |
| size = (size_t) WideCharToMultiByte( CP_UTF8, 0, utf16String, ( int ) wcslen( utf16String ), utf8String, (int) size, NULL, NULL); |
| |
| err = translate_errno( size != 0, GetLastError(), kUnknownErr ); |
| |
| require_noerr( err, exit ); |
| |
| |
| |
| // have to add the trailing 0 because WideCharToMultiByte doesn't do it, |
| |
| // although it does return the correct size |
| |
| |
| |
| utf8String[size] = '\0'; |
| |
| outString = utf8String; |
| |
| } |
| } |
| |
| |
| |
| exit: |
| |
| |
| |
| if ( utf8String != NULL ) |
| |
| { |
| |
| delete [] utf8String; |
| |
| } |
| |
| |
| |
| return ( !err ) ? TRUE : FALSE; |
| |
| } |
| |
| |
| |
| |
| |
| extern BOOL |
| |
| UTF8ToBSTR |
| |
| ( |
| |
| const char * inString, |
| |
| CComBSTR & outString |
| |
| ) |
| |
| { |
| |
| wchar_t * unicode = NULL; |
| |
| OSStatus err = 0; |
| |
| |
| |
| if ( inString ) |
| |
| { |
| int n; |
| |
| n = MultiByteToWideChar( CP_UTF8, 0, inString, -1, NULL, 0 ); |
| |
| |
| |
| if ( n > 0 ) |
| |
| { |
| |
| try |
| |
| { |
| |
| unicode = new wchar_t[ n ]; |
| |
| } |
| |
| catch ( ... ) |
| |
| { |
| |
| unicode = NULL; |
| |
| } |
| |
| |
| |
| require_action( unicode, exit, err = ERROR_INSUFFICIENT_BUFFER ); |
| |
| |
| |
| n = MultiByteToWideChar( CP_UTF8, 0, inString, -1, unicode, n ); |
| |
| } |
| |
| |
| |
| outString = unicode; |
| |
| } |
| |
| |
| exit: |
| |
| |
| |
| if ( unicode != NULL ) |
| |
| { |
| |
| delete [] unicode; |
| |
| } |
| |
| |
| |
| return ( !err ) ? TRUE : FALSE; |
| |
| } |
| |
| |
| |
| |
| |
| BOOL |
| |
| ByteArrayToVariant |
| |
| ( |
| |
| const void * inArray, |
| |
| size_t inArrayLen, |
| |
| VARIANT * outVariant |
| |
| ) |
| |
| { |
| |
| LPBYTE buf = NULL; |
| |
| HRESULT hr = 0; |
| |
| BOOL ok = TRUE; |
| |
| |
| |
| VariantClear( outVariant ); |
| |
| outVariant->vt = VT_ARRAY|VT_UI1; |
| |
| outVariant->parray = SafeArrayCreateVector( VT_UI1, 0, ( ULONG ) inArrayLen ); |
| |
| require_action( outVariant->parray, exit, ok = FALSE ); |
| |
| hr = SafeArrayAccessData( outVariant->parray, (LPVOID *)&buf ); |
| |
| require_action( hr == S_OK, exit, ok = FALSE ); |
| |
| memcpy( buf, inArray, inArrayLen ); |
| |
| hr = SafeArrayUnaccessData( outVariant->parray ); |
| |
| require_action( hr == S_OK, exit, ok = FALSE ); |
| |
| |
| |
| exit: |
| |
| |
| |
| return ok; |
| |
| } |
| |
| |
| |
| |
| |
| extern BOOL |
| |
| VariantToByteArray |
| |
| ( |
| |
| VARIANT * inVariant, |
| |
| std::vector< BYTE > & outArray |
| |
| ) |
| |
| { |
| |
| SAFEARRAY * psa = NULL; |
| |
| BYTE * pData = NULL; |
| |
| ULONG cElements = 0; |
| |
| HRESULT hr; |
| |
| BOOL ok = TRUE; |
| |
| |
| |
| require_action( V_VT( inVariant ) == ( VT_ARRAY|VT_UI1 ), exit, ok = FALSE ); |
| |
| psa = V_ARRAY( inVariant ); |
| |
| require_action( psa, exit, ok = FALSE ); |
| |
| require_action( SafeArrayGetDim( psa ) == 1, exit, ok = FALSE ); |
| |
| hr = SafeArrayAccessData( psa, ( LPVOID* )&pData ); |
| |
| require_action( hr == S_OK, exit, ok = FALSE ); |
| |
| cElements = psa->rgsabound[0].cElements; |
| |
| outArray.reserve( cElements ); |
| |
| outArray.assign( cElements, 0 ); |
| |
| memcpy( &outArray[ 0 ], pData, cElements ); |
| |
| SafeArrayUnaccessData( psa ); |
| |
| |
| |
| exit: |
| |
| |
| |
| return ok; |
| |
| } |