PageRenderTime 55ms CodeModel.GetById 12ms app.highlight 38ms RepoModel.GetById 1ms app.codeStats 1ms

/thirdparty/breakpad/common/string_conversion.cc

http://github.com/tomahawk-player/tomahawk
C++ | 154 lines | 95 code | 23 blank | 36 comment | 13 complexity | 8a27df77ef7e8dcc15272c881bc43993 MD5 | raw file
  1// Copyright (c) 2006, Google Inc.
  2// All rights reserved.
  3//
  4// Redistribution and use in source and binary forms, with or without
  5// modification, are permitted provided that the following conditions are
  6// met:
  7//
  8//     * Redistributions of source code must retain the above copyright
  9// notice, this list of conditions and the following disclaimer.
 10//     * Redistributions in binary form must reproduce the above
 11// copyright notice, this list of conditions and the following disclaimer
 12// in the documentation and/or other materials provided with the
 13// distribution.
 14//     * Neither the name of Google Inc. nor the names of its
 15// contributors may be used to endorse or promote products derived from
 16// this software without specific prior written permission.
 17//
 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 29
 30#include "common/convert_UTF.h"
 31#include "processor/scoped_ptr.h"
 32#include "common/string_conversion.h"
 33#include <string.h>
 34
 35namespace google_breakpad {
 36
 37using std::string;
 38using std::vector;
 39
 40void UTF8ToUTF16(const char *in, vector<u_int16_t> *out) {
 41  size_t source_length = strlen(in);
 42  const UTF8 *source_ptr = reinterpret_cast<const UTF8 *>(in);
 43  const UTF8 *source_end_ptr = source_ptr + source_length;
 44  // Erase the contents and zero fill to the expected size
 45  out->clear();
 46  out->insert(out->begin(), source_length, 0);
 47  u_int16_t *target_ptr = &(*out)[0];
 48  u_int16_t *target_end_ptr = target_ptr + out->capacity() * sizeof(u_int16_t);
 49  ConversionResult result = ConvertUTF8toUTF16(&source_ptr, source_end_ptr,
 50                                               &target_ptr, target_end_ptr,
 51                                               strictConversion);
 52
 53  // Resize to be the size of the # of converted characters + NULL
 54  out->resize(result == conversionOK ? target_ptr - &(*out)[0] + 1: 0);
 55}
 56
 57int UTF8ToUTF16Char(const char *in, int in_length, u_int16_t out[2]) {
 58  const UTF8 *source_ptr = reinterpret_cast<const UTF8 *>(in);
 59  const UTF8 *source_end_ptr = source_ptr + sizeof(char);
 60  u_int16_t *target_ptr = out;
 61  u_int16_t *target_end_ptr = target_ptr + 2 * sizeof(u_int16_t);
 62  out[0] = out[1] = 0;
 63
 64  // Process one character at a time
 65  while (1) {
 66    ConversionResult result = ConvertUTF8toUTF16(&source_ptr, source_end_ptr,
 67                                                 &target_ptr, target_end_ptr,
 68                                                 strictConversion);
 69
 70    if (result == conversionOK)
 71      return static_cast<int>(source_ptr - reinterpret_cast<const UTF8 *>(in));
 72
 73    // Add another character to the input stream and try again
 74    source_ptr = reinterpret_cast<const UTF8 *>(in);
 75    ++source_end_ptr;
 76
 77    if (source_end_ptr > reinterpret_cast<const UTF8 *>(in) + in_length)
 78      break;
 79  }
 80
 81  return 0;
 82}
 83
 84void UTF32ToUTF16(const wchar_t *in, vector<u_int16_t> *out) {
 85  size_t source_length = wcslen(in);
 86  const UTF32 *source_ptr = reinterpret_cast<const UTF32 *>(in);
 87  const UTF32 *source_end_ptr = source_ptr + source_length;
 88  // Erase the contents and zero fill to the expected size
 89  out->clear();
 90  out->insert(out->begin(), source_length, 0);
 91  u_int16_t *target_ptr = &(*out)[0];
 92  u_int16_t *target_end_ptr = target_ptr + out->capacity() * sizeof(u_int16_t);
 93  ConversionResult result = ConvertUTF32toUTF16(&source_ptr, source_end_ptr,
 94                                                &target_ptr, target_end_ptr,
 95                                                strictConversion);
 96
 97  // Resize to be the size of the # of converted characters + NULL
 98  out->resize(result == conversionOK ? target_ptr - &(*out)[0] + 1: 0);
 99}
100
101void UTF32ToUTF16Char(wchar_t in, u_int16_t out[2]) {
102  const UTF32 *source_ptr = reinterpret_cast<const UTF32 *>(&in);
103  const UTF32 *source_end_ptr = source_ptr + 1;
104  u_int16_t *target_ptr = out;
105  u_int16_t *target_end_ptr = target_ptr + 2 * sizeof(u_int16_t);
106  out[0] = out[1] = 0;
107  ConversionResult result = ConvertUTF32toUTF16(&source_ptr, source_end_ptr,
108                                                &target_ptr, target_end_ptr,
109                                                strictConversion);
110
111  if (result != conversionOK) {
112    out[0] = out[1] = 0;
113  }
114}
115
116static inline u_int16_t Swap(u_int16_t value) {
117  return (value >> 8) | (value << 8);
118}
119
120string UTF16ToUTF8(const vector<u_int16_t> &in, bool swap) {
121  const UTF16 *source_ptr = &in[0];
122  scoped_ptr<u_int16_t> source_buffer;
123
124  // If we're to swap, we need to make a local copy and swap each byte pair
125  if (swap) {
126    int idx = 0;
127    source_buffer.reset(new u_int16_t[in.size()]);
128    UTF16 *source_buffer_ptr = source_buffer.get();
129    for (vector<u_int16_t>::const_iterator it = in.begin();
130         it != in.end(); ++it, ++idx)
131      source_buffer_ptr[idx] = Swap(*it);
132
133    source_ptr = source_buffer.get();
134  }
135
136  // The maximum expansion would be 4x the size of the input string.
137  const UTF16 *source_end_ptr = source_ptr + in.size();
138  size_t target_capacity = in.size() * 4;
139  scoped_array<UTF8> target_buffer(new UTF8[target_capacity]);
140  UTF8 *target_ptr = target_buffer.get();
141  UTF8 *target_end_ptr = target_ptr + target_capacity;
142  ConversionResult result = ConvertUTF16toUTF8(&source_ptr, source_end_ptr, 
143                                               &target_ptr, target_end_ptr,
144                                               strictConversion);
145
146  if (result == conversionOK) {
147    const char *targetPtr = reinterpret_cast<const char *>(target_buffer.get());
148    return targetPtr;
149  }
150
151  return "";
152}
153
154}  // namespace google_breakpad