string_utils.cc
1 // Copyright 2006 Google LLC 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google LLC nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #ifdef HAVE_CONFIG_H 30 #include <config.h> // Must come first 31 #endif 32 33 #include <cassert> 34 #include <vector> 35 36 #include "common/windows/string_utils-inl.h" 37 38 namespace google_breakpad { 39 40 // static 41 wstring WindowsStringUtils::GetBaseName(const wstring& filename) { 42 wstring base_name(filename); 43 size_t slash_pos = base_name.find_last_of(L"/\\"); 44 if (slash_pos != wstring::npos) { 45 base_name.erase(0, slash_pos + 1); 46 } 47 return base_name; 48 } 49 50 // static 51 bool WindowsStringUtils::safe_mbstowcs(const string& mbs, wstring* wcs) { 52 assert(wcs); 53 54 // First, determine the length of the destination buffer. 55 size_t wcs_length; 56 57 #if _MSC_VER >= 1400 // MSVC 2005/8 58 errno_t err; 59 if ((err = mbstowcs_s(&wcs_length, NULL, 0, mbs.c_str(), _TRUNCATE)) != 0) { 60 return false; 61 } 62 assert(wcs_length > 0); 63 #else // _MSC_VER >= 1400 64 if ((wcs_length = mbstowcs(NULL, mbs.c_str(), mbs.length())) == (size_t)-1) { 65 return false; 66 } 67 68 // Leave space for the 0-terminator. 69 ++wcs_length; 70 #endif // _MSC_VER >= 1400 71 72 std::vector<wchar_t> wcs_v(wcs_length); 73 74 // Now, convert. 75 #if _MSC_VER >= 1400 // MSVC 2005/8 76 if ((err = mbstowcs_s(NULL, &wcs_v[0], wcs_length, mbs.c_str(), 77 _TRUNCATE)) != 0) { 78 return false; 79 } 80 #else // _MSC_VER >= 1400 81 if (mbstowcs(&wcs_v[0], mbs.c_str(), mbs.length()) == (size_t)-1) { 82 return false; 83 } 84 85 // Ensure presence of 0-terminator. 86 wcs_v[wcs_length - 1] = '\0'; 87 #endif // _MSC_VER >= 1400 88 89 *wcs = &wcs_v[0]; 90 return true; 91 } 92 93 // static 94 bool WindowsStringUtils::safe_wcstombs(const wstring& wcs, string* mbs) { 95 assert(mbs); 96 97 // First, determine the length of the destination buffer. 98 size_t mbs_length; 99 100 #if _MSC_VER >= 1400 // MSVC 2005/8 101 errno_t err; 102 if ((err = wcstombs_s(&mbs_length, NULL, 0, wcs.c_str(), _TRUNCATE)) != 0) { 103 return false; 104 } 105 assert(mbs_length > 0); 106 #else // _MSC_VER >= 1400 107 if ((mbs_length = wcstombs(NULL, wcs.c_str(), wcs.length())) == (size_t)-1) { 108 return false; 109 } 110 111 // Leave space for the 0-terminator. 112 ++mbs_length; 113 #endif // _MSC_VER >= 1400 114 115 std::vector<char> mbs_v(mbs_length); 116 117 // Now, convert. 118 #if _MSC_VER >= 1400 // MSVC 2005/8 119 if ((err = wcstombs_s(NULL, &mbs_v[0], mbs_length, wcs.c_str(), 120 _TRUNCATE)) != 0) { 121 return false; 122 } 123 #else // _MSC_VER >= 1400 124 if (wcstombs(&mbs_v[0], wcs.c_str(), wcs.length()) == (size_t)-1) { 125 return false; 126 } 127 128 // Ensure presence of 0-terminator. 129 mbs_v[mbs_length - 1] = '\0'; 130 #endif // _MSC_VER >= 1400 131 132 *mbs = &mbs_v[0]; 133 return true; 134 } 135 136 } // namespace google_breakpad