Silicium
os_string.hpp
Go to the documentation of this file.
1 #ifndef SILICIUM_OS_STRING_HPP
2 #define SILICIUM_OS_STRING_HPP
3 
6 #ifdef _WIN32
7 # include <silicium/win32/win32.hpp>
8 #endif
9 #include <string>
10 
11 namespace Si
12 {
13  typedef
14 #ifdef _WIN32
15  wchar_t
16 #else
17  char
18 #endif
20 
21 #ifdef _WIN32
22  typedef std::basic_string<os_char> os_string;
23  namespace win32
24  {
25  typedef os_string winapi_string;
26  }
27 #else
29 #endif
30 
31  inline os_string to_os_string(os_string original)
32  {
33  return original;
34  }
35 
36 #ifndef _WIN32
37  inline os_string to_os_string(std::string const &original)
38  {
39  return os_string(original.begin(), original.end());
40  }
41 
42  inline os_string to_os_string(char const *original)
43  {
44  return original;
45  }
46 
47  inline os_string to_os_string(char const *begin, char const *end)
48  {
49  return os_string(begin, end);
50  }
51 #endif
52 
53 #ifdef _WIN32
54  namespace win32
55  {
56  inline winapi_string utf8_to_winapi_string(char const *original, size_t length)
57  {
58  if (length > static_cast<size_t>((std::numeric_limits<int>::max)()))
59  {
60  throw std::invalid_argument("Input string is too long for WinAPI");
61  }
62  int const output_size = MultiByteToWideChar(CP_UTF8, 0, original, static_cast<int>(length), nullptr, 0);
63  assert(output_size >= 0);
64  if (output_size == 0)
65  {
66  assert(GetLastError() == ERROR_NO_UNICODE_TRANSLATION);
67  throw std::invalid_argument("Input string is not UTF-8");
68  }
69  winapi_string result;
70  result.resize(static_cast<size_t>(output_size));
71  if (!result.empty())
72  {
73  MultiByteToWideChar(CP_UTF8, 0, original, static_cast<int>(length), &result[0], output_size);
74  }
75  return result;
76  }
77  }
78 
79  inline os_string to_os_string(char const *c_str)
80  {
81  return win32::utf8_to_winapi_string(c_str, std::strlen(c_str));
82  }
83 
84  inline os_string to_os_string(noexcept_string const &original)
85  {
86  return win32::utf8_to_winapi_string(original.data(), original.size());
87  }
88 
89  inline os_string to_os_string(char const *begin, char const *end)
90  {
91  return win32::utf8_to_winapi_string(begin, end - begin);
92  }
93 
94  inline std::string to_utf8_string(os_string const &str)
95  {
96  if (str.empty())
97  {
98  //because WideCharToMultiByte fails for empty input
99  return {};
100  }
101  if (str.length() > static_cast<size_t>((std::numeric_limits<int>::max)()))
102  {
103  throw std::invalid_argument("Input string is too long for WinAPI");
104  }
105  int destination_length = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), nullptr, 0, 0, FALSE);
106  if (!destination_length)
107  {
109  }
110  std::string result;
111  result.resize(destination_length);
112  if (!WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), &result.front(), destination_length, 0, FALSE))
113  {
115  }
116  return result;
117  }
118 #else
119  inline std::string to_utf8_string(os_string const &str)
120  {
121  return std::string(str.begin(), str.end());
122  }
123 #endif
124 }
125 
126 #endif
os_string to_os_string(os_string original)
Definition: os_string.hpp:31
Definition: absolute_path.hpp:19
BOOST_CONSTEXPR Iterator const & end(iterator_range< Iterator > const &range)
Definition: iterator_range.hpp:136
boost::container::string noexcept_string
Definition: noexcept_string.hpp:26
void throw_last_error()
Definition: throw_last_error.hpp:13
char os_char
Definition: os_string.hpp:19
BOOST_CONSTEXPR Iterator const & begin(iterator_range< Iterator > const &range)
Definition: iterator_range.hpp:123
std::string to_utf8_string(os_string const &str)
Definition: os_string.hpp:119
noexcept_string os_string
Definition: os_string.hpp:28