ipc/chromium/src/base/sys_string_conversions_mac.mm

changeset 0
6474c204b198
     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

mercurial