| 226 | |
| 227 | template<typename decoder_t, typename encoder_t, typename char_t = char, typename orgchar_t> |
| 228 | void Convert(const orgchar_t* nullTerminatedString, std::basic_string<char_t>& ret) |
| 229 | { |
| 230 | decoder_t decoder; |
| 231 | encoder_t encoder; |
| 232 | |
| 233 | ret.clear(); |
| 234 | char32_t ucs4; |
| 235 | bool de_finished = true; |
| 236 | uint8_t* buf; |
| 237 | size_t size = 0; |
| 238 | bool en_finished = true; |
| 239 | |
| 240 | const char* p = (const char*)nullTerminatedString; |
| 241 | while (*nullTerminatedString != 0) |
| 242 | { |
| 243 | if (decoder(*p, ucs4)) |
| 244 | { |
| 245 | de_finished = true; |
| 246 | if (encoder(ucs4, buf, size)) |
| 247 | { |
| 248 | en_finished = true; |
| 249 | |
| 250 | if (buf) |
| 251 | { |
| 252 | if (size % sizeof(char_t) != 0) |
| 253 | ret.push_back((char_t)'?'); |
| 254 | else |
| 255 | ret.append(reinterpret_cast<char_t*>(buf), size / sizeof(char_t)); |
| 256 | } |
| 257 | } |
| 258 | else |
| 259 | en_finished = false; |
| 260 | } |
| 261 | else |
| 262 | de_finished = false; |
| 263 | |
| 264 | ++p; |
| 265 | if ((size_t)p - (size_t)nullTerminatedString == sizeof(orgchar_t)) |
| 266 | ++nullTerminatedString; |
| 267 | } |
| 268 | |
| 269 | if (!de_finished) |
| 270 | ret.push_back((char_t)'?'); |
| 271 | else if (!en_finished) |
| 272 | ret.push_back((char_t)'?'); |
| 273 | } |
| 274 | |
| 275 | std::wstring LuaSTGPlus::Utf8ToUtf16(const char* p) |
| 276 | { |
nothing calls this directly
no outgoing calls
no test coverage detected