* Removed my custom String class, as well as removed the really old
Unicode ConvertUTF, the UTF Converter, and the UTF Encode/Decode
functions.
* Replaced the above with using standard C++ std::wstring_convert and
std::codecvt_utf8.
* Added headers adapted from llvm's libc++ project for allowing the
above C++ classes to exist with GCC and Clang when libc++ isn't being
used.
* Used std::string over std::wstring whenever possible.
* Added header adapted from llvm's libc++ project to create special
versions of the ifstream and ofstream classes that would utilize _wfopen
on non-MSVC Windows compilers, so those compilers could access files on
Windows that use characters outside the current codepage.
* Removed the -static-libgcc and -static-libstdc++ flags from the
Makefile for non-MSVC builds. The generated DLLs will require extra DLLs
from either Cygwin or MinGW (whichever is used to compile), I've only
tested with MinGW and for some reason they crash Winamp on exit, I have
no idea why.
| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,60 +0,0 @@ |
| 1 |
-// original code is from here: http://www.codeproject.com/Tips/197097/Converting-ANSI-to-Unicode-and-back |
|
| 2 |
-// License: The Code Project Open License (CPOL) http://www.codeproject.com/info/cpol10.aspx |
|
| 3 |
- |
|
| 4 |
-#pragma once |
|
| 5 |
- |
|
| 6 |
-#include <string> |
|
| 7 |
-#include <locale> |
|
| 8 |
-#include <sstream> |
|
| 9 |
-#include <stdexcept> |
|
| 10 |
- |
|
| 11 |
-std::string EncodeToUTF8(const std::string &, const std::locale & = std::locale::classic()); |
|
| 12 |
-std::string DecodeFromUTF8(const std::string &, const std::locale & = std::locale::classic()); |
|
| 13 |
- |
|
| 14 |
-template<size_t buf_size = 100> class cp_converter |
|
| 15 |
-{
|
|
| 16 |
- const std::locale loc; |
|
| 17 |
-public: |
|
| 18 |
- cp_converter(const std::locale &L = std::locale::classic()) : loc(L) { }
|
|
| 19 |
- std::wstring widen(const std::string &in) |
|
| 20 |
- {
|
|
| 21 |
- return this->convert<char, wchar_t>(in); |
|
| 22 |
- } |
|
| 23 |
- std::string narrow(const std::wstring &in) |
|
| 24 |
- {
|
|
| 25 |
- return this->convert<wchar_t, char>(in); |
|
| 26 |
- } |
|
| 27 |
-private: |
|
| 28 |
- typedef std::codecvt<wchar_t, char, mbstate_t> codecvt_facet; |
|
| 29 |
- |
|
| 30 |
- // widen |
|
| 31 |
- codecvt_facet::result cv(const codecvt_facet &facet, mbstate_t &s, const char *f1, const char *l1, const char *&n1, wchar_t *f2, wchar_t *l2, wchar_t *&n2) const |
|
| 32 |
- {
|
|
| 33 |
- return facet.in(s, f1, l1, n1, f2, l2, n2); |
|
| 34 |
- } |
|
| 35 |
- |
|
| 36 |
- // narrow |
|
| 37 |
- codecvt_facet::result cv(const codecvt_facet &facet, mbstate_t &s, const wchar_t *f1, const wchar_t *l1, const wchar_t *&n1, char *f2, char *l2, char *&n2) const |
|
| 38 |
- {
|
|
| 39 |
- return facet.out(s, f1, l1, n1, f2, l2, n2); |
|
| 40 |
- } |
|
| 41 |
- |
|
| 42 |
- template<class ct_in, class ct_out> std::basic_string<ct_out> convert(const std::basic_string<ct_in> &in) |
|
| 43 |
- {
|
|
| 44 |
- auto &facet = std::use_facet<codecvt_facet>(this->loc); |
|
| 45 |
- std::basic_stringstream<ct_out> os; |
|
| 46 |
- ct_out buf[buf_size]; |
|
| 47 |
- mbstate_t state = {0};
|
|
| 48 |
- codecvt_facet::result result; |
|
| 49 |
- const ct_in *ipc = &in[0]; |
|
| 50 |
- do |
|
| 51 |
- {
|
|
| 52 |
- ct_out *opc = nullptr; |
|
| 53 |
- result = this->cv(facet, state, ipc, &in[0] + in.length(), ipc, buf, buf + buf_size, opc); |
|
| 54 |
- os << std::basic_string<ct_out>(buf, opc - buf); |
|
| 55 |
- } while (ipc < &in[0] + in.length() && result != codecvt_facet::error); |
|
| 56 |
- if (result != codecvt_facet::ok) |
|
| 57 |
- throw std::runtime_error("result is not ok!");
|
|
| 58 |
- return os.str(); |
|
| 59 |
- } |
|
| 60 |
-}; |
| ... | ... |
@@ -1,8 +1,7 @@ |
| 1 | 1 |
// original code is from here: http://www.codeproject.com/Tips/197097/Converting-ANSI-to-Unicode-and-back |
| 2 | 2 |
// License: The Code Project Open License (CPOL) http://www.codeproject.com/info/cpol10.aspx |
| 3 | 3 |
|
| 4 |
-#ifndef UTFENCODEDECODE_H |
|
| 5 |
-#define UTFENCODEDECODE_H |
|
| 4 |
+#pragma once |
|
| 6 | 5 |
|
| 7 | 6 |
#include <string> |
| 8 | 7 |
#include <locale> |
| ... | ... |
@@ -59,5 +58,3 @@ private: |
| 59 | 58 |
return os.str(); |
| 60 | 59 |
} |
| 61 | 60 |
}; |
| 62 |
- |
|
| 63 |
-#endif |
| ... | ... |
@@ -17,11 +17,11 @@ template<size_t buf_size = 100> class cp_converter |
| 17 | 17 |
const std::locale loc; |
| 18 | 18 |
public: |
| 19 | 19 |
cp_converter(const std::locale &L = std::locale::classic()) : loc(L) { }
|
| 20 |
- inline std::wstring widen(const std::string &in) |
|
| 20 |
+ std::wstring widen(const std::string &in) |
|
| 21 | 21 |
{
|
| 22 | 22 |
return this->convert<char, wchar_t>(in); |
| 23 | 23 |
} |
| 24 |
- inline std::string narrow(const std::wstring &in) |
|
| 24 |
+ std::string narrow(const std::wstring &in) |
|
| 25 | 25 |
{
|
| 26 | 26 |
return this->convert<wchar_t, char>(in); |
| 27 | 27 |
} |
| ... | ... |
@@ -29,13 +29,13 @@ private: |
| 29 | 29 |
typedef std::codecvt<wchar_t, char, mbstate_t> codecvt_facet; |
| 30 | 30 |
|
| 31 | 31 |
// widen |
| 32 |
- inline codecvt_facet::result cv(const codecvt_facet &facet, mbstate_t &s, const char *f1, const char *l1, const char *&n1, wchar_t *f2, wchar_t *l2, wchar_t *&n2) const |
|
| 32 |
+ codecvt_facet::result cv(const codecvt_facet &facet, mbstate_t &s, const char *f1, const char *l1, const char *&n1, wchar_t *f2, wchar_t *l2, wchar_t *&n2) const |
|
| 33 | 33 |
{
|
| 34 | 34 |
return facet.in(s, f1, l1, n1, f2, l2, n2); |
| 35 | 35 |
} |
| 36 | 36 |
|
| 37 | 37 |
// narrow |
| 38 |
- inline codecvt_facet::result cv(const codecvt_facet &facet, mbstate_t &s, const wchar_t *f1, const wchar_t *l1, const wchar_t *&n1, char *f2, char *l2, char *&n2) const |
|
| 38 |
+ codecvt_facet::result cv(const codecvt_facet &facet, mbstate_t &s, const wchar_t *f1, const wchar_t *l1, const wchar_t *&n1, char *f2, char *l2, char *&n2) const |
|
| 39 | 39 |
{
|
| 40 | 40 |
return facet.out(s, f1, l1, n1, f2, l2, n2); |
| 41 | 41 |
} |
| ... | ... |
@@ -50,7 +50,7 @@ private: |
| 50 | 50 |
const ct_in *ipc = &in[0]; |
| 51 | 51 |
do |
| 52 | 52 |
{
|
| 53 |
- ct_out *opc = NULL; |
|
| 53 |
+ ct_out *opc = nullptr; |
|
| 54 | 54 |
result = this->cv(facet, state, ipc, &in[0] + in.length(), ipc, buf, buf + buf_size, opc); |
| 55 | 55 |
os << std::basic_string<ct_out>(buf, opc - buf); |
| 56 | 56 |
} while (ipc < &in[0] + in.length() && result != codecvt_facet::error); |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,63 @@ |
| 1 |
+// original code is from here: http://www.codeproject.com/Tips/197097/Converting-ANSI-to-Unicode-and-back |
|
| 2 |
+// License: The Code Project Open License (CPOL) http://www.codeproject.com/info/cpol10.aspx |
|
| 3 |
+ |
|
| 4 |
+#ifndef UTFENCODEDECODE_H |
|
| 5 |
+#define UTFENCODEDECODE_H |
|
| 6 |
+ |
|
| 7 |
+#include <string> |
|
| 8 |
+#include <locale> |
|
| 9 |
+#include <sstream> |
|
| 10 |
+#include <stdexcept> |
|
| 11 |
+ |
|
| 12 |
+std::string EncodeToUTF8(const std::string &, const std::locale & = std::locale::classic()); |
|
| 13 |
+std::string DecodeFromUTF8(const std::string &, const std::locale & = std::locale::classic()); |
|
| 14 |
+ |
|
| 15 |
+template<size_t buf_size = 100> class cp_converter |
|
| 16 |
+{
|
|
| 17 |
+ const std::locale loc; |
|
| 18 |
+public: |
|
| 19 |
+ cp_converter(const std::locale &L = std::locale::classic()) : loc(L) { }
|
|
| 20 |
+ inline std::wstring widen(const std::string &in) |
|
| 21 |
+ {
|
|
| 22 |
+ return this->convert<char, wchar_t>(in); |
|
| 23 |
+ } |
|
| 24 |
+ inline std::string narrow(const std::wstring &in) |
|
| 25 |
+ {
|
|
| 26 |
+ return this->convert<wchar_t, char>(in); |
|
| 27 |
+ } |
|
| 28 |
+private: |
|
| 29 |
+ typedef std::codecvt<wchar_t, char, mbstate_t> codecvt_facet; |
|
| 30 |
+ |
|
| 31 |
+ // widen |
|
| 32 |
+ inline codecvt_facet::result cv(const codecvt_facet &facet, mbstate_t &s, const char *f1, const char *l1, const char *&n1, wchar_t *f2, wchar_t *l2, wchar_t *&n2) const |
|
| 33 |
+ {
|
|
| 34 |
+ return facet.in(s, f1, l1, n1, f2, l2, n2); |
|
| 35 |
+ } |
|
| 36 |
+ |
|
| 37 |
+ // narrow |
|
| 38 |
+ inline codecvt_facet::result cv(const codecvt_facet &facet, mbstate_t &s, const wchar_t *f1, const wchar_t *l1, const wchar_t *&n1, char *f2, char *l2, char *&n2) const |
|
| 39 |
+ {
|
|
| 40 |
+ return facet.out(s, f1, l1, n1, f2, l2, n2); |
|
| 41 |
+ } |
|
| 42 |
+ |
|
| 43 |
+ template<class ct_in, class ct_out> std::basic_string<ct_out> convert(const std::basic_string<ct_in> &in) |
|
| 44 |
+ {
|
|
| 45 |
+ auto &facet = std::use_facet<codecvt_facet>(this->loc); |
|
| 46 |
+ std::basic_stringstream<ct_out> os; |
|
| 47 |
+ ct_out buf[buf_size]; |
|
| 48 |
+ mbstate_t state = {0};
|
|
| 49 |
+ codecvt_facet::result result; |
|
| 50 |
+ const ct_in *ipc = &in[0]; |
|
| 51 |
+ do |
|
| 52 |
+ {
|
|
| 53 |
+ ct_out *opc = NULL; |
|
| 54 |
+ result = this->cv(facet, state, ipc, &in[0] + in.length(), ipc, buf, buf + buf_size, opc); |
|
| 55 |
+ os << std::basic_string<ct_out>(buf, opc - buf); |
|
| 56 |
+ } while (ipc < &in[0] + in.length() && result != codecvt_facet::error); |
|
| 57 |
+ if (result != codecvt_facet::ok) |
|
| 58 |
+ throw std::runtime_error("result is not ok!");
|
|
| 59 |
+ return os.str(); |
|
| 60 |
+ } |
|
| 61 |
+}; |
|
| 62 |
+ |
|
| 63 |
+#endif |