Home | History | Annotate | Download | only in windows
      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 <cassert>
     31 #include <vector>
     32 
     33 #include "common/windows/string_utils-inl.h"
     34 
     35 namespace google_breakpad {
     36 
     37 // static
     38 wstring WindowsStringUtils::GetBaseName(const wstring &filename) {
     39   wstring base_name(filename);
     40   size_t slash_pos = base_name.find_last_of(L"/\\");
     41   if (slash_pos != wstring::npos) {
     42     base_name.erase(0, slash_pos + 1);
     43   }
     44   return base_name;
     45 }
     46 
     47 // static
     48 bool WindowsStringUtils::safe_mbstowcs(const string &mbs, wstring *wcs) {
     49   assert(wcs);
     50 
     51   // First, determine the length of the destination buffer.
     52   size_t wcs_length;
     53 
     54 #if _MSC_VER >= 1400  // MSVC 2005/8
     55   errno_t err;
     56   if ((err = mbstowcs_s(&wcs_length, NULL, 0, mbs.c_str(), _TRUNCATE)) != 0) {
     57     return false;
     58   }
     59   assert(wcs_length > 0);
     60 #else  // _MSC_VER >= 1400
     61   if ((wcs_length = mbstowcs(NULL, mbs.c_str(), mbs.length())) == (size_t)-1) {
     62     return false;
     63   }
     64 
     65   // Leave space for the 0-terminator.
     66   ++wcs_length;
     67 #endif  // _MSC_VER >= 1400
     68 
     69   std::vector<wchar_t> wcs_v(wcs_length);
     70 
     71   // Now, convert.
     72 #if _MSC_VER >= 1400  // MSVC 2005/8
     73   if ((err = mbstowcs_s(NULL, &wcs_v[0], wcs_length, mbs.c_str(),
     74                         _TRUNCATE)) != 0) {
     75     return false;
     76   }
     77 #else  // _MSC_VER >= 1400
     78   if (mbstowcs(&wcs_v[0], mbs.c_str(), mbs.length()) == (size_t)-1) {
     79     return false;
     80   }
     81 
     82   // Ensure presence of 0-terminator.
     83   wcs_v[wcs_length - 1] = '\0';
     84 #endif  // _MSC_VER >= 1400
     85 
     86   *wcs = &wcs_v[0];
     87   return true;
     88 }
     89 
     90 // static
     91 bool WindowsStringUtils::safe_wcstombs(const wstring &wcs, string *mbs) {
     92   assert(mbs);
     93 
     94   // First, determine the length of the destination buffer.
     95   size_t mbs_length;
     96 
     97 #if _MSC_VER >= 1400  // MSVC 2005/8
     98   errno_t err;
     99   if ((err = wcstombs_s(&mbs_length, NULL, 0, wcs.c_str(), _TRUNCATE)) != 0) {
    100     return false;
    101   }
    102   assert(mbs_length > 0);
    103 #else  // _MSC_VER >= 1400
    104   if ((mbs_length = wcstombs(NULL, wcs.c_str(), wcs.length())) == (size_t)-1) {
    105     return false;
    106   }
    107 
    108   // Leave space for the 0-terminator.
    109   ++mbs_length;
    110 #endif  // _MSC_VER >= 1400
    111 
    112   std::vector<char> mbs_v(mbs_length);
    113 
    114   // Now, convert.
    115 #if _MSC_VER >= 1400  // MSVC 2005/8
    116   if ((err = wcstombs_s(NULL, &mbs_v[0], mbs_length, wcs.c_str(),
    117                         _TRUNCATE)) != 0) {
    118     return false;
    119   }
    120 #else  // _MSC_VER >= 1400
    121   if (wcstombs(&mbs_v[0], wcs.c_str(), wcs.length()) == (size_t)-1) {
    122     return false;
    123   }
    124 
    125   // Ensure presence of 0-terminator.
    126   mbs_v[mbs_length - 1] = '\0';
    127 #endif  // _MSC_VER >= 1400
    128 
    129   *mbs = &mbs_v[0];
    130   return true;
    131 }
    132 
    133 }  // namespace google_breakpad
    134