Consolix
Loading...
Searching...
No Matches
encoding_utils.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _CONSOLIX_ENCODING_UTILS_HPP_INCLUDED
3#define _CONSOLIX_ENCODING_UTILS_HPP_INCLUDED
4
8
9#if defined(_WIN32)
10
11#include <string>
12
13namespace consolix {
14
18 inline std::string utf8_to_ansi(const std::string& utf8) noexcept {
19 const int wide_length = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, nullptr, 0);
20 if (wide_length <= 0) return {};
21
22 std::wstring wide_string(static_cast<std::size_t>(wide_length), L'\0');
23 MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, &wide_string[0], wide_length);
24
25 const int ansi_length = WideCharToMultiByte(CP_ACP, 0, wide_string.c_str(), -1, nullptr, 0, nullptr, nullptr);
26 if (ansi_length <= 0) return {};
27
28 std::string ansi_string(static_cast<std::size_t>(ansi_length), '\0');
29 WideCharToMultiByte(CP_ACP, 0, wide_string.c_str(), -1, &ansi_string[0], ansi_length, nullptr, nullptr);
30 if (!ansi_string.empty()) {
31 ansi_string.pop_back();
32 }
33
34 return ansi_string;
35 }
36
40 inline std::string ansi_to_utf8(const std::string& ansi) noexcept {
41 const int wide_length = MultiByteToWideChar(CP_ACP, 0, ansi.c_str(), -1, nullptr, 0);
42 if (wide_length <= 0) return {};
43
44 std::wstring wide_string(static_cast<std::size_t>(wide_length), L'\0');
45 MultiByteToWideChar(CP_ACP, 0, ansi.c_str(), -1, &wide_string[0], wide_length);
46
47 const int utf8_length = WideCharToMultiByte(CP_UTF8, 0, wide_string.c_str(), -1, nullptr, 0, nullptr, nullptr);
48 if (utf8_length <= 0) return {};
49
50 std::string utf8_string(static_cast<std::size_t>(utf8_length), '\0');
51 WideCharToMultiByte(CP_UTF8, 0, wide_string.c_str(), -1, &utf8_string[0], utf8_length, nullptr, nullptr);
52 if (!utf8_string.empty()) {
53 utf8_string.pop_back();
54 }
55
56 return utf8_string;
57 }
58
62 inline std::string utf8_to_cp866(const std::string& utf8) noexcept {
63 std::string temp = utf8_to_ansi(utf8);
64 if (!temp.empty()) {
65 CharToOemA(temp.c_str(), &temp[0]);
66 }
67 return temp;
68 }
69
73 inline bool is_valid_utf8(const char* message) {
74 if (!message) return true;
75
76 const unsigned char* bytes = reinterpret_cast<const unsigned char*>(message);
77 while (*bytes != 0x00) {
78 int num = 0;
79 unsigned int cp = 0;
80 if ((*bytes & 0x80) == 0x00) { cp = (*bytes & 0x7F); num = 1; }
81 else if ((*bytes & 0xE0) == 0xC0) { cp = (*bytes & 0x1F); num = 2; }
82 else if ((*bytes & 0xF0) == 0xE0) { cp = (*bytes & 0x0F); num = 3; }
83 else if ((*bytes & 0xF8) == 0xF0) { cp = (*bytes & 0x07); num = 4; }
84 else return false;
85
86 ++bytes;
87 for (int i = 1; i < num; ++i) {
88 if ((*bytes & 0xC0) != 0x80) return false;
89 cp = (cp << 6) | (*bytes & 0x3F);
90 ++bytes;
91 }
92
93 if (cp > 0x10FFFF || (cp >= 0xD800 && cp <= 0xDFFF)) return false;
94 }
95
96 return true;
97 }
98
102 inline std::string cp1251_to_utf8(const std::string& cp1251_string) {
103 const int wide_length = MultiByteToWideChar(1251, 0, cp1251_string.c_str(), -1, nullptr, 0);
104 if (wide_length <= 0) return {};
105
106 std::wstring wide_string(static_cast<std::size_t>(wide_length), L'\0');
107 MultiByteToWideChar(1251, 0, cp1251_string.c_str(), -1, &wide_string[0], wide_length);
108
109 const int utf8_length = WideCharToMultiByte(CP_UTF8, 0, wide_string.c_str(), -1, nullptr, 0, nullptr, nullptr);
110 if (utf8_length <= 0) return {};
111
112 std::string utf8_string(static_cast<std::size_t>(utf8_length), '\0');
113 WideCharToMultiByte(CP_UTF8, 0, wide_string.c_str(), -1, &utf8_string[0], utf8_length, nullptr, nullptr);
114 if (!utf8_string.empty()) {
115 utf8_string.pop_back();
116 }
117
118 return utf8_string;
119 }
120
124 inline std::string utf16_to_utf8(const wchar_t* utf16_string) {
125 const int buffer_size = WideCharToMultiByte(CP_UTF8, 0, utf16_string, -1, nullptr, 0, nullptr, nullptr);
126 if (buffer_size <= 0) return {};
127
128 std::string utf8_string(static_cast<std::size_t>(buffer_size), '\0');
129 WideCharToMultiByte(CP_UTF8, 0, utf16_string, -1, &utf8_string[0], buffer_size, nullptr, nullptr);
130 if (!utf8_string.empty()) {
131 utf8_string.pop_back();
132 }
133 return utf8_string;
134 }
135
139 inline std::wstring utf8_to_utf16(const std::string& utf8) noexcept {
140 const int utf16_length = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, nullptr, 0);
141 if (utf16_length <= 0) return {};
142
143 std::wstring utf16_string(static_cast<std::size_t>(utf16_length), L'\0');
144 MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, &utf16_string[0], utf16_length);
145 if (!utf16_string.empty()) {
146 utf16_string.pop_back();
147 }
148
149 return utf16_string;
150 }
151
152} // namespace consolix
153
154#endif
155
156#endif // _CONSOLIX_ENCODING_UTILS_HPP_INCLUDED
< Utility modules and helpers.