193fa375b580a647904925cb741266f2d679cb448mmentovai// Copyright (c) 2006, Google Inc.
293fa375b580a647904925cb741266f2d679cb448mmentovai// All rights reserved.
393fa375b580a647904925cb741266f2d679cb448mmentovai//
493fa375b580a647904925cb741266f2d679cb448mmentovai// Redistribution and use in source and binary forms, with or without
593fa375b580a647904925cb741266f2d679cb448mmentovai// modification, are permitted provided that the following conditions are
693fa375b580a647904925cb741266f2d679cb448mmentovai// met:
793fa375b580a647904925cb741266f2d679cb448mmentovai//
893fa375b580a647904925cb741266f2d679cb448mmentovai//     * Redistributions of source code must retain the above copyright
993fa375b580a647904925cb741266f2d679cb448mmentovai// notice, this list of conditions and the following disclaimer.
1093fa375b580a647904925cb741266f2d679cb448mmentovai//     * Redistributions in binary form must reproduce the above
1193fa375b580a647904925cb741266f2d679cb448mmentovai// copyright notice, this list of conditions and the following disclaimer
1293fa375b580a647904925cb741266f2d679cb448mmentovai// in the documentation and/or other materials provided with the
1393fa375b580a647904925cb741266f2d679cb448mmentovai// distribution.
1493fa375b580a647904925cb741266f2d679cb448mmentovai//     * Neither the name of Google Inc. nor the names of its
1593fa375b580a647904925cb741266f2d679cb448mmentovai// contributors may be used to endorse or promote products derived from
1693fa375b580a647904925cb741266f2d679cb448mmentovai// this software without specific prior written permission.
1793fa375b580a647904925cb741266f2d679cb448mmentovai//
1893fa375b580a647904925cb741266f2d679cb448mmentovai// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1993fa375b580a647904925cb741266f2d679cb448mmentovai// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2093fa375b580a647904925cb741266f2d679cb448mmentovai// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2193fa375b580a647904925cb741266f2d679cb448mmentovai// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2293fa375b580a647904925cb741266f2d679cb448mmentovai// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2393fa375b580a647904925cb741266f2d679cb448mmentovai// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2493fa375b580a647904925cb741266f2d679cb448mmentovai// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2593fa375b580a647904925cb741266f2d679cb448mmentovai// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2693fa375b580a647904925cb741266f2d679cb448mmentovai// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2793fa375b580a647904925cb741266f2d679cb448mmentovai// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2893fa375b580a647904925cb741266f2d679cb448mmentovai// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2993fa375b580a647904925cb741266f2d679cb448mmentovai
3050e299b00e803f085b34847dfe5232b471d84197mmentovai#include <cassert>
31d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek#include <vector>
3250e299b00e803f085b34847dfe5232b471d84197mmentovai
3393fa375b580a647904925cb741266f2d679cb448mmentovai#include "common/windows/string_utils-inl.h"
3493fa375b580a647904925cb741266f2d679cb448mmentovai
35e5dc60822e5938fea2ae892ccddb906641ba174emmentovainamespace google_breakpad {
3693fa375b580a647904925cb741266f2d679cb448mmentovai
3793fa375b580a647904925cb741266f2d679cb448mmentovai// static
3893fa375b580a647904925cb741266f2d679cb448mmentovaiwstring WindowsStringUtils::GetBaseName(const wstring &filename) {
3993fa375b580a647904925cb741266f2d679cb448mmentovai  wstring base_name(filename);
4093fa375b580a647904925cb741266f2d679cb448mmentovai  size_t slash_pos = base_name.find_last_of(L"/\\");
4193fa375b580a647904925cb741266f2d679cb448mmentovai  if (slash_pos != wstring::npos) {
4293fa375b580a647904925cb741266f2d679cb448mmentovai    base_name.erase(0, slash_pos + 1);
4393fa375b580a647904925cb741266f2d679cb448mmentovai  }
4493fa375b580a647904925cb741266f2d679cb448mmentovai  return base_name;
4593fa375b580a647904925cb741266f2d679cb448mmentovai}
4693fa375b580a647904925cb741266f2d679cb448mmentovai
4750e299b00e803f085b34847dfe5232b471d84197mmentovai// static
4850e299b00e803f085b34847dfe5232b471d84197mmentovaibool WindowsStringUtils::safe_mbstowcs(const string &mbs, wstring *wcs) {
4950e299b00e803f085b34847dfe5232b471d84197mmentovai  assert(wcs);
5050e299b00e803f085b34847dfe5232b471d84197mmentovai
5150e299b00e803f085b34847dfe5232b471d84197mmentovai  // First, determine the length of the destination buffer.
5250e299b00e803f085b34847dfe5232b471d84197mmentovai  size_t wcs_length;
5350e299b00e803f085b34847dfe5232b471d84197mmentovai
5450e299b00e803f085b34847dfe5232b471d84197mmentovai#if _MSC_VER >= 1400  // MSVC 2005/8
5550e299b00e803f085b34847dfe5232b471d84197mmentovai  errno_t err;
5650e299b00e803f085b34847dfe5232b471d84197mmentovai  if ((err = mbstowcs_s(&wcs_length, NULL, 0, mbs.c_str(), _TRUNCATE)) != 0) {
5750e299b00e803f085b34847dfe5232b471d84197mmentovai    return false;
5850e299b00e803f085b34847dfe5232b471d84197mmentovai  }
59d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  assert(wcs_length > 0);
6050e299b00e803f085b34847dfe5232b471d84197mmentovai#else  // _MSC_VER >= 1400
61de9fe36b16a45972571b9d650633fe5cb156b536ted.mielczarek@gmail.com  if ((wcs_length = mbstowcs(NULL, mbs.c_str(), mbs.length())) == (size_t)-1) {
6250e299b00e803f085b34847dfe5232b471d84197mmentovai    return false;
6350e299b00e803f085b34847dfe5232b471d84197mmentovai  }
6450e299b00e803f085b34847dfe5232b471d84197mmentovai
6550e299b00e803f085b34847dfe5232b471d84197mmentovai  // Leave space for the 0-terminator.
6650e299b00e803f085b34847dfe5232b471d84197mmentovai  ++wcs_length;
6750e299b00e803f085b34847dfe5232b471d84197mmentovai#endif  // _MSC_VER >= 1400
6850e299b00e803f085b34847dfe5232b471d84197mmentovai
69d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  std::vector<wchar_t> wcs_v(wcs_length);
7050e299b00e803f085b34847dfe5232b471d84197mmentovai
7150e299b00e803f085b34847dfe5232b471d84197mmentovai  // Now, convert.
7250e299b00e803f085b34847dfe5232b471d84197mmentovai#if _MSC_VER >= 1400  // MSVC 2005/8
73d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  if ((err = mbstowcs_s(NULL, &wcs_v[0], wcs_length, mbs.c_str(),
7450e299b00e803f085b34847dfe5232b471d84197mmentovai                        _TRUNCATE)) != 0) {
7550e299b00e803f085b34847dfe5232b471d84197mmentovai    return false;
7650e299b00e803f085b34847dfe5232b471d84197mmentovai  }
7750e299b00e803f085b34847dfe5232b471d84197mmentovai#else  // _MSC_VER >= 1400
78de9fe36b16a45972571b9d650633fe5cb156b536ted.mielczarek@gmail.com  if (mbstowcs(&wcs_v[0], mbs.c_str(), mbs.length()) == (size_t)-1) {
7950e299b00e803f085b34847dfe5232b471d84197mmentovai    return false;
8050e299b00e803f085b34847dfe5232b471d84197mmentovai  }
8150e299b00e803f085b34847dfe5232b471d84197mmentovai
8250e299b00e803f085b34847dfe5232b471d84197mmentovai  // Ensure presence of 0-terminator.
83d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  wcs_v[wcs_length - 1] = '\0';
8450e299b00e803f085b34847dfe5232b471d84197mmentovai#endif  // _MSC_VER >= 1400
8550e299b00e803f085b34847dfe5232b471d84197mmentovai
86d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  *wcs = &wcs_v[0];
87d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  return true;
88d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek}
89d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek
90d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek// static
91d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarekbool WindowsStringUtils::safe_wcstombs(const wstring &wcs, string *mbs) {
92d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  assert(mbs);
93d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek
94d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  // First, determine the length of the destination buffer.
95d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  size_t mbs_length;
96d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek
97d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek#if _MSC_VER >= 1400  // MSVC 2005/8
98d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  errno_t err;
99d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  if ((err = wcstombs_s(&mbs_length, NULL, 0, wcs.c_str(), _TRUNCATE)) != 0) {
100d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek    return false;
101d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  }
102d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  assert(mbs_length > 0);
103d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek#else  // _MSC_VER >= 1400
104de9fe36b16a45972571b9d650633fe5cb156b536ted.mielczarek@gmail.com  if ((mbs_length = wcstombs(NULL, wcs.c_str(), wcs.length())) == (size_t)-1) {
105d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek    return false;
106d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  }
107d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek
108d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  // Leave space for the 0-terminator.
109d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  ++mbs_length;
110d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek#endif  // _MSC_VER >= 1400
111d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek
112d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  std::vector<char> mbs_v(mbs_length);
113d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek
114d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  // Now, convert.
115d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek#if _MSC_VER >= 1400  // MSVC 2005/8
116d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  if ((err = wcstombs_s(NULL, &mbs_v[0], mbs_length, wcs.c_str(),
117d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek                        _TRUNCATE)) != 0) {
118d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek    return false;
119d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  }
120d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek#else  // _MSC_VER >= 1400
121de9fe36b16a45972571b9d650633fe5cb156b536ted.mielczarek@gmail.com  if (wcstombs(&mbs_v[0], wcs.c_str(), wcs.length()) == (size_t)-1) {
122d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek    return false;
123d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  }
124d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek
125d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  // Ensure presence of 0-terminator.
126d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  mbs_v[mbs_length - 1] = '\0';
127d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek#endif  // _MSC_VER >= 1400
128d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek
129d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  *mbs = &mbs_v[0];
13050e299b00e803f085b34847dfe5232b471d84197mmentovai  return true;
13150e299b00e803f085b34847dfe5232b471d84197mmentovai}
13250e299b00e803f085b34847dfe5232b471d84197mmentovai
133e5dc60822e5938fea2ae892ccddb906641ba174emmentovai}  // namespace google_breakpad
134