EncodingCXX.cxx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing#kwsys for details. */
  3. #ifdef __osf__
  4. #define _OSF_SOURCE
  5. #define _POSIX_C_SOURCE 199506L
  6. #define _XOPEN_SOURCE_EXTENDED
  7. #endif
  8. #include "kwsysPrivate.h"
  9. #include KWSYS_HEADER(Encoding.hxx)
  10. #include KWSYS_HEADER(Encoding.h)
  11. // Work-around CMake dependency scanning limitation. This must
  12. // duplicate the above list of headers.
  13. #if 0
  14. #include "Encoding.h.in"
  15. #include "Encoding.hxx.in"
  16. #endif
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <vector>
  20. #ifdef _MSC_VER
  21. #pragma warning(disable : 4786)
  22. #endif
  23. // Windows API.
  24. #if defined(_WIN32)
  25. #include <windows.h>
  26. #include <shellapi.h>
  27. #endif
  28. namespace KWSYS_NAMESPACE {
  29. Encoding::CommandLineArguments Encoding::CommandLineArguments::Main(
  30. int argc, char const* const* argv)
  31. {
  32. #ifdef _WIN32
  33. (void)argc;
  34. (void)argv;
  35. int ac;
  36. LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &ac);
  37. std::vector<std::string> av1(ac);
  38. std::vector<char const*> av2(ac);
  39. for (int i = 0; i < ac; i++) {
  40. av1[i] = ToNarrow(w_av[i]);
  41. av2[i] = av1[i].c_str();
  42. }
  43. LocalFree(w_av);
  44. return CommandLineArguments(ac, &av2[0]);
  45. #else
  46. return CommandLineArguments(argc, argv);
  47. #endif
  48. }
  49. Encoding::CommandLineArguments::CommandLineArguments(int ac,
  50. char const* const* av)
  51. {
  52. this->argv_.resize(ac + 1);
  53. for (int i = 0; i < ac; i++) {
  54. this->argv_[i] = strdup(av[i]);
  55. }
  56. this->argv_[ac] = 0;
  57. }
  58. Encoding::CommandLineArguments::CommandLineArguments(int ac,
  59. wchar_t const* const* av)
  60. {
  61. this->argv_.resize(ac + 1);
  62. for (int i = 0; i < ac; i++) {
  63. this->argv_[i] = kwsysEncoding_DupToNarrow(av[i]);
  64. }
  65. this->argv_[ac] = 0;
  66. }
  67. Encoding::CommandLineArguments::~CommandLineArguments()
  68. {
  69. for (size_t i = 0; i < this->argv_.size(); i++) {
  70. free(argv_[i]);
  71. }
  72. }
  73. Encoding::CommandLineArguments::CommandLineArguments(
  74. const CommandLineArguments& other)
  75. {
  76. this->argv_.resize(other.argv_.size());
  77. for (size_t i = 0; i < this->argv_.size(); i++) {
  78. this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : 0;
  79. }
  80. }
  81. Encoding::CommandLineArguments& Encoding::CommandLineArguments::operator=(
  82. const CommandLineArguments& other)
  83. {
  84. if (this != &other) {
  85. size_t i;
  86. for (i = 0; i < this->argv_.size(); i++) {
  87. free(this->argv_[i]);
  88. }
  89. this->argv_.resize(other.argv_.size());
  90. for (i = 0; i < this->argv_.size(); i++) {
  91. this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : 0;
  92. }
  93. }
  94. return *this;
  95. }
  96. int Encoding::CommandLineArguments::argc() const
  97. {
  98. return static_cast<int>(this->argv_.size() - 1);
  99. }
  100. char const* const* Encoding::CommandLineArguments::argv() const
  101. {
  102. return &this->argv_[0];
  103. }
  104. #if KWSYS_STL_HAS_WSTRING
  105. std::wstring Encoding::ToWide(const std::string& str)
  106. {
  107. std::wstring wstr;
  108. #if defined(_WIN32)
  109. const int wlength = MultiByteToWideChar(
  110. KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(), int(str.size()), NULL, 0);
  111. if (wlength > 0) {
  112. wchar_t* wdata = new wchar_t[wlength];
  113. int r = MultiByteToWideChar(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.data(),
  114. int(str.size()), wdata, wlength);
  115. if (r > 0) {
  116. wstr = std::wstring(wdata, wlength);
  117. }
  118. delete[] wdata;
  119. }
  120. #else
  121. size_t pos = 0;
  122. size_t nullPos = 0;
  123. do {
  124. if (pos < str.size() && str.at(pos) != '\0') {
  125. wstr += ToWide(str.c_str() + pos);
  126. }
  127. nullPos = str.find('\0', pos);
  128. if (nullPos != str.npos) {
  129. pos = nullPos + 1;
  130. wstr += wchar_t('\0');
  131. }
  132. } while (nullPos != str.npos);
  133. #endif
  134. return wstr;
  135. }
  136. std::string Encoding::ToNarrow(const std::wstring& str)
  137. {
  138. std::string nstr;
  139. #if defined(_WIN32)
  140. int length =
  141. WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(),
  142. int(str.size()), NULL, 0, NULL, NULL);
  143. if (length > 0) {
  144. char* data = new char[length];
  145. int r =
  146. WideCharToMultiByte(KWSYS_ENCODING_DEFAULT_CODEPAGE, 0, str.c_str(),
  147. int(str.size()), data, length, NULL, NULL);
  148. if (r > 0) {
  149. nstr = std::string(data, length);
  150. }
  151. delete[] data;
  152. }
  153. #else
  154. size_t pos = 0;
  155. size_t nullPos = 0;
  156. do {
  157. if (pos < str.size() && str.at(pos) != '\0') {
  158. nstr += ToNarrow(str.c_str() + pos);
  159. }
  160. nullPos = str.find(wchar_t('\0'), pos);
  161. if (nullPos != str.npos) {
  162. pos = nullPos + 1;
  163. nstr += '\0';
  164. }
  165. } while (nullPos != str.npos);
  166. #endif
  167. return nstr;
  168. }
  169. std::wstring Encoding::ToWide(const char* cstr)
  170. {
  171. std::wstring wstr;
  172. size_t length = kwsysEncoding_mbstowcs(0, cstr, 0) + 1;
  173. if (length > 0) {
  174. std::vector<wchar_t> wchars(length);
  175. if (kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0) {
  176. wstr = &wchars[0];
  177. }
  178. }
  179. return wstr;
  180. }
  181. std::string Encoding::ToNarrow(const wchar_t* wcstr)
  182. {
  183. std::string str;
  184. size_t length = kwsysEncoding_wcstombs(0, wcstr, 0) + 1;
  185. if (length > 0) {
  186. std::vector<char> chars(length);
  187. if (kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0) {
  188. str = &chars[0];
  189. }
  190. }
  191. return str;
  192. }
  193. #endif // KWSYS_STL_HAS_WSTRING
  194. } // namespace KWSYS_NAMESPACE