1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/sys_string_conversions_mac.mm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,145 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/sys_string_conversions.h" 1.9 + 1.10 +#import <Foundation/Foundation.h> 1.11 + 1.12 +#include <vector> 1.13 + 1.14 +#include "base/scoped_cftyperef.h" 1.15 +#include "base/string_piece.h" 1.16 + 1.17 +namespace base { 1.18 + 1.19 +namespace { 1.20 + 1.21 +// Convert the supplied CFString into the specified encoding, and return it as 1.22 +// an STL string of the template type. Returns an empty string on failure. 1.23 +// 1.24 +// Do not assert in this function since it is used by the asssertion code! 1.25 +template<typename StringType> 1.26 +static StringType CFStringToSTLStringWithEncodingT(CFStringRef cfstring, 1.27 + CFStringEncoding encoding) { 1.28 + CFIndex length = CFStringGetLength(cfstring); 1.29 + if (length == 0) 1.30 + return StringType(); 1.31 + 1.32 + CFRange whole_string = CFRangeMake(0, length); 1.33 + CFIndex out_size; 1.34 + CFIndex converted = CFStringGetBytes(cfstring, 1.35 + whole_string, 1.36 + encoding, 1.37 + 0, // lossByte 1.38 + false, // isExternalRepresentation 1.39 + NULL, // buffer 1.40 + 0, // maxBufLen 1.41 + &out_size); 1.42 + if (converted == 0 || out_size == 0) 1.43 + return StringType(); 1.44 + 1.45 + // out_size is the number of UInt8-sized units needed in the destination. 1.46 + // A buffer allocated as UInt8 units might not be properly aligned to 1.47 + // contain elements of StringType::value_type. Use a container for the 1.48 + // proper value_type, and convert out_size by figuring the number of 1.49 + // value_type elements per UInt8. Leave room for a NUL terminator. 1.50 + typename StringType::size_type elements = 1.51 + out_size * sizeof(UInt8) / sizeof(typename StringType::value_type) + 1; 1.52 + 1.53 + std::vector<typename StringType::value_type> out_buffer(elements); 1.54 + converted = CFStringGetBytes(cfstring, 1.55 + whole_string, 1.56 + encoding, 1.57 + 0, // lossByte 1.58 + false, // isExternalRepresentation 1.59 + reinterpret_cast<UInt8*>(&out_buffer[0]), 1.60 + out_size, 1.61 + NULL); // usedBufLen 1.62 + if (converted == 0) 1.63 + return StringType(); 1.64 + 1.65 + out_buffer[elements - 1] = '\0'; 1.66 + return StringType(&out_buffer[0], elements - 1); 1.67 +} 1.68 + 1.69 +// Given an STL string |in| with an encoding specified by |in_encoding|, 1.70 +// convert it to |out_encoding| and return it as an STL string of the 1.71 +// |OutStringType| template type. Returns an empty string on failure. 1.72 +// 1.73 +// Do not assert in this function since it is used by the asssertion code! 1.74 +template<typename InStringType, typename OutStringType> 1.75 +static OutStringType STLStringToSTLStringWithEncodingsT( 1.76 + const InStringType& in, 1.77 + CFStringEncoding in_encoding, 1.78 + CFStringEncoding out_encoding) { 1.79 + typename InStringType::size_type in_length = in.length(); 1.80 + if (in_length == 0) 1.81 + return OutStringType(); 1.82 + 1.83 + scoped_cftyperef<CFStringRef> cfstring( 1.84 + CFStringCreateWithBytesNoCopy(NULL, 1.85 + reinterpret_cast<const UInt8*>(in.data()), 1.86 + in_length * 1.87 + sizeof(typename InStringType::value_type), 1.88 + in_encoding, 1.89 + false, 1.90 + kCFAllocatorNull)); 1.91 + if (!cfstring) 1.92 + return OutStringType(); 1.93 + 1.94 + return CFStringToSTLStringWithEncodingT<OutStringType>(cfstring, 1.95 + out_encoding); 1.96 +} 1.97 + 1.98 +// Given an STL string |in| with an encoding specified by |in_encoding|, 1.99 +// return it as a CFStringRef. Returns NULL on failure. 1.100 +template<typename StringType> 1.101 +static CFStringRef STLStringToCFStringWithEncodingsT( 1.102 + const StringType& in, 1.103 + CFStringEncoding in_encoding) { 1.104 + typename StringType::size_type in_length = in.length(); 1.105 + if (in_length == 0) 1.106 + return CFSTR(""); 1.107 + 1.108 + return CFStringCreateWithBytes(kCFAllocatorDefault, 1.109 + reinterpret_cast<const UInt8*>(in.data()), 1.110 + in_length * 1.111 + sizeof(typename StringType::value_type), 1.112 + in_encoding, 1.113 + false); 1.114 +} 1.115 + 1.116 +// Specify the byte ordering explicitly, otherwise CFString will be confused 1.117 +// when strings don't carry BOMs, as they typically won't. 1.118 +static const CFStringEncoding kNarrowStringEncoding = kCFStringEncodingUTF8; 1.119 + 1.120 +#ifdef __BIG_ENDIAN__ 1.121 +static const CFStringEncoding kWideStringEncoding = kCFStringEncodingUTF32BE; 1.122 +#elif defined(__LITTLE_ENDIAN__) 1.123 +static const CFStringEncoding kWideStringEncoding = kCFStringEncodingUTF32LE; 1.124 +#endif // __LITTLE_ENDIAN__ 1.125 + 1.126 +} // namespace 1.127 + 1.128 +// Do not assert in this function since it is used by the asssertion code! 1.129 +std::string SysWideToUTF8(const std::wstring& wide) { 1.130 + return STLStringToSTLStringWithEncodingsT<std::wstring, std::string>( 1.131 + wide, kWideStringEncoding, kNarrowStringEncoding); 1.132 +} 1.133 + 1.134 +// Do not assert in this function since it is used by the asssertion code! 1.135 +std::wstring SysUTF8ToWide(const StringPiece& utf8) { 1.136 + return STLStringToSTLStringWithEncodingsT<StringPiece, std::wstring>( 1.137 + utf8, kNarrowStringEncoding, kWideStringEncoding); 1.138 +} 1.139 + 1.140 +std::string SysWideToNativeMB(const std::wstring& wide) { 1.141 + return SysWideToUTF8(wide); 1.142 +} 1.143 + 1.144 +std::wstring SysNativeMBToWide(const StringPiece& native_mb) { 1.145 + return SysUTF8ToWide(native_mb); 1.146 +} 1.147 + 1.148 +} // namespace base