Browse code

Lots of changes in regards to strings, as follows:

* 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.

Naram Qashat authored on 2014/09/24 13:58:55
Showing 34 changed files
... ...
@@ -20,18 +20,12 @@ DLLS:=	$(sort $(addsuffix .dll,$(DLLS)))
20 20
 COMPILER:=	$(shell $(CXX) -v 2>/dev/stdout)
21 21
 
22 22
 CPPFLAGS+=	-std=gnu++11 -I$(SRCDIR)in_xsf_framework -I/g/Code/Winamp\ SDK -DWINAMP_PLUGIN -DUNICODE_INPUT_PLUGIN
23
-CXXFLAGS+=	-std=gnu++11 -pipe -Wall -Wctor-dtor-privacy -Wold-style-cast -Wextra -Wno-div-by-zero -Wfloat-equal -Wshadow -Winit-self -Wcast-qual -Wunreachable-code -Wabi -Woverloaded-virtual -Wno-long-long -I$(SRCDIR)in_xsf_framework -I/g/Code/Winamp\ SDK -DWINAMP_PLUGIN -DUNICODE_INPUT_PLUGIN
23
+CXXFLAGS+=	-std=gnu++11 -pipe -Wall -Wctor-dtor-privacy -Wold-style-cast -Wextra -Wno-div-by-zero -Wfloat-equal -Wshadow -Winit-self -Wcast-qual -Wunreachable-code -Wabi -Woverloaded-virtual -Wno-long-long -Wno-switch -I$(SRCDIR)in_xsf_framework -I/g/Code/Winamp\ SDK -DWINAMP_PLUGIN -DUNICODE_INPUT_PLUGIN
24 24
 ifeq (,$(findstring clang,$(COMPILER)))
25 25
 CXXFLAGS+=	-Wlogical-op
26 26
 endif
27 27
 LDFLAGS+=	-lz
28 28
 
29
-ifneq (,$(findstring MINGW,$(UNAME)))
30
-ifeq (,$(findstring clang,$(COMPILER)))
31
-LDFLAGS+=	-static-libgcc -static-libstdc++
32
-endif
33
-endif
34
-
35 29
 DLL_SRCS_template=	$(1)_SRCS:=	$$(sort $$($(1)_SRCS))
36 30
 DLL_OBJS_template=	$(1)_OBJS:=	$$(subst $(SRCDIR),,$$($(1)_SRCS:%.cpp=%.o))
37 31
 
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - 2SF configuration
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -10,7 +10,6 @@
10 10
 #include "XSFPlayer.h"
11 11
 #include "XSFConfig.h"
12 12
 #include "convert.h"
13
-#include "BigSString.h"
14 13
 #include "desmume/NDSSystem.h"
15 14
 #include "desmume/version.h"
16 15
 
... ...
@@ -24,7 +23,7 @@ class XSFConfig_2SF : public XSFConfig
24 23
 {
25 24
 protected:
26 25
 	static unsigned initInterpolation;
27
-	static std::wstring initMutes;
26
+	static std::string initMutes;
28 27
 
29 28
 	friend class XSFConfig;
30 29
 	unsigned interpolation;
... ...
@@ -43,10 +42,10 @@ public:
43 42
 };
44 43
 
45 44
 unsigned XSFConfig::initSampleRate = 44100;
46
-std::wstring XSFConfig::commonName = L"2SF Decoder";
47
-std::wstring XSFConfig::versionNumber = L"0.9b";
45
+std::string XSFConfig::commonName = "2SF Decoder";
46
+std::string XSFConfig::versionNumber = "0.9b";
48 47
 unsigned XSFConfig_2SF::initInterpolation = 2;
49
-std::wstring XSFConfig_2SF::initMutes = L"0000000000000000";
48
+std::string XSFConfig_2SF::initMutes = "0000000000000000";
50 49
 
51 50
 XSFConfig *XSFConfig::Create()
52 51
 {
... ...
@@ -60,15 +59,15 @@ XSFConfig_2SF::XSFConfig_2SF() : XSFConfig(), interpolation(0), mutes()
60 59
 
61 60
 void XSFConfig_2SF::LoadSpecificConfig()
62 61
 {
63
-	this->interpolation = this->configIO->GetValue(L"Interpolation", XSFConfig_2SF::initInterpolation);
64
-	std::wstringstream mutesSS(this->configIO->GetValue(L"Mutes", XSFConfig_2SF::initMutes));
62
+	this->interpolation = this->configIO->GetValue("Interpolation", XSFConfig_2SF::initInterpolation);
63
+	std::stringstream mutesSS(this->configIO->GetValue("Mutes", XSFConfig_2SF::initMutes));
65 64
 	mutesSS >> this->mutes;
66 65
 }
67 66
 
68 67
 void XSFConfig_2SF::SaveSpecificConfig()
69 68
 {
70
-	this->configIO->SetValue(L"Interpolation", this->interpolation);
71
-	this->configIO->SetValue(L"Mutes", this->mutes.to_string<wchar_t>());
69
+	this->configIO->SetValue("Interpolation", this->interpolation);
70
+	this->configIO->SetValue("Mutes", this->mutes.to_string<char>());
72 71
 }
73 72
 
74 73
 void XSFConfig_2SF::GenerateSpecificDialogs()
... ...
@@ -132,6 +131,6 @@ void XSFConfig_2SF::CopySpecificConfigToMemory(XSFPlayer *, bool preLoad)
132 131
 
133 132
 void XSFConfig_2SF::About(HWND parent)
134 133
 {
135
-	MessageBoxW(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
136
-		L"Utilizes modified " + String(EMU_DESMUME_NAME_AND_VERSION()).GetWStr() + L" for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK);
134
+	MessageBoxW(parent, ConvertFuncs::StringToWString(XSFConfig::commonName + " v" + XSFConfig::versionNumber + ", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
135
+		"Utilizes modified " + EMU_DESMUME_NAME_AND_VERSION() + " for audio playback.").c_str(), ConvertFuncs::StringToWString(XSFConfig::commonName + " v" + XSFConfig::versionNumber).c_str(), MB_OK);
137 136
 }
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - 2SF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Based on a modified vio2sf v0.22c
7 7
  *
... ...
@@ -28,7 +28,7 @@ class XSFPlayer_2SF : public XSFPlayer
28 28
 	bool Load2SF(XSFFile *xSFToLoad);
29 29
 public:
30 30
 	XSFPlayer_2SF(const std::string &filename);
31
-#ifdef _MSC_VER
31
+#ifdef _WIN32
32 32
 	XSFPlayer_2SF(const std::wstring &filename);
33 33
 #endif
34 34
 	~XSFPlayer_2SF() { this->Terminate(); }
... ...
@@ -45,7 +45,7 @@ XSFPlayer *XSFPlayer::Create(const std::string &fn)
45 45
 	return new XSFPlayer_2SF(fn);
46 46
 }
47 47
 
48
-#ifdef _MSC_VER
48
+#ifdef _WIN32
49 49
 XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
50 50
 {
51 51
 	return new XSFPlayer_2SF(fn);
... ...
@@ -146,10 +146,10 @@ bool XSFPlayer_2SF::RecursiveLoad2SF(XSFFile *xSFToLoad, int level)
146 146
 {
147 147
 	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
148 148
 	{
149
-#ifdef _MSC_VER
150
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue("_lib").GetWStr(), 4, 8));
149
+#ifdef _WIN32
150
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib")), 4, 8));
151 151
 #else
152
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue("_lib").GetAnsi(), 4, 8));
152
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib"), 4, 8));
153 153
 #endif
154 154
 		if (!this->RecursiveLoad2SF(libxSF.get(), level + 1))
155 155
 			return false;
... ...
@@ -167,10 +167,10 @@ bool XSFPlayer_2SF::RecursiveLoad2SF(XSFFile *xSFToLoad, int level)
167 167
 		if (xSFToLoad->GetTagExists(libTag))
168 168
 		{
169 169
 			found = true;
170
-#ifdef _MSC_VER
171
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue(libTag).GetWStr(), 4, 8));
170
+#ifdef _WIN32
171
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag)), 4, 8));
172 172
 #else
173
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue(libTag).GetAnsi(), 4, 8));
173
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag), 4, 8));
174 174
 #endif
175 175
 			if (!this->RecursiveLoad2SF(libxSF.get(), level + 1))
176 176
 				return false;
... ...
@@ -192,7 +192,7 @@ XSFPlayer_2SF::XSFPlayer_2SF(const std::string &filename) : XSFPlayer()
192 192
 	this->xSF.reset(new XSFFile(filename, 4, 8));
193 193
 }
194 194
 
195
-#ifdef _MSC_VER
195
+#ifdef _WIN32
196 196
 XSFPlayer_2SF::XSFPlayer_2SF(const std::wstring &filename) : XSFPlayer()
197 197
 {
198 198
 	this->xSF.reset(new XSFFile(filename, 4, 8));
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - GSF configuration
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -10,7 +10,6 @@
10 10
 #include "XSFPlayer.h"
11 11
 #include "XSFConfig.h"
12 12
 #include "convert.h"
13
-#include "BigSString.h"
14 13
 #include "vbam/gba/Sound.h"
15 14
 
16 15
 enum
... ...
@@ -23,7 +22,7 @@ class XSFConfig_GSF : public XSFConfig
23 22
 {
24 23
 protected:
25 24
 	static bool initLowPassFiltering;
26
-	static std::wstring initMutes;
25
+	static std::string initMutes;
27 26
 
28 27
 	friend class XSFConfig;
29 28
 	bool lowPassFiltering;
... ...
@@ -42,10 +41,10 @@ public:
42 41
 };
43 42
 
44 43
 unsigned XSFConfig::initSampleRate = 44100;
45
-std::wstring XSFConfig::commonName = L"GSF Decoder";
46
-std::wstring XSFConfig::versionNumber = L"0.9b";
44
+std::string XSFConfig::commonName = "GSF Decoder";
45
+std::string XSFConfig::versionNumber = "0.9b";
47 46
 bool XSFConfig_GSF::initLowPassFiltering = true;
48
-std::wstring XSFConfig_GSF::initMutes = L"000000";
47
+std::string XSFConfig_GSF::initMutes = "000000";
49 48
 
50 49
 XSFConfig *XSFConfig::Create()
51 50
 {
... ...
@@ -69,15 +68,15 @@ XSFConfig_GSF::XSFConfig_GSF() : XSFConfig(), lowPassFiltering(false), mutes()
69 68
 
70 69
 void XSFConfig_GSF::LoadSpecificConfig()
71 70
 {
72
-	this->lowPassFiltering = this->configIO->GetValue(L"LowPassFiltering", XSFConfig_GSF::initLowPassFiltering);
73
-	std::wstringstream mutesSS(this->configIO->GetValue(L"Mutes", XSFConfig_GSF::initMutes));
71
+	this->lowPassFiltering = this->configIO->GetValue("LowPassFiltering", XSFConfig_GSF::initLowPassFiltering);
72
+	std::stringstream mutesSS(this->configIO->GetValue("Mutes", XSFConfig_GSF::initMutes));
74 73
 	mutesSS >> this->mutes;
75 74
 }
76 75
 
77 76
 void XSFConfig_GSF::SaveSpecificConfig()
78 77
 {
79
-	this->configIO->SetValue(L"LowPassFiltering", this->lowPassFiltering);
80
-	this->configIO->SetValue(L"Mutes", this->mutes.to_string<wchar_t>());
78
+	this->configIO->SetValue("LowPassFiltering", this->lowPassFiltering);
79
+	this->configIO->SetValue("Mutes", this->mutes.to_string<char>());
81 80
 }
82 81
 
83 82
 void XSFConfig_GSF::GenerateSpecificDialogs()
... ...
@@ -141,6 +140,6 @@ void XSFConfig_GSF::CopySpecificConfigToMemory(XSFPlayer *, bool preLoad)
141 140
 
142 141
 void XSFConfig_GSF::About(HWND parent)
143 142
 {
144
-	MessageBoxW(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
145
-		L"Utilizes modified VBA-M, SVN revision 1231, for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK);
143
+	MessageBoxW(parent, ConvertFuncs::StringToWString(XSFConfig::commonName + " v" + XSFConfig::versionNumber + ", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
144
+		"Utilizes modified VBA-M, SVN revision 1231, for audio playback.").c_str(), ConvertFuncs::StringToWString(XSFConfig::commonName + " v" + XSFConfig::versionNumber).c_str(), MB_OK);
146 145
 }
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - GSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Based on a modified viogsf v0.08
7 7
  *
... ...
@@ -24,7 +24,7 @@ class XSFPlayer_GSF : public XSFPlayer
24 24
 {
25 25
 public:
26 26
 	XSFPlayer_GSF(const std::string &filename);
27
-#ifdef _MSC_VER
27
+#ifdef _WIN32
28 28
 	XSFPlayer_GSF(const std::wstring &filename);
29 29
 #endif
30 30
 	~XSFPlayer_GSF() { this->Terminate(); }
... ...
@@ -41,7 +41,7 @@ XSFPlayer *XSFPlayer::Create(const std::string &fn)
41 41
 	return new XSFPlayer_GSF(fn);
42 42
 }
43 43
 
44
-#ifdef _MSC_VER
44
+#ifdef _WIN32
45 45
 XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
46 46
 {
47 47
 	return new XSFPlayer_GSF(fn);
... ...
@@ -152,10 +152,10 @@ static bool RecursiveLoad2SF(XSFFile *xSF, int level)
152 152
 {
153 153
 	if (level <= 10 && xSF->GetTagExists("_lib"))
154 154
 	{
155
-#ifdef _MSC_VER
156
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetWStr()) + xSF->GetTagValue("_lib").GetWStr(), 8, 12));
155
+#ifdef _WIN32
156
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue("_lib")), 8, 12));
157 157
 #else
158
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetAnsi()) + xSF->GetTagValue("_lib").GetAnsi(), 8, 12));
158
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue("_lib"), 8, 12));
159 159
 #endif
160 160
 		if (!RecursiveLoad2SF(libxSF.get(), level + 1))
161 161
 			return false;
... ...
@@ -173,10 +173,10 @@ static bool RecursiveLoad2SF(XSFFile *xSF, int level)
173 173
 		if (xSF->GetTagExists(libTag))
174 174
 		{
175 175
 			found = true;
176
-#ifdef _MSC_VER
177
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetWStr()) + xSF->GetTagValue(libTag).GetWStr(), 8, 12));
176
+#ifdef _WIN32
177
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue(libTag)), 8, 12));
178 178
 #else
179
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetAnsi()) + xSF->GetTagValue(libTag).GetAnsi(), 8, 12));
179
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue(libTag), 8, 12));
180 180
 #endif
181 181
 			if (!RecursiveLoad2SF(libxSF.get(), level + 1))
182 182
 				return false;
... ...
@@ -199,7 +199,7 @@ XSFPlayer_GSF::XSFPlayer_GSF(const std::string &filename) : XSFPlayer()
199 199
 	this->xSF.reset(new XSFFile(filename, 8, 12));
200 200
 }
201 201
 
202
-#ifdef _MSC_VER
202
+#ifdef _WIN32
203 203
 XSFPlayer_GSF::XSFPlayer_GSF(const std::wstring &filename) : XSFPlayer()
204 204
 {
205 205
 	this->xSF.reset(new XSFFile(filename, 8, 12));
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - NCSF configuration
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -10,7 +10,6 @@
10 10
 #include "XSFPlayer_NCSF.h"
11 11
 #include "XSFConfig.h"
12 12
 #include "convert.h"
13
-#include "BigSString.h"
14 13
 
15 14
 enum
16 15
 {
... ...
@@ -22,7 +21,7 @@ class XSFConfig_NCSF : public XSFConfig
22 21
 {
23 22
 protected:
24 23
 	static unsigned initInterpolation;
25
-	static std::wstring initMutes;
24
+	static std::string initMutes;
26 25
 
27 26
 	friend class XSFConfig;
28 27
 	unsigned interpolation;
... ...
@@ -41,10 +40,10 @@ public:
41 40
 };
42 41
 
43 42
 unsigned XSFConfig::initSampleRate = 44100;
44
-std::wstring XSFConfig::commonName = L"NCSF Decoder";
45
-std::wstring XSFConfig::versionNumber = L"1.8.1";
43
+std::string XSFConfig::commonName = "NCSF Decoder";
44
+std::string XSFConfig::versionNumber = "1.8.1";
46 45
 unsigned XSFConfig_NCSF::initInterpolation = 5;
47
-std::wstring XSFConfig_NCSF::initMutes = L"0000000000000000";
46
+std::string XSFConfig_NCSF::initMutes = "0000000000000000";
48 47
 
49 48
 XSFConfig *XSFConfig::Create()
50 49
 {
... ...
@@ -68,15 +67,15 @@ XSFConfig_NCSF::XSFConfig_NCSF() : XSFConfig(), interpolation(0), mutes()
68 67
 
69 68
 void XSFConfig_NCSF::LoadSpecificConfig()
70 69
 {
71
-	this->interpolation = this->configIO->GetValue(L"Interpolation", XSFConfig_NCSF::initInterpolation);
72
-	std::wstringstream mutesSS(this->configIO->GetValue(L"Mutes", XSFConfig_NCSF::initMutes));
70
+	this->interpolation = this->configIO->GetValue("Interpolation", XSFConfig_NCSF::initInterpolation);
71
+	std::stringstream mutesSS(this->configIO->GetValue("Mutes", XSFConfig_NCSF::initMutes));
73 72
 	mutesSS >> this->mutes;
74 73
 }
75 74
 
76 75
 void XSFConfig_NCSF::SaveSpecificConfig()
77 76
 {
78
-	this->configIO->SetValue(L"Interpolation", this->interpolation);
79
-	this->configIO->SetValue(L"Mutes", this->mutes.to_string<wchar_t>());
77
+	this->configIO->SetValue("Interpolation", this->interpolation);
78
+	this->configIO->SetValue("Mutes", this->mutes.to_string<char>());
80 79
 }
81 80
 
82 81
 void XSFConfig_NCSF::GenerateSpecificDialogs()
... ...
@@ -141,6 +140,6 @@ void XSFConfig_NCSF::CopySpecificConfigToMemory(XSFPlayer *xSFPlayer, bool)
141 140
 
142 141
 void XSFConfig_NCSF::About(HWND parent)
143 142
 {
144
-	MessageBoxW(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
145
-		L"Utilizes code adapted from the FeOS Sound System library by fincs, git revision 5204c55 on GitHub, for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK);
143
+	MessageBoxW(parent, ConvertFuncs::StringToWString(XSFConfig::commonName + " v" + XSFConfig::versionNumber + ", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
144
+		"Utilizes code adapted from the FeOS Sound System library by fincs, git revision 5204c55 on GitHub, for audio playback.").c_str(), ConvertFuncs::StringToWString(XSFConfig::commonName + " v" + XSFConfig::versionNumber).c_str(), MB_OK);
146 145
 }
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -25,7 +25,7 @@ XSFPlayer *XSFPlayer::Create(const std::string &fn)
25 25
 	return new XSFPlayer_NCSF(fn);
26 26
 }
27 27
 
28
-#ifdef _MSC_VER
28
+#ifdef _WIN32
29 29
 XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
30 30
 {
31 31
 	return new XSFPlayer_NCSF(fn);
... ...
@@ -62,10 +62,10 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
62 62
 {
63 63
 	if (level <= 10 && xSFToLoad->GetTagExists("_lib"))
64 64
 	{
65
-#ifdef _MSC_VER
66
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue("_lib").GetWStr(), 8, 12));
65
+#ifdef _WIN32
66
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib")), 8, 12));
67 67
 #else
68
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue("_lib").GetAnsi(), 8, 12));
68
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue("_lib"), 8, 12));
69 69
 #endif
70 70
 		if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
71 71
 			return false;
... ...
@@ -83,10 +83,10 @@ bool XSFPlayer_NCSF::RecursiveLoadNCSF(XSFFile *xSFToLoad, int level)
83 83
 		if (xSFToLoad->GetTagExists(libTag))
84 84
 		{
85 85
 			found = true;
86
-#ifdef _MSC_VER
87
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetWStr()) + xSFToLoad->GetTagValue(libTag).GetWStr(), 8, 12));
86
+#ifdef _WIN32
87
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag)), 8, 12));
88 88
 #else
89
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename().GetAnsi()) + xSFToLoad->GetTagValue(libTag).GetAnsi(), 8, 12));
89
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSFToLoad->GetFilename()) + xSFToLoad->GetTagValue(libTag), 8, 12));
90 90
 #endif
91 91
 			if (!this->RecursiveLoadNCSF(libxSF.get(), level + 1))
92 92
 				return false;
... ...
@@ -107,7 +107,7 @@ XSFPlayer_NCSF::XSFPlayer_NCSF(const std::string &filename) : XSFPlayer()
107 107
 	this->xSF.reset(new XSFFile(filename, 8, 12));
108 108
 }
109 109
 
110
-#ifdef _MSC_VER
110
+#ifdef _WIN32
111 111
 XSFPlayer_NCSF::XSFPlayer_NCSF(const std::wstring &filename) : XSFPlayer()
112 112
 {
113 113
 	this->uses32BitSamplesClampedTo16Bit = true;
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - NCSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -33,7 +33,7 @@ class XSFPlayer_NCSF : public XSFPlayer
33 33
 	bool LoadNCSF();
34 34
 public:
35 35
 	XSFPlayer_NCSF(const std::string &filename);
36
-#ifdef _MSC_VER
36
+#ifdef _WIN32
37 37
 	XSFPlayer_NCSF(const std::wstring &filename);
38 38
 #endif
39 39
 	bool Load();
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - SNSF configuration
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -12,7 +12,6 @@
12 12
 
13 13
 #include "XSFConfig_SNSF.h"
14 14
 #include "convert.h"
15
-#include "BigSString.h"
16 15
 #include "snes9x/apu/apu.h"
17 16
 
18 17
 enum
... ...
@@ -24,12 +23,12 @@ enum
24 23
 };
25 24
 
26 25
 unsigned XSFConfig::initSampleRate = 44100;
27
-std::wstring XSFConfig::commonName = L"SNSF Decoder";
28
-std::wstring XSFConfig::versionNumber = L"0.9b";
26
+std::string XSFConfig::commonName = "SNSF Decoder";
27
+std::string XSFConfig::versionNumber = "0.9b";
29 28
 //bool XSFConfig_SNSF::initSixteenBitSound = true;
30 29
 bool XSFConfig_SNSF::initReverseStereo = false;
31 30
 unsigned XSFConfig_SNSF::initResampler = 1;
32
-std::wstring XSFConfig_SNSF::initMutes = L"00000000";
31
+std::string XSFConfig_SNSF::initMutes = "00000000";
33 32
 
34 33
 XSFConfig *XSFConfig::Create()
35 34
 {
... ...
@@ -53,19 +52,19 @@ XSFConfig_SNSF::XSFConfig_SNSF() : XSFConfig(), /*sixteenBitSound(false), */reve
53 52
 
54 53
 void XSFConfig_SNSF::LoadSpecificConfig()
55 54
 {
56
-	//this->sixteenBitSound = this->configIO->GetValue(L"SixteenBitSound", XSFConfig_SNSF::initSixteenBitSound);
57
-	this->reverseStereo = this->configIO->GetValue(L"ReverseStereo", XSFConfig_SNSF::initReverseStereo);
58
-	this->resampler = this->configIO->GetValue(L"Resampler", XSFConfig_SNSF::initResampler);
59
-	std::wstringstream mutesSS(this->configIO->GetValue(L"Mutes", XSFConfig_SNSF::initMutes));
55
+	//this->sixteenBitSound = this->configIO->GetValue("SixteenBitSound", XSFConfig_SNSF::initSixteenBitSound);
56
+	this->reverseStereo = this->configIO->GetValue("ReverseStereo", XSFConfig_SNSF::initReverseStereo);
57
+	this->resampler = this->configIO->GetValue("Resampler", XSFConfig_SNSF::initResampler);
58
+	std::stringstream mutesSS(this->configIO->GetValue("Mutes", XSFConfig_SNSF::initMutes));
60 59
 	mutesSS >> this->mutes;
61 60
 }
62 61
 
63 62
 void XSFConfig_SNSF::SaveSpecificConfig()
64 63
 {
65
-	//this->configIO->SetValue(L"SixteenBitSound", this->sixteenBitSound);
66
-	this->configIO->SetValue(L"ReverseStereo", this->reverseStereo);
67
-	this->configIO->SetValue(L"Resampler", this->resampler);
68
-	this->configIO->SetValue(L"Mutes", this->mutes.to_string<wchar_t>());
64
+	//this->configIO->SetValue("SixteenBitSound", this->sixteenBitSound);
65
+	this->configIO->SetValue("ReverseStereo", this->reverseStereo);
66
+	this->configIO->SetValue("Resampler", this->resampler);
67
+	this->configIO->SetValue("Mutes", this->mutes.to_string<char>());
69 68
 }
70 69
 
71 70
 void XSFConfig_SNSF::GenerateSpecificDialogs()
... ...
@@ -147,6 +146,6 @@ void XSFConfig_SNSF::CopySpecificConfigToMemory(XSFPlayer *, bool preLoad)
147 146
 
148 147
 void XSFConfig_SNSF::About(HWND parent)
149 148
 {
150
-	MessageBoxW(parent, (XSFConfig::commonName + L" v" + XSFConfig::versionNumber + L", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
151
-		L"Utilizes modified snes9x v1.53 for audio playback.").c_str(), (XSFConfig::commonName + L" v" + XSFConfig::versionNumber).c_str(), MB_OK);
149
+	MessageBoxW(parent, ConvertFuncs::StringToWString(XSFConfig::commonName + " v" + XSFConfig::versionNumber + ", using xSF Winamp plugin framework (based on the vio*sf plugins) by Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]\n\n"
150
+		"Utilizes modified snes9x v1.53 for audio playback.").c_str(), ConvertFuncs::StringToWString(XSFConfig::commonName + " v" + XSFConfig::versionNumber).c_str(), MB_OK);
152 151
 }
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - SNSF configuration
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  *
... ...
@@ -21,7 +21,7 @@ class XSFConfig_SNSF : public XSFConfig
21 21
 protected:
22 22
 	static bool /*initSixteenBitSound, */initReverseStereo;
23 23
 	static unsigned initResampler;
24
-	static std::wstring initMutes;
24
+	static std::string initMutes;
25 25
 
26 26
 	friend class XSFConfig;
27 27
 	bool /*sixteenBitSound, */reverseStereo;
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - SNSF Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Based on a modified in_snsf by Caitsith2
7 7
  * http://snsf.caitsith2.net/
... ...
@@ -33,7 +33,7 @@ class XSFPlayer_SNSF : public XSFPlayer
33 33
 {
34 34
 public:
35 35
 	XSFPlayer_SNSF(const std::string &filename);
36
-#ifdef _MSC_VER
36
+#ifdef _WIN32
37 37
 	XSFPlayer_SNSF(const std::wstring &filename);
38 38
 #endif
39 39
 	~XSFPlayer_SNSF() { this->Terminate(); }
... ...
@@ -52,7 +52,7 @@ XSFPlayer *XSFPlayer::Create(const std::string &fn)
52 52
 	return new XSFPlayer_SNSF(fn);
53 53
 }
54 54
 
55
-#ifdef _MSC_VER
55
+#ifdef _WIN32
56 56
 XSFPlayer *XSFPlayer::Create(const std::wstring &fn)
57 57
 {
58 58
 	return new XSFPlayer_SNSF(fn);
... ...
@@ -169,10 +169,10 @@ static bool RecursiveLoad2SF(XSFFile *xSF, int level)
169 169
 {
170 170
 	if (level <= 10 && xSF->GetTagExists("_lib"))
171 171
 	{
172
-#ifdef _MSC_VER
173
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetWStr()) + xSF->GetTagValue("_lib").GetWStr(), 4, 8));
172
+#ifdef _WIN32
173
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue("_lib")), 4, 8));
174 174
 #else
175
-		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetAnsi()) + xSF->GetTagValue("_lib").GetAnsi(), 4, 8));
175
+		auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue("_lib"), 4, 8));
176 176
 #endif
177 177
 		if (!RecursiveLoad2SF(libxSF.get(), level + 1))
178 178
 			return false;
... ...
@@ -190,10 +190,10 @@ static bool RecursiveLoad2SF(XSFFile *xSF, int level)
190 190
 		if (xSF->GetTagExists(libTag))
191 191
 		{
192 192
 			found = true;
193
-#ifdef _MSC_VER
194
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetWStr()) + xSF->GetTagValue(libTag).GetWStr(), 4, 8));
193
+#ifdef _WIN32
194
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ConvertFuncs::StringToWString(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue(libTag)), 4, 8));
195 195
 #else
196
-			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename().GetAnsi()) + xSF->GetTagValue(libTag).GetAnsi(), 4, 8));
196
+			auto libxSF = std::unique_ptr<XSFFile>(new XSFFile(ExtractDirectoryFromPath(xSF->GetFilename()) + xSF->GetTagValue(libTag), 4, 8));
197 197
 #endif
198 198
 			if (!RecursiveLoad2SF(libxSF.get(), level + 1))
199 199
 				return false;
... ...
@@ -218,7 +218,7 @@ XSFPlayer_SNSF::XSFPlayer_SNSF(const std::string &filename) : XSFPlayer()
218 218
 	this->xSF.reset(new XSFFile(filename, 4, 8));
219 219
 }
220 220
 
221
-#ifdef _MSC_VER
221
+#ifdef _WIN32
222 222
 XSFPlayer_SNSF::XSFPlayer_SNSF(const std::wstring &filename) : XSFPlayer()
223 223
 {
224 224
 	this->xSF.reset(new XSFFile(filename, 4, 8));
225 225
deleted file mode 100644
... ...
@@ -1,217 +0,0 @@
1
-/*
2
- * String class in ANSI (or rather, current Windows code page), UTF-8, and UTF-16
3
- * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
5
- */
6
-
7
-#pragma once
8
-
9
-#include <string>
10
-#include <cstring>
11
-#include <cwchar>
12
-#include "UtfConverter.h"
13
-#include "UTFEncodeDecode.h"
14
-
15
-class String
16
-{
17
-public:
18
-	String(const std::locale &L = std::locale::classic()) : ansi(""), utf8(""), utf16(L""), loc(L) { }
19
-	String(const char *new_str, bool is_utf8 = false, const std::locale &L = std::locale::classic()) : ansi(is_utf8 ? DecodeFromUTF8(new_str, L) : new_str), utf8(is_utf8 ? new_str : EncodeToUTF8(new_str, L)),
20
-		utf16(UtfConverter::FromUtf8(utf8)), loc(L) { }
21
-	String(const std::string &new_str, bool is_utf8 = false, const std::locale &L = std::locale::classic()) : ansi(is_utf8 ? DecodeFromUTF8(new_str, L) : new_str), utf8(is_utf8 ? new_str : EncodeToUTF8(new_str, L)),
22
-		utf16(UtfConverter::FromUtf8(utf8)), loc(L) { }
23
-	String(const wchar_t *new_wstr, const std::locale &L = std::locale::classic()) : ansi(DecodeFromUTF8(UtfConverter::ToUtf8(new_wstr), L)), utf8(UtfConverter::ToUtf8(new_wstr)), utf16(new_wstr), loc(L) { }
24
-	String(const std::wstring &new_wstr, const std::locale &L = std::locale::classic()) : ansi(DecodeFromUTF8(UtfConverter::ToUtf8(new_wstr), L)), utf8(UtfConverter::ToUtf8(new_wstr)), utf16(new_wstr), loc(L) { }
25
-	bool empty() const { return this->utf8.empty(); }
26
-	std::string GetAnsi() const { return this->ansi; }
27
-	const char *GetAnsiC() const { return this->ansi.c_str(); }
28
-	std::string GetStr() const { return this->utf8; }
29
-	const char *GetStrC() const { return this->utf8.c_str(); }
30
-	std::wstring GetWStr() const { return this->utf16; }
31
-	const wchar_t *GetWStrC() const { return this->utf16.c_str(); }
32
-	bool operator==(const String &str2) const
33
-	{
34
-		return this->utf8 == str2.utf8;
35
-	}
36
-	String &operator=(const std::string &new_str)
37
-	{
38
-		this->ansi = DecodeFromUTF8(new_str, this->loc);
39
-		this->utf8 = new_str;
40
-		this->utf16 = UtfConverter::FromUtf8(new_str);
41
-		return *this;
42
-	}
43
-	String &operator=(const std::wstring &new_wstr)
44
-	{
45
-		this->utf8 = UtfConverter::ToUtf8(new_wstr);
46
-		this->ansi = DecodeFromUTF8(this->utf8, this->loc);
47
-		this->utf16 = new_wstr;
48
-		return *this;
49
-	}
50
-	String &operator=(const String &new_string)
51
-	{
52
-		if (this != &new_string)
53
-		{
54
-			this->ansi = new_string.ansi;
55
-			this->utf8 = new_string.utf8;
56
-			this->utf16 = new_string.utf16;
57
-		}
58
-		return *this;
59
-	}
60
-	String &SetISO8859_1(const std::string &new_str)
61
-	{
62
-		this->ansi = new_str;
63
-		this->utf8 = EncodeToUTF8(new_str, this->loc);
64
-		this->utf16 = UtfConverter::FromUtf8(this->utf8);
65
-		return *this;
66
-	}
67
-	String operator+(const String &str2) const
68
-	{
69
-		String new_string = String(*this);
70
-		new_string.ansi.append(str2.ansi);
71
-		new_string.utf8.append(str2.utf8);
72
-		new_string.utf16.append(str2.utf16);
73
-		return new_string;
74
-	}
75
-	String operator+(char chr) const
76
-	{
77
-		String new_string = String(*this);
78
-		char str2[] = { chr, 0 };
79
-		new_string.ansi.append(str2);
80
-		std::string new_utf8 = EncodeToUTF8(str2, this->loc);
81
-		new_string.utf8.append(new_utf8);
82
-		new_string.utf16.append(UtfConverter::FromUtf8(new_utf8));
83
-		return new_string;
84
-	}
85
-	String operator+(wchar_t wchr) const
86
-	{
87
-		String new_string = String(*this);
88
-		wchar_t wstr2[] = { wchr, 0 };
89
-		std::string new_utf8 = UtfConverter::ToUtf8(wstr2);
90
-		new_string.ansi.append(DecodeFromUTF8(new_utf8, this->loc));
91
-		new_string.utf8.append(new_utf8);
92
-		new_string.utf16.append(wstr2);
93
-		return new_string;
94
-	}
95
-	String operator+(const char *str2) const
96
-	{
97
-		String new_string = String(*this);
98
-		new_string.ansi.append(DecodeFromUTF8(str2, this->loc));
99
-		new_string.utf8.append(str2);
100
-		new_string.utf16.append(UtfConverter::FromUtf8(str2));
101
-		return new_string;
102
-	}
103
-	String operator+(const std::string &str2) const
104
-	{
105
-		String new_string = String(*this);
106
-		new_string.ansi.append(DecodeFromUTF8(str2, this->loc));
107
-		new_string.utf8.append(str2);
108
-		new_string.utf16.append(UtfConverter::FromUtf8(str2));
109
-		return new_string;
110
-	}
111
-	String operator+(const wchar_t *wstr2) const
112
-	{
113
-		String new_string = String(*this);
114
-		std::string new_utf8 = UtfConverter::ToUtf8(wstr2);
115
-		new_string.ansi.append(DecodeFromUTF8(new_utf8, this->loc));
116
-		new_string.utf8.append(new_utf8);
117
-		new_string.utf16.append(wstr2);
118
-		return new_string;
119
-	}
120
-	String operator+(const std::wstring &wstr2) const
121
-	{
122
-		String new_string = String(*this);
123
-		std::string new_utf8 = UtfConverter::ToUtf8(wstr2);
124
-		new_string.ansi.append(DecodeFromUTF8(new_utf8, this->loc));
125
-		new_string.utf8.append(new_utf8);
126
-		new_string.utf16.append(wstr2);
127
-		return new_string;
128
-	}
129
-	String &operator+=(const String &str2)
130
-	{
131
-		if (this != &str2)
132
-		{
133
-			this->ansi.append(str2.ansi);
134
-			this->utf8.append(str2.utf8);
135
-			this->utf16.append(str2.utf16);
136
-		}
137
-		return *this;
138
-	}
139
-	String &operator+=(char chr)
140
-	{
141
-		char str2[] = { chr, 0 };
142
-		this->ansi.append(str2);
143
-		std::string new_utf8 = EncodeToUTF8(str2, this->loc);
144
-		this->utf8.append(new_utf8);
145
-		this->utf16.append(UtfConverter::FromUtf8(new_utf8));
146
-		return *this;
147
-	}
148
-	String &operator+=(wchar_t wchr)
149
-	{
150
-		wchar_t wstr2[] = { wchr, 0 };
151
-		std::string new_utf8 = UtfConverter::ToUtf8(wstr2);
152
-		this->ansi.append(DecodeFromUTF8(new_utf8, this->loc));
153
-		this->utf8.append(new_utf8);
154
-		this->utf16.append(wstr2);
155
-		return *this;
156
-	}
157
-	String &operator+=(const char *str2)
158
-	{
159
-		this->ansi.append(DecodeFromUTF8(str2, this->loc));
160
-		this->utf8.append(str2);
161
-		this->utf16.append(UtfConverter::FromUtf8(str2));
162
-		return *this;
163
-	}
164
-	String &operator+=(const std::string &str2)
165
-	{
166
-		this->ansi.append(DecodeFromUTF8(str2, this->loc));
167
-		this->utf8.append(str2);
168
-		this->utf16.append(UtfConverter::FromUtf8(str2));
169
-		return *this;
170
-	}
171
-	String &operator+=(const wchar_t *wstr2)
172
-	{
173
-		std::string new_utf8 = UtfConverter::ToUtf8(wstr2);
174
-		this->ansi.append(DecodeFromUTF8(new_utf8, this->loc));
175
-		this->utf8.append(new_utf8);
176
-		this->utf16.append(wstr2);
177
-		return *this;
178
-	}
179
-	String &operator+=(const std::wstring &wstr2)
180
-	{
181
-		std::string new_utf8 = UtfConverter::ToUtf8(wstr2);
182
-		this->ansi.append(DecodeFromUTF8(new_utf8, this->loc));
183
-		this->utf8.append(new_utf8);
184
-		this->utf16.append(wstr2);
185
-		return *this;
186
-	}
187
-	String &AppendISO8859_1(const std::string &str2)
188
-	{
189
-		this->ansi.append(str2);
190
-		std::string new_utf8 = EncodeToUTF8(str2, this->loc);
191
-		this->utf8.append(new_utf8);
192
-		this->utf16.append(UtfConverter::FromUtf8(new_utf8));
193
-		return *this;
194
-	}
195
-	String Substring(size_t pos = 0, size_t n = std::string::npos) const
196
-	{
197
-		String new_string = String(*this);
198
-		new_string.ansi.substr(pos, n);
199
-		new_string.utf8.substr(pos, n);
200
-		if (n == std::string::npos)
201
-			n = std::wstring::npos;
202
-		new_string.utf16.substr(pos, n);
203
-		return new_string;
204
-	}
205
-	void CopyToString(wchar_t *str, bool = false) const
206
-	{
207
-		wcscpy(str, utf16.c_str());
208
-	}
209
-	void CopyToString(char *str, bool use_utf8 = false) const
210
-	{
211
-		strcpy(str, (use_utf8 ? utf8 : ansi).c_str());
212
-	}
213
-protected:
214
-	std::string ansi, utf8;
215
-	std::wstring utf16;
216
-	std::locale loc;
217
-};
218 0
deleted file mode 100644
... ...
@@ -1,602 +0,0 @@
1
-/*
2
- * Copyright 2001-2004 Unicode, Inc.
3
- *
4
- * Disclaimer
5
- *
6
- * This source code is provided as is by Unicode, Inc. No claims are
7
- * made as to fitness for any particular purpose. No warranties of any
8
- * kind are expressed or implied. The recipient agrees to determine
9
- * applicability of information provided. If this file has been
10
- * purchased on magnetic or optical media from Unicode, Inc., the
11
- * sole remedy for any claim will be exchange of defective media
12
- * within 90 days of receipt.
13
- *
14
- * Limitations on Rights to Redistribute This Code
15
- *
16
- * Unicode, Inc. hereby grants the right to freely use the information
17
- * supplied in this file in the creation of products supporting the
18
- * Unicode Standard, and to make copies of this file in any form
19
- * for internal or external distribution as long as this notice
20
- * remains attached.
21
- */
22
-
23
-/* ---------------------------------------------------------------------
24
-
25
-    Conversions between UTF32, UTF-16, and UTF-8. Source code file.
26
-    Author: Mark E. Davis, 1994.
27
-    Rev History: Rick McGowan, fixes & updates May 2001.
28
-    Sept 2001: fixed const & error conditions per
29
-	mods suggested by S. Parent & A. Lillich.
30
-    June 2002: Tim Dodd added detection and handling of incomplete
31
-	source sequences, enhanced error detection, added casts
32
-	to eliminate compiler warnings.
33
-    July 2003: slight mods to back out aggressive FFFE detection.
34
-    Jan 2004: updated switches in from-UTF8 conversions.
35
-    Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
36
-
37
-    See the header file "ConvertUTF.h" for complete documentation.
38
-
39
-
40
-#include "ConvertUTF.h"
41
-
42
-static const int halfShift  = 10; /* used for shifting by 10 bits */
43
-
44
-static const UTF32 halfBase = 0x0010000UL;
45
-static const UTF32 halfMask = 0x3FFUL;
46
-
47
-static const UTF32 UNI_SUR_HIGH_START = 0xD800;
48
-static const UTF32 UNI_SUR_HIGH_END = 0xDBFF;
49
-static const UTF32 UNI_SUR_LOW_START = 0xDC00;
50
-static const UTF32 UNI_SUR_LOW_END = 0xDFFF;
51
-
52
-/* --------------------------------------------------------------------- */
53
-
54
-ConversionResult ConvertUTF32toUTF16(const UTF32 **sourceStart, const UTF32 *sourceEnd, UTF16 **targetStart, UTF16 *targetEnd, ConversionFlags flags)
55
-{
56
-	ConversionResult result = conversionOK;
57
-	const UTF32 *source = *sourceStart;
58
-	UTF16 *target = *targetStart;
59
-	while (source < sourceEnd)
60
-	{
61
-		if (target >= targetEnd)
62
-		{
63
-			result = targetExhausted;
64
-			break;
65
-		}
66
-		UTF32 ch = *source++;
67
-		if (ch <= UNI_MAX_BMP) /* Target is a character <= 0xFFFF */
68
-		{
69
-			/* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
70
-			if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
71
-			{
72
-				if (flags == strictConversion)
73
-				{
74
-					--source; /* return to the illegal value itself */
75
-					result = sourceIllegal;
76
-					break;
77
-				}
78
-				else
79
-					*target++ = UNI_REPLACEMENT_CHAR;
80
-			}
81
-			else
82
-				*target++ = static_cast<UTF16>(ch); /* normal case */
83
-		}
84
-		else if (ch > UNI_MAX_LEGAL_UTF32)
85
-		{
86
-			if (flags == strictConversion)
87
-				result = sourceIllegal;
88
-			else
89
-				*target++ = UNI_REPLACEMENT_CHAR;
90
-		}
91
-		else
92
-		{
93
-			/* target is a character in range 0xFFFF - 0x10FFFF. */
94
-			if (target + 1 >= targetEnd)
95
-			{
96
-				--source; /* Back up source pointer! */
97
-				result = targetExhausted;
98
-				break;
99
-			}
100
-			ch -= halfBase;
101
-			*target++ = static_cast<UTF16>((ch >> halfShift) + UNI_SUR_HIGH_START);
102
-			*target++ = static_cast<UTF16>((ch & halfMask) + UNI_SUR_LOW_START);
103
-		}
104
-	}
105
-	*sourceStart = source;
106
-	*targetStart = target;
107
-	return result;
108
-}
109
-
110
-/* --------------------------------------------------------------------- */
111
-
112
-ConversionResult ConvertUTF16toUTF32(const UTF16 **sourceStart, const UTF16 *sourceEnd, UTF32 **targetStart, UTF32 *targetEnd, ConversionFlags flags)
113
-{
114
-	ConversionResult result = conversionOK;
115
-	const UTF16 *source = *sourceStart;
116
-	UTF32 *target = *targetStart;
117
-	while (source < sourceEnd)
118
-	{
119
-		const UTF16 *oldSource = source; /* In case we have to back up because of target overflow. */
120
-		UTF32 ch = *source++;
121
-		/* If we have a surrogate pair, convert to UTF32 first. */
122
-		if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END)
123
-		{
124
-			/* If the 16 bits following the high surrogate are in the source buffer... */
125
-			if (source < sourceEnd)
126
-			{
127
-				UTF32 ch2 = *source;
128
-				/* If it's a low surrogate, convert to UTF32. */
129
-				if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END)
130
-				{
131
-					ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) + halfBase;
132
-					++source;
133
-				}
134
-				else if (flags == strictConversion) /* it's an unpaired high surrogate */
135
-				{
136
-					--source; /* return to the illegal value itself */
137
-					result = sourceIllegal;
138
-					break;
139
-				}
140
-			}
141
-			else /* We don't have the 16 bits following the high surrogate. */
142
-			{
143
-				--source; /* return to the high surrogate */
144
-				result = sourceExhausted;
145
-				break;
146
-			}
147
-		}
148
-		else if (flags == strictConversion)
149
-		{
150
-			/* UTF-16 surrogate values are illegal in UTF-32 */
151
-			if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END)
152
-			{
153
-				--source; /* return to the illegal value itself */
154
-				result = sourceIllegal;
155
-				break;
156
-			}
157
-		}
158
-		if (target >= targetEnd)
159
-		{
160
-			source = oldSource; /* Back up source pointer! */
161
-			result = targetExhausted;
162
-			break;
163
-		}
164
-		*target++ = ch;
165
-	}
166
-	*sourceStart = source;
167
-	*targetStart = target;
168
-	return result;
169
-}
170
-
171
-/* --------------------------------------------------------------------- */
172
-
173
-/*
174
- * Index into the table below with the first byte of a UTF-8 sequence to
175
- * get the number of trailing bytes that are supposed to follow it.
176
- * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is
177
- * left as-is for anyone who may want to do such conversion, which was
178
- * allowed in earlier algorithms.
179
- */
180
-static const char trailingBytesForUTF8[256] = {
181
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
182
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
183
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
184
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
185
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
186
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
187
-	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
188
-	2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
189
-};
190
-
191
-/*
192
- * Magic values subtracted from a buffer value during UTF8 conversion.
193
- * This table contains as many values as there might be trailing bytes
194
- * in a UTF-8 sequence.
195
- */
196
-static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
197
-
198
-/*
199
- * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed
200
- * into the first byte, depending on how many bytes follow.  There are
201
- * as many entries in this table as there are UTF-8 sequence types.
202
- * (I.e., one byte sequence, two byte... etc.). Remember that sequencs
203
- * for *legal* UTF-8 will be 4 or fewer bytes total.
204
- */
205
-static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
206
-
207
-/* --------------------------------------------------------------------- */
208
-
209
-/* The interface converts a whole buffer to avoid function-call overhead.
210
- * Constants have been gathered. Loops & conditionals have been removed as
211
- * much as possible for efficiency, in favor of drop-through switches.
212
- * (See "Note A" at the bottom of the file for equivalent code.)
213
- * If your compiler supports it, the "isLegalUTF8" call can be turned
214
- * into an inline function.
215
- */
216
-
217
-/* --------------------------------------------------------------------- */
218
-
219
-ConversionResult ConvertUTF16toUTF8(const UTF16 **sourceStart, const UTF16 *sourceEnd, UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags)
220
-{
221
-	ConversionResult result = conversionOK;
222
-	const UTF16 *source = *sourceStart;
223
-	UTF8 *target = *targetStart;
224
-	while (source < sourceEnd)
225
-	{
226
-		const UTF32 byteMask = 0xBF, byteMark = 0x80;
227
-		const UTF16 *oldSource = source; /* In case we have to back up because of target overflow. */
228
-		UTF32 ch = *source++;
229
-		/* If we have a surrogate pair, convert to UTF32 first. */
230
-		if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END)
231
-		{
232
-			/* If the 16 bits following the high surrogate are in the source buffer... */
233
-			if (source < sourceEnd)
234
-			{
235
-				UTF32 ch2 = *source;
236
-				/* If it's a low surrogate, convert to UTF32. */
237
-				if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END)
238
-				{
239
-					ch = ((ch - UNI_SUR_HIGH_START) << halfShift) + (ch2 - UNI_SUR_LOW_START) + halfBase;
240
-					++source;
241
-				}
242
-				else if (flags == strictConversion) /* it's an unpaired high surrogate */
243
-				{
244
-					--source; /* return to the illegal value itself */
245
-					result = sourceIllegal;
246
-					break;
247
-				}
248
-			}
249
-			else /* We don't have the 16 bits following the high surrogate. */
250
-			{
251
-				--source; /* return to the high surrogate */
252
-				result = sourceExhausted;
253
-				break;
254
-			}
255
-		}
256
-		else if (flags == strictConversion)
257
-		{
258
-			/* UTF-16 surrogate values are illegal in UTF-32 */
259
-			if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END)
260
-			{
261
-				--source; /* return to the illegal value itself */
262
-				result = sourceIllegal;
263
-				break;
264
-			}
265
-		}
266
-		/* Figure out how many bytes the result will require */
267
-		unsigned short bytesToWrite = 0;
268
-		if (ch < 0x80)
269
-			bytesToWrite = 1;
270
-		else if (ch < 0x800)
271
-			bytesToWrite = 2;
272
-		else if (ch < 0x10000)
273
-			bytesToWrite = 3;
274
-		else if (ch < 0x110000)
275
-			bytesToWrite = 4;
276
-		else
277
-		{
278
-			bytesToWrite = 3;
279
-			ch = UNI_REPLACEMENT_CHAR;
280
-		}
281
-		target += bytesToWrite;
282
-		if (target > targetEnd)
283
-		{
284
-			source = oldSource; /* Back up source pointer! */
285
-			target -= bytesToWrite;
286
-			result = targetExhausted;
287
-			break;
288
-		}
289
-		switch (bytesToWrite) /* note: everything falls through. */
290
-		{
291
-			case 4: *--target = static_cast<UTF8>((ch | byteMark) & byteMask); ch >>= 6;
292
-			case 3: *--target = static_cast<UTF8>((ch | byteMark) & byteMask); ch >>= 6;
293
-			case 2: *--target = static_cast<UTF8>((ch | byteMark) & byteMask); ch >>= 6;
294
-			case 1: *--target = static_cast<UTF8>(ch | firstByteMark[bytesToWrite]);
295
-		}
296
-		target += bytesToWrite;
297
-	}
298
-	*sourceStart = source;
299
-	*targetStart = target;
300
-	return result;
301
-}
302
-
303
-/* --------------------------------------------------------------------- */
304
-
305
-/*
306
- * Utility routine to tell whether a sequence of bytes is legal UTF-8.
307
- * This must be called with the length pre-determined by the first byte.
308
- * If not calling this from ConvertUTF8to*, then the length can be set by:
309
- *  length = trailingBytesForUTF8[*source]+1;
310
- * and the sequence is illegal right away if there aren't that many bytes
311
- * available.
312
- * If presented with a length > 4, this returns false.  The Unicode
313
- * definition of UTF-8 goes up to 4-byte sequences.
314
- */
315
-
316
-static bool isLegalUTF8(const UTF8 *source, int length)
317
-{
318
-	const UTF8 *srcptr = source + length;
319
-	UTF8 a;
320
-	switch (length)
321
-	{
322
-		default: return false;
323
-		/* Everything else falls through when "true"... */
324
-		case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
325
-		case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
326
-		case 2: if ((a = (*--srcptr)) > 0xBF) return false;
327
-
328
-		switch (*source)
329
-		{
330
-			/* no fall-through in this inner switch */
331
-			case 0xE0: if (a < 0xA0) return false; break;
332
-			case 0xED: if (a > 0x9F) return false; break;
333
-			case 0xF0: if (a < 0x90) return false; break;
334
-			case 0xF4: if (a > 0x8F) return false; break;
335
-			default: if (a < 0x80) return false;
336
-		}
337
-
338
-		case 1: if (*source >= 0x80 && *source < 0xC2) return false;
339
-	}
340
-	if (*source > 0xF4)
341
-		return false;
342
-	return true;
343
-}
344
-
345
-/* --------------------------------------------------------------------- */
346
-
347
-/*
348
- * Exported function to return whether a UTF-8 sequence is legal or not.
349
- * This is not used here; it's just exported.
350
- */
351
-bool isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd)
352
-{
353
-	int length = trailingBytesForUTF8[*source] + 1;
354
-	if (source + length > sourceEnd)
355
-		return false;
356
-	return isLegalUTF8(source, length);
357
-}
358
-
359
-/* --------------------------------------------------------------------- */
360
-
361
-ConversionResult ConvertUTF8toUTF16(const UTF8 **sourceStart, const UTF8 *sourceEnd, UTF16 **targetStart, UTF16 *targetEnd, ConversionFlags flags)
362
-{
363
-	ConversionResult result = conversionOK;
364
-	const UTF8 *source = *sourceStart;
365
-	UTF16 *target = *targetStart;
366
-	while (source < sourceEnd)
367
-	{
368
-		UTF32 ch = 0;
369
-		unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
370
-		if (source + extraBytesToRead >= sourceEnd)
371
-		{
372
-			result = sourceExhausted;
373
-			break;
374
-		}
375
-		/* Do this check whether lenient or strict */
376
-		if (!isLegalUTF8(source, extraBytesToRead + 1))
377
-		{
378
-			result = sourceIllegal;
379
-			break;
380
-		}
381
-		/*
382
-		 * The cases all fall through. See "Note A" below.
383
-		 */
384
-		switch (extraBytesToRead)
385
-		{
386
-			case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
387
-			case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
388
-			case 3: ch += *source++; ch <<= 6;
389
-			case 2: ch += *source++; ch <<= 6;
390
-			case 1: ch += *source++; ch <<= 6;
391
-			case 0: ch += *source++;
392
-		}
393
-		ch -= offsetsFromUTF8[extraBytesToRead];
394
-
395
-		if (target >= targetEnd)
396
-		{
397
-			source -= extraBytesToRead + 1; /* Back up source pointer! */
398
-			result = targetExhausted;
399
-			break;
400
-		}
401
-		if (ch <= UNI_MAX_BMP) /* Target is a character <= 0xFFFF */
402
-		{
403
-			/* UTF-16 surrogate values are illegal in UTF-32 */
404
-			if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
405
-			{
406
-				if (flags == strictConversion)
407
-				{
408
-					source -= extraBytesToRead + 1; /* return to the illegal value itself */
409
-					result = sourceIllegal;
410
-					break;
411
-				}
412
-				else
413
-					*target++ = UNI_REPLACEMENT_CHAR;
414
-			}
415
-			else
416
-				*target++ = static_cast<UTF16>(ch); /* normal case */
417
-		}
418
-		else if (ch > UNI_MAX_UTF16)
419
-		{
420
-			if (flags == strictConversion)
421
-			{
422
-				result = sourceIllegal;
423
-				source -= extraBytesToRead + 1; /* return to the start */
424
-				break; /* Bail out; shouldn't continue */
425
-			}
426
-			else
427
-				*target++ = UNI_REPLACEMENT_CHAR;
428
-		}
429
-		else
430
-		{
431
-			/* target is a character in range 0xFFFF - 0x10FFFF. */
432
-			if (target + 1 >= targetEnd)
433
-			{
434
-				source -= extraBytesToRead + 1; /* Back up source pointer! */
435
-				result = targetExhausted;
436
-				break;
437
-			}
438
-			ch -= halfBase;
439
-			*target++ = static_cast<UTF16>((ch >> halfShift) + UNI_SUR_HIGH_START);
440
-			*target++ = static_cast<UTF16>((ch & halfMask) + UNI_SUR_LOW_START);
441
-		}
442
-	}
443
-	*sourceStart = source;
444
-	*targetStart = target;
445
-	return result;
446
-}
447
-
448
-/* --------------------------------------------------------------------- */
449
-
450
-ConversionResult ConvertUTF32toUTF8(const UTF32 **sourceStart, const UTF32 *sourceEnd, UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags)
451
-{
452
-	ConversionResult result = conversionOK;
453
-	const UTF32 *source = *sourceStart;
454
-	UTF8 *target = *targetStart;
455
-	while (source < sourceEnd)
456
-	{
457
-		const UTF32 byteMask = 0xBF, byteMark = 0x80;
458
-		UTF32 ch = *source++;
459
-		if (flags == strictConversion)
460
-		{
461
-			/* UTF-16 surrogate values are illegal in UTF-32 */
462
-			if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
463
-			{
464
-				--source; /* return to the illegal value itself */
465
-				result = sourceIllegal;
466
-				break;
467
-			}
468
-		}
469
-		/*
470
-		 * Figure out how many bytes the result will require. Turn any
471
-		 * illegally large UTF32 things (> Plane 17) into replacement chars.
472
-		 */
473
-		unsigned short bytesToWrite = 0;
474
-		if (ch < 0x80)
475
-			bytesToWrite = 1;
476
-		else if (ch < 0x800)
477
-			bytesToWrite = 2;
478
-		else if (ch < 0x10000)
479
-			bytesToWrite = 3;
480
-		else if (ch <= UNI_MAX_LEGAL_UTF32)
481
-			bytesToWrite = 4;
482
-		else
483
-		{
484
-			bytesToWrite = 3;
485
-			ch = UNI_REPLACEMENT_CHAR;
486
-			result = sourceIllegal;
487
-		}
488
-
489
-		target += bytesToWrite;
490
-		if (target > targetEnd)
491
-		{
492
-			--source; /* Back up source pointer! */
493
-			target -= bytesToWrite;
494
-			result = targetExhausted;
495
-			break;
496
-		}
497
-		switch (bytesToWrite) /* note: everything falls through. */
498
-		{
499
-			case 4: *--target = static_cast<UTF8>((ch | byteMark) & byteMask); ch >>= 6;
500
-			case 3: *--target = static_cast<UTF8>((ch | byteMark) & byteMask); ch >>= 6;
501
-			case 2: *--target = static_cast<UTF8>((ch | byteMark) & byteMask); ch >>= 6;
502
-			case 1: *--target = static_cast<UTF8>(ch | firstByteMark[bytesToWrite]);
503
-		}
504
-		target += bytesToWrite;
505
-	}
506
-	*sourceStart = source;
507
-	*targetStart = target;
508
-	return result;
509
-}
510
-
511
-/* --------------------------------------------------------------------- */
512
-
513
-ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, UTF32 **targetStart, UTF32 *targetEnd, ConversionFlags flags)
514
-{
515
-	ConversionResult result = conversionOK;
516
-	const UTF8 *source = *sourceStart;
517
-	UTF32 *target = *targetStart;
518
-	while (source < sourceEnd)
519
-	{
520
-		UTF32 ch = 0;
521
-		unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
522
-		if (source + extraBytesToRead >= sourceEnd)
523
-		{
524
-			result = sourceExhausted;
525
-			break;
526
-		}
527
-		/* Do this check whether lenient or strict */
528
-		if (!isLegalUTF8(source, extraBytesToRead + 1))
529
-		{
530
-			result = sourceIllegal;
531
-			break;
532
-		}
533
-		/*
534
-		 * The cases all fall through. See "Note A" below.
535
-		 */
536
-		switch (extraBytesToRead)
537
-		{
538
-			case 5: ch += *source++; ch <<= 6;
539
-			case 4: ch += *source++; ch <<= 6;
540
-			case 3: ch += *source++; ch <<= 6;
541
-			case 2: ch += *source++; ch <<= 6;
542
-			case 1: ch += *source++; ch <<= 6;
543
-			case 0: ch += *source++;
544
-		}
545
-		ch -= offsetsFromUTF8[extraBytesToRead];
546
-
547
-		if (target >= targetEnd)
548
-		{
549
-			source -= extraBytesToRead + 1; /* Back up the source pointer! */
550
-			result = targetExhausted;
551
-			break;
552
-		}
553
-		if (ch <= UNI_MAX_LEGAL_UTF32)
554
-		{
555
-			/*
556
-			 * UTF-16 surrogate values are illegal in UTF-32, and anything
557
-			 * over Plane 17 (> 0x10FFFF) is illegal.
558
-			 */
559
-			if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
560
-			{
561
-				if (flags == strictConversion)
562
-				{
563
-					source -= extraBytesToRead + 1; /* return to the illegal value itself */
564
-					result = sourceIllegal;
565
-					break;
566
-				}
567
-				else
568
-					*target++ = UNI_REPLACEMENT_CHAR;
569
-			}
570
-			else
571
-				*target++ = ch;
572
-		}
573
-		else /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
574
-		{
575
-			result = sourceIllegal;
576
-			*target++ = UNI_REPLACEMENT_CHAR;
577
-		}
578
-	}
579
-	*sourceStart = source;
580
-	*targetStart = target;
581
-	return result;
582
-}
583
-
584
-/* ---------------------------------------------------------------------
585
-
586
-    Note A.
587
-    The fall-through switches in UTF-8 reading code save a
588
-    temp variable, some decrements & conditionals.  The switches
589
-    are equivalent to the following loop:
590
-	{
591
-	    int tmpBytesToRead = extraBytesToRead+1;
592
-	    do {
593
-		ch += *source++;
594
-		--tmpBytesToRead;
595
-		if (tmpBytesToRead) ch <<= 6;
596
-	    } while (tmpBytesToRead > 0);
597
-	}
598
-    In UTF-8 writing code, the switches on "bytesToWrite" are
599
-    similarly unrolled loops.
600
-
601
-   --------------------------------------------------------------------- */
602 0
deleted file mode 100644
... ...
@@ -1,131 +0,0 @@
1
-/*
2
- * Copyright 2001-2004 Unicode, Inc.
3
- *
4
- * Disclaimer
5
- *
6
- * This source code is provided as is by Unicode, Inc. No claims are
7
- * made as to fitness for any particular purpose. No warranties of any
8
- * kind are expressed or implied. The recipient agrees to determine
9
- * applicability of information provided. If this file has been
10
- * purchased on magnetic or optical media from Unicode, Inc., the
11
- * sole remedy for any claim will be exchange of defective media
12
- * within 90 days of receipt.
13
- *
14
- * Limitations on Rights to Redistribute This Code
15
- *
16
- * Unicode, Inc. hereby grants the right to freely use the information
17
- * supplied in this file in the creation of products supporting the
18
- * Unicode Standard, and to make copies of this file in any form
19
- * for internal or external distribution as long as this notice
20
- * remains attached.
21
- */
22
-
23
-/* ---------------------------------------------------------------------
24
-
25
-    Conversions between UTF32, UTF-16, and UTF-8.  Header file.
26
-
27
-    Several funtions are included here, forming a complete set of
28
-    conversions between the three formats.  UTF-7 is not included
29
-    here, but is handled in a separate source file.
30
-
31
-    Each of these routines takes pointers to input buffers and output
32
-    buffers.  The input buffers are const.
33
-
34
-    Each routine converts the text between *sourceStart and sourceEnd,
35
-    putting the result into the buffer between *targetStart and
36
-    targetEnd. Note: the end pointers are *after* the last item: e.g.
37
-    *(sourceEnd - 1) is the last item.
38
-
39
-    The return result indicates whether the conversion was successful,
40
-    and if not, whether the problem was in the source or target buffers.
41
-    (Only the first encountered problem is indicated.)
42
-
43
-    After the conversion, *sourceStart and *targetStart are both
44
-    updated to point to the end of last text successfully converted in
45
-    the respective buffers.
46
-
47
-    Input parameters:
48
-	sourceStart - pointer to a pointer to the source buffer.
49
-		The contents of this are modified on return so that
50
-		it points at the next thing to be converted.
51
-	targetStart - similarly, pointer to pointer to the target buffer.
52
-	sourceEnd, targetEnd - respectively pointers to the ends of the
53
-		two buffers, for overflow checking only.
54
-
55
-    These conversion functions take a ConversionFlags argument. When this
56
-    flag is set to strict, both irregular sequences and isolated surrogates
57
-    will cause an error.  When the flag is set to lenient, both irregular
58
-    sequences and isolated surrogates are converted.
59
-
60
-    Whether the flag is strict or lenient, all illegal sequences will cause
61
-    an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
62
-    or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
63
-    must check for illegal sequences.
64
-
65
-    When the flag is set to lenient, characters over 0x10FFFF are converted
66
-    to the replacement character; otherwise (when the flag is set to strict)
67
-    they constitute an error.
68
-
69
-    Output parameters:
70
-	The value "sourceIllegal" is returned from some routines if the input
71
-	sequence is malformed.  When "sourceIllegal" is returned, the source
72
-	value will point to the illegal value that caused the problem. E.g.,
73
-	in UTF-8 when a sequence is malformed, it points to the start of the
74
-	malformed sequence.
75
-
76
-    Author: Mark E. Davis, 1994.
77
-    Rev History: Rick McGowan, fixes & updates May 2001.
78
-		 Fixes & updates, Sept 2001.
79
-
80
-
81
-#pragma once
82
-
83
-/* ---------------------------------------------------------------------
84
-    The following 4 definitions are compiler-specific.
85
-    The C standard does not guarantee that wchar_t has at least
86
-    16 bits, so wchar_t is no less portable than unsigned short!
87
-    All should be unsigned values to avoid sign extension during
88
-    bit mask & shift operations.
89
-
90
-typedef unsigned long UTF32; /* at least 32 bits */
91
-typedef unsigned short UTF16; /* at least 16 bits */
92
-typedef unsigned char UTF8; /* typically 8 bits */
93
-
94
-/* Some fundamental constants */
95
-static const UTF32 UNI_REPLACEMENT_CHAR = 0x0000FFFD;
96
-static const UTF32 UNI_MAX_BMP = 0x0000FFFF;
97
-static const UTF32 UNI_MAX_UTF16 = 0x0010FFFF;
98
-static const UTF32 UNI_MAX_UTF32 = 0x7FFFFFFF;
99
-static const UTF32 UNI_MAX_LEGAL_UTF32 = 0x0010FFFF;
100
-
101
-enum ConversionResult
102
-{
103
-	conversionOK,		/* conversion successful */
104
-	sourceExhausted,	/* partial character in source, but hit end */
105
-	targetExhausted,	/* insuff. room in target for conversion */
106
-	sourceIllegal		/* source sequence is illegal/malformed */
107
-};
108
-
109
-enum ConversionFlags
110
-{
111
-	strictConversion,
112
-	lenientConversion
113
-};
114
-
115
-ConversionResult ConvertUTF8toUTF16(const UTF8 **, const UTF8 *, UTF16 **, UTF16 *, ConversionFlags);
116
-
117
-ConversionResult ConvertUTF16toUTF8(const UTF16 **, const UTF16 *, UTF8 **, UTF8 *, ConversionFlags);
118
-
119
-ConversionResult ConvertUTF8toUTF32(const UTF8 **, const UTF8 *, UTF32 **, UTF32 *, ConversionFlags);
120
-
121
-ConversionResult ConvertUTF32toUTF8(const UTF32 **, const UTF32 *, UTF8 **, UTF8 *, ConversionFlags);
122
-
123
-ConversionResult ConvertUTF16toUTF32(const UTF16 **, const UTF16 *, UTF32 **, UTF32 *, ConversionFlags);
124
-
125
-ConversionResult ConvertUTF32toUTF16(const UTF32 **, const UTF32 *, UTF16 **, UTF16 *, ConversionFlags);
126
-
127
-bool isLegalUTF8Sequence(const UTF8 *, const UTF8 *);
128
-
129
-/* --------------------------------------------------------------------- */
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * Windows Dynamic Dialog Builder framework
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  */
6 6
 
7 7
 #pragma once
... ...
@@ -12,8 +12,8 @@
12 12
 #include <algorithm>
13 13
 #include <stdexcept>
14 14
 #include <cstdint>
15
+#include "XSFCommon.h"
15 16
 #include "windowsh_wrapper.h"
16
-#include "UtfConverter.h"
17 17
 
18 18
 template<typename T> struct Point
19 19
 {
... ...
@@ -621,7 +621,7 @@ class DialogTemplate
621 621
 					return;
622 622
 				}
623 623
 			}
624
-			throw std::runtime_error("Group " + UtfConverter::ToUtf8(groupBuilder.groupName) + " was not found.");
624
+			throw std::runtime_error("Group " + ConvertFuncs::WStringToString(groupBuilder.groupName) + " was not found.");
625 625
 		}
626 626
 	}
627 627
 	uint16_t GetTotalControlCount() const;
628 628
deleted file mode 100644
... ...
@@ -1,29 +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
-#include "UTFEncodeDecode.h"
5
-#include "UtfConverter.h"
6
-
7
-std::string EncodeToUTF8(const std::string &source, const std::locale &L)
8
-{
9
-	try
10
-	{
11
-		return UtfConverter::ToUtf8(cp_converter<>(L).widen(source));
12
-	}
13
-	catch (const std::runtime_error &)
14
-	{
15
-		return "";
16
-	}
17
-}
18
-
19
-std::string DecodeFromUTF8(const std::string &source, const std::locale &L)
20
-{
21
-	try
22
-	{
23
-		return cp_converter<>(L).narrow(UtfConverter::FromUtf8(source));
24
-	}
25
-	catch (const std::runtime_error &)
26
-	{
27
-		return "";
28
-	}
29
-}
30 0
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
-};
61 0
deleted file mode 100644
... ...
@@ -1,69 +0,0 @@
1
-// original code is from here: http://www.codeproject.com/Articles/17573/Convert-Between-std-string-and-std-wstring-UTF-8-a
2
-// License: The Code Project Open License (CPOL) http://www.codeproject.com/info/cpol10.aspx
3
-
4
-#include <string>
5
-#include <vector>
6
-#include <stdexcept>
7
-#include "ConvertUTF.h"
8
-
9
-namespace UtfConverter
10
-{
11
-	std::wstring FromUtf8(const std::string &utf8string)
12
-	{
13
-		auto widesize = utf8string.length();
14
-		auto result = std::vector<wchar_t>(widesize + 1, L'\0');
15
-		auto orig = std::vector<char>(widesize + 1, '\0');
16
-		std::copy(utf8string.begin(), utf8string.end(), orig.begin());
17
-		auto sourcestart = reinterpret_cast<const UTF8 *>(&orig[0]), sourceend = sourcestart + widesize;
18
-		ConversionResult res;
19
-		if (sizeof(wchar_t) == 2)
20
-		{
21
-			auto targetstart = reinterpret_cast<UTF16 *>(&result[0]), targetend = targetstart + widesize;
22
-			res = ConvertUTF8toUTF16(&sourcestart, sourceend, &targetstart, targetend, strictConversion);
23
-			*targetstart = 0;
24
-			unsigned end = targetstart - reinterpret_cast<UTF16 *>(&result[0]);
25
-			result.erase(result.begin() + end, result.end());
26
-		}
27
-		else if (sizeof(wchar_t) == 4)
28
-		{
29
-			auto targetstart = reinterpret_cast<UTF32 *>(&result[0]), targetend = targetstart + widesize;
30
-			res = ConvertUTF8toUTF32(&sourcestart, sourceend, &targetstart, targetend, strictConversion);
31
-			*targetstart = 0;
32
-			unsigned end = targetstart - reinterpret_cast<UTF32 *>(&result[0]);
33
-			result.erase(result.begin() + end, result.end());
34
-		}
35
-		else
36
-			throw std::runtime_error("UtfConverter::FromUtf8: sizeof(wchar_t) is not 2 or 4.");
37
-		if (res != conversionOK)
38
-			throw std::runtime_error("UtfConverter::FromUtf8: Conversion failed.");
39
-		return std::wstring(result.begin(), result.end());
40
-	}
41
-
42
-	std::string ToUtf8(const std::wstring &widestring)
43
-	{
44
-		auto widesize = widestring.length(), utf8size = (sizeof(wchar_t) == 2 ? 3 : 4) * widesize + 1;
45
-		auto result = std::vector<char>(utf8size, '\0');
46
-		auto orig = std::vector<wchar_t>(widesize + 1, L'\0');
47
-		std::copy(widestring.begin(), widestring.end(), orig.begin());
48
-		auto targetstart = reinterpret_cast<UTF8 *>(&result[0]), targetend = targetstart + utf8size;
49
-		ConversionResult res;
50
-		if (sizeof(wchar_t) == 2)
51
-		{
52
-			auto sourcestart = reinterpret_cast<const UTF16 *>(&orig[0]), sourceend = sourcestart + widesize;
53
-			res = ConvertUTF16toUTF8(&sourcestart, sourceend, &targetstart, targetend, strictConversion);
54
-		}
55
-		else if (sizeof(wchar_t) == 4)
56
-		{
57
-			auto sourcestart = reinterpret_cast<const UTF32 *>(&orig[0]), sourceend = sourcestart + widesize;
58
-			res = ConvertUTF32toUTF8(&sourcestart, sourceend, &targetstart, targetend, strictConversion);
59
-		}
60
-		else
61
-			throw std::runtime_error("UtfConverter::ToUtf8: sizeof(wchar_t) is not 2 or 4.");
62
-		if (res != conversionOK)
63
-			throw std::runtime_error("UtfConverter::ToUtf8: Conversion failed.");
64
-		*targetstart = 0;
65
-		auto end = targetstart - reinterpret_cast<UTF8 *>(&result[0]);
66
-		result.erase(result.begin() + end, result.end());
67
-		return std::string(result.begin(), result.end());
68
-	}
69
-}
70 0
deleted file mode 100644
... ...
@@ -1,12 +0,0 @@
1
-// original code is from here: http://www.codeproject.com/Articles/17573/Convert-Between-std-string-and-std-wstring-UTF-8-a
2
-// License: The Code Project Open License (CPOL) http://www.codeproject.com/info/cpol10.aspx
3
-
4
-#pragma once
5
-
6
-#include <string>
7
-
8
-namespace UtfConverter
9
-{
10
-	std::wstring FromUtf8(const std::string &);
11
-	std::string ToUtf8(const std::wstring &);
12
-}
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Common functions
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -10,10 +10,16 @@
10 10
 
11 11
 #include <limits>
12 12
 #include <fstream>
13
+#if defined(_WIN32) && !defined(_MSC_VER)
14
+# include "fstream_wfopen.h"
15
+#endif
13 16
 #include <string>
14 17
 #define _USE_MATH_DEFINES
15 18
 #include <cmath>
16 19
 #include <cstdint>
20
+#include <cwchar>
21
+#include <cstring>
22
+#include "convert.h"
17 23
 
18 24
 // Code from http://learningcppisfun.blogspot.com/2010/04/comparing-floating-point-numbers.html
19 25
 template<typename T> inline bool fEqual(T x, T y, int N = 1)
... ...
@@ -80,10 +86,34 @@ inline bool FileExists(const std::string &filename)
80 86
 	return !!file;
81 87
 }
82 88
 
83
-#ifdef _MSC_VER
89
+#ifdef _WIN32
84 90
 inline bool FileExists(const std::wstring &filename)
85 91
 {
92
+#ifdef _MSC_VER
86 93
 	std::ifstream file(filename.c_str());
94
+#else
95
+	ifstream_wfopen file(filename.c_str());
96
+#endif
87 97
 	return !!file;
88 98
 }
89 99
 #endif
100
+
101
+inline void CopyToString(const std::wstring &src, wchar_t *dst)
102
+{
103
+	wcscpy(dst, src.c_str());
104
+}
105
+
106
+inline void CopyToString(const std::string &src, wchar_t *dst)
107
+{
108
+	wcscpy(dst, ConvertFuncs::StringToWString(src).c_str());
109
+}
110
+
111
+inline void CopyToString(const std::string &src, char *dst)
112
+{
113
+	strcpy(dst, src.c_str());
114
+}
115
+
116
+inline void CopyToString(const std::wstring &src, char *dst)
117
+{
118
+	strcpy(dst, ConvertFuncs::WStringToString(src).c_str());
119
+}
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Core configuration handler
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -9,7 +9,6 @@
9 9
 #include "XSFConfig.h"
10 10
 #include "XSFPlayer.h"
11 11
 #include "convert.h"
12
-#include "BigSString.h"
13 12
 
14 13
 enum
15 14
 {
... ...
@@ -34,23 +33,23 @@ enum
34 33
 };
35 34
 
36 35
 bool XSFConfig::initPlayInfinitely = false;
37
-std::wstring XSFConfig::initSkipSilenceOnStartSec = L"5";
38
-std::wstring XSFConfig::initDetectSilenceSec = L"5";
39
-std::wstring XSFConfig::initDefaultLength = L"1:55";
40
-std::wstring XSFConfig::initDefaultFade = L"5";
41
-std::wstring XSFConfig::initTitleFormat = L"%game%[ - [%disc%.]%track%] - %title%";
36
+std::string XSFConfig::initSkipSilenceOnStartSec = "5";
37
+std::string XSFConfig::initDetectSilenceSec = "5";
38
+std::string XSFConfig::initDefaultLength = "1:55";
39
+std::string XSFConfig::initDefaultFade = "5";
40
+std::string XSFConfig::initTitleFormat = "%game%[ - [%disc%.]%track%] - %title%";
42 41
 double XSFConfig::initVolume = 1.0;
43 42
 VolumeType XSFConfig::initVolumeType = VOLUMETYPE_REPLAYGAIN_ALBUM;
44 43
 PeakType XSFConfig::initPeakType = PEAKTYPE_REPLAYGAIN_TRACK;
45 44
 
46 45
 XSFConfig::XSFConfig() : playInfinitely(false), skipSilenceOnStartSec(0), detectSilenceSec(0), defaultLength(0), defaultFade(0), volume(0.0), volumeType(VOLUMETYPE_NONE), peakType(PEAKTYPE_NONE),
47
-	sampleRate(0), titleFormat(L""), configDialog(), configDialogProperty(), infoDialog(), supportedSampleRates(), configIO(XSFConfigIO::Create())
46
+	sampleRate(0), titleFormat(""), configDialog(), configDialogProperty(), infoDialog(), supportedSampleRates(), configIO(XSFConfigIO::Create())
48 47
 {
49 48
 }
50 49
 
51
-const String &XSFConfig::CommonNameWithVersion()
50
+const std::string &XSFConfig::CommonNameWithVersion()
52 51
 {
53
-	static const auto commonNameWithVersion = String(XSFConfig::commonName + L" v" + XSFConfig::versionNumber);
52
+	static const auto commonNameWithVersion = XSFConfig::commonName + " v" + XSFConfig::versionNumber;
54 53
 	return commonNameWithVersion;
55 54
 }
56 55
 
... ...
@@ -64,32 +63,32 @@ std::wstring XSFConfig::GetTextFromWindow(HWND hwnd)
64 63
 
65 64
 void XSFConfig::LoadConfig()
66 65
 {
67
-	this->playInfinitely = this->configIO->GetValue(L"PlayInfinitely", XSFConfig::initPlayInfinitely);
68
-	this->skipSilenceOnStartSec = ConvertFuncs::StringToMS(this->configIO->GetValue(L"SkipSilenceOnStartSec", XSFConfig::initSkipSilenceOnStartSec));
69
-	this->detectSilenceSec = ConvertFuncs::StringToMS(this->configIO->GetValue(L"DetectSilenceSec", XSFConfig::initDetectSilenceSec));
70
-	this->defaultLength = ConvertFuncs::StringToMS(this->configIO->GetValue(L"DefaultLength", XSFConfig::initDefaultLength));
71
-	this->defaultFade = ConvertFuncs::StringToMS(this->configIO->GetValue(L"DefaultFade", XSFConfig::initDefaultFade));
72
-	this->volume = this->configIO->GetValue(L"Volume", XSFConfig::initVolume);
73
-	this->volumeType = static_cast<VolumeType>(this->configIO->GetValue(L"VolumeType", static_cast<int>(XSFConfig::initVolumeType)));
74
-	this->peakType = static_cast<PeakType>(this->configIO->GetValue(L"PeakType", static_cast<int>(XSFConfig::initPeakType)));
75
-	this->sampleRate = this->configIO->GetValue(L"SampleRate", XSFConfig::initSampleRate);
76
-	this->titleFormat = this->configIO->GetValue(L"TitleFormat", XSFConfig::initTitleFormat);
66
+	this->playInfinitely = this->configIO->GetValue("PlayInfinitely", XSFConfig::initPlayInfinitely);
67
+	this->skipSilenceOnStartSec = ConvertFuncs::StringToMS(this->configIO->GetValue("SkipSilenceOnStartSec", XSFConfig::initSkipSilenceOnStartSec));
68
+	this->detectSilenceSec = ConvertFuncs::StringToMS(this->configIO->GetValue("DetectSilenceSec", XSFConfig::initDetectSilenceSec));
69
+	this->defaultLength = ConvertFuncs::StringToMS(this->configIO->GetValue("DefaultLength", XSFConfig::initDefaultLength));
70
+	this->defaultFade = ConvertFuncs::StringToMS(this->configIO->GetValue("DefaultFade", XSFConfig::initDefaultFade));
71
+	this->volume = this->configIO->GetValue("Volume", XSFConfig::initVolume);
72
+	this->volumeType = static_cast<VolumeType>(this->configIO->GetValue("VolumeType", static_cast<int>(XSFConfig::initVolumeType)));
73
+	this->peakType = static_cast<PeakType>(this->configIO->GetValue("PeakType", static_cast<int>(XSFConfig::initPeakType)));
74
+	this->sampleRate = this->configIO->GetValue("SampleRate", XSFConfig::initSampleRate);
75
+	this->titleFormat = this->configIO->GetValue("TitleFormat", XSFConfig::initTitleFormat);
77 76
 
78 77
 	this->LoadSpecificConfig();
79 78
 }
80 79
 
81 80
 void XSFConfig::SaveConfig()
82 81
 {
83
-	this->configIO->SetValue(L"PlayInfinitely", this->playInfinitely);
84
-	this->configIO->SetValue(L"SkipSilenceOnStartSec", ConvertFuncs::MSToWString(this->skipSilenceOnStartSec));
85
-	this->configIO->SetValue(L"DetectSilenceSec", ConvertFuncs::MSToWString(this->detectSilenceSec));
86
-	this->configIO->SetValue(L"DefaultLength", ConvertFuncs::MSToWString(this->defaultLength));
87
-	this->configIO->SetValue(L"DefaultFade", ConvertFuncs::MSToWString(this->defaultFade));
88
-	this->configIO->SetValue(L"Volume", this->volume);
89
-	this->configIO->SetValue(L"VolumeType", this->volumeType);
90
-	this->configIO->SetValue(L"PeakType", this->peakType);
91
-	this->configIO->SetValue(L"SampleRate", this->sampleRate);
92
-	this->configIO->SetValue(L"TitleFormat", this->titleFormat);
82
+	this->configIO->SetValue("PlayInfinitely", this->playInfinitely);
83
+	this->configIO->SetValue("SkipSilenceOnStartSec", ConvertFuncs::MSToString(this->skipSilenceOnStartSec));
84
+	this->configIO->SetValue("DetectSilenceSec", ConvertFuncs::MSToString(this->detectSilenceSec));
85
+	this->configIO->SetValue("DefaultLength", ConvertFuncs::MSToString(this->defaultLength));
86
+	this->configIO->SetValue("DefaultFade", ConvertFuncs::MSToString(this->defaultFade));
87
+	this->configIO->SetValue("Volume", this->volume);
88
+	this->configIO->SetValue("VolumeType", this->volumeType);
89
+	this->configIO->SetValue("PeakType", this->peakType);
90
+	this->configIO->SetValue("SampleRate", this->sampleRate);
91
+	this->configIO->SetValue("TitleFormat", this->titleFormat);
93 92
 
94 93
 	this->SaveSpecificConfig();
95 94
 }
... ...
@@ -119,7 +118,7 @@ void XSFConfig::GenerateDialogs()
119 118
 	this->infoDialog.AddEditBoxControl(DialogEditBoxBuilder().WithSize(200, 54).WithRelativePositionToSibling(RelativePosition::FROM_TOPRIGHT, Point<short>(5, -3)).IsLeftJustified().WithAutoVScroll().WithBorder().
120 119
 		WithTabStop().WithID(idInfoComment).WithVerticalScrollbar().WithWantReturn().IsMultiline());
121 120
 
122
-	this->configDialog = DialogBuilder().WithTitle(XSFConfig::commonName + L" v" + XSFConfig::versionNumber).IsPopup().WithBorder().WithDialogFrame().WithDialogModalFrame().WithSystemMenu().WithFont(L"MS Shell Dlg", 8);
121
+	this->configDialog = DialogBuilder().WithTitle(ConvertFuncs::StringToWString(XSFConfig::commonName + " v" + XSFConfig::versionNumber)).IsPopup().WithBorder().WithDialogFrame().WithDialogModalFrame().WithSystemMenu().WithFont(L"MS Shell Dlg", 8);
123 122
 	this->configDialog.AddGroupControl(DialogGroupBuilder(L"General").WithRelativePositionToParent(RelativePositionToParent::FROM_TOPLEFT, Point<short>(7, 7)));
124 123
 	this->configDialog.AddCheckBoxControl(DialogCheckBoxBuilder(L"Play infinitely").WithSize(60, 10).InGroup(L"General").WithRelativePositionToParent(RelativePosition::FROM_TOPLEFT, Point<short>(6, 11)).WithTabStop().
125 124
 		WithID(idPlayInfinitely));
... ...
@@ -247,7 +246,7 @@ INT_PTR CALLBACK XSFConfig::ConfigDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wPa
247 246
 				if (this->sampleRate == rate)
248 247
 					SendMessageW(GetDlgItem(hwndDlg, idSampleRate), CB_SETCURSEL, x, 0);
249 248
 			}
250
-			SetWindowTextW(GetDlgItem(hwndDlg, idTitleFormat), this->titleFormat.c_str());
249
+			SetWindowTextW(GetDlgItem(hwndDlg, idTitleFormat), ConvertFuncs::StringToWString(this->titleFormat).c_str());
251 250
 			break;
252 251
 		case WM_COMMAND:
253 252
 			switch (GET_WM_COMMAND_ID(wParam, lParam))
... ...
@@ -283,14 +282,14 @@ INT_PTR CALLBACK XSFConfig::InfoDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wPara
283 282
 			EndDialog(hwndDlg, IDCANCEL);
284 283
 			break;
285 284
 		case WM_INITDIALOG:
286
-			SetWindowTextW(hwndDlg, xSFFileInInfo->GetFilename().GetWStrC());
287
-			SetWindowTextW(GetDlgItem(hwndDlg, idInfoTitle), xSFFileInInfo->GetTagValue("title").GetWStrC());
288
-			SetWindowTextW(GetDlgItem(hwndDlg, idInfoArtist), xSFFileInInfo->GetTagValue("artist").GetWStrC());
289
-			SetWindowTextW(GetDlgItem(hwndDlg, idInfoGame), xSFFileInInfo->GetTagValue("game").GetWStrC());
290
-			SetWindowTextW(GetDlgItem(hwndDlg, idInfoYear), xSFFileInInfo->GetTagValue("year").GetWStrC());
291
-			SetWindowTextW(GetDlgItem(hwndDlg, idInfoGenre), xSFFileInInfo->GetTagValue("genre").GetWStrC());
292
-			SetWindowTextW(GetDlgItem(hwndDlg, idInfoCopyright), xSFFileInInfo->GetTagValue("copyright").GetWStrC());
293
-			SetWindowTextW(GetDlgItem(hwndDlg, idInfoComment), xSFFileInInfo->GetTagValue("comment").GetWStrC());
285
+			SetWindowTextW(hwndDlg, ConvertFuncs::StringToWString(xSFFileInInfo->GetFilename()).c_str());
286
+			SetWindowTextW(GetDlgItem(hwndDlg, idInfoTitle), ConvertFuncs::StringToWString(xSFFileInInfo->GetTagValue("title")).c_str());
287
+			SetWindowTextW(GetDlgItem(hwndDlg, idInfoArtist), ConvertFuncs::StringToWString(xSFFileInInfo->GetTagValue("artist")).c_str());
288
+			SetWindowTextW(GetDlgItem(hwndDlg, idInfoGame), ConvertFuncs::StringToWString(xSFFileInInfo->GetTagValue("game")).c_str());
289
+			SetWindowTextW(GetDlgItem(hwndDlg, idInfoYear), ConvertFuncs::StringToWString(xSFFileInInfo->GetTagValue("year")).c_str());
290
+			SetWindowTextW(GetDlgItem(hwndDlg, idInfoGenre), ConvertFuncs::StringToWString(xSFFileInInfo->GetTagValue("genre")).c_str());
291
+			SetWindowTextW(GetDlgItem(hwndDlg, idInfoCopyright), ConvertFuncs::StringToWString(xSFFileInInfo->GetTagValue("copyright")).c_str());
292
+			SetWindowTextW(GetDlgItem(hwndDlg, idInfoComment), ConvertFuncs::StringToWString(xSFFileInInfo->GetTagValue("comment")).c_str());
294 293
 			break;
295 294
 		case WM_COMMAND:
296 295
 			switch (GET_WM_COMMAND_ID(wParam, lParam))
... ...
@@ -333,16 +332,16 @@ void XSFConfig::CallInfoDialog(HINSTANCE hInstance, HWND hwndParent)
333 332
 void XSFConfig::ResetConfigDefaults(HWND hwndDlg)
334 333
 {
335 334
 	SendMessageW(GetDlgItem(hwndDlg, idPlayInfinitely), BM_SETCHECK, XSFConfig::initPlayInfinitely ? BST_CHECKED : BST_UNCHECKED, 0);
336
-	SetWindowTextW(GetDlgItem(hwndDlg, idDefaultLength), XSFConfig::initDefaultLength.c_str());
337
-	SetWindowTextW(GetDlgItem(hwndDlg, idDefaultFade), XSFConfig::initDefaultFade.c_str());
338
-	SetWindowTextW(GetDlgItem(hwndDlg, idSkipSilenceOnStartSec), XSFConfig::initSkipSilenceOnStartSec.c_str());
339
-	SetWindowTextW(GetDlgItem(hwndDlg, idDetectSilenceSec), XSFConfig::initDetectSilenceSec.c_str());
335
+	SetWindowTextW(GetDlgItem(hwndDlg, idDefaultLength), ConvertFuncs::StringToWString(XSFConfig::initDefaultLength).c_str());
336
+	SetWindowTextW(GetDlgItem(hwndDlg, idDefaultFade), ConvertFuncs::StringToWString(XSFConfig::initDefaultFade).c_str());
337
+	SetWindowTextW(GetDlgItem(hwndDlg, idSkipSilenceOnStartSec), ConvertFuncs::StringToWString(XSFConfig::initSkipSilenceOnStartSec).c_str());
338
+	SetWindowTextW(GetDlgItem(hwndDlg, idDetectSilenceSec), ConvertFuncs::StringToWString(XSFConfig::initDetectSilenceSec).c_str());
340 339
 	SetWindowTextW(GetDlgItem(hwndDlg, idVolume), wstringify(XSFConfig::initVolume).c_str());
341 340
 	SendMessageW(GetDlgItem(hwndDlg, idReplayGain), CB_SETCURSEL, XSFConfig::initVolumeType, 0);
342 341
 	SendMessageW(GetDlgItem(hwndDlg, idClipProtect), CB_SETCURSEL, XSFConfig::initPeakType, 0);
343 342
 	auto found = std::find(this->supportedSampleRates.begin(), this->supportedSampleRates.end(), XSFConfig::initSampleRate);
344 343
 	SendMessageW(GetDlgItem(hwndDlg, idSampleRate), CB_SETCURSEL, found - this->supportedSampleRates.begin(), 0);
345
-	SetWindowTextW(GetDlgItem(hwndDlg, idTitleFormat), XSFConfig::initTitleFormat.c_str());
344
+	SetWindowTextW(GetDlgItem(hwndDlg, idTitleFormat), ConvertFuncs::StringToWString(XSFConfig::initTitleFormat).c_str());
346 345
 
347 346
 	this->ResetSpecificConfigDefaults(hwndDlg);
348 347
 }
... ...
@@ -358,7 +357,7 @@ void XSFConfig::SaveConfigDialog(HWND hwndDlg)
358 357
 	this->volumeType = static_cast<VolumeType>(SendMessageW(GetDlgItem(hwndDlg, idReplayGain), CB_GETCURSEL, 0, 0));
359 358
 	this->peakType = static_cast<PeakType>(SendMessageW(GetDlgItem(hwndDlg, idClipProtect), CB_GETCURSEL, 0, 0));
360 359
 	this->sampleRate = XSFConfig::supportedSampleRates[SendMessageW(GetDlgItem(hwndDlg, idSampleRate), CB_GETCURSEL, 0, 0)];
361
-	this->titleFormat = this->GetTextFromWindow(GetDlgItem(hwndDlg, idTitleFormat));
360
+	this->titleFormat = ConvertFuncs::WStringToString(this->GetTextFromWindow(GetDlgItem(hwndDlg, idTitleFormat)));
362 361
 
363 362
 	this->SaveSpecificConfigDialog(hwndDlg);
364 363
 }
... ...
@@ -411,7 +410,7 @@ PeakType XSFConfig::GetPeakType() const
411 410
 	return this->peakType;
412 411
 }
413 412
 
414
-const std::wstring &XSFConfig::GetTitleFormat() const
413
+const std::string &XSFConfig::GetTitleFormat() const
415 414
 {
416 415
 	return this->titleFormat;
417 416
 }
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Core configuration handler
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -24,12 +24,12 @@ public:
24 24
 	static XSFConfigIO *Create();
25 25
 
26 26
 	virtual ~XSFConfigIO() { }
27
-	virtual void SetValueString(const std::wstring &name, const std::wstring &value) = 0;
28
-	template<typename T> void SetValue(const std::wstring &name, const T &value) { this->SetValueString(name, wstringify(value)); }
29
-	void SetValue(const std::wstring &name, const std::wstring &value) { this->SetValueString(name, value); }
30
-	virtual std::wstring GetValueString(const std::wstring &name, const std::wstring &defaultValue) = 0;
31
-	template<typename T> T GetValue(const std::wstring &name, const T &defaultValue) { return convertTo<T>(this->GetValueString(name, wstringify(defaultValue))); }
32
-	std::wstring GetValue(const std::wstring &name, const std::wstring &defaultValue) { return this->GetValueString(name, defaultValue); }
27
+	virtual void SetValueString(const std::string &name, const std::string &value) = 0;
28
+	template<typename T> void SetValue(const std::string &name, const T &value) { this->SetValueString(name, stringify(value)); }
29
+	void SetValue(const std::string &name, const std::string &value) { this->SetValueString(name, value); }
30
+	virtual std::string GetValueString(const std::string &name, const std::string &defaultValue) = 0;
31
+	template<typename T> T GetValue(const std::string &name, const T &defaultValue) { return convertTo<T>(this->GetValueString(name, stringify(defaultValue))); }
32
+	std::string GetValue(const std::string &name, const std::string &defaultValue) { return this->GetValueString(name, defaultValue); }
33 33
 };
34 34
 
35 35
 class XSFConfig
... ...
@@ -41,7 +41,7 @@ protected:
41 41
 	VolumeType volumeType;
42 42
 	PeakType peakType;
43 43
 	unsigned sampleRate;
44
-	std::wstring titleFormat;
44
+	std::string titleFormat;
45 45
 	DialogTemplate configDialog, configDialogProperty, infoDialog;
46 46
 	std::vector<unsigned> supportedSampleRates;
47 47
 	std::unique_ptr<XSFConfigIO> configIO;
... ...
@@ -58,17 +58,17 @@ protected:
58 58
 	virtual void CopySpecificConfigToMemory(XSFPlayer *xSFPlayer, bool preLoad) = 0;
59 59
 public:
60 60
 	static bool initPlayInfinitely;
61
-	static std::wstring initSkipSilenceOnStartSec, initDetectSilenceSec, initDefaultLength, initDefaultFade, initTitleFormat;
61
+	static std::string initSkipSilenceOnStartSec, initDetectSilenceSec, initDefaultLength, initDefaultFade, initTitleFormat;
62 62
 	static double initVolume;
63 63
 	static VolumeType initVolumeType;
64 64
 	static PeakType initPeakType;
65 65
 	// These are not defined in XSFConfig.cpp, they should be defined in your own config's source.
66 66
 	static unsigned initSampleRate;
67
-	static std::wstring commonName;
68
-	static std::wstring versionNumber;
67
+	static std::string commonName;
68
+	static std::string versionNumber;
69 69
 	// The Create function is not defined in XSFConfig.cpp, it should be defined in your own config's source and return a pointer to your config's class.
70 70
 	static XSFConfig *Create();
71
-	static const String &CommonNameWithVersion();
71
+	static const std::string &CommonNameWithVersion();
72 72
 
73 73
 	virtual ~XSFConfig() { }
74 74
 	void LoadConfig();
... ...
@@ -92,5 +92,5 @@ public:
92 92
 	double GetVolume() const;
93 93
 	VolumeType GetVolumeType() const;
94 94
 	PeakType GetPeakType() const;
95
-	const std::wstring &GetTitleFormat() const;
95
+	const std::string &GetTitleFormat() const;
96 96
 };
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Winamp-specification configuration handler
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2013-04-23
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -21,8 +21,8 @@ protected:
21 21
 
22 22
 	XSFConfigIO_Winamp();
23 23
 public:
24
-	void SetValueString(const std::wstring &name, const std::wstring &value);
25
-	std::wstring GetValueString(const std::wstring &name, const std::wstring &defaultValue);
24
+	void SetValueString(const std::string &name, const std::string &value);
25
+	std::string GetValueString(const std::string &name, const std::string &defaultValue);
26 26
 };
27 27
 
28 28
 XSFConfigIO *XSFConfigIO::Create()
... ...
@@ -33,7 +33,7 @@ XSFConfigIO *XSFConfigIO::Create()
33 33
 XSFConfigIO_Winamp::XSFConfigIO_Winamp() : iniFilename(L"")
34 34
 {
35 35
 	if (SendMessage(inMod.hMainWindow, WM_WA_IPC, 0, IPC_GETVERSION) >= 0x2900)
36
-		this->iniFilename = String(reinterpret_cast<char *>(SendMessage(inMod.hMainWindow, WM_WA_IPC, 0, IPC_GETINIFILE))).GetWStr();
36
+		this->iniFilename = ConvertFuncs::StringToWString(reinterpret_cast<char *>(SendMessage(inMod.hMainWindow, WM_WA_IPC, 0, IPC_GETINIFILE)));
37 37
 	else
38 38
 	{
39 39
 		auto executablePath = std::vector<wchar_t>(MAX_PATH / 2);
... ...
@@ -52,12 +52,12 @@ XSFConfigIO_Winamp::XSFConfigIO_Winamp() : iniFilename(L"")
52 52
 	}
53 53
 }
54 54
 
55
-void XSFConfigIO_Winamp::SetValueString(const std::wstring &name, const std::wstring &value)
55
+void XSFConfigIO_Winamp::SetValueString(const std::string &name, const std::string &value)
56 56
 {
57
-	WritePrivateProfileStringW(XSFConfig::commonName.c_str(), name.c_str(), value.c_str(), this->iniFilename.c_str());
57
+	WritePrivateProfileStringW(ConvertFuncs::StringToWString(XSFConfig::commonName).c_str(), ConvertFuncs::StringToWString(name).c_str(), ConvertFuncs::StringToWString(value).c_str(), this->iniFilename.c_str());
58 58
 }
59 59
 
60
-std::wstring XSFConfigIO_Winamp::GetValueString(const std::wstring &name, const std::wstring &defaultValue)
60
+std::string XSFConfigIO_Winamp::GetValueString(const std::string &name, const std::string &defaultValue)
61 61
 {
62 62
 	auto value = std::vector<wchar_t>(MAX_PATH / 2);
63 63
 
... ...
@@ -65,11 +65,11 @@ std::wstring XSFConfigIO_Winamp::GetValueString(const std::wstring &name, const
65 65
 	do
66 66
 	{
67 67
 		value.resize(value.size() * 2);
68
-		result = GetPrivateProfileStringW(XSFConfig::commonName.c_str(), name.c_str(), defaultValue.c_str(), &value[0], value.size(), this->iniFilename.c_str());
68
+		result = GetPrivateProfileStringW(ConvertFuncs::StringToWString(XSFConfig::commonName).c_str(), ConvertFuncs::StringToWString(name).c_str(), ConvertFuncs::StringToWString(defaultValue).c_str(), &value[0], value.size(), this->iniFilename.c_str());
69 69
 	} while (result + 1 == value.size());
70 70
 
71 71
 	if (!result)
72 72
 		throw std::runtime_error("Unable to get value from INI file.");
73 73
 
74
-	return std::wstring(value.begin(), value.begin() + result);
74
+	return ConvertFuncs::WStringToString(std::wstring(value.begin(), value.begin() + result));
75 75
 }
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - File structure
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -64,13 +64,13 @@ XSFFile::XSFFile(const std::string &filename, uint32_t programSizeOffset, uint32
64 64
 	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
65 65
 }
66 66
 
67
-#ifdef _MSC_VER
68
-XSFFile::XSFFile(const std::wstring &filename) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
67
+#ifdef _WIN32
68
+XSFFile::XSFFile(const std::wstring &filename) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(ConvertFuncs::WStringToString(filename))
69 69
 {
70 70
 	this->ReadXSF(filename, 0, 0, true);
71 71
 }
72 72
 
73
-XSFFile::XSFFile(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(filename)
73
+XSFFile::XSFFile(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize) : xSFType(0), hasFile(false), rawData(), reservedSection(), programSection(), tags(), fileName(ConvertFuncs::WStringToString(filename))
74 74
 {
75 75
 	this->ReadXSF(filename, programSizeOffset, programHeaderSize);
76 76
 }
... ...
@@ -86,19 +86,27 @@ void XSFFile::ReadXSF(const std::string &filename, uint32_t programSizeOffset, u
86 86
 	xSF.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
87 87
 
88 88
 	this->ReadXSF(xSF, programSizeOffset, programHeaderSize, readTagsOnly);
89
+
90
+	xSF.close();
89 91
 }
90 92
 
91
-#ifdef _MSC_VER
93
+#ifdef _WIN32
92 94
 void XSFFile::ReadXSF(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly)
93 95
 {
94 96
 	if (!FileExists(filename))
95
-		throw std::logic_error("File " + String(filename).GetAnsi() + " does not exist.");
97
+		throw std::logic_error("File " + ConvertFuncs::WStringToString(filename) + " does not exist.");
96 98
 
99
+#if defined(_WIN32) && !defined(_MSC_VER)
100
+	ifstream_wfopen xSF;
101
+#else
97 102
 	std::ifstream xSF;
103
+#endif
98 104
 	xSF.exceptions(std::ifstream::failbit | std::ifstream::badbit);
99 105
 	xSF.open(filename.c_str(), std::ifstream::in | std::ifstream::binary);
100 106
 
101 107
 	this->ReadXSF(xSF, programSizeOffset, programHeaderSize, readTagsOnly);
108
+
109
+	xSF.close();
102 110
 }
103 111
 #endif
104 112
 
... ...
@@ -214,8 +222,6 @@ void XSFFile::ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t p
214 222
 		}
215 223
 	}
216 224
 
217
-	xSF.close();
218
-
219 225
 	this->hasFile = true;
220 226
 }
221 227
 
... ...
@@ -268,9 +274,14 @@ void XSFFile::SetAllTags(const TagList &newTags)
268 274
 	this->tags = newTags;
269 275
 }
270 276
 
271
-void XSFFile::SetTag(const std::string &name, const String &value)
277
+void XSFFile::SetTag(const std::string &name, const std::string &value)
278
+{
279
+	this->tags[name] = value;
280
+}
281
+
282
+void XSFFile::SetTag(const std::string &name, const std::wstring &value)
272 283
 {
273
-	this->tags[name] = value.GetStr();
284
+	this->tags[name] = ConvertFuncs::WStringToString(value);
274 285
 }
275 286
 
276 287
 bool XSFFile::GetTagExists(const std::string &name) const
... ...
@@ -278,17 +289,17 @@ bool XSFFile::GetTagExists(const std::string &name) const
278 289
 	return this->tags.Exists(name);
279 290
 }
280 291
 
281
-String XSFFile::GetTagValue(const std::string &name) const
292
+std::string XSFFile::GetTagValue(const std::string &name) const
282 293
 {
283
-	return String(this->GetTagExists(name) ? this->tags[name] : "", this->GetTagExists("utf8"));
294
+	return this->GetTagExists(name) ? this->tags[name] : "";
284 295
 }
285 296
 
286 297
 unsigned long XSFFile::GetLengthMS(unsigned long defaultLength) const
287 298
 {
288 299
 	unsigned long length = 0;
289
-	String value = this->GetTagValue("length");
300
+	std::string value = this->GetTagValue("length");
290 301
 	if (!value.empty())
291
-		length = ConvertFuncs::StringToMS(value.GetAnsi());
302
+		length = ConvertFuncs::StringToMS(value);
292 303
 	if (!length)
293 304
 		length = defaultLength;
294 305
 	return length;
... ...
@@ -297,9 +308,9 @@ unsigned long XSFFile::GetLengthMS(unsigned long defaultLength) const
297 308
 unsigned long XSFFile::GetFadeMS(unsigned long defaultFade) const
298 309
 {
299 310
 	unsigned long fade = defaultFade;
300
-	String value = this->GetTagValue("fade");
311
+	std::string value = this->GetTagValue("fade");
301 312
 	if (!value.empty())
302
-		fade = ConvertFuncs::StringToMS(value.GetAnsi());
313
+		fade = ConvertFuncs::StringToMS(value);
303 314
 	return fade;
304 315
 }
305 316
 
... ...
@@ -307,49 +318,49 @@ double XSFFile::GetVolume(VolumeType preferredVolumeType, PeakType preferredPeak
307 318
 {
308 319
 	if (preferredVolumeType == VOLUMETYPE_NONE)
309 320
 		return 1.0;
310
-	String replaygain_album_gain = this->GetTagValue("replaygain_album_gain"), replaygain_album_peak = this->GetTagValue("replaygain_album_peak");
311
-	String replaygain_track_gain = this->GetTagValue("replaygain_track_gain"), replaygain_track_peak = this->GetTagValue("replaygain_track_peak");
312
-	String volume = this->GetTagValue("volume");
321
+	std::string replaygain_album_gain = this->GetTagValue("replaygain_album_gain"), replaygain_album_peak = this->GetTagValue("replaygain_album_peak");
322
+	std::string replaygain_track_gain = this->GetTagValue("replaygain_track_gain"), replaygain_track_peak = this->GetTagValue("replaygain_track_peak");
323
+	std::string volume = this->GetTagValue("volume");
313 324
 	double gain = 0.0;
314 325
 	bool hadReplayGain = false;
315 326
 	if (preferredVolumeType == VOLUMETYPE_REPLAYGAIN_ALBUM && !replaygain_album_gain.empty())
316 327
 	{
317
-		gain = convertTo<double>(replaygain_album_gain.GetAnsi(), false);
328
+		gain = convertTo<double>(replaygain_album_gain, false);
318 329
 		hadReplayGain = true;
319 330
 	}
320 331
 	if (!hadReplayGain && preferredVolumeType != VOLUMETYPE_VOLUME && !replaygain_track_gain.empty())
321 332
 	{
322
-		gain = convertTo<double>(replaygain_track_gain.GetAnsi(), false);
333
+		gain = convertTo<double>(replaygain_track_gain, false);
323 334
 		hadReplayGain = true;
324 335
 	}
325 336
 	if (hadReplayGain)
326 337
 	{
327 338
 		double vol = std::pow(10.0, gain / 20.0), peak = 1.0;
328 339
 		if (preferredPeakType == PEAKTYPE_REPLAYGAIN_ALBUM && !replaygain_album_peak.empty())
329
-			peak = convertTo<double>(replaygain_album_peak.GetAnsi(), false);
340
+			peak = convertTo<double>(replaygain_album_peak, false);
330 341
 		else if (preferredPeakType != PEAKTYPE_NONE && !replaygain_track_peak.empty())
331
-			peak = convertTo<double>(replaygain_track_peak.GetAnsi(), false);
342
+			peak = convertTo<double>(replaygain_track_peak, false);
332 343
 		return !fEqual(peak, 1.0) ? std::min(vol, 1.0 / peak) : vol;
333 344
 	}
334
-	return volume.empty() ? 1.0 : convertTo<double>(volume.GetAnsi(), false);
345
+	return volume.empty() ? 1.0 : convertTo<double>(volume, false);
335 346
 }
336 347
 
337
-String XSFFile::FormattedTitleOptionalBlock(const std::wstring &block, bool &hadReplacement, unsigned level) const
348
+std::string XSFFile::FormattedTitleOptionalBlock(const std::string &block, bool &hadReplacement, unsigned level) const
338 349
 {
339
-	String formattedBlock;
350
+	std::string formattedBlock;
340 351
 	for (size_t x = 0, len = block.length(); x < len; ++x)
341 352
 	{
342
-		wchar_t c = block[x];
343
-		if (c == L'%')
353
+		char c = block[x];
354
+		if (c == '%')
344 355
 		{
345 356
 			size_t origX = x;
346 357
 			for (++x; x < len; ++x)
347
-				if (block[x] == L'%')
358
+				if (block[x] == '%')
348 359
 					break;
349 360
 			if (x != len)
350 361
 			{
351
-				std::wstring tagname = block.substr(origX + 1, x - origX - 1);
352
-				String value = this->GetTagValue(String(tagname).GetAnsi());
362
+				std::string tagname = block.substr(origX + 1, x - origX - 1);
363
+				std::string value = this->GetTagValue(tagname);
353 364
 				if (!value.empty())
354 365
 				{
355 366
 					formattedBlock += value;
... ...
@@ -358,15 +369,15 @@ String XSFFile::FormattedTitleOptionalBlock(const std::wstring &block, bool &had
358 369
 			}
359 370
 			continue;
360 371
 		}
361
-		if (c == L'[' && level + 1 < 10)
372
+		if (c == '[' && level + 1 < 10)
362 373
 		{
363 374
 			size_t origX = x;
364 375
 			unsigned nests = 0;
365 376
 			for (++x; x < len; ++x)
366 377
 			{
367
-				if (block[x] == L'[')
378
+				if (block[x] == '[')
368 379
 					++nests;
369
-				else if (block[x] == L']')
380
+				else if (block[x] == ']')
370 381
 				{
371 382
 					if (!nests)
372 383
 						break;
... ...
@@ -375,9 +386,9 @@ String XSFFile::FormattedTitleOptionalBlock(const std::wstring &block, bool &had
375 386
 			}
376 387
 			if (x != len)
377 388
 			{
378
-				std::wstring innerBlock = block.substr(origX + 1, x - origX - 1);
389
+				std::string innerBlock = block.substr(origX + 1, x - origX - 1);
379 390
 				bool hadInnerReplacement = false;
380
-				String replacedBlock = this->FormattedTitleOptionalBlock(innerBlock, hadInnerReplacement, level + 1);
391
+				std::string replacedBlock = this->FormattedTitleOptionalBlock(innerBlock, hadInnerReplacement, level + 1);
381 392
 				if (hadInnerReplacement)
382 393
 					formattedBlock += replacedBlock;
383 394
 			}
... ...
@@ -388,37 +399,37 @@ String XSFFile::FormattedTitleOptionalBlock(const std::wstring &block, bool &had
388 399
 	return formattedBlock;
389 400
 }
390 401
 
391
-String XSFFile::GetFormattedTitle(const std::wstring &format) const
402
+std::string XSFFile::GetFormattedTitle(const std::string &format) const
392 403
 {
393
-	String formattedTitle;
404
+	std::string formattedTitle;
394 405
 	for (size_t x = 0, len = format.length(); x < len; ++x)
395 406
 	{
396
-		wchar_t c = format[x];
397
-		if (c == L'%')
407
+		char c = format[x];
408
+		if (c == '%')
398 409
 		{
399 410
 			size_t origX = x;
400 411
 			for (++x; x < len; ++x)
401
-				if (format[x] == L'%')
412
+				if (format[x] == '%')
402 413
 					break;
403 414
 			if (x != len)
404 415
 			{
405
-				std::wstring tagname = format.substr(origX + 1, x - origX - 1);
406
-				String value = this->GetTagValue(String(tagname).GetAnsi());
416
+				std::string tagname = format.substr(origX + 1, x - origX - 1);
417
+				std::string value = this->GetTagValue(tagname);
407 418
 				if (value.empty())
408 419
 					formattedTitle += "???";
409 420
 				else
410 421
 					formattedTitle += value;
411 422
 			}
412 423
 		}
413
-		else if (c == L'[')
424
+		else if (c == '[')
414 425
 		{
415 426
 			size_t origX = x;
416 427
 			unsigned nests = 0;
417 428
 			for (++x; x < len; ++x)
418 429
 			{
419
-				if (format[x] == L'[')
430
+				if (format[x] == '[')
420 431
 					++nests;
421
-				else if (format[x] == L']')
432
+				else if (format[x] == ']')
422 433
 				{
423 434
 					if (!nests)
424 435
 						break;
... ...
@@ -427,9 +438,9 @@ String XSFFile::GetFormattedTitle(const std::wstring &format) const
427 438
 			}
428 439
 			if (x != len)
429 440
 			{
430
-				std::wstring block = format.substr(origX + 1, x - origX - 1);
441
+				std::string block = format.substr(origX + 1, x - origX - 1);
431 442
 				bool hadReplacement = false;
432
-				String replacedBlock = this->FormattedTitleOptionalBlock(block, hadReplacement, 1);
443
+				std::string replacedBlock = this->FormattedTitleOptionalBlock(block, hadReplacement, 1);
433 444
 				if (hadReplacement)
434 445
 					formattedTitle += replacedBlock;
435 446
 			}
... ...
@@ -440,24 +451,28 @@ String XSFFile::GetFormattedTitle(const std::wstring &format) const
440 451
 	return formattedTitle;
441 452
 }
442 453
 
443
-String XSFFile::GetFilename() const
454
+std::string XSFFile::GetFilename() const
444 455
 {
445 456
 	return this->fileName;
446 457
 }
447 458
 
448
-String XSFFile::GetFilenameWithoutPath() const
459
+std::string XSFFile::GetFilenameWithoutPath() const
449 460
 {
450
-	return ExtractFilenameFromPath(this->fileName.GetStr());
461
+	return ExtractFilenameFromPath(this->fileName);
451 462
 }
452 463
 
453 464
 void XSFFile::SaveFile() const
454 465
 {
466
+#if defined(_WIN32) && !defined(_MSC_VER)
467
+	ofstream_wfopen xSF;
468
+#else
455 469
 	std::ofstream xSF;
470
+#endif
456 471
 	xSF.exceptions(std::ofstream::failbit);
457
-#ifdef _MSC_VER
458
-	xSF.open(this->fileName.GetWStrC(), std::ofstream::out | std::ofstream::binary);
472
+#ifdef _WIN32
473
+	xSF.open(ConvertFuncs::StringToWString(this->fileName).c_str(), std::ofstream::out | std::ofstream::binary);
459 474
 #else
460
-	xSF.open(this->fileName.GetStrC(), std::ofstream::out | std::ofstream::binary);
475
+	xSF.open(this->fileName.c_str(), std::ofstream::out | std::ofstream::binary);
461 476
 #endif
462 477
 
463 478
 	xSF.write(reinterpret_cast<const char *>(&this->rawData[0]), this->rawData.size());
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - File structure
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -11,7 +11,6 @@
11 11
 #include <cstdint>
12 12
 #include "convert.h"
13 13
 #include "TagList.h"
14
-#include "BigSString.h"
15 14
 
16 15
 enum VolumeType
17 16
 {
... ...
@@ -35,18 +34,18 @@ protected:
35 34
 	bool hasFile;
36 35
 	std::vector<uint8_t> rawData, reservedSection, programSection;
37 36
 	TagList tags;
38
-	String fileName;
37
+	std::string fileName;
39 38
 	void ReadXSF(const std::string &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly = false);
40
-#ifdef _MSC_VER
39
+#ifdef _WIN32
41 40
 	void ReadXSF(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly = false);
42 41
 #endif
43 42
 	void ReadXSF(std::ifstream &xSF, uint32_t programSizeOffset, uint32_t programHeaderSize, bool readTagsOnly = false);
44
-	String FormattedTitleOptionalBlock(const std::wstring &block, bool &hadReplacement, unsigned level) const;
43
+	std::string FormattedTitleOptionalBlock(const std::string &block, bool &hadReplacement, unsigned level) const;
45 44
 public:
46 45
 	XSFFile();
47 46
 	XSFFile(const std::string &filename);
48 47
 	XSFFile(const std::string &filename, uint32_t programSizeOffset, uint32_t programHeaderSize);
49
-#ifdef _MSC_VER
48
+#ifdef _WIN32
50 49
 	XSFFile(const std::wstring &filename);
51 50
 	XSFFile(const std::wstring &filename, uint32_t programSizeOffset, uint32_t programHeaderSize);
52 51
 #endif
... ...
@@ -59,18 +58,19 @@ public:
59 58
 	std::vector<uint8_t> GetProgramSection() const;
60 59
 	const TagList &GetAllTags() const;
61 60
 	void SetAllTags(const TagList &newTags);
62
-	void SetTag(const std::string &name, const String &value);
61
+	void SetTag(const std::string &name, const std::string &value);
62
+	void SetTag(const std::string &name, const std::wstring &value);
63 63
 	bool GetTagExists(const std::string &name) const;
64
-	String GetTagValue(const std::string &name) const;
64
+	std::string GetTagValue(const std::string &name) const;
65 65
 	template<typename T> T GetTagValue(const std::string &name, const T &defaultValue) const
66 66
 	{
67
-		return this->GetTagExists(name) ? convertTo<T>(this->GetTagValue(name).GetAnsi(), false) : defaultValue;
67
+		return this->GetTagExists(name) ? convertTo<T>(this->GetTagValue(name), false) : defaultValue;
68 68
 	}
69 69
 	unsigned long GetLengthMS(unsigned long defaultLength) const;
70 70
 	unsigned long GetFadeMS(unsigned long defaultFade) const;
71 71
 	double GetVolume(VolumeType preferredVolumeType, PeakType preferredPeakType) const;
72
-	String GetFormattedTitle(const std::wstring &format) const;
73
-	String GetFilename() const;
74
-	String GetFilenameWithoutPath() const;
72
+	std::string GetFormattedTitle(const std::string &format) const;
73
+	std::string GetFilename() const;
74
+	std::string GetFilenameWithoutPath() const;
75 75
 	void SaveFile() const;
76 76
 };
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Core Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-08
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * xSF - Core Player
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
... ...
@@ -37,7 +37,7 @@ public:
37 37
 	static const char *WinampDescription;
38 38
 	static const char *WinampExts;
39 39
 	static XSFPlayer *Create(const std::string &fn);
40
-#ifdef _MSC_VER
40
+#ifdef _WIN32
41 41
 	static XSFPlayer *Create(const std::wstring &fn);
42 42
 #endif
43 43
 
44 44
new file mode 100644
... ...
@@ -0,0 +1,2098 @@
1
+// This comes from llvm's libcxx project. I've copied the code from there (with very minor modifications) for use with GCC and Clang when libcxx isn't being used.
2
+
3
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(_LIBCPP_VERSION)
4
+#pragma once
5
+
6
+#include <locale>
7
+
8
+namespace std
9
+{
10
+
11
+enum codecvt_mode
12
+{
13
+	consume_header = 4,
14
+	generate_header = 2,
15
+	little_endian = 1
16
+};
17
+
18
+//                                     Valid UTF ranges
19
+//     UTF-32               UTF-16                          UTF-8               # of code points
20
+//                     first      second       first   second    third   fourth
21
+// 000000 - 00007F  0000 - 007F               00 - 7F                                 127
22
+// 000080 - 0007FF  0080 - 07FF               C2 - DF, 80 - BF                       1920
23
+// 000800 - 000FFF  0800 - 0FFF               E0 - E0, A0 - BF, 80 - BF              2048
24
+// 001000 - 00CFFF  1000 - CFFF               E1 - EC, 80 - BF, 80 - BF             49152
25
+// 00D000 - 00D7FF  D000 - D7FF               ED - ED, 80 - 9F, 80 - BF              2048
26
+// 00D800 - 00DFFF                invalid
27
+// 00E000 - 00FFFF  E000 - FFFF               EE - EF, 80 - BF, 80 - BF              8192
28
+// 010000 - 03FFFF  D800 - D8BF, DC00 - DFFF  F0 - F0, 90 - BF, 80 - BF, 80 - BF   196608
29
+// 040000 - 0FFFFF  D8C0 - DBBF, DC00 - DFFF  F1 - F3, 80 - BF, 80 - BF, 80 - BF   786432
30
+// 100000 - 10FFFF  DBC0 - DBFF, DC00 - DFFF  F4 - F4, 80 - 8F, 80 - BF, 80 - BF    65536
31
+
32
+namespace UnicodeConverters
33
+{
34
+	inline codecvt_base::result utf16_to_utf8(const uint16_t *frm, const uint16_t *frm_end, const uint16_t *&frm_nxt, uint8_t *to, uint8_t *to_end, uint8_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
35
+	{
36
+		frm_nxt = frm;
37
+		to_nxt = to;
38
+		if (mode & generate_header)
39
+		{
40
+			if (to_end - to_nxt < 3)
41
+				return codecvt_base::partial;
42
+			*to_nxt++ = 0xEF;
43
+			*to_nxt++ = 0xBB;
44
+			*to_nxt++ = 0xBF;
45
+		}
46
+		for (; frm_nxt < frm_end; ++frm_nxt)
47
+		{
48
+			uint16_t wc1 = *frm_nxt;
49
+			if (wc1 > Maxcode)
50
+				return codecvt_base::error;
51
+			if (wc1 < 0x0080)
52
+			{
53
+				if (to_end - to_nxt < 1)
54
+					return codecvt_base::partial;
55
+				*to_nxt++ = static_cast<uint8_t>(wc1);
56
+			}
57
+			else if (wc1 < 0x0800)
58
+			{
59
+				if (to_end - to_nxt < 2)
60
+					return codecvt_base::partial;
61
+				*to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
62
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
63
+			}
64
+			else if (wc1 < 0xD800)
65
+			{
66
+				if (to_end - to_nxt < 3)
67
+					return codecvt_base::partial;
68
+				*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
69
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
70
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
71
+			}
72
+			else if (wc1 < 0xDC00)
73
+			{
74
+				if (frm_end - frm_nxt < 2)
75
+					return codecvt_base::partial;
76
+				uint16_t wc2 = frm_nxt[1];
77
+				if ((wc2 & 0xFC00) != 0xDC00)
78
+					return codecvt_base::error;
79
+				if (to_end - to_nxt < 4)
80
+					return codecvt_base::partial;
81
+				if (((((static_cast<unsigned long>(wc1) & 0x03C0) >> 6) + 1) << 16) + ((static_cast<unsigned long>(wc1) & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
82
+					return codecvt_base::error;
83
+				++frm_nxt;
84
+				uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
85
+				*to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
86
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
87
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
88
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
89
+			}
90
+			else if (wc1 < 0xE000)
91
+				return codecvt_base::error;
92
+			else
93
+			{
94
+				if (to_end - to_nxt < 3)
95
+					return codecvt_base::partial;
96
+				*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
97
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
98
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
99
+			}
100
+		}
101
+		return codecvt_base::ok;
102
+	}
103
+
104
+	inline codecvt_base::result utf16_to_utf8(const uint32_t *frm, const uint32_t *frm_end, const uint32_t *&frm_nxt, uint8_t *to, uint8_t *to_end, uint8_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
105
+	{
106
+		frm_nxt = frm;
107
+		to_nxt = to;
108
+		if (mode & generate_header)
109
+		{
110
+			if (to_end - to_nxt < 3)
111
+				return codecvt_base::partial;
112
+			*to_nxt++ = 0xEF;
113
+			*to_nxt++ = 0xBB;
114
+			*to_nxt++ = 0xBF;
115
+		}
116
+		for (; frm_nxt < frm_end; ++frm_nxt)
117
+		{
118
+			uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
119
+			if (wc1 > Maxcode)
120
+				return codecvt_base::error;
121
+			if (wc1 < 0x0080)
122
+			{
123
+				if (to_end - to_nxt < 1)
124
+					return codecvt_base::partial;
125
+				*to_nxt++ = static_cast<uint8_t>(wc1);
126
+			}
127
+			else if (wc1 < 0x0800)
128
+			{
129
+				if (to_end - to_nxt < 2)
130
+					return codecvt_base::partial;
131
+				*to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
132
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
133
+			}
134
+			else if (wc1 < 0xD800)
135
+			{
136
+				if (to_end - to_nxt < 3)
137
+					return codecvt_base::partial;
138
+				*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
139
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
140
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
141
+			}
142
+			else if (wc1 < 0xDC00)
143
+			{
144
+				if (frm_end - frm_nxt < 2)
145
+					return codecvt_base::partial;
146
+				uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
147
+				if ((wc2 & 0xFC00) != 0xDC00)
148
+					return codecvt_base::error;
149
+				if (to_end - to_nxt < 4)
150
+					return codecvt_base::partial;
151
+				if (((((static_cast<unsigned long>(wc1) & 0x03C0) >> 6) + 1) << 16) + ((static_cast<unsigned long>(wc1) & 0x003F) << 10) + (wc2 & 0x03FF) > Maxcode)
152
+					return codecvt_base::error;
153
+				++frm_nxt;
154
+				uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
155
+				*to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
156
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
157
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
158
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
159
+			}
160
+			else if (wc1 < 0xE000)
161
+				return codecvt_base::error;
162
+			else
163
+			{
164
+				if (to_end - to_nxt < 3)
165
+					return codecvt_base::partial;
166
+				*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
167
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
168
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
169
+			}
170
+		}
171
+		return codecvt_base::ok;
172
+	}
173
+
174
+	inline codecvt_base::result utf8_to_utf16(const uint8_t *frm, const uint8_t *frm_end, const uint8_t *&frm_nxt, uint16_t *to, uint16_t *to_end, uint16_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
175
+	{
176
+		frm_nxt = frm;
177
+		to_nxt = to;
178
+		if ((mode & consume_header) && frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
179
+			frm_nxt += 3;
180
+		for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
181
+		{
182
+			uint8_t c1 = *frm_nxt;
183
+			if (c1 > Maxcode)
184
+				return codecvt_base::error;
185
+			if (c1 < 0x80)
186
+			{
187
+				*to_nxt = static_cast<uint16_t>(c1);
188
+				++frm_nxt;
189
+			}
190
+			else if (c1 < 0xC2)
191
+				return codecvt_base::error;
192
+			else if (c1 < 0xE0)
193
+			{
194
+				if (frm_end - frm_nxt < 2)
195
+					return codecvt_base::partial;
196
+				uint8_t c2 = frm_nxt[1];
197
+				if ((c2 & 0xC0) != 0x80)
198
+					return codecvt_base::error;
199
+				uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
200
+				if (t > Maxcode)
201
+					return codecvt_base::error;
202
+				*to_nxt = t;
203
+				frm_nxt += 2;
204
+			}
205
+			else if (c1 < 0xF0)
206
+			{
207
+				if (frm_end - frm_nxt < 3)
208
+					return codecvt_base::partial;
209
+				uint8_t c2 = frm_nxt[1];
210
+				uint8_t c3 = frm_nxt[2];
211
+				switch (c1)
212
+				{
213
+					case 0xE0:
214
+						if ((c2 & 0xE0) != 0xA0)
215
+							return codecvt_base::error;
216
+						break;
217
+					case 0xED:
218
+						if ((c2 & 0xE0) != 0x80)
219
+							return codecvt_base::error;
220
+						break;
221
+					default:
222
+						if ((c2 & 0xC0) != 0x80)
223
+							return codecvt_base::error;
224
+				}
225
+				if ((c3 & 0xC0) != 0x80)
226
+					return codecvt_base::error;
227
+				uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
228
+				if (t > Maxcode)
229
+					return codecvt_base::error;
230
+				*to_nxt = t;
231
+				frm_nxt += 3;
232
+			}
233
+			else if (c1 < 0xF5)
234
+			{
235
+				if (frm_end - frm_nxt < 4)
236
+					return codecvt_base::partial;
237
+				uint8_t c2 = frm_nxt[1];
238
+				uint8_t c3 = frm_nxt[2];
239
+				uint8_t c4 = frm_nxt[3];
240
+				switch (c1)
241
+				{
242
+					case 0xF0:
243
+						if (c2 < 0x90 || c2 > 0xBF)
244
+							return codecvt_base::error;
245
+						break;
246
+					case 0xF4:
247
+						if ((c2 & 0xF0) != 0x80)
248
+							return codecvt_base::error;
249
+						break;
250
+					default:
251
+						if ((c2 & 0xC0) != 0x80)
252
+							return codecvt_base::error;
253
+				}
254
+				if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
255
+					return codecvt_base::error;
256
+				if (to_end - to_nxt < 2)
257
+					return codecvt_base::partial;
258
+				if ((((static_cast<unsigned long>(c1) & 7) << 18) + ((static_cast<unsigned long>(c2) & 0x3F) << 12) + ((static_cast<unsigned long>(c3) & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
259
+					return codecvt_base::error;
260
+				*to_nxt = static_cast<uint16_t>(0xD800 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) | ((c2 & 0x0F) << 2) | ((c3 & 0x30) >> 4));
261
+				*++to_nxt = static_cast<uint16_t>(0xDC00 | ((c3 & 0x0F) << 6) | (c4 & 0x3F));
262
+				frm_nxt += 4;
263
+			}
264
+			else
265
+				return codecvt_base::error;
266
+		}
267
+		return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
268
+	}
269
+
270
+	inline codecvt_base::result utf8_to_utf16(const uint8_t *frm, const uint8_t *frm_end, const uint8_t *&frm_nxt, uint32_t *to, uint32_t *to_end, uint32_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
271
+	{
272
+		frm_nxt = frm;
273
+		to_nxt = to;
274
+		if ((mode & consume_header) && frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
275
+			frm_nxt += 3;
276
+		for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
277
+		{
278
+			uint8_t c1 = *frm_nxt;
279
+			if (c1 > Maxcode)
280
+				return codecvt_base::error;
281
+			if (c1 < 0x80)
282
+			{
283
+				*to_nxt = static_cast<uint32_t>(c1);
284
+				++frm_nxt;
285
+			}
286
+			else if (c1 < 0xC2)
287
+				return codecvt_base::error;
288
+			else if (c1 < 0xE0)
289
+			{
290
+				if (frm_end - frm_nxt < 2)
291
+					return codecvt_base::partial;
292
+				uint8_t c2 = frm_nxt[1];
293
+				if ((c2 & 0xC0) != 0x80)
294
+					return codecvt_base::error;
295
+				uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
296
+				if (t > Maxcode)
297
+					return codecvt_base::error;
298
+				*to_nxt = static_cast<uint32_t>(t);
299
+				frm_nxt += 2;
300
+			}
301
+			else if (c1 < 0xF0)
302
+			{
303
+				if (frm_end - frm_nxt < 3)
304
+					return codecvt_base::partial;
305
+				uint8_t c2 = frm_nxt[1];
306
+				uint8_t c3 = frm_nxt[2];
307
+				switch (c1)
308
+				{
309
+					case 0xE0:
310
+						if ((c2 & 0xE0) != 0xA0)
311
+							return codecvt_base::error;
312
+						break;
313
+					case 0xED:
314
+						if ((c2 & 0xE0) != 0x80)
315
+							return codecvt_base::error;
316
+						break;
317
+					default:
318
+						if ((c2 & 0xC0) != 0x80)
319
+							return codecvt_base::error;
320
+				}
321
+				if ((c3 & 0xC0) != 0x80)
322
+					return codecvt_base::error;
323
+				uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
324
+				if (t > Maxcode)
325
+					return codecvt_base::error;
326
+				*to_nxt = static_cast<uint32_t>(t);
327
+				frm_nxt += 3;
328
+			}
329
+			else if (c1 < 0xF5)
330
+			{
331
+				if (frm_end - frm_nxt < 4)
332
+					return codecvt_base::partial;
333
+				uint8_t c2 = frm_nxt[1];
334
+				uint8_t c3 = frm_nxt[2];
335
+				uint8_t c4 = frm_nxt[3];
336
+				switch (c1)
337
+				{
338
+					case 0xF0:
339
+						if (c2 < 0x90 || c2 > 0xBF)
340
+							return codecvt_base::error;
341
+						break;
342
+					case 0xF4:
343
+						if ((c2 & 0xF0) != 0x80)
344
+							return codecvt_base::error;
345
+						break;
346
+					default:
347
+						if ((c2 & 0xC0) != 0x80)
348
+							return codecvt_base::error;
349
+				}
350
+				if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
351
+					return codecvt_base::error;
352
+				if (to_end - to_nxt < 2)
353
+					return codecvt_base::partial;
354
+				if ((((static_cast<unsigned long>(c1) & 7) << 18) + ((static_cast<unsigned long>(c2) & 0x3F) << 12) + ((static_cast<unsigned long>(c3) & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
355
+					return codecvt_base::error;
356
+				*to_nxt = static_cast<uint32_t>(0xD800 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6) | ((c2 & 0x0F) << 2) | ((c3 & 0x30) >> 4));
357
+				*++to_nxt = static_cast<uint32_t>( 0xDC00 | ((c3 & 0x0F) << 6) | (c4 & 0x3F));
358
+				frm_nxt += 4;
359
+			}
360
+			else
361
+				return codecvt_base::error;
362
+		}
363
+		return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
364
+	}
365
+
366
+	inline int utf8_to_utf16_length(const uint8_t *frm, const uint8_t *frm_end, size_t mx, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
367
+	{
368
+		auto frm_nxt = frm;
369
+		if ((mode & consume_header) && frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
370
+			frm_nxt += 3;
371
+		for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
372
+		{
373
+			uint8_t c1 = *frm_nxt;
374
+			if (c1 > Maxcode)
375
+				break;
376
+			if (c1 < 0x80)
377
+				++frm_nxt;
378
+			else if (c1 < 0xC2)
379
+				break;
380
+			else if (c1 < 0xE0)
381
+			{
382
+				if (frm_end - frm_nxt < 2 || (frm_nxt[1] & 0xC0) != 0x80)
383
+					break;
384
+				uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
385
+				if (t > Maxcode)
386
+					break;
387
+				frm_nxt += 2;
388
+			}
389
+			else if (c1 < 0xF0)
390
+			{
391
+				if (frm_end - frm_nxt < 3)
392
+					break;
393
+				uint8_t c2 = frm_nxt[1];
394
+				uint8_t c3 = frm_nxt[2];
395
+				switch (c1)
396
+				{
397
+					case 0xE0:
398
+						if ((c2 & 0xE0) != 0xA0)
399
+							return static_cast<int>(frm_nxt - frm);
400
+						break;
401
+					case 0xED:
402
+						if ((c2 & 0xE0) != 0x80)
403
+							return static_cast<int>(frm_nxt - frm);
404
+						break;
405
+					default:
406
+						if ((c2 & 0xC0) != 0x80)
407
+							return static_cast<int>(frm_nxt - frm);
408
+				}
409
+				if ((c3 & 0xC0) != 0x80)
410
+					break;
411
+				if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
412
+					break;
413
+				frm_nxt += 3;
414
+			}
415
+			else if (c1 < 0xF5)
416
+			{
417
+				if (frm_end - frm_nxt < 4 || mx - nchar16_t < 2)
418
+					break;
419
+				uint8_t c2 = frm_nxt[1];
420
+				uint8_t c3 = frm_nxt[2];
421
+				uint8_t c4 = frm_nxt[3];
422
+				switch (c1)
423
+				{
424
+					case 0xF0:
425
+						if (c2 < 0x90 || c2 > 0xBF)
426
+							return static_cast<int>(frm_nxt - frm);
427
+						break;
428
+					case 0xF4:
429
+						if ((c2 & 0xF0) != 0x80)
430
+							return static_cast<int>(frm_nxt - frm);
431
+						break;
432
+					default:
433
+						if ((c2 & 0xC0) != 0x80)
434
+							return static_cast<int>(frm_nxt - frm);
435
+				}
436
+				if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
437
+					break;
438
+				if ((((static_cast<unsigned long>(c1) & 7) << 18) + ((static_cast<unsigned long>(c2) & 0x3F) << 12) + ((static_cast<unsigned long>(c3) & 0x3F) << 6) + (c4 & 0x3F)) > Maxcode)
439
+					break;
440
+				++nchar16_t;
441
+				frm_nxt += 4;
442
+			}
443
+			else
444
+				break;
445
+		}
446
+		return static_cast<int>(frm_nxt - frm);
447
+	}
448
+
449
+	inline codecvt_base::result ucs4_to_utf8(const uint32_t *frm, const uint32_t *frm_end, const uint32_t *&frm_nxt, uint8_t *to, uint8_t *to_end, uint8_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
450
+	{
451
+		frm_nxt = frm;
452
+		to_nxt = to;
453
+		if (mode & generate_header)
454
+		{
455
+			if (to_end - to_nxt < 3)
456
+				return codecvt_base::partial;
457
+			*to_nxt++ = 0xEF;
458
+			*to_nxt++ = 0xBB;
459
+			*to_nxt++ = 0xBF;
460
+		}
461
+		for (; frm_nxt < frm_end; ++frm_nxt)
462
+		{
463
+			uint32_t wc = *frm_nxt;
464
+			if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
465
+				return codecvt_base::error;
466
+			if (wc < 0x000080)
467
+			{
468
+				if (to_end - to_nxt < 1)
469
+					return codecvt_base::partial;
470
+				*to_nxt++ = static_cast<uint8_t>(wc);
471
+			}
472
+			else if (wc < 0x000800)
473
+			{
474
+				if (to_end - to_nxt < 2)
475
+					return codecvt_base::partial;
476
+				*to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
477
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
478
+			}
479
+			else if (wc < 0x010000)
480
+			{
481
+				if (to_end - to_nxt < 3)
482
+					return codecvt_base::partial;
483
+				*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
484
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
485
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
486
+			}
487
+			else // if (wc < 0x110000)
488
+			{
489
+				if (to_end - to_nxt < 4)
490
+					return codecvt_base::partial;
491
+				*to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
492
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
493
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
494
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
495
+			}
496
+		}
497
+		return codecvt_base::ok;
498
+	}
499
+
500
+	inline codecvt_base::result utf8_to_ucs4(const uint8_t *frm, const uint8_t *frm_end, const uint8_t *&frm_nxt, uint32_t *to, uint32_t *to_end, uint32_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
501
+	{
502
+		frm_nxt = frm;
503
+		to_nxt = to;
504
+		if ((mode & consume_header) && frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
505
+			frm_nxt += 3;
506
+		for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
507
+		{
508
+			uint8_t c1 = *frm_nxt;
509
+			if (c1 < 0x80)
510
+			{
511
+				if (c1 > Maxcode)
512
+					return codecvt_base::error;
513
+				*to_nxt = static_cast<uint32_t>(c1);
514
+				++frm_nxt;
515
+			}
516
+			else if (c1 < 0xC2)
517
+				return codecvt_base::error;
518
+			else if (c1 < 0xE0)
519
+			{
520
+				if (frm_end - frm_nxt < 2)
521
+					return codecvt_base::partial;
522
+				uint8_t c2 = frm_nxt[1];
523
+				if ((c2 & 0xC0) != 0x80)
524
+					return codecvt_base::error;
525
+				uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
526
+				if (t > Maxcode)
527
+					return codecvt_base::error;
528
+				*to_nxt = t;
529
+				frm_nxt += 2;
530
+			}
531
+			else if (c1 < 0xF0)
532
+			{
533
+				if (frm_end - frm_nxt < 3)
534
+					return codecvt_base::partial;
535
+				uint8_t c2 = frm_nxt[1];
536
+				uint8_t c3 = frm_nxt[2];
537
+				switch (c1)
538
+				{
539
+					case 0xE0:
540
+						if ((c2 & 0xE0) != 0xA0)
541
+							return codecvt_base::error;
542
+						break;
543
+					case 0xED:
544
+						if ((c2 & 0xE0) != 0x80)
545
+							return codecvt_base::error;
546
+						break;
547
+					default:
548
+						if ((c2 & 0xC0) != 0x80)
549
+							return codecvt_base::error;
550
+				}
551
+				if ((c3 & 0xC0) != 0x80)
552
+					return codecvt_base::error;
553
+				uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) |  (c3 & 0x3F));
554
+				if (t > Maxcode)
555
+					return codecvt_base::error;
556
+				*to_nxt = t;
557
+				frm_nxt += 3;
558
+			}
559
+			else if (c1 < 0xF5)
560
+			{
561
+				if (frm_end - frm_nxt < 4)
562
+					return codecvt_base::partial;
563
+				uint8_t c2 = frm_nxt[1];
564
+				uint8_t c3 = frm_nxt[2];
565
+				uint8_t c4 = frm_nxt[3];
566
+				switch (c1)
567
+				{
568
+					case 0xF0:
569
+						if (c2 < 0x90 || c2 > 0xBF)
570
+							return codecvt_base::error;
571
+						break;
572
+					case 0xF4:
573
+						if ((c2 & 0xF0) != 0x80)
574
+							return codecvt_base::error;
575
+						break;
576
+					default:
577
+						if ((c2 & 0xC0) != 0x80)
578
+							return codecvt_base::error;
579
+				}
580
+				if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
581
+					return codecvt_base::error;
582
+				uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) | ((c3 & 0x3F) << 6) |  (c4 & 0x3F));
583
+				if (t > Maxcode)
584
+					return codecvt_base::error;
585
+				*to_nxt = t;
586
+				frm_nxt += 4;
587
+			}
588
+			else
589
+				return codecvt_base::error;
590
+		}
591
+		return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
592
+	}
593
+
594
+	inline int utf8_to_ucs4_length(const uint8_t *frm, const uint8_t *frm_end, size_t mx, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
595
+	{
596
+		auto frm_nxt = frm;
597
+		if ((mode & consume_header) && frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
598
+			frm_nxt += 3;
599
+		for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
600
+		{
601
+			uint8_t c1 = *frm_nxt;
602
+			if (c1 < 0x80)
603
+			{
604
+				if (c1 > Maxcode)
605
+					break;
606
+				++frm_nxt;
607
+			}
608
+			else if (c1 < 0xC2)
609
+				break;
610
+			else if (c1 < 0xE0)
611
+			{
612
+				if (frm_end - frm_nxt < 2 || (frm_nxt[1] & 0xC0) != 0x80)
613
+					break;
614
+				if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
615
+					break;
616
+				frm_nxt += 2;
617
+			}
618
+			else if (c1 < 0xF0)
619
+			{
620
+				if (frm_end - frm_nxt < 3)
621
+					break;
622
+				uint8_t c2 = frm_nxt[1];
623
+				uint8_t c3 = frm_nxt[2];
624
+				switch (c1)
625
+				{
626
+					case 0xE0:
627
+						if ((c2 & 0xE0) != 0xA0)
628
+							return static_cast<int>(frm_nxt - frm);
629
+						break;
630
+					case 0xED:
631
+						if ((c2 & 0xE0) != 0x80)
632
+							return static_cast<int>(frm_nxt - frm);
633
+						break;
634
+					default:
635
+						if ((c2 & 0xC0) != 0x80)
636
+							return static_cast<int>(frm_nxt - frm);
637
+				}
638
+				if ((c3 & 0xC0) != 0x80)
639
+					break;
640
+				if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
641
+					break;
642
+				frm_nxt += 3;
643
+			}
644
+			else if (c1 < 0xF5)
645
+			{
646
+				if (frm_end - frm_nxt < 4)
647
+					break;
648
+				uint8_t c2 = frm_nxt[1];
649
+				uint8_t c3 = frm_nxt[2];
650
+				uint8_t c4 = frm_nxt[3];
651
+				switch (c1)
652
+				{
653
+					case 0xF0:
654
+						if (c2 < 0x90 || c2 > 0xBF)
655
+							return static_cast<int>(frm_nxt - frm);
656
+						break;
657
+					case 0xF4:
658
+						if ((c2 & 0xF0) != 0x80)
659
+							return static_cast<int>(frm_nxt - frm);
660
+						break;
661
+					default:
662
+						if ((c2 & 0xC0) != 0x80)
663
+							return static_cast<int>(frm_nxt - frm);
664
+				}
665
+				if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
666
+					break;
667
+				if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) | ((c3 & 0x3Fu) << 6)  |  (c4 & 0x3Fu)) > Maxcode)
668
+					break;
669
+				frm_nxt += 4;
670
+			}
671
+			else
672
+				break;
673
+		}
674
+		return static_cast<int>(frm_nxt - frm);
675
+	}
676
+
677
+	inline codecvt_base::result ucs2_to_utf8(const uint16_t *frm, const uint16_t *frm_end, const uint16_t *&frm_nxt, uint8_t *to, uint8_t *to_end, uint8_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
678
+	{
679
+		frm_nxt = frm;
680
+		to_nxt = to;
681
+		if (mode & generate_header)
682
+		{
683
+			if (to_end - to_nxt < 3)
684
+				return codecvt_base::partial;
685
+			*to_nxt++ = 0xEF;
686
+			*to_nxt++ = 0xBB;
687
+			*to_nxt++ = 0xBF;
688
+		}
689
+		for (; frm_nxt < frm_end; ++frm_nxt)
690
+		{
691
+			uint16_t wc = *frm_nxt;
692
+			if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
693
+				return codecvt_base::error;
694
+			if (wc < 0x0080)
695
+			{
696
+				if (to_end - to_nxt < 1)
697
+					return codecvt_base::partial;
698
+				*to_nxt++ = static_cast<uint8_t>(wc);
699
+			}
700
+			else if (wc < 0x0800)
701
+			{
702
+				if (to_end - to_nxt < 2)
703
+					return codecvt_base::partial;
704
+				*to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
705
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
706
+			}
707
+			else // if (wc <= 0xFFFF)
708
+			{
709
+				if (to_end - to_nxt < 3)
710
+					return codecvt_base::partial;
711
+				*to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
712
+				*to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
713
+				*to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
714
+			}
715
+		}
716
+		return codecvt_base::ok;
717
+	}
718
+
719
+	inline codecvt_base::result utf8_to_ucs2(const uint8_t *frm, const uint8_t *frm_end, const uint8_t *&frm_nxt, uint16_t *to, uint16_t *to_end, uint16_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
720
+	{
721
+		frm_nxt = frm;
722
+		to_nxt = to;
723
+		if ((mode & consume_header) && frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
724
+			frm_nxt += 3;
725
+		for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
726
+		{
727
+			uint8_t c1 = *frm_nxt;
728
+			if (c1 < 0x80)
729
+			{
730
+				if (c1 > Maxcode)
731
+					return codecvt_base::error;
732
+				*to_nxt = static_cast<uint16_t>(c1);
733
+				++frm_nxt;
734
+			}
735
+			else if (c1 < 0xC2)
736
+				return codecvt_base::error;
737
+			else if (c1 < 0xE0)
738
+			{
739
+				if (frm_end - frm_nxt < 2)
740
+					return codecvt_base::partial;
741
+				uint8_t c2 = frm_nxt[1];
742
+				if ((c2 & 0xC0) != 0x80)
743
+					return codecvt_base::error;
744
+				uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
745
+				if (t > Maxcode)
746
+					return codecvt_base::error;
747
+				*to_nxt = t;
748
+				frm_nxt += 2;
749
+			}
750
+			else if (c1 < 0xF0)
751
+			{
752
+				if (frm_end - frm_nxt < 3)
753
+					return codecvt_base::partial;
754
+				uint8_t c2 = frm_nxt[1];
755
+				uint8_t c3 = frm_nxt[2];
756
+				switch (c1)
757
+				{
758
+					case 0xE0:
759
+						if ((c2 & 0xE0) != 0xA0)
760
+							return codecvt_base::error;
761
+						break;
762
+					case 0xED:
763
+						if ((c2 & 0xE0) != 0x80)
764
+							return codecvt_base::error;
765
+						break;
766
+					default:
767
+						if ((c2 & 0xC0) != 0x80)
768
+							return codecvt_base::error;
769
+				}
770
+				if ((c3 & 0xC0) != 0x80)
771
+					return codecvt_base::error;
772
+				uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) |  (c3 & 0x3F));
773
+				if (t > Maxcode)
774
+					return codecvt_base::error;
775
+				*to_nxt = t;
776
+				frm_nxt += 3;
777
+			}
778
+			else
779
+				return codecvt_base::error;
780
+		}
781
+		return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
782
+	}
783
+
784
+	inline int utf8_to_ucs2_length(const uint8_t *frm, const uint8_t *frm_end, size_t mx, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
785
+	{
786
+		auto frm_nxt = frm;
787
+		if ((mode & consume_header) && frm_end - frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB && frm_nxt[2] == 0xBF)
788
+			frm_nxt += 3;
789
+		for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
790
+		{
791
+			uint8_t c1 = *frm_nxt;
792
+			if (c1 < 0x80)
793
+			{
794
+				if (c1 > Maxcode)
795
+					break;
796
+				++frm_nxt;
797
+			}
798
+			else if (c1 < 0xC2)
799
+				break;
800
+			else if (c1 < 0xE0)
801
+			{
802
+				if (frm_end - frm_nxt < 2 || (frm_nxt[1] & 0xC0) != 0x80)
803
+					break;
804
+				if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
805
+					break;
806
+				frm_nxt += 2;
807
+			}
808
+			else if (c1 < 0xF0)
809
+			{
810
+				if (frm_end - frm_nxt < 3)
811
+					break;
812
+				uint8_t c2 = frm_nxt[1];
813
+				uint8_t c3 = frm_nxt[2];
814
+				switch (c1)
815
+				{
816
+					case 0xE0:
817
+						if ((c2 & 0xE0) != 0xA0)
818
+							return static_cast<int>(frm_nxt - frm);
819
+						break;
820
+					case 0xED:
821
+						if ((c2 & 0xE0) != 0x80)
822
+							return static_cast<int>(frm_nxt - frm);
823
+						break;
824
+					default:
825
+						if ((c2 & 0xC0) != 0x80)
826
+							return static_cast<int>(frm_nxt - frm);
827
+				}
828
+				if ((c3 & 0xC0) != 0x80)
829
+					break;
830
+				if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
831
+					break;
832
+				frm_nxt += 3;
833
+			}
834
+			else
835
+				break;
836
+		}
837
+		return static_cast<int>(frm_nxt - frm);
838
+	}
839
+
840
+	inline codecvt_base::result ucs4_to_utf16be(const uint32_t *frm, const uint32_t *frm_end, const uint32_t *&frm_nxt, uint8_t *to, uint8_t *to_end, uint8_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
841
+	{
842
+		frm_nxt = frm;
843
+		to_nxt = to;
844
+		if (mode & generate_header)
845
+		{
846
+			if (to_end - to_nxt < 2)
847
+				return codecvt_base::partial;
848
+			*to_nxt++ = 0xFE;
849
+			*to_nxt++ = 0xFF;
850
+		}
851
+		for (; frm_nxt < frm_end; ++frm_nxt)
852
+		{
853
+			uint32_t wc = *frm_nxt;
854
+			if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
855
+				return codecvt_base::error;
856
+			if (wc < 0x010000)
857
+			{
858
+				if (to_end - to_nxt < 2)
859
+					return codecvt_base::partial;
860
+				*to_nxt++ = static_cast<uint8_t>(wc >> 8);
861
+				*to_nxt++ = static_cast<uint8_t>(wc);
862
+			}
863
+			else
864
+			{
865
+				if (to_end - to_nxt < 4)
866
+					return codecvt_base::partial;
867
+				uint16_t t = static_cast<uint16_t>(0xD800 | ((((wc & 0x1F0000) >> 16) - 1) << 6) | ((wc & 0x00FC00) >> 10));
868
+				*to_nxt++ = static_cast<uint8_t>(t >> 8);
869
+				*to_nxt++ = static_cast<uint8_t>(t);
870
+				t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
871
+				*to_nxt++ = static_cast<uint8_t>(t >> 8);
872
+				*to_nxt++ = static_cast<uint8_t>(t);
873
+			}
874
+		}
875
+		return codecvt_base::ok;
876
+	}
877
+
878
+	inline codecvt_base::result utf16be_to_ucs4(const uint8_t *frm, const uint8_t *frm_end, const uint8_t *&frm_nxt, uint32_t *to, uint32_t *to_end, uint32_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
879
+	{
880
+		frm_nxt = frm;
881
+		to_nxt = to;
882
+		if ((mode & consume_header) && frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
883
+			frm_nxt += 2;
884
+		for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
885
+		{
886
+			uint16_t c1 = static_cast<uint16_t>((frm_nxt[0] << 8) | frm_nxt[1]);
887
+			if ((c1 & 0xFC00) == 0xDC00)
888
+				return codecvt_base::error;
889
+			if ((c1 & 0xFC00) != 0xD800)
890
+			{
891
+				if (c1 > Maxcode)
892
+					return codecvt_base::error;
893
+				*to_nxt = static_cast<uint32_t>(c1);
894
+				frm_nxt += 2;
895
+			}
896
+			else
897
+			{
898
+				if (frm_end - frm_nxt < 4)
899
+					return codecvt_base::partial;
900
+				uint16_t c2 = static_cast<uint16_t>((frm_nxt[2] << 8) | frm_nxt[3]);
901
+				if ((c2 & 0xFC00) != 0xDC00)
902
+					return codecvt_base::error;
903
+				uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));
904
+				if (t > Maxcode)
905
+					return codecvt_base::error;
906
+				*to_nxt = t;
907
+				frm_nxt += 4;
908
+			}
909
+		}
910
+		return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
911
+	}
912
+
913
+	inline int utf16be_to_ucs4_length(const uint8_t *frm, const uint8_t *frm_end, size_t mx, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
914
+	{
915
+		auto frm_nxt = frm;
916
+		if ((mode & consume_header) && frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
917
+			frm_nxt += 2;
918
+		for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
919
+		{
920
+			uint16_t c1 = static_cast<uint16_t>((frm_nxt[0] << 8) | frm_nxt[1]);
921
+			if ((c1 & 0xFC00) == 0xDC00)
922
+				break;
923
+			if ((c1 & 0xFC00) != 0xD800)
924
+			{
925
+				if (c1 > Maxcode)
926
+					break;
927
+				frm_nxt += 2;
928
+			}
929
+			else
930
+			{
931
+				if (frm_end - frm_nxt < 4)
932
+					break;
933
+				uint16_t c2 = static_cast<uint16_t>((frm_nxt[2] << 8) | frm_nxt[3]);
934
+				if ((c2 & 0xFC00) != 0xDC00)
935
+					break;
936
+				uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));
937
+				if (t > Maxcode)
938
+					break;
939
+				frm_nxt += 4;
940
+			}
941
+		}
942
+		return static_cast<int>(frm_nxt - frm);
943
+	}
944
+
945
+	inline codecvt_base::result ucs4_to_utf16le(const uint32_t *frm, const uint32_t *frm_end, const uint32_t *&frm_nxt, uint8_t *to, uint8_t *to_end, uint8_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
946
+	{
947
+		frm_nxt = frm;
948
+		to_nxt = to;
949
+		if (mode & generate_header)
950
+		{
951
+			if (to_end - to_nxt < 2)
952
+				return codecvt_base::partial;
953
+			*to_nxt++ = 0xFF;
954
+			*to_nxt++ = 0xFE;
955
+		}
956
+		for (; frm_nxt < frm_end; ++frm_nxt)
957
+		{
958
+			uint32_t wc = *frm_nxt;
959
+			if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
960
+				return codecvt_base::error;
961
+			if (wc < 0x010000)
962
+			{
963
+				if (to_end - to_nxt < 2)
964
+					return codecvt_base::partial;
965
+				*to_nxt++ = static_cast<uint8_t>(wc);
966
+				*to_nxt++ = static_cast<uint8_t>(wc >> 8);
967
+			}
968
+			else
969
+			{
970
+				if (to_end - to_nxt < 4)
971
+					return codecvt_base::partial;
972
+				uint16_t t = static_cast<uint16_t>(0xD800 | ((((wc & 0x1F0000) >> 16) - 1) << 6) | ((wc & 0x00FC00) >> 10));
973
+				*to_nxt++ = static_cast<uint8_t>(t);
974
+				*to_nxt++ = static_cast<uint8_t>(t >> 8);
975
+				t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
976
+				*to_nxt++ = static_cast<uint8_t>(t);
977
+				*to_nxt++ = static_cast<uint8_t>(t >> 8);
978
+			}
979
+		}
980
+		return codecvt_base::ok;
981
+	}
982
+
983
+	inline codecvt_base::result utf16le_to_ucs4(const uint8_t *frm, const uint8_t *frm_end, const uint8_t *&frm_nxt, uint32_t *to, uint32_t *to_end, uint32_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
984
+	{
985
+		frm_nxt = frm;
986
+		to_nxt = to;
987
+		if ((mode & consume_header) && frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
988
+			frm_nxt += 2;
989
+		for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
990
+		{
991
+			uint16_t c1 = static_cast<uint16_t>((frm_nxt[1] << 8) | frm_nxt[0]);
992
+			if ((c1 & 0xFC00) == 0xDC00)
993
+				return codecvt_base::error;
994
+			if ((c1 & 0xFC00) != 0xD800)
995
+			{
996
+				if (c1 > Maxcode)
997
+					return codecvt_base::error;
998
+				*to_nxt = static_cast<uint32_t>(c1);
999
+				frm_nxt += 2;
1000
+			}
1001
+			else
1002
+			{
1003
+				if (frm_end - frm_nxt < 4)
1004
+					return codecvt_base::partial;
1005
+				uint16_t c2 = static_cast<uint16_t>((frm_nxt[3] << 8) | frm_nxt[2]);
1006
+				if ((c2 & 0xFC00) != 0xDC00)
1007
+					return codecvt_base::error;
1008
+				uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));
1009
+				if (t > Maxcode)
1010
+					return codecvt_base::error;
1011
+				*to_nxt = t;
1012
+				frm_nxt += 4;
1013
+			}
1014
+		}
1015
+		return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1016
+	}
1017
+
1018
+	inline int utf16le_to_ucs4_length(const uint8_t *frm, const uint8_t *frm_end, size_t mx, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
1019
+	{
1020
+		auto frm_nxt = frm;
1021
+		if ((mode & consume_header) && frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
1022
+			frm_nxt += 2;
1023
+		for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
1024
+		{
1025
+			uint16_t c1 = static_cast<uint16_t>((frm_nxt[1] << 8) | frm_nxt[0]);
1026
+			if ((c1 & 0xFC00) == 0xDC00)
1027
+				break;
1028
+			if ((c1 & 0xFC00) != 0xD800)
1029
+			{
1030
+				if (c1 > Maxcode)
1031
+					break;
1032
+				frm_nxt += 2;
1033
+			}
1034
+			else
1035
+			{
1036
+				if (frm_end - frm_nxt < 4)
1037
+					break;
1038
+				uint16_t c2 = static_cast<uint16_t>((frm_nxt[3] << 8) | frm_nxt[2]);
1039
+				if ((c2 & 0xFC00) != 0xDC00)
1040
+					break;
1041
+				uint32_t t = static_cast<uint32_t>(((((c1 & 0x03C0) >> 6) + 1) << 16) | ((c1 & 0x003F) << 10) | (c2 & 0x03FF));
1042
+				if (t > Maxcode)
1043
+					break;
1044
+				frm_nxt += 4;
1045
+			}
1046
+		}
1047
+		return static_cast<int>(frm_nxt - frm);
1048
+	}
1049
+
1050
+	inline codecvt_base::result ucs2_to_utf16be(const uint16_t *frm, const uint16_t *frm_end, const uint16_t *&frm_nxt, uint8_t *to, uint8_t *to_end, uint8_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
1051
+	{
1052
+		frm_nxt = frm;
1053
+		to_nxt = to;
1054
+		if (mode & generate_header)
1055
+		{
1056
+			if (to_end - to_nxt < 2)
1057
+				return codecvt_base::partial;
1058
+			*to_nxt++ = 0xFE;
1059
+			*to_nxt++ = 0xFF;
1060
+		}
1061
+		for (; frm_nxt < frm_end; ++frm_nxt)
1062
+		{
1063
+			uint16_t wc = *frm_nxt;
1064
+			if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
1065
+				return codecvt_base::error;
1066
+			if (to_end - to_nxt < 2)
1067
+				return codecvt_base::partial;
1068
+			*to_nxt++ = static_cast<uint8_t>(wc >> 8);
1069
+			*to_nxt++ = static_cast<uint8_t>(wc);
1070
+		}
1071
+		return codecvt_base::ok;
1072
+	}
1073
+
1074
+	inline codecvt_base::result utf16be_to_ucs2(const uint8_t *frm, const uint8_t *frm_end, const uint8_t *&frm_nxt, uint16_t *to, uint16_t *to_end, uint16_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
1075
+	{
1076
+		frm_nxt = frm;
1077
+		to_nxt = to;
1078
+		if ((mode & consume_header) && frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
1079
+			frm_nxt += 2;
1080
+		for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
1081
+		{
1082
+			uint16_t c1 = static_cast<uint16_t>((frm_nxt[0] << 8) | frm_nxt[1]);
1083
+			if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
1084
+				return codecvt_base::error;
1085
+			*to_nxt = c1;
1086
+			frm_nxt += 2;
1087
+		}
1088
+		return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1089
+	}
1090
+
1091
+	inline int utf16be_to_ucs2_length(const uint8_t *frm, const uint8_t *frm_end, size_t mx, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
1092
+	{
1093
+		auto frm_nxt = frm;
1094
+		if ((mode & consume_header) && frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
1095
+			frm_nxt += 2;
1096
+		for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
1097
+		{
1098
+			uint16_t c1 = static_cast<uint16_t>((frm_nxt[0] << 8) | frm_nxt[1]);
1099
+			if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
1100
+				break;
1101
+			frm_nxt += 2;
1102
+		}
1103
+		return static_cast<int>(frm_nxt - frm);
1104
+	}
1105
+
1106
+	inline codecvt_base::result ucs2_to_utf16le(const uint16_t *frm, const uint16_t *frm_end, const uint16_t *&frm_nxt, uint8_t *to, uint8_t *to_end, uint8_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
1107
+	{
1108
+		frm_nxt = frm;
1109
+		to_nxt = to;
1110
+		if (mode & generate_header)
1111
+		{
1112
+			if (to_end - to_nxt < 2)
1113
+				return codecvt_base::partial;
1114
+			*to_nxt++ = 0xFF;
1115
+			*to_nxt++ = 0xFE;
1116
+		}
1117
+		for (; frm_nxt < frm_end; ++frm_nxt)
1118
+		{
1119
+			uint16_t wc = *frm_nxt;
1120
+			if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
1121
+				return codecvt_base::error;
1122
+			if (to_end - to_nxt < 2)
1123
+				return codecvt_base::partial;
1124
+			*to_nxt++ = static_cast<uint8_t>(wc);
1125
+			*to_nxt++ = static_cast<uint8_t>(wc >> 8);
1126
+		}
1127
+		return codecvt_base::ok;
1128
+	}
1129
+
1130
+	inline codecvt_base::result utf16le_to_ucs2(const uint8_t *frm, const uint8_t *frm_end, const uint8_t *&frm_nxt, uint16_t *to, uint16_t *to_end, uint16_t *&to_nxt, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
1131
+	{
1132
+		frm_nxt = frm;
1133
+		to_nxt = to;
1134
+		if ((mode & consume_header) && frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
1135
+			frm_nxt += 2;
1136
+		for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
1137
+		{
1138
+			uint16_t c1 = static_cast<uint16_t>((frm_nxt[1] << 8) | frm_nxt[0]);
1139
+			if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
1140
+				return codecvt_base::error;
1141
+			*to_nxt = c1;
1142
+			frm_nxt += 2;
1143
+		}
1144
+		return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1145
+	}
1146
+
1147
+	inline int utf16le_to_ucs2_length(const uint8_t *frm, const uint8_t *frm_end, size_t mx, unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = static_cast<codecvt_mode>(0))
1148
+	{
1149
+		auto frm_nxt = frm;
1150
+		if ((mode & consume_header) && frm_end - frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
1151
+			frm_nxt += 2;
1152
+		for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
1153
+		{
1154
+			uint16_t c1 = static_cast<uint16_t>((frm_nxt[1] << 8) | frm_nxt[0]);
1155
+			if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
1156
+				break;
1157
+			frm_nxt += 2;
1158
+		}
1159
+		return static_cast<int>(frm_nxt - frm);
1160
+	}
1161
+}
1162
+
1163
+template<> class codecvt<char16_t, char, mbstate_t> : public locale::facet, public codecvt_base
1164
+{
1165
+public:
1166
+	typedef char16_t intern_type;
1167
+	typedef char extern_type;
1168
+	typedef mbstate_t state_type;
1169
+
1170
+	explicit codecvt(size_t __refs = 0) : locale::facet(__refs) { }
1171
+
1172
+	result out(state_type &__st, const intern_type *__frm, const intern_type *__frm_end, const intern_type *&__frm_nxt, extern_type *__to, extern_type *__to_end, extern_type *&__to_nxt) const
1173
+	{
1174
+		return this->do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1175
+	}
1176
+
1177
+	result unshift(state_type &__st, extern_type *__to, extern_type *__to_end, extern_type *&__to_nxt) const
1178
+	{
1179
+		return this->do_unshift(__st, __to, __to_end, __to_nxt);
1180
+	}
1181
+
1182
+	result in(state_type &__st, const extern_type *__frm, const extern_type *__frm_end, const extern_type *&__frm_nxt, intern_type *__to, intern_type *__to_end, intern_type *&__to_nxt) const
1183
+	{
1184
+		return this->do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1185
+	}
1186
+
1187
+	int encoding() const throw()
1188
+	{
1189
+		return this->do_encoding();
1190
+	}
1191
+
1192
+	bool always_noconv() const throw()
1193
+	{
1194
+		return this->do_always_noconv();
1195
+	}
1196
+
1197
+	int length(state_type &__st, const extern_type *__frm, const extern_type *__end, size_t __mx) const
1198
+	{
1199
+		return this->do_length(__st, __frm, __end, __mx);
1200
+	}
1201
+
1202
+	int max_length() const throw()
1203
+	{
1204
+		return this->do_max_length();
1205
+	}
1206
+
1207
+	static locale::id id;
1208
+
1209
+protected:
1210
+	explicit codecvt(const char *, size_t __refs = 0) : locale::facet(__refs) { }
1211
+
1212
+	~codecvt() { }
1213
+
1214
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1215
+	{
1216
+		auto _frm = reinterpret_cast<const uint16_t *>(frm);
1217
+		auto _frm_end = reinterpret_cast<const uint16_t *>(frm_end);
1218
+		auto _frm_nxt = _frm;
1219
+		auto _to = reinterpret_cast<uint8_t *>(to);
1220
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1221
+		auto _to_nxt = _to;
1222
+		auto r = UnicodeConverters::utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
1223
+		frm_nxt = frm + (_frm_nxt - _frm);
1224
+		to_nxt = to + (_to_nxt - _to);
1225
+		return r;
1226
+	}
1227
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1228
+	{
1229
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1230
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1231
+		auto _frm_nxt = _frm;
1232
+		auto _to = reinterpret_cast<uint16_t *>(to);
1233
+		auto _to_end = reinterpret_cast<uint16_t *>(to_end);
1234
+		auto _to_nxt = _to;
1235
+		auto r = UnicodeConverters::utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
1236
+		frm_nxt = frm + (_frm_nxt - _frm);
1237
+		to_nxt = to + (_to_nxt - _to);
1238
+		return r;
1239
+	}
1240
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1241
+	{
1242
+		to_nxt = to;
1243
+		return noconv;
1244
+	}
1245
+	virtual int do_encoding() const throw() { return 0; }
1246
+	virtual bool do_always_noconv() const throw() { return false; }
1247
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1248
+	{
1249
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1250
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1251
+		return UnicodeConverters::utf8_to_utf16_length(_frm, _frm_end, mx);
1252
+	}
1253
+	virtual int do_max_length() const throw() { return 4; }
1254
+};
1255
+
1256
+template<> class codecvt<char32_t, char, mbstate_t> : public locale::facet, public codecvt_base
1257
+{
1258
+public:
1259
+	typedef char32_t intern_type;
1260
+	typedef char extern_type;
1261
+	typedef mbstate_t state_type;
1262
+
1263
+	explicit codecvt(size_t __refs = 0) : locale::facet(__refs) { }
1264
+
1265
+	result out(state_type &__st, const intern_type *__frm, const intern_type *__frm_end, const intern_type *&__frm_nxt, extern_type *__to, extern_type *__to_end, extern_type *&__to_nxt) const
1266
+	{
1267
+		return this->do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1268
+	}
1269
+
1270
+	result unshift(state_type &__st, extern_type *__to, extern_type *__to_end, extern_type *&__to_nxt) const
1271
+	{
1272
+		return this->do_unshift(__st, __to, __to_end, __to_nxt);
1273
+	}
1274
+
1275
+	result in(state_type &__st, const extern_type *__frm, const extern_type *__frm_end, const extern_type *&__frm_nxt, intern_type *__to, intern_type *__to_end, intern_type *&__to_nxt) const
1276
+	{
1277
+		return this->do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1278
+	}
1279
+
1280
+	int encoding() const throw()
1281
+	{
1282
+		return this->do_encoding();
1283
+	}
1284
+
1285
+	bool always_noconv() const throw()
1286
+	{
1287
+		return this->do_always_noconv();
1288
+	}
1289
+
1290
+	int length(state_type &__st, const extern_type *__frm, const extern_type *__end, size_t __mx) const
1291
+	{
1292
+		return this->do_length(__st, __frm, __end, __mx);
1293
+	}
1294
+
1295
+	int max_length() const throw()
1296
+	{
1297
+		return this->do_max_length();
1298
+	}
1299
+
1300
+	static locale::id id;
1301
+
1302
+protected:
1303
+	explicit codecvt(const char *, size_t __refs = 0) : locale::facet(__refs) { }
1304
+
1305
+	~codecvt() { }
1306
+
1307
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1308
+	{
1309
+		auto _frm = reinterpret_cast<const uint32_t *>(frm);
1310
+		auto _frm_end = reinterpret_cast<const uint32_t *>(frm_end);
1311
+		auto _frm_nxt = _frm;
1312
+		auto _to = reinterpret_cast<uint8_t *>(to);
1313
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1314
+		auto _to_nxt = _to;
1315
+		auto r = UnicodeConverters::ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
1316
+		frm_nxt = frm + (_frm_nxt - _frm);
1317
+		to_nxt = to + (_to_nxt - _to);
1318
+		return r;
1319
+	}
1320
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1321
+	{
1322
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1323
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1324
+		auto _frm_nxt = _frm;
1325
+		auto _to = reinterpret_cast<uint32_t *>(to);
1326
+		auto _to_end = reinterpret_cast<uint32_t *>(to_end);
1327
+		auto _to_nxt = _to;
1328
+		auto r = UnicodeConverters::utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
1329
+		frm_nxt = frm + (_frm_nxt - _frm);
1330
+		to_nxt = to + (_to_nxt - _to);
1331
+		return r;
1332
+	}
1333
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1334
+	{
1335
+		to_nxt = to;
1336
+		return noconv;
1337
+	}
1338
+	virtual int do_encoding() const throw() { return 0; }
1339
+	virtual bool do_always_noconv() const throw() { return false; }
1340
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1341
+	{
1342
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1343
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1344
+		return UnicodeConverters::utf8_to_ucs4_length(_frm, _frm_end, mx);
1345
+	}
1346
+	virtual int do_max_length() const throw() { return 4; }
1347
+};
1348
+
1349
+template<class _Elem> class __codecvt_utf8;
1350
+
1351
+template<> class __codecvt_utf8<wchar_t> : public codecvt<wchar_t, char, mbstate_t>
1352
+{
1353
+	unsigned long _Maxcode_;
1354
+	codecvt_mode _Mode_;
1355
+public:
1356
+	typedef wchar_t intern_type;
1357
+	typedef char extern_type;
1358
+	typedef mbstate_t state_type;
1359
+
1360
+	explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1361
+protected:
1362
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1363
+	{
1364
+#ifdef _WIN32
1365
+		auto _frm = reinterpret_cast<const uint16_t *>(frm);
1366
+		auto _frm_end = reinterpret_cast<const uint16_t *>(frm_end);
1367
+#else
1368
+		auto _frm = reinterpret_cast<const uint32_t *>(frm);
1369
+		auto _frm_end = reinterpret_cast<const uint32_t *>(frm_end);
1370
+#endif
1371
+		auto _frm_nxt = _frm;
1372
+		auto _to = reinterpret_cast<uint8_t *>(to);
1373
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1374
+		auto _to_nxt = _to;
1375
+		auto r = UnicodeConverters::
1376
+#ifdef _WIN32
1377
+			ucs2_to_utf8
1378
+#else
1379
+			ucs4_to_utf8
1380
+#endif
1381
+			(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1382
+		frm_nxt = frm + (_frm_nxt - _frm);
1383
+		to_nxt = to + (_to_nxt - _to);
1384
+		return r;
1385
+	}
1386
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1387
+	{
1388
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1389
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1390
+		auto _frm_nxt = _frm;
1391
+#ifdef _WIN32
1392
+		auto _to = reinterpret_cast<uint16_t *>(to);
1393
+		auto _to_end = reinterpret_cast<uint16_t *>(to_end);
1394
+#else
1395
+		auto _to = reinterpret_cast<uint32_t *>(to);
1396
+		auto _to_end = reinterpret_cast<uint32_t *>(to_end);
1397
+#endif
1398
+		auto _to_nxt = _to;
1399
+		auto r = UnicodeConverters::
1400
+#ifdef _WIN32
1401
+			utf8_to_ucs2
1402
+#else
1403
+			utf8_to_ucs4
1404
+#endif
1405
+			(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1406
+		frm_nxt = frm + (_frm_nxt - _frm);
1407
+		to_nxt = to + (_to_nxt - _to);
1408
+		return r;
1409
+	}
1410
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1411
+	{
1412
+		to_nxt = to;
1413
+		return noconv;
1414
+	}
1415
+	virtual int do_encoding() const throw() { return 0; }
1416
+	virtual bool do_always_noconv() const throw() { return false; }
1417
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1418
+	{
1419
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1420
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1421
+		return UnicodeConverters::utf8_to_ucs4_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
1422
+	}
1423
+	virtual int do_max_length() const throw()
1424
+	{
1425
+		if (this->_Mode_ & consume_header)
1426
+			return 7;
1427
+		return 4;
1428
+	}
1429
+};
1430
+
1431
+template<> class __codecvt_utf8<char16_t> : public codecvt<char16_t, char, mbstate_t>
1432
+{
1433
+	unsigned long _Maxcode_;
1434
+	codecvt_mode _Mode_;
1435
+public:
1436
+	typedef char16_t intern_type;
1437
+	typedef char extern_type;
1438
+	typedef mbstate_t state_type;
1439
+
1440
+	explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1441
+protected:
1442
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1443
+	{
1444
+		auto _frm = reinterpret_cast<const uint16_t *>(frm);
1445
+		auto _frm_end = reinterpret_cast<const uint16_t *>(frm_end);
1446
+		auto _frm_nxt = _frm;
1447
+		auto _to = reinterpret_cast<uint8_t *>(to);
1448
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1449
+		auto _to_nxt = _to;
1450
+		auto r = UnicodeConverters::ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1451
+		frm_nxt = frm + (_frm_nxt - _frm);
1452
+		to_nxt = to + (_to_nxt - _to);
1453
+		return r;
1454
+	}
1455
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1456
+	{
1457
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1458
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1459
+		auto _frm_nxt = _frm;
1460
+		auto _to = reinterpret_cast<uint16_t *>(to);
1461
+		auto _to_end = reinterpret_cast<uint16_t *>(to_end);
1462
+		auto _to_nxt = _to;
1463
+		auto r = UnicodeConverters::utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1464
+		frm_nxt = frm + (_frm_nxt - _frm);
1465
+		to_nxt = to + (_to_nxt - _to);
1466
+		return r;
1467
+	}
1468
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1469
+	{
1470
+		to_nxt = to;
1471
+		return noconv;
1472
+	}
1473
+	virtual int do_encoding() const throw() { return 0; }
1474
+	virtual bool do_always_noconv() const throw() { return false; }
1475
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1476
+	{
1477
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1478
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1479
+		return UnicodeConverters::utf8_to_ucs2_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
1480
+	}
1481
+	virtual int do_max_length() const throw()
1482
+	{
1483
+		if (this->_Mode_ & consume_header)
1484
+			return 6;
1485
+		return 3;
1486
+	}
1487
+};
1488
+
1489
+template<> class __codecvt_utf8<char32_t> : public codecvt<char32_t, char, mbstate_t>
1490
+{
1491
+	unsigned long _Maxcode_;
1492
+	codecvt_mode _Mode_;
1493
+public:
1494
+	typedef char32_t intern_type;
1495
+	typedef char extern_type;
1496
+	typedef mbstate_t state_type;
1497
+
1498
+	explicit __codecvt_utf8(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1499
+protected:
1500
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1501
+	{
1502
+		auto _frm = reinterpret_cast<const uint32_t *>(frm);
1503
+		auto _frm_end = reinterpret_cast<const uint32_t *>(frm_end);
1504
+		auto _frm_nxt = _frm;
1505
+		auto _to = reinterpret_cast<uint8_t *>(to);
1506
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1507
+		auto _to_nxt = _to;
1508
+		auto r = UnicodeConverters::ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1509
+		frm_nxt = frm + (_frm_nxt - _frm);
1510
+		to_nxt = to + (_to_nxt - _to);
1511
+		return r;
1512
+	}
1513
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1514
+	{
1515
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1516
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1517
+		auto _frm_nxt = _frm;
1518
+		auto _to = reinterpret_cast<uint32_t *>(to);
1519
+		auto _to_end = reinterpret_cast<uint32_t *>(to_end);
1520
+		auto _to_nxt = _to;
1521
+		auto r = UnicodeConverters::utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1522
+		frm_nxt = frm + (_frm_nxt - _frm);
1523
+		to_nxt = to + (_to_nxt - _to);
1524
+		return r;
1525
+	}
1526
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1527
+	{
1528
+		to_nxt = to;
1529
+		return noconv;
1530
+	}
1531
+	virtual int do_encoding() const throw() { return 0; }
1532
+	virtual bool do_always_noconv() const throw() { return false; }
1533
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1534
+	{
1535
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1536
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1537
+		return UnicodeConverters::utf8_to_ucs4_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
1538
+	}
1539
+	virtual int do_max_length() const throw()
1540
+	{
1541
+		if (this->_Mode_ & consume_header)
1542
+			return 7;
1543
+		return 4;
1544
+	}
1545
+};
1546
+
1547
+template<class _Elem, unsigned long _Maxcode = 0x10ffff, codecvt_mode _Mode = static_cast<codecvt_mode>(0)> class codecvt_utf8 : public __codecvt_utf8<_Elem>
1548
+{
1549
+public:
1550
+	explicit codecvt_utf8(size_t __refs = 0) : __codecvt_utf8<_Elem>(__refs, _Maxcode, _Mode) { }
1551
+
1552
+	~codecvt_utf8() { }
1553
+};
1554
+
1555
+template<class _Elem, bool _LittleEndian> class __codecvt_utf16;
1556
+
1557
+template<> class __codecvt_utf16<wchar_t, false> : public codecvt<wchar_t, char, mbstate_t>
1558
+{
1559
+	unsigned long _Maxcode_;
1560
+	codecvt_mode _Mode_;
1561
+public:
1562
+	typedef wchar_t intern_type;
1563
+	typedef char extern_type;
1564
+	typedef mbstate_t state_type;
1565
+
1566
+	explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1567
+protected:
1568
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1569
+	{
1570
+		auto _frm = reinterpret_cast<const uint32_t *>(frm);
1571
+		auto _frm_end = reinterpret_cast<const uint32_t *>(frm_end);
1572
+		auto _frm_nxt = _frm;
1573
+		auto _to = reinterpret_cast<uint8_t *>(to);
1574
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1575
+		auto _to_nxt = _to;
1576
+		auto r = UnicodeConverters::ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1577
+		frm_nxt = frm + (_frm_nxt - _frm);
1578
+		to_nxt = to + (_to_nxt - _to);
1579
+		return r;
1580
+	}
1581
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1582
+	{
1583
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1584
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1585
+		auto _frm_nxt = _frm;
1586
+		auto _to = reinterpret_cast<uint32_t *>(to);
1587
+		auto _to_end = reinterpret_cast<uint32_t *>(to_end);
1588
+		auto _to_nxt = _to;
1589
+		auto r = UnicodeConverters::utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1590
+		frm_nxt = frm + (_frm_nxt - _frm);
1591
+		to_nxt = to + (_to_nxt - _to);
1592
+		return r;
1593
+	}
1594
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1595
+	{
1596
+		to_nxt = to;
1597
+		return noconv;
1598
+	}
1599
+	virtual int do_encoding() const throw() { return 0; }
1600
+	virtual bool do_always_noconv() const throw() { return false; }
1601
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1602
+	{
1603
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1604
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1605
+		return UnicodeConverters::utf16be_to_ucs4_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
1606
+	}
1607
+	virtual int do_max_length() const throw()
1608
+	{
1609
+		if (this->_Mode_ & consume_header)
1610
+			return 6;
1611
+		return 4;
1612
+	}
1613
+};
1614
+
1615
+template<> class __codecvt_utf16<wchar_t, true> : public codecvt<wchar_t, char, mbstate_t>
1616
+{
1617
+	unsigned long _Maxcode_;
1618
+	codecvt_mode _Mode_;
1619
+public:
1620
+	typedef wchar_t intern_type;
1621
+	typedef char extern_type;
1622
+	typedef mbstate_t state_type;
1623
+
1624
+	explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1625
+protected:
1626
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1627
+	{
1628
+		auto _frm = reinterpret_cast<const uint32_t *>(frm);
1629
+		auto _frm_end = reinterpret_cast<const uint32_t *>(frm_end);
1630
+		auto _frm_nxt = _frm;
1631
+		auto _to = reinterpret_cast<uint8_t *>(to);
1632
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1633
+		auto _to_nxt = _to;
1634
+		auto r = UnicodeConverters::ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1635
+		frm_nxt = frm + (_frm_nxt - _frm);
1636
+		to_nxt = to + (_to_nxt - _to);
1637
+		return r;
1638
+	}
1639
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1640
+	{
1641
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1642
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1643
+		auto _frm_nxt = _frm;
1644
+		auto _to = reinterpret_cast<uint32_t *>(to);
1645
+		auto _to_end = reinterpret_cast<uint32_t *>(to_end);
1646
+		auto _to_nxt = _to;
1647
+		auto r = UnicodeConverters::utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1648
+		frm_nxt = frm + (_frm_nxt - _frm);
1649
+		to_nxt = to + (_to_nxt - _to);
1650
+		return r;
1651
+	}
1652
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1653
+	{
1654
+		to_nxt = to;
1655
+		return noconv;
1656
+	}
1657
+	virtual int do_encoding() const throw() { return 0; }
1658
+	virtual bool do_always_noconv() const throw() { return false; }
1659
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1660
+	{
1661
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1662
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1663
+		return UnicodeConverters::utf16le_to_ucs4_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
1664
+	}
1665
+	virtual int do_max_length() const throw()
1666
+	{
1667
+		if (this->_Mode_ & consume_header)
1668
+			return 6;
1669
+		return 4;
1670
+	}
1671
+};
1672
+
1673
+template<> class __codecvt_utf16<char16_t, false> : public codecvt<char16_t, char, mbstate_t>
1674
+{
1675
+	unsigned long _Maxcode_;
1676
+	codecvt_mode _Mode_;
1677
+public:
1678
+	typedef char16_t intern_type;
1679
+	typedef char extern_type;
1680
+	typedef mbstate_t state_type;
1681
+
1682
+	explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1683
+protected:
1684
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1685
+	{
1686
+		auto _frm = reinterpret_cast<const uint16_t *>(frm);
1687
+		auto _frm_end = reinterpret_cast<const uint16_t *>(frm_end);
1688
+		auto _frm_nxt = _frm;
1689
+		auto _to = reinterpret_cast<uint8_t *>(to);
1690
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1691
+		auto _to_nxt = _to;
1692
+		auto r = UnicodeConverters::ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1693
+		frm_nxt = frm + (_frm_nxt - _frm);
1694
+		to_nxt = to + (_to_nxt - _to);
1695
+		return r;
1696
+	}
1697
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1698
+	{
1699
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1700
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1701
+		auto _frm_nxt = _frm;
1702
+		auto _to = reinterpret_cast<uint16_t *>(to);
1703
+		auto _to_end = reinterpret_cast<uint16_t *>(to_end);
1704
+		auto _to_nxt = _to;
1705
+		auto r = UnicodeConverters::utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1706
+		frm_nxt = frm + (_frm_nxt - _frm);
1707
+		to_nxt = to + (_to_nxt - _to);
1708
+		return r;
1709
+	}
1710
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1711
+	{
1712
+		to_nxt = to;
1713
+		return noconv;
1714
+	}
1715
+	virtual int do_encoding() const throw() { return 0; }
1716
+	virtual bool do_always_noconv() const throw() { return false; }
1717
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1718
+	{
1719
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1720
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1721
+		return UnicodeConverters::utf16be_to_ucs2_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
1722
+	}
1723
+	virtual int do_max_length() const throw()
1724
+	{
1725
+		if (this->_Mode_ & consume_header)
1726
+			return 4;
1727
+		return 2;
1728
+	}
1729
+};
1730
+
1731
+template<> class __codecvt_utf16<char16_t, true> : public codecvt<char16_t, char, mbstate_t>
1732
+{
1733
+	unsigned long _Maxcode_;
1734
+	codecvt_mode _Mode_;
1735
+public:
1736
+	typedef char16_t intern_type;
1737
+	typedef char extern_type;
1738
+	typedef mbstate_t state_type;
1739
+
1740
+	explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1741
+protected:
1742
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1743
+	{
1744
+		auto _frm = reinterpret_cast<const uint16_t *>(frm);
1745
+		auto _frm_end = reinterpret_cast<const uint16_t *>(frm_end);
1746
+		auto _frm_nxt = _frm;
1747
+		auto _to = reinterpret_cast<uint8_t *>(to);
1748
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1749
+		auto _to_nxt = _to;
1750
+		auto r = UnicodeConverters::ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1751
+		frm_nxt = frm + (_frm_nxt - _frm);
1752
+		to_nxt = to + (_to_nxt - _to);
1753
+		return r;
1754
+	}
1755
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1756
+	{
1757
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1758
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1759
+		auto _frm_nxt = _frm;
1760
+		auto _to = reinterpret_cast<uint16_t *>(to);
1761
+		auto _to_end = reinterpret_cast<uint16_t *>(to_end);
1762
+		auto _to_nxt = _to;
1763
+		auto r = UnicodeConverters::utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1764
+		frm_nxt = frm + (_frm_nxt - _frm);
1765
+		to_nxt = to + (_to_nxt - _to);
1766
+		return r;
1767
+	}
1768
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1769
+	{
1770
+		to_nxt = to;
1771
+		return noconv;
1772
+	}
1773
+	virtual int do_encoding() const throw() { return 0; }
1774
+	virtual bool do_always_noconv() const throw() { return false; }
1775
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1776
+	{
1777
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1778
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1779
+		return UnicodeConverters::utf16le_to_ucs2_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
1780
+	}
1781
+	virtual int do_max_length() const throw()
1782
+	{
1783
+		if (this->_Mode_ & consume_header)
1784
+			return 4;
1785
+		return 2;
1786
+	}
1787
+};
1788
+
1789
+template<> class __codecvt_utf16<char32_t, false> : public codecvt<char32_t, char, mbstate_t>
1790
+{
1791
+	unsigned long _Maxcode_;
1792
+	codecvt_mode _Mode_;
1793
+public:
1794
+	typedef char32_t intern_type;
1795
+	typedef char extern_type;
1796
+	typedef mbstate_t state_type;
1797
+
1798
+	explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1799
+protected:
1800
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1801
+	{
1802
+		auto _frm = reinterpret_cast<const uint32_t *>(frm);
1803
+		auto _frm_end = reinterpret_cast<const uint32_t *>(frm_end);
1804
+		auto _frm_nxt = _frm;
1805
+		auto _to = reinterpret_cast<uint8_t *>(to);
1806
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1807
+		auto _to_nxt = _to;
1808
+		auto r = UnicodeConverters::ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1809
+		frm_nxt = frm + (_frm_nxt - _frm);
1810
+		to_nxt = to + (_to_nxt - _to);
1811
+		return r;
1812
+	}
1813
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1814
+	{
1815
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1816
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1817
+		auto _frm_nxt = _frm;
1818
+		auto _to = reinterpret_cast<uint32_t *>(to);
1819
+		auto _to_end = reinterpret_cast<uint32_t *>(to_end);
1820
+		auto _to_nxt = _to;
1821
+		auto r = UnicodeConverters::utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1822
+		frm_nxt = frm + (_frm_nxt - _frm);
1823
+		to_nxt = to + (_to_nxt - _to);
1824
+		return r;
1825
+	}
1826
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1827
+	{
1828
+		to_nxt = to;
1829
+		return noconv;
1830
+	}
1831
+	virtual int do_encoding() const throw() { return 0; }
1832
+	virtual bool do_always_noconv() const throw() { return false; }
1833
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1834
+	{
1835
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1836
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1837
+		return UnicodeConverters::utf16be_to_ucs4_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
1838
+	}
1839
+	virtual int do_max_length() const throw()
1840
+	{
1841
+		if (this->_Mode_ & consume_header)
1842
+			return 6;
1843
+		return 4;
1844
+	}
1845
+};
1846
+
1847
+template<> class __codecvt_utf16<char32_t, true> : public codecvt<char32_t, char, mbstate_t>
1848
+{
1849
+	unsigned long _Maxcode_;
1850
+	codecvt_mode _Mode_;
1851
+public:
1852
+	typedef char32_t intern_type;
1853
+	typedef char extern_type;
1854
+	typedef mbstate_t state_type;
1855
+
1856
+	explicit __codecvt_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1857
+protected:
1858
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1859
+	{
1860
+		auto _frm = reinterpret_cast<const uint32_t *>(frm);
1861
+		auto _frm_end = reinterpret_cast<const uint32_t *>(frm_end);
1862
+		auto _frm_nxt = _frm;
1863
+		auto _to = reinterpret_cast<uint8_t *>(to);
1864
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1865
+		auto _to_nxt = _to;
1866
+		auto r = UnicodeConverters::ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1867
+		frm_nxt = frm + (_frm_nxt - _frm);
1868
+		to_nxt = to + (_to_nxt - _to);
1869
+		return r;
1870
+	}
1871
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1872
+	{
1873
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1874
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1875
+		auto _frm_nxt = _frm;
1876
+		auto _to = reinterpret_cast<uint32_t *>(to);
1877
+		auto _to_end = reinterpret_cast<uint32_t *>(to_end);
1878
+		auto _to_nxt = _to;
1879
+		auto r = UnicodeConverters::utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1880
+		frm_nxt = frm + (_frm_nxt - _frm);
1881
+		to_nxt = to + (_to_nxt - _to);
1882
+		return r;
1883
+	}
1884
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1885
+	{
1886
+		to_nxt = to;
1887
+		return noconv;
1888
+	}
1889
+	virtual int do_encoding() const throw() { return 0; }
1890
+	virtual bool do_always_noconv() const throw() { return false; }
1891
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1892
+	{
1893
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1894
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1895
+		return UnicodeConverters::utf16le_to_ucs4_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
1896
+	}
1897
+	virtual int do_max_length() const throw()
1898
+	{
1899
+		if (this->_Mode_ & consume_header)
1900
+			return 6;
1901
+		return 4;
1902
+	}
1903
+};
1904
+
1905
+template<class _Elem, unsigned long _Maxcode = 0x10ffff, codecvt_mode _Mode = static_cast<codecvt_mode>(0)> class codecvt_utf16 : public __codecvt_utf16<_Elem, _Mode & little_endian>
1906
+{
1907
+public:
1908
+	explicit codecvt_utf16(size_t __refs = 0) : __codecvt_utf16<_Elem, _Mode & little_endian>(__refs, _Maxcode, _Mode) { }
1909
+
1910
+	~codecvt_utf16() { }
1911
+};
1912
+
1913
+template<class _Elem> class __codecvt_utf8_utf16;
1914
+
1915
+template<> class __codecvt_utf8_utf16<wchar_t> : public codecvt<wchar_t, char, mbstate_t>
1916
+{
1917
+	unsigned long _Maxcode_;
1918
+	codecvt_mode _Mode_;
1919
+public:
1920
+	typedef wchar_t intern_type;
1921
+	typedef char extern_type;
1922
+	typedef mbstate_t state_type;
1923
+
1924
+	explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<wchar_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1925
+protected:
1926
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1927
+	{
1928
+		auto _frm = reinterpret_cast<const uint32_t *>(frm);
1929
+		auto _frm_end = reinterpret_cast<const uint32_t *>(frm_end);
1930
+		auto _frm_nxt = _frm;
1931
+		auto _to = reinterpret_cast<uint8_t *>(to);
1932
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1933
+		auto _to_nxt = _to;
1934
+		auto r = UnicodeConverters::utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1935
+		frm_nxt = frm + (_frm_nxt - _frm);
1936
+		to_nxt = to + (_to_nxt - _to);
1937
+		return r;
1938
+	}
1939
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1940
+	{
1941
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1942
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1943
+		auto _frm_nxt = _frm;
1944
+		auto _to = reinterpret_cast<uint32_t *>(to);
1945
+		auto _to_end = reinterpret_cast<uint32_t *>(to_end);
1946
+		auto _to_nxt = _to;
1947
+		auto r = UnicodeConverters::utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1948
+		frm_nxt = frm + (_frm_nxt - _frm);
1949
+		to_nxt = to + (_to_nxt - _to);
1950
+		return r;
1951
+	}
1952
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
1953
+	{
1954
+		to_nxt = to;
1955
+		return noconv;
1956
+	}
1957
+	virtual int do_encoding() const throw() { return 0; }
1958
+	virtual bool do_always_noconv() const throw() { return false; }
1959
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
1960
+	{
1961
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
1962
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
1963
+		return UnicodeConverters::utf8_to_utf16_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
1964
+	}
1965
+	virtual int do_max_length() const throw()
1966
+	{
1967
+		if (this->_Mode_ & consume_header)
1968
+			return 7;
1969
+		return 4;
1970
+	}
1971
+};
1972
+
1973
+template<> class __codecvt_utf8_utf16<char32_t> : public codecvt<char32_t, char, mbstate_t>
1974
+{
1975
+	unsigned long _Maxcode_;
1976
+	codecvt_mode _Mode_;
1977
+public:
1978
+	typedef char32_t intern_type;
1979
+	typedef char extern_type;
1980
+	typedef mbstate_t state_type;
1981
+
1982
+	explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char32_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
1983
+protected:
1984
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
1985
+	{
1986
+		auto _frm = reinterpret_cast<const uint32_t *>(frm);
1987
+		auto _frm_end = reinterpret_cast<const uint32_t *>(frm_end);
1988
+		auto _frm_nxt = _frm;
1989
+		auto _to = reinterpret_cast<uint8_t *>(to);
1990
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
1991
+		auto _to_nxt = _to;
1992
+		auto r = UnicodeConverters::utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
1993
+		frm_nxt = frm + (_frm_nxt - _frm);
1994
+		to_nxt = to + (_to_nxt - _to);
1995
+		return r;
1996
+	}
1997
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
1998
+	{
1999
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
2000
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
2001
+		auto _frm_nxt = _frm;
2002
+		auto _to = reinterpret_cast<uint32_t *>(to);
2003
+		auto _to_end = reinterpret_cast<uint32_t *>(to_end);
2004
+		auto _to_nxt = _to;
2005
+		auto r = UnicodeConverters::utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
2006
+		frm_nxt = frm + (_frm_nxt - _frm);
2007
+		to_nxt = to + (_to_nxt - _to);
2008
+		return r;
2009
+	}
2010
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
2011
+	{
2012
+		to_nxt = to;
2013
+		return noconv;
2014
+	}
2015
+	virtual int do_encoding() const throw() { return 0; }
2016
+	virtual bool do_always_noconv() const throw() { return false; }
2017
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
2018
+	{
2019
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
2020
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
2021
+		return UnicodeConverters::utf8_to_utf16_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
2022
+	}
2023
+	virtual int do_max_length() const throw()
2024
+	{
2025
+		if (this->_Mode_ & consume_header)
2026
+			return 7;
2027
+		return 4;
2028
+	}
2029
+};
2030
+
2031
+template<> class __codecvt_utf8_utf16<char16_t> : public codecvt<char16_t, char, mbstate_t>
2032
+{
2033
+	unsigned long _Maxcode_;
2034
+	codecvt_mode _Mode_;
2035
+public:
2036
+	typedef char16_t intern_type;
2037
+	typedef char extern_type;
2038
+	typedef mbstate_t state_type;
2039
+
2040
+	explicit __codecvt_utf8_utf16(size_t __refs, unsigned long _Maxcode, codecvt_mode _Mode) : codecvt<char16_t, char, mbstate_t>(__refs), _Maxcode_(_Maxcode), _Mode_(_Mode) { }
2041
+protected:
2042
+	virtual result do_out(state_type &, const intern_type *frm, const intern_type *frm_end, const intern_type *&frm_nxt, extern_type *to, extern_type *to_end, extern_type *&to_nxt) const
2043
+	{
2044
+		auto _frm = reinterpret_cast<const uint16_t *>(frm);
2045
+		auto _frm_end = reinterpret_cast<const uint16_t *>(frm_end);
2046
+		auto _frm_nxt = _frm;
2047
+		auto _to = reinterpret_cast<uint8_t *>(to);
2048
+		auto _to_end = reinterpret_cast<uint8_t *>(to_end);
2049
+		auto _to_nxt = _to;
2050
+		auto r = UnicodeConverters::utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
2051
+		frm_nxt = frm + (_frm_nxt - _frm);
2052
+		to_nxt = to + (_to_nxt - _to);
2053
+		return r;
2054
+	}
2055
+	virtual result do_in(state_type &, const extern_type *frm, const extern_type *frm_end, const extern_type *&frm_nxt, intern_type *to, intern_type *to_end, intern_type *&to_nxt) const
2056
+	{
2057
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
2058
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
2059
+		auto _frm_nxt = _frm;
2060
+		auto _to = reinterpret_cast<uint16_t *>(to);
2061
+		auto _to_end = reinterpret_cast<uint16_t *>(to_end);
2062
+		auto _to_nxt = _to;
2063
+		auto r = UnicodeConverters::utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt, this->_Maxcode_, this->_Mode_);
2064
+		frm_nxt = frm + (_frm_nxt - _frm);
2065
+		to_nxt = to + (_to_nxt - _to);
2066
+		return r;
2067
+	}
2068
+	virtual result do_unshift(state_type &, extern_type *to, extern_type *, extern_type *&to_nxt) const
2069
+	{
2070
+		to_nxt = to;
2071
+		return noconv;
2072
+	}
2073
+	virtual int do_encoding() const throw() { return 0; }
2074
+	virtual bool do_always_noconv() const throw() { return false; }
2075
+	virtual int do_length(state_type &, const extern_type *frm, const extern_type *frm_end, size_t mx) const
2076
+	{
2077
+		auto _frm = reinterpret_cast<const uint8_t *>(frm);
2078
+		auto _frm_end = reinterpret_cast<const uint8_t *>(frm_end);
2079
+		return UnicodeConverters::utf8_to_utf16_length(_frm, _frm_end, mx, this->_Maxcode_, this->_Mode_);
2080
+	}
2081
+	virtual int do_max_length() const throw()
2082
+	{
2083
+		if (this->_Mode_ & consume_header)
2084
+			return 7;
2085
+		return 4;
2086
+	}
2087
+};
2088
+
2089
+template<class _Elem, unsigned long _Maxcode = 0x10ffff, codecvt_mode _Mode = static_cast<codecvt_mode>(0)> class codecvt_utf8_utf16 : public __codecvt_utf8_utf16<_Elem>
2090
+{
2091
+public:
2092
+	explicit codecvt_utf8_utf16(size_t __refs = 0) : __codecvt_utf8_utf16<_Elem>(__refs, _Maxcode, _Mode) { }
2093
+
2094
+	~codecvt_utf8_utf16() {}
2095
+};
2096
+
2097
+};
2098
+#endif
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  * Common conversion functions
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-17
4
+ * Last modification on 2014-09-24
5 5
  */
6 6
 
7 7
 #pragma once
... ...
@@ -11,10 +11,15 @@
11 11
 #include <sstream>
12 12
 #include <typeinfo>
13 13
 #include <locale>
14
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(_LIBCPP_VERSION)
15
+# include "wstring_convert.h"
16
+# include "codecvt.h"
17
+#else
18
+# include <codecvt>
19
+#endif
14 20
 #include <vector>
15 21
 #include <memory>
16 22
 #include <cmath>
17
-#include "BigSString.h"
18 23
 
19 24
 /*
20 25
  * The following exception class and the *stringify and convert* functions are
... ...
@@ -130,7 +135,7 @@ public:
130 135
 
131 136
 	static unsigned long StringToMS(const std::wstring &time)
132 137
 	{
133
-		return ConvertFuncs::StringToMS(String(time).GetAnsi());
138
+		return ConvertFuncs::StringToMS(ConvertFuncs::WStringToString(time));
134 139
 	}
135 140
 
136 141
 	static std::string MSToString(unsigned long time)
... ...
@@ -149,6 +154,18 @@ public:
149 154
 
150 155
 	static std::wstring MSToWString(unsigned long time)
151 156
 	{
152
-		return String(ConvertFuncs::MSToString(time)).GetWStr();
157
+		return ConvertFuncs::StringToWString(ConvertFuncs::MSToString(time));
158
+	}
159
+
160
+	static std::wstring StringToWString(const std::string &str)
161
+	{
162
+		static std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
163
+		return conv.from_bytes(str);
164
+	}
165
+
166
+	static std::string WStringToString(const std::wstring &wstr)
167
+	{
168
+		static std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
169
+		return conv.to_bytes(wstr);
153 170
 	}
154 171
 };
155 172
new file mode 100644
... ...
@@ -0,0 +1,763 @@
1
+// This comes from llvm's libcxx project. I've copied the code from there (with heavy modifications) for use with MinGW to support opening Windows "Unicode" filenames.
2
+
3
+#if defined(_WIN32) && !defined(_MSC_VER)
4
+#pragma once
5
+
6
+#include <streambuf>
7
+#include <locale>
8
+#include <memory>
9
+#include <fstream>
10
+
11
+class filebuf_wfopen : public std::filebuf
12
+{
13
+public:
14
+	typedef typename traits_type::state_type state_type;
15
+
16
+	// 27.9.1.2 Constructors/destructor:
17
+	filebuf_wfopen() : __extbuf_(nullptr), __extbufnext_(nullptr), __extbufend_(nullptr), __ebs_(0),
18
+		__intbuf_(nullptr), __ibs_(0), __file_(nullptr), __cv_(nullptr), __st_(), __st_last_(),
19
+		__om_(static_cast<std::ios_base::openmode>(0)), __cm_(static_cast<std::ios_base::openmode>(0)),
20
+		__owns_eb_(false), __owns_ib_(false), __always_noconv_(false)
21
+	{
22
+		if (std::has_facet<std::codecvt<char, char, state_type>>(this->getloc()))
23
+		{
24
+			this->__cv_ = &std::use_facet<std::codecvt<char, char, state_type>>(this->getloc());
25
+			this->__always_noconv_ = this->__cv_->always_noconv();
26
+		}
27
+		this->setbuf(nullptr, 4096);
28
+	}
29
+
30
+	virtual ~filebuf_wfopen()
31
+	{
32
+		try
33
+		{
34
+			this->close();
35
+		}
36
+		catch (...)
37
+		{
38
+		}
39
+		if (this->__owns_eb_)
40
+			delete[] this->__extbuf_;
41
+		if (this->__owns_ib_)
42
+			delete[] this->__intbuf_;
43
+	}
44
+
45
+	// 27.9.1.4 Members:
46
+	bool is_open() const
47
+	{
48
+		return !!this->__file_;
49
+	}
50
+	filebuf_wfopen *open(const char *__s, std::ios_base::openmode __mode)
51
+	{
52
+		filebuf_wfopen *__rt = nullptr;
53
+		if (!this->__file_)
54
+		{
55
+			__rt = this;
56
+			const char *__mdstr;
57
+			switch (__mode & ~std::ios_base::ate)
58
+			{
59
+				case std::ios_base::out:
60
+				case std::ios_base::out | std::ios_base::trunc:
61
+					__mdstr = "w";
62
+					break;
63
+				case std::ios_base::out | std::ios_base::app:
64
+				case std::ios_base::app:
65
+					__mdstr = "a";
66
+					break;
67
+				case std::ios_base::in:
68
+					__mdstr = "r";
69
+					break;
70
+				case std::ios_base::in | std::ios_base::out:
71
+					__mdstr = "r+";
72
+					break;
73
+				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc:
74
+					__mdstr = "w+";
75
+					break;
76
+				case std::ios_base::in | std::ios_base::out | std::ios_base::app:
77
+				case std::ios_base::in | std::ios_base::app:
78
+					__mdstr = "a+";
79
+					break;
80
+				case std::ios_base::out | std::ios_base::binary:
81
+				case std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
82
+					__mdstr = "wb";
83
+					break;
84
+				case std::ios_base::out | std::ios_base::app | std::ios_base::binary:
85
+				case std::ios_base::app | std::ios_base::binary:
86
+					__mdstr = "ab";
87
+					break;
88
+				case std::ios_base::in | std::ios_base::binary:
89
+					__mdstr = "rb";
90
+					break;
91
+				case std::ios_base::in | std::ios_base::out | std::ios_base::binary:
92
+					__mdstr = "r+b";
93
+					break;
94
+				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
95
+					__mdstr = "w+b";
96
+					break;
97
+				case std::ios_base::in | std::ios_base::out | std::ios_base::app | std::ios_base::binary:
98
+				case std::ios_base::in | std::ios_base::app | std::ios_base::binary:
99
+					__mdstr = "a+b";
100
+					break;
101
+				default:
102
+					__rt = nullptr;
103
+			}
104
+			if (__rt)
105
+			{
106
+				this->__file_ = fopen(__s, __mdstr);
107
+				if (this->__file_)
108
+				{
109
+					this->__om_ = __mode;
110
+					if ((__mode & std::ios_base::ate) && fseek(this->__file_, 0, SEEK_END))
111
+					{
112
+						fclose(this->__file_);
113
+						this->__file_ = nullptr;
114
+						__rt = nullptr;
115
+					}
116
+				}
117
+				else
118
+					__rt = nullptr;
119
+			}
120
+		}
121
+		return __rt;
122
+	}
123
+	filebuf_wfopen *open(const std::string &__s, std::ios_base::openmode __mode)
124
+	{
125
+		return this->open(__s.c_str(), __mode);
126
+	}
127
+	filebuf_wfopen *open(const wchar_t *__s, std::ios_base::openmode __mode)
128
+	{
129
+		filebuf_wfopen *__rt = nullptr;
130
+		if (!this->__file_)
131
+		{
132
+			__rt = this;
133
+			const wchar_t *__mdstr;
134
+			switch (__mode & ~std::ios_base::ate)
135
+			{
136
+				case std::ios_base::out:
137
+				case std::ios_base::out | std::ios_base::trunc:
138
+					__mdstr = L"w";
139
+					break;
140
+				case std::ios_base::out | std::ios_base::app:
141
+				case std::ios_base::app:
142
+					__mdstr = L"a";
143
+					break;
144
+				case std::ios_base::in:
145
+					__mdstr = L"r";
146
+					break;
147
+				case std::ios_base::in | std::ios_base::out:
148
+					__mdstr = L"r+";
149
+					break;
150
+				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc:
151
+					__mdstr = L"w+";
152
+					break;
153
+				case std::ios_base::in | std::ios_base::out | std::ios_base::app:
154
+				case std::ios_base::in | std::ios_base::app:
155
+					__mdstr = L"a+";
156
+					break;
157
+				case std::ios_base::out | std::ios_base::binary:
158
+				case std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
159
+					__mdstr = L"wb";
160
+					break;
161
+				case std::ios_base::out | std::ios_base::app | std::ios_base::binary:
162
+				case std::ios_base::app | std::ios_base::binary:
163
+					__mdstr = L"ab";
164
+					break;
165
+				case std::ios_base::in | std::ios_base::binary:
166
+					__mdstr = L"rb";
167
+					break;
168
+				case std::ios_base::in | std::ios_base::out | std::ios_base::binary:
169
+					__mdstr = L"r+b";
170
+					break;
171
+				case std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
172
+					__mdstr = L"w+b";
173
+					break;
174
+				case std::ios_base::in | std::ios_base::out | std::ios_base::app | std::ios_base::binary:
175
+				case std::ios_base::in | std::ios_base::app | std::ios_base::binary:
176
+					__mdstr = L"a+b";
177
+					break;
178
+				default:
179
+					__rt = nullptr;
180
+			}
181
+			if (__rt)
182
+			{
183
+				this->__file_ = _wfopen(__s, __mdstr);
184
+				if (this->__file_)
185
+				{
186
+					this->__om_ = __mode;
187
+					if ((__mode & std::ios_base::ate) && fseek(this->__file_, 0, SEEK_END))
188
+					{
189
+						fclose(this->__file_);
190
+						this->__file_ = nullptr;
191
+						__rt = nullptr;
192
+					}
193
+				}
194
+				else
195
+					__rt = nullptr;
196
+			}
197
+		}
198
+		return __rt;
199
+	}
200
+	filebuf_wfopen *open(const std::wstring &__s, std::ios_base::openmode __mode)
201
+	{
202
+		return this->open(__s.c_str(), __mode);
203
+	}
204
+	filebuf_wfopen *close()
205
+	{
206
+		filebuf_wfopen *__rt = nullptr;
207
+		if (this->__file_)
208
+		{
209
+			__rt = this;
210
+			std::unique_ptr<FILE, int (*)(FILE *)> __h(this->__file_, fclose);
211
+			if (this->sync())
212
+				__rt = nullptr;
213
+			if (!fclose(__h.release()))
214
+				this->__file_ = nullptr;
215
+			else
216
+				__rt = nullptr;
217
+		}
218
+		return __rt;
219
+	}
220
+
221
+protected:
222
+	// 27.9.1.5 Overridden virtual functions:
223
+	virtual int_type underflow()
224
+	{
225
+		if (!this->__file_)
226
+			return traits_type::eof();
227
+		bool __initial = this->__read_mode();
228
+		char __1buf;
229
+		if (!this->gptr())
230
+			this->setg(&__1buf, &__1buf + 1, &__1buf + 1);
231
+		const size_t __unget_sz = __initial ? 0 : std::min<size_t>((this->egptr() - this->eback()) / 2, 4);
232
+		int_type __c = traits_type::eof();
233
+		if (this->gptr() == this->egptr())
234
+		{
235
+			memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz);
236
+			if (this->__always_noconv_)
237
+			{
238
+				size_t __nmemb = static_cast<size_t>(this->egptr() - this->eback() - __unget_sz);
239
+				__nmemb = fread(this->eback() + __unget_sz, 1, __nmemb, this->__file_);
240
+				if (__nmemb)
241
+				{
242
+					this->setg(this->eback(), this->eback() + __unget_sz, this->eback() + __unget_sz + __nmemb);
243
+					__c = traits_type::to_int_type(*this->gptr());
244
+				}
245
+			}
246
+			else
247
+			{
248
+				memmove(this->__extbuf_, this->__extbufnext_, this->__extbufend_ - this->__extbufnext_);
249
+				this->__extbufnext_ = this->__extbuf_ + (this->__extbufend_ - this->__extbufnext_);
250
+				this->__extbufend_ = this->__extbuf_ +
251
+					(this->__extbuf_ == this->__extbuf_min_ ? sizeof(this->__extbuf_min_) : this->__ebs_);
252
+				size_t __nmemb = std::min<size_t>(this->__ibs_ - __unget_sz,
253
+					this->__extbufend_ - this->__extbufnext_);
254
+				std::codecvt_base::result __r;
255
+				this->__st_last_ = this->__st_;
256
+				size_t __nr = fread(const_cast<char *>(this->__extbufnext_), 1, __nmemb, this->__file_);
257
+				if (__nr)
258
+				{
259
+					if (!this->__cv_)
260
+						throw std::bad_cast();
261
+					this->__extbufend_ = this->__extbufnext_ + __nr;
262
+					char *__inext;
263
+					__r = this->__cv_->in(this->__st_, this->__extbuf_, this->__extbufend_, this->__extbufnext_,
264
+						this->eback() + __unget_sz, this->eback() + this->__ibs_, __inext);
265
+					if (__r == std::codecvt_base::noconv)
266
+					{
267
+						this->setg(this->__extbuf_, this->__extbuf_, const_cast<char *>(this->__extbufend_));
268
+						__c = traits_type::to_int_type(*this->gptr());
269
+					}
270
+					else if (__inext != this->eback() + __unget_sz)
271
+					{
272
+						this->setg(this->eback(), this->eback() + __unget_sz, __inext);
273
+						__c = traits_type::to_int_type(*this->gptr());
274
+					}
275
+				}
276
+			}
277
+		}
278
+		else
279
+			__c = traits_type::to_int_type(*this->gptr());
280
+		if (this->eback() == &__1buf)
281
+			this->setg(nullptr, nullptr, nullptr);
282
+		return __c;
283
+	}
284
+	virtual int_type pbackfail(int_type __c = traits_type::eof())
285
+	{
286
+		if (this->__file_ && this->eback() < this->gptr())
287
+		{
288
+			if (traits_type::eq_int_type(__c, traits_type::eof()))
289
+			{
290
+				this->gbump(-1);
291
+				return traits_type::not_eof(__c);
292
+			}
293
+			if ((this->__om_ & std::ios_base::out) ||
294
+				traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1]))
295
+			{
296
+				this->gbump(-1);
297
+				*this->gptr() = traits_type::to_char_type(__c);
298
+				return __c;
299
+			}
300
+		}
301
+		return traits_type::eof();
302
+	}
303
+	virtual int_type overflow (int_type __c = traits_type::eof())
304
+	{
305
+		if (!this->__file_)
306
+			return traits_type::eof();
307
+		this->__write_mode();
308
+		char __1buf;
309
+		char *__pb_save = this->pbase();
310
+		char *__epb_save = this->epptr();
311
+		if (!traits_type::eq_int_type(__c, traits_type::eof()))
312
+		{
313
+			if (!this->pptr())
314
+				this->setp(&__1buf, &__1buf + 1);
315
+			*this->pptr() = traits_type::to_char_type(__c);
316
+			this->pbump(1);
317
+		}
318
+		if (this->pptr() != this->pbase())
319
+		{
320
+			if (this->__always_noconv_)
321
+			{
322
+				size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
323
+				if (fwrite(this->pbase(), 1, __nmemb, __file_) != __nmemb)
324
+					return traits_type::eof();
325
+			}
326
+			else
327
+			{
328
+				char *__extbe = this->__extbuf_;
329
+				std::codecvt_base::result __r;
330
+				do
331
+				{
332
+					if (!this->__cv_)
333
+						throw std::bad_cast();
334
+					const char *__e;
335
+					__r = this->__cv_->out(this->__st_, this->pbase(), this->pptr(), __e, this->__extbuf_,
336
+						this->__extbuf_ + this->__ebs_, __extbe);
337
+					if (__e == this->pbase())
338
+						return traits_type::eof();
339
+					if (__r == std::codecvt_base::noconv)
340
+					{
341
+						size_t __nmemb = static_cast<size_t>(this->pptr() - this->pbase());
342
+						if (fwrite(this->pbase(), 1, __nmemb, this->__file_) != __nmemb)
343
+							return traits_type::eof();
344
+					}
345
+					else if (__r == std::codecvt_base::ok || __r == std::codecvt_base::partial)
346
+					{
347
+						size_t __nmemb = static_cast<size_t>(__extbe - this->__extbuf_);
348
+						if (fwrite(this->__extbuf_, 1, __nmemb, this->__file_) != __nmemb)
349
+							return traits_type::eof();
350
+						if (__r == std::codecvt_base::partial)
351
+						{
352
+							this->setp(const_cast<char *>(__e), this->pptr());
353
+							this->pbump(this->epptr() - this->pbase());
354
+						}
355
+					}
356
+					else
357
+						return traits_type::eof();
358
+				} while (__r == std::codecvt_base::partial);
359
+			}
360
+			this->setp(__pb_save, __epb_save);
361
+		}
362
+		return traits_type::not_eof(__c);
363
+	}
364
+	virtual std::streambuf *setbuf(char *__s, std::streamsize __n)
365
+	{
366
+		this->setg(nullptr, nullptr, nullptr);
367
+		this->setp(nullptr, nullptr);
368
+		if (this->__owns_eb_)
369
+			delete[] this->__extbuf_;
370
+		if (this->__owns_ib_)
371
+			delete[] this->__intbuf_;
372
+		this->__ebs_ = __n;
373
+		if (this->__ebs_ > sizeof(this->__extbuf_min_))
374
+		{
375
+			if (this->__always_noconv_ && __s)
376
+			{
377
+				this->__extbuf_ = __s;
378
+				this->__owns_eb_ = false;
379
+			}
380
+			else
381
+			{
382
+				this->__extbuf_ = new char[this->__ebs_];
383
+				this->__owns_eb_ = true;
384
+			}
385
+		}
386
+		else
387
+		{
388
+			this->__extbuf_ = this->__extbuf_min_;
389
+			this->__ebs_ = sizeof(this->__extbuf_min_);
390
+			this->__owns_eb_ = false;
391
+		}
392
+		if (!this->__always_noconv_)
393
+		{
394
+			this->__ibs_ = std::max<std::streamsize>(__n, sizeof(this->__extbuf_min_));
395
+			if (__s && this->__ibs_ >= sizeof(this->__extbuf_min_))
396
+			{
397
+				this->__intbuf_ = __s;
398
+				this->__owns_ib_ = false;
399
+			}
400
+			else
401
+			{
402
+				this->__intbuf_ = new char[this->__ibs_];
403
+				this->__owns_ib_ = true;
404
+			}
405
+		}
406
+		else
407
+		{
408
+			this->__ibs_ = 0;
409
+			this->__intbuf_ = nullptr;
410
+			this->__owns_ib_ = false;
411
+		}
412
+		return this;
413
+	}
414
+	virtual pos_type seekoff(off_type __off, std::ios_base::seekdir __way,
415
+		std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
416
+	{
417
+		if (!this->__cv_)
418
+			throw std::bad_cast();
419
+		int __width = this->__cv_->encoding();
420
+		if (!this->__file_ || (__width <= 0 && __off) || this->sync())
421
+			return pos_type(off_type(-1));
422
+		// __width > 0 || __off == 0
423
+		int __whence;
424
+		switch (__way)
425
+		{
426
+			case std::ios_base::beg:
427
+				__whence = SEEK_SET;
428
+				break;
429
+			case std::ios_base::cur:
430
+				__whence = SEEK_CUR;
431
+				break;
432
+			case std::ios_base::end:
433
+				__whence = SEEK_END;
434
+				break;
435
+			default:
436
+				return pos_type(off_type(-1));
437
+		}
438
+		if (fseek(this->__file_, __width > 0 ? __width * __off : 0, __whence))
439
+			return pos_type(off_type(-1));
440
+		pos_type __r = ftell(this->__file_);
441
+		__r.state(this->__st_);
442
+		return __r;
443
+	}
444
+	virtual pos_type seekpos(pos_type __sp,
445
+		std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
446
+	{
447
+		if (!this->__file_ || this->sync())
448
+			return pos_type(off_type(-1));
449
+		if (fseek(this->__file_, __sp, SEEK_SET))
450
+			return pos_type(off_type(-1));
451
+		this->__st_ = __sp.state();
452
+		return __sp;
453
+	}
454
+	virtual int sync()
455
+	{
456
+		if (!this->__file_)
457
+			return 0;
458
+		if (!this->__cv_)
459
+			throw std::bad_cast();
460
+		if (this->__cm_ & std::ios_base::out)
461
+		{
462
+			if (this->pptr() != this->pbase() && this->overflow() == traits_type::eof())
463
+				return -1;
464
+			std::codecvt_base::result __r;
465
+			do
466
+			{
467
+				char *__extbe;
468
+				__r = this->__cv_->unshift(this->__st_, this->__extbuf_, this->__extbuf_ + this->__ebs_,
469
+					__extbe);
470
+				size_t __nmemb = static_cast<size_t>(__extbe - this->__extbuf_);
471
+				if (fwrite(this->__extbuf_, 1, __nmemb, this->__file_) != __nmemb)
472
+					return -1;
473
+			} while (__r == std::codecvt_base::partial);
474
+			if (__r == std::codecvt_base::error)
475
+				return -1;
476
+			if (fflush(this->__file_))
477
+				return -1;
478
+		}
479
+		else if (this->__cm_ & std::ios_base::in)
480
+		{
481
+			off_type __c;
482
+			state_type __state = this->__st_last_;
483
+			bool __update_st = false;
484
+			if (this->__always_noconv_)
485
+				__c = this->egptr() - this->gptr();
486
+			else
487
+			{
488
+				int __width = this->__cv_->encoding();
489
+				__c = this->__extbufend_ - this->__extbufnext_;
490
+				if (__width > 0)
491
+					__c += __width * (this->egptr() - this->gptr());
492
+				else if (this->gptr() != this->egptr())
493
+				{
494
+					int __off =  this->__cv_->length(__state, this->__extbuf_, this->__extbufnext_,
495
+						this->gptr() - this->eback());
496
+					__c += this->__extbufnext_ - this->__extbuf_ - __off;
497
+					__update_st = true;
498
+				}
499
+			}
500
+			if (fseek(this->__file_, -__c, SEEK_CUR))
501
+				return -1;
502
+			if (__update_st)
503
+				this->__st_ = __state;
504
+			this->__extbufnext_ = this->__extbufend_ = this->__extbuf_;
505
+			this->setg(nullptr, nullptr, nullptr);
506
+			this->__cm_ = static_cast<std::ios_base::openmode>(0);
507
+		}
508
+		return 0;
509
+	}
510
+	virtual void imbue(const std::locale &__loc)
511
+	{
512
+		this->sync();
513
+		this->__cv_ = &std::use_facet<std::codecvt<char, char, state_type>>(__loc);
514
+		bool __old_anc = this->__always_noconv_;
515
+		this->__always_noconv_ = this->__cv_->always_noconv();
516
+		if (__old_anc != this->__always_noconv_)
517
+		{
518
+			this->setg(nullptr, nullptr, nullptr);
519
+			this->setp(nullptr, nullptr);
520
+			// invariant, char_type is char, else we couldn't get here
521
+			if (this->__always_noconv_) // need to dump __intbuf_
522
+			{
523
+				if (this->__owns_eb_)
524
+					delete[] this->__extbuf_;
525
+				this->__owns_eb_ = this->__owns_ib_;
526
+				this->__ebs_ = this->__ibs_;
527
+				this->__extbuf_ = this->__intbuf_;
528
+				this->__ibs_ = 0;
529
+				this->__intbuf_ = nullptr;
530
+				this->__owns_ib_ = false;
531
+			}
532
+			// need to obtain an __intbuf_.
533
+			else if (!this->__owns_eb_ && this->__extbuf_ != this->__extbuf_min_)
534
+				// If __extbuf_ is user-supplied, use it, else new __intbuf_
535
+			{
536
+				this->__ibs_ = this->__ebs_;
537
+				this->__intbuf_ = this->__extbuf_;
538
+				this->__owns_ib_ = false;
539
+				this->__extbuf_ = new char[this->__ebs_];
540
+				this->__owns_eb_ = true;
541
+			}
542
+			else
543
+			{
544
+				this->__ibs_ = this->__ebs_;
545
+				this->__intbuf_ = new char[this->__ibs_];
546
+				this->__owns_ib_ = true;
547
+			}
548
+		}
549
+	}
550
+
551
+private:
552
+	char *__extbuf_;
553
+	const char *__extbufnext_;
554
+	const char *__extbufend_;
555
+	char __extbuf_min_[8];
556
+	size_t __ebs_;
557
+	char *__intbuf_;
558
+	size_t __ibs_;
559
+	FILE *__file_;
560
+	const std::codecvt<char, char, state_type> *__cv_;
561
+	state_type __st_;
562
+	state_type __st_last_;
563
+	std::ios_base::openmode __om_;
564
+	std::ios_base::openmode __cm_;
565
+	bool __owns_eb_;
566
+	bool __owns_ib_;
567
+	bool __always_noconv_;
568
+
569
+	bool __read_mode()
570
+	{
571
+		if (!(this->__cm_ & std::ios_base::in))
572
+		{
573
+			this->setp(nullptr, nullptr);
574
+			if (this->__always_noconv_)
575
+				this->setg(this->__extbuf_, this->__extbuf_ + this->__ebs_, this->__extbuf_ + this->__ebs_);
576
+			else
577
+				this->setg(this->__intbuf_, this->__intbuf_ + this->__ibs_, this->__intbuf_ + this->__ibs_);
578
+			this->__cm_ = std::ios_base::in;
579
+			return true;
580
+		}
581
+		return false;
582
+	}
583
+	void __write_mode()
584
+	{
585
+		if (!(this->__cm_ & std::ios_base::out))
586
+		{
587
+			this->setg(nullptr, nullptr, nullptr);
588
+			if (this->__ebs_ > sizeof(this->__extbuf_min_))
589
+			{
590
+				if (this->__always_noconv_)
591
+					this->setp(this->__extbuf_, this->__extbuf_ + (this->__ebs_ - 1));
592
+				else
593
+					this->setp(this->__intbuf_, this->__intbuf_ + (this->__ibs_ - 1));
594
+			}
595
+			else
596
+				this->setp(nullptr, nullptr);
597
+			this->__cm_ = std::ios_base::out;
598
+		}
599
+	}
600
+};
601
+
602
+// basic_ifstream
603
+
604
+class ifstream_wfopen : public std::ifstream
605
+{
606
+public:
607
+	ifstream_wfopen() { std::ios::rdbuf(&this->__sb_); }
608
+	explicit ifstream_wfopen(const char *__s, std::ios_base::openmode __mode = std::ios_base::in)
609
+	{
610
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
611
+			std::ios::rdbuf(&this->__sb_);
612
+		else
613
+			this->setstate(std::ios_base::failbit);
614
+	}
615
+	explicit ifstream_wfopen(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::in)
616
+	{
617
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
618
+			std::ios::rdbuf(&this->__sb_);
619
+		else
620
+			this->setstate(std::ios_base::failbit);
621
+	}
622
+	explicit ifstream_wfopen(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::in)
623
+	{
624
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
625
+			std::ios::rdbuf(&this->__sb_);
626
+		else
627
+			this->setstate(std::ios_base::failbit);
628
+	}
629
+	explicit ifstream_wfopen(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::in)
630
+	{
631
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
632
+			std::ios::rdbuf(&this->__sb_);
633
+		else
634
+			this->setstate(std::ios_base::failbit);
635
+	}
636
+
637
+	std::filebuf *rdbuf() const
638
+	{
639
+		return const_cast<std::filebuf *>(static_cast<const std::filebuf *>(&this->__sb_));
640
+	}
641
+	bool is_open() const
642
+	{
643
+		return this->__sb_.is_open();
644
+	}
645
+	void open(const char *__s, std::ios_base::openmode __mode = std::ios_base::in)
646
+	{
647
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
648
+			this->clear();
649
+		else
650
+			this->setstate(std::ios_base::failbit);
651
+	}
652
+	void open(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::in)
653
+	{
654
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
655
+			this->clear();
656
+		else
657
+			this->setstate(std::ios_base::failbit);
658
+	}
659
+	void open(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::in)
660
+	{
661
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
662
+			this->clear();
663
+		else
664
+			this->setstate(std::ios_base::failbit);
665
+	}
666
+	void open(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::in)
667
+	{
668
+		if (this->__sb_.open(__s, __mode | std::ios_base::in))
669
+			this->clear();
670
+		else
671
+			this->setstate(std::ios_base::failbit);
672
+	}
673
+	void close()
674
+	{
675
+		if (!this->__sb_.close())
676
+			this->setstate(std::ios_base::failbit);
677
+	}
678
+
679
+private:
680
+	filebuf_wfopen __sb_;
681
+};
682
+
683
+// basic_ofstream
684
+
685
+class ofstream_wfopen : public std::ofstream
686
+{
687
+public:
688
+	ofstream_wfopen() { std::ios::rdbuf(&this->__sb_); }
689
+	explicit ofstream_wfopen(const char *__s, std::ios_base::openmode __mode = std::ios_base::out)
690
+	{
691
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
692
+			std::ios::rdbuf(&this->__sb_);
693
+		else
694
+			this->setstate(std::ios_base::failbit);
695
+	}
696
+	explicit ofstream_wfopen(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::out)
697
+	{
698
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
699
+			std::ios::rdbuf(&this->__sb_);
700
+		else
701
+			this->setstate(std::ios_base::failbit);
702
+	}
703
+	explicit ofstream_wfopen(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::out)
704
+	{
705
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
706
+			std::ios::rdbuf(&this->__sb_);
707
+		else
708
+			this->setstate(std::ios_base::failbit);
709
+	}
710
+	explicit ofstream_wfopen(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::out)
711
+	{
712
+		if (!this->__sb_.open(__s, __mode | std::ios_base::out))
713
+			std::ios::rdbuf(&this->__sb_);
714
+		else
715
+			this->setstate(std::ios_base::failbit);
716
+	}
717
+
718
+	std::filebuf *rdbuf() const
719
+	{
720
+		return const_cast<std::filebuf *>(static_cast<const std::filebuf *>(&this->__sb_));
721
+	}
722
+	bool is_open() const
723
+	{
724
+		return this->__sb_.is_open();
725
+	}
726
+	void open(const char *__s, std::ios_base::openmode __mode = std::ios_base::out)
727
+	{
728
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
729
+			this->clear();
730
+		else
731
+			this->setstate(std::ios_base::failbit);
732
+	}
733
+	void open(const std::string &__s, std::ios_base::openmode __mode = std::ios_base::out)
734
+	{
735
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
736
+			this->clear();
737
+		else
738
+			this->setstate(std::ios_base::failbit);
739
+	}
740
+	void open(const wchar_t *__s, std::ios_base::openmode __mode = std::ios_base::out)
741
+	{
742
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
743
+			this->clear();
744
+		else
745
+			this->setstate(std::ios_base::failbit);
746
+	}
747
+	void open(const std::wstring &__s, std::ios_base::openmode __mode = std::ios_base::out)
748
+	{
749
+		if (this->__sb_.open(__s, __mode | std::ios_base::out))
750
+			this->clear();
751
+		else
752
+			this->setstate(std::ios_base::failbit);
753
+	}
754
+	void close()
755
+	{
756
+		if (!this->__sb_.close())
757
+			this->setstate(std::ios_base::failbit);
758
+	}
759
+
760
+private:
761
+	filebuf_wfopen __sb_;
762
+};
763
+#endif
... ...
@@ -1,17 +1,23 @@
1 1
 /*
2 2
  * xSF - Winamp plugin
3 3
  * By Naram Qashat (CyberBotX) [cyberbotx@cyberbotx.com]
4
- * Last modification on 2014-09-18
4
+ * Last modification on 2014-09-24
5 5
  *
6 6
  * Partially based on the vio*sf framework
7 7
  */
8 8
 
9 9
 #include "XSFPlayer.h"
10 10
 #include "XSFConfig.h"
11
+#include "XSFCommon.h"
11 12
 #include "windowsh_wrapper.h"
12 13
 #include <winamp/in2.h>
13 14
 #include <winamp/wa_ipc.h>
14 15
 
16
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(_LIBCPP_VERSION)
17
+std::locale::id std::codecvt<char16_t, char, mbstate_t>::id;
18
+std::locale::id std::codecvt<char32_t, char, mbstate_t>::id;
19
+#endif
20
+
15 21
 extern In_Module inMod;
16 22
 const XSFFile *xSFFile = nullptr;
17 23
 XSFFile *xSFFileInInfo = nullptr;
... ...
@@ -110,7 +116,7 @@ void getFileInfo(const in_char *file, in_char *title, int *length_in_ms)
110 116
 		catch (const std::exception &)
111 117
 		{
112 118
 			if (title)
113
-				String("").CopyToString(title);
119
+				CopyToString("", title);
114 120
 			if (length_in_ms)
115 121
 				*length_in_ms = -1000;
116 122
 			return;
... ...
@@ -118,10 +124,7 @@ void getFileInfo(const in_char *file, in_char *title, int *length_in_ms)
118 124
 		toFree = true;
119 125
 	}
120 126
 	if (title)
121
-	{
122
-		String formattedTitle = xSF->GetFormattedTitle(xSFConfig->GetTitleFormat()).Substring(0, GETFILEINFO_TITLE_LENGTH - 1);
123
-		formattedTitle.CopyToString(title);
124
-	}
127
+		CopyToString(xSF->GetFormattedTitle(xSFConfig->GetTitleFormat()).substr(0, GETFILEINFO_TITLE_LENGTH - 1), title);
125 128
 	if (length_in_ms)
126 129
 		*length_in_ms = xSF->GetLengthMS(xSFConfig->GetDefaultLength()) + xSF->GetFadeMS(xSFConfig->GetDefaultFade());
127 130
 	if (toFree)
... ...
@@ -148,17 +151,16 @@ int infoBox(const in_char *file, HWND hwndParent)
148 151
 	// TODO: Eventually make a dialog box for editing the info
149 152
 	/*xSFFileInInfo = xSF.get();
150 153
 	xSFConfig->CallInfoDialog(inMod.hDllInstance, hwndParent);*/
151
-	bool utf8 = xSF->GetTagExists("utf8");
152 154
 	auto tags = xSF->GetAllTags();
153 155
 	auto keys = tags.GetKeys();
154
-	String info;
156
+	std::wstring info;
155 157
 	for (unsigned x = 0, numTags = keys.size(); x < numTags; ++x)
156 158
 	{
157 159
 		if (x)
158
-			info += "\n";
159
-		info += String(keys[x] + "=") + String(tags[keys[x]], utf8);
160
+			info += L"\n";
161
+		info += ConvertFuncs::StringToWString(keys[x] + "=" + tags[keys[x]]);
160 162
 	}
161
-	MessageBoxW(hwndParent, info.GetWStrC(), xSF->GetFilenameWithoutPath().GetWStrC(), MB_OK);
163
+	MessageBoxW(hwndParent, info.c_str(), ConvertFuncs::StringToWString(xSF->GetFilenameWithoutPath()).c_str(), MB_OK);
162 164
 	return INFOBOX_EDITED;
163 165
 }
164 166
 
... ...
@@ -271,7 +273,7 @@ void eqSet(int, char [10], int)
271 273
 In_Module inMod =
272 274
 {
273 275
 	IN_VER,
274
-	const_cast<char *>(XSFConfig::CommonNameWithVersion().GetStrC()), /* Unsafe but Winamp's SDK requires this */
276
+	const_cast<char *>(XSFConfig::CommonNameWithVersion().c_str()), /* Unsafe but Winamp's SDK requires this */
275 277
 	nullptr, /* Filled by Winamp */
276 278
 	nullptr, /* Filled by Winamp */
277 279
 	const_cast<char *>(XSFPlayer::WinampExts), /* Unsafe but Winamp's SDK requires this */
... ...
@@ -317,9 +319,7 @@ template<typename T> int wrapperWinampGetExtendedFileInfo(const XSFFile &file, c
317 319
 		return 1;
318 320
 	}
319 321
 	else if (eqstr(data, "family"))
320
-	{
321 322
 		return 0;
322
-	}
323 323
 	else
324 324
 	{
325 325
 		try
... ...
@@ -327,6 +327,7 @@ template<typename T> int wrapperWinampGetExtendedFileInfo(const XSFFile &file, c
327 327
 			std::string tagToGet = data;
328 328
 			if (eqstr(data, "album"))
329 329
 				tagToGet = "game";
330
+			std::string tag = "";
330 331
 			if (!file.GetTagExists(tagToGet))
331 332
 			{
332 333
 				if (eqstr(tagToGet, "replaygain_track_gain"))
... ...
@@ -334,11 +335,10 @@ template<typename T> int wrapperWinampGetExtendedFileInfo(const XSFFile &file, c
334 335
 				return 0;
335 336
 			}
336 337
 			else if (eqstr(tagToGet, "length"))
337
-			{
338
-				String(stringify(file.GetLengthMS(xSFConfig->GetDefaultLength()) + file.GetFadeMS(xSFConfig->GetDefaultFade()))).Substring(0, destlen - 1).CopyToString(dest, true);
339
-				return 1;
340
-			}
341
-			file.GetTagValue(tagToGet).Substring(0, destlen - 1).CopyToString(dest, true);
338
+				tag = stringify(file.GetLengthMS(xSFConfig->GetDefaultLength()) + file.GetFadeMS(xSFConfig->GetDefaultFade()));
339
+			else
340
+				tag = file.GetTagValue(tagToGet);
341
+			CopyToString(tag.substr(0, destlen - 1), dest);
342 342
 			return 1;
343 343
 		}
344 344
 		catch (const std::exception &)
... ...
@@ -361,7 +361,6 @@ extern "C" __declspec(dllexport) int winampGetExtendedFileInfo(const char *fn, c
361 361
 	}
362 362
 }
363 363
 
364
-#ifdef _MSC_VER
365 364
 extern "C" __declspec(dllexport) int winampGetExtendedFileInfoW(const wchar_t *fn, const char *data, wchar_t *dest, size_t destlen)
366 365
 {
367 366
 	try
... ...
@@ -374,7 +373,6 @@ extern "C" __declspec(dllexport) int winampGetExtendedFileInfoW(const wchar_t *f
374 373
 		return 0;
375 374
 	}
376 375
 }
377
-#endif
378 376
 
379 377
 std::unique_ptr<XSFFile> extendedXSFFile;
380 378
 
... ...
@@ -388,7 +386,7 @@ extern "C" __declspec(dllexport) int winampSetExtendedFileInfo(const char *fn, c
388 386
 {
389 387
 	try
390 388
 	{
391
-		if (!extendedXSFFile || extendedXSFFile->GetFilename().GetStr() != fn)
389
+		if (!extendedXSFFile || extendedXSFFile->GetFilename() != fn)
392 390
 			extendedXSFFile.reset(new XSFFile(fn));
393 391
 		return wrapperWinampSetExtendedFileInfo(data, val);
394 392
 	}
... ...
@@ -398,12 +396,11 @@ extern "C" __declspec(dllexport) int winampSetExtendedFileInfo(const char *fn, c
398 396
 	}
399 397
 }
400 398
 
401
-#ifdef _MSC_VER
402 399
 extern "C" __declspec(dllexport) int winampSetExtendedFileInfoW(const wchar_t *fn, const char *data, const wchar_t *val)
403 400
 {
404 401
 	try
405 402
 	{
406
-		if (!extendedXSFFile || extendedXSFFile->GetFilename().GetWStr() != fn)
403
+		if (!extendedXSFFile || ConvertFuncs::StringToWString(extendedXSFFile->GetFilename()) != fn)
407 404
 			extendedXSFFile.reset(new XSFFile(fn));
408 405
 		return wrapperWinampSetExtendedFileInfo(data, val);
409 406
 	}
... ...
@@ -412,7 +409,6 @@ extern "C" __declspec(dllexport) int winampSetExtendedFileInfoW(const wchar_t *f
412 409
 		return 0;
413 410
 	}
414 411
 }
415
-#endif
416 412
 
417 413
 extern "C" __declspec(dllexport) int winampWriteExtendedFileInfo()
418 414
 {
... ...
@@ -422,12 +418,10 @@ extern "C" __declspec(dllexport) int winampWriteExtendedFileInfo()
422 418
 	return 1;
423 419
 }
424 420
 
425
-#ifdef _MSC_VER
426 421
 extern "C" __declspec(dllexport) int winampClearExtendedFileInfoW(const wchar_t *)
427 422
 {
428 423
 	return 0;
429 424
 }
430
-#endif
431 425
 
432 426
 intptr_t wrapperWinampGetExtendedRead_open(std::unique_ptr<XSFPlayer> tmpxSFPlayer, int *size, int *bps, int *nch, int *srate)
433 427
 {
... ...
@@ -460,7 +454,6 @@ extern "C" __declspec(dllexport) intptr_t winampGetExtendedRead_open(const char
460 454
 	}
461 455
 }
462 456
 
463
-#ifdef _MSC_VER
464 457
 extern "C" __declspec(dllexport) intptr_t winampGetExtendedRead_openW(const wchar_t *fn, int *size, int *bps, int *nch, int *srate)
465 458
 {
466 459
 	try
... ...
@@ -473,7 +466,6 @@ extern "C" __declspec(dllexport) intptr_t winampGetExtendedRead_openW(const wcha
473 466
 		return 0;
474 467
 	}
475 468
 }
476
-#endif
477 469
 
478 470
 int extendedSeekNeeded = -1;
479 471
 
... ...
@@ -71,15 +71,11 @@
71 71
     </Link>
72 72
   </ItemDefinitionGroup>
73 73
   <ItemGroup>
74
-    <ClInclude Include="BigSString.h" />
75 74
     <ClInclude Include="convert.h" />
76
-    <ClInclude Include="ConvertUTF.h" />
77 75
     <ClInclude Include="DialogBuilder.h" />
78 76
     <ClInclude Include="eqstr.h" />
79 77
     <ClInclude Include="ltstr.h" />
80 78
     <ClInclude Include="TagList.h" />
81
-    <ClInclude Include="UtfConverter.h" />
82
-    <ClInclude Include="UTFEncodeDecode.h" />
83 79
     <ClInclude Include="windowsh_wrapper.h" />
84 80
     <ClInclude Include="XSFCommon.h" />
85 81
     <ClInclude Include="XSFConfig.h" />
... ...
@@ -87,12 +83,9 @@
87 83
     <ClInclude Include="XSFPlayer.h" />
88 84
   </ItemGroup>
89 85
   <ItemGroup>
90
-    <ClCompile Include="ConvertUTF.cpp" />
91 86
     <ClCompile Include="DialogBuilder.cpp" />
92 87
     <ClCompile Include="in_xsf.cpp" />
93 88
     <ClCompile Include="TagList.cpp" />
94
-    <ClCompile Include="UtfConverter.cpp" />
95
-    <ClCompile Include="UTFEncodeDecode.cpp" />
96 89
     <ClCompile Include="XSFConfig.cpp" />
97 90
     <ClCompile Include="XSFConfig_Winamp.cpp" />
98 91
     <ClCompile Include="XSFFile.cpp" />
... ...
@@ -15,27 +15,15 @@
15 15
     </Filter>
16 16
   </ItemGroup>
17 17
   <ItemGroup>
18
-    <ClInclude Include="BigSString.h">
19
-      <Filter>Header Files</Filter>
20
-    </ClInclude>
21 18
     <ClInclude Include="convert.h">
22 19
       <Filter>Header Files</Filter>
23 20
     </ClInclude>
24
-    <ClInclude Include="ConvertUTF.h">
25
-      <Filter>Header Files</Filter>
26
-    </ClInclude>
27 21
     <ClInclude Include="DialogBuilder.h">
28 22
       <Filter>Header Files</Filter>
29 23
     </ClInclude>
30 24
     <ClInclude Include="eqstr.h">
31 25
       <Filter>Header Files</Filter>
32 26
     </ClInclude>
33
-    <ClInclude Include="UtfConverter.h">
34
-      <Filter>Header Files</Filter>
35
-    </ClInclude>
36
-    <ClInclude Include="UTFEncodeDecode.h">
37
-      <Filter>Header Files</Filter>
38
-    </ClInclude>
39 27
     <ClInclude Include="windowsh_wrapper.h">
40 28
       <Filter>Header Files</Filter>
41 29
     </ClInclude>
... ...
@@ -59,21 +47,12 @@
59 47
     </ClInclude>
60 48
   </ItemGroup>
61 49
   <ItemGroup>
62
-    <ClCompile Include="ConvertUTF.cpp">
63
-      <Filter>Source Files</Filter>
64
-    </ClCompile>
65 50
     <ClCompile Include="DialogBuilder.cpp">
66 51
       <Filter>Source Files</Filter>
67 52
     </ClCompile>
68 53
     <ClCompile Include="in_xsf.cpp">
69 54
       <Filter>Source Files</Filter>
70 55
     </ClCompile>
71
-    <ClCompile Include="UtfConverter.cpp">
72
-      <Filter>Source Files</Filter>
73
-    </ClCompile>
74
-    <ClCompile Include="UTFEncodeDecode.cpp">
75
-      <Filter>Source Files</Filter>
76
-    </ClCompile>
77 56
     <ClCompile Include="XSFConfig.cpp">
78 57
       <Filter>Source Files</Filter>
79 58
     </ClCompile>
80 59
new file mode 100644
... ...
@@ -0,0 +1,183 @@
1
+// This comes from llvm's libcxx project. I've copied the code from there (with very minor modifications) for use with GCC and Clang when libcxx isn't being used.
2
+
3
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(_LIBCPP_VERSION)
4
+#pragma once
5
+
6
+#include <memory>
7
+#include <string>
8
+#include <locale>
9
+
10
+namespace std
11
+{
12
+
13
+template<class _Codecvt, class _Elem = wchar_t, class _Wide_alloc = allocator<_Elem>, class _Byte_alloc = allocator<char>> class wstring_convert
14
+{
15
+public:
16
+	typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string;
17
+	typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string;
18
+	typedef typename _Codecvt::state_type state_type;
19
+	typedef typename wide_string::traits_type::int_type int_type;
20
+
21
+private:
22
+	byte_string __byte_err_string_;
23
+	wide_string __wide_err_string_;
24
+	_Codecvt *__cvtptr_;
25
+	state_type __cvtstate_;
26
+	size_t __cvtcount_;
27
+
28
+	wstring_convert(const wstring_convert &__wc);
29
+	wstring_convert& operator=(const wstring_convert &__wc);
30
+public:
31
+	wstring_convert(_Codecvt *__pcvt = new _Codecvt) : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) { }
32
+	wstring_convert(_Codecvt *__pcvt, state_type __state) : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) { }
33
+	wstring_convert(const byte_string &__byte_err, const wide_string &__wide_err = wide_string()) : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), __cvtptr_(new _Codecvt), __cvtstate_(), __cvtcount_(0) { }
34
+	wstring_convert(wstring_convert &&__wc) : __byte_err_string_(move(__wc.__byte_err_string_)), __wide_err_string_(move(__wc.__wide_err_string_)), __cvtptr_(__wc.__cvtptr_), __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_)
35
+	{
36
+		__wc.__cvtptr_ = nullptr;
37
+	}
38
+	~wstring_convert() { delete this->__cvtptr_; }
39
+
40
+	wide_string from_bytes(char __byte) { return from_bytes(&__byte, &__byte + 1); }
41
+	wide_string from_bytes(const char *__ptr) { return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr)); }
42
+	wide_string from_bytes(const byte_string &__str) { return from_bytes(__str.data(), __str.data() + __str.size()); }
43
+	wide_string from_bytes(const char *__frm, const char *__frm_end)
44
+	{
45
+		this->__cvtcount_ = 0;
46
+		if (this->__cvtptr_)
47
+		{
48
+			wide_string __ws(2 * (__frm_end - __frm), _Elem());
49
+			if (__frm != __frm_end)
50
+				__ws.resize(__ws.capacity());
51
+			auto __r = codecvt_base::ok;
52
+			auto __st = this->__cvtstate_;
53
+			if (__frm != __frm_end)
54
+			{
55
+				auto __to = &__ws[0];
56
+				auto __to_end = __to + __ws.size();
57
+				const char *__frm_nxt;
58
+				do
59
+				{
60
+					_Elem *__to_nxt;
61
+					__r = this->__cvtptr_->in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
62
+					this->__cvtcount_ += __frm_nxt - __frm;
63
+					if (__frm_nxt == __frm)
64
+						__r = codecvt_base::error;
65
+					else if (__r == codecvt_base::noconv)
66
+					{
67
+						__ws.resize(__to - &__ws[0]);
68
+						// This only gets executed if _Elem is char
69
+						__ws.append(reinterpret_cast<const _Elem *>(__frm), reinterpret_cast<const _Elem *>(__frm_end));
70
+						__frm = __frm_nxt;
71
+						__r = codecvt_base::ok;
72
+					}
73
+					else if (__r == codecvt_base::ok)
74
+					{
75
+						__ws.resize(__to_nxt - &__ws[0]);
76
+						__frm = __frm_nxt;
77
+					}
78
+					else if (__r == codecvt_base::partial)
79
+					{
80
+						ptrdiff_t __s = __to_nxt - &__ws[0];
81
+						__ws.resize(2 * __s);
82
+						__to = &__ws[0] + __s;
83
+						__to_end = &__ws[0] + __ws.size();
84
+						__frm = __frm_nxt;
85
+					}
86
+				} while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
87
+			}
88
+			if (__r == codecvt_base::ok)
89
+				return __ws;
90
+		}
91
+		if (this->__wide_err_string_.empty())
92
+			throw range_error("wstring_convert: from_bytes error");
93
+		return this->__wide_err_string_;
94
+	}
95
+
96
+	byte_string to_bytes(_Elem __wchar) { return to_bytes(&__wchar, &__wchar + 1); }
97
+	byte_string to_bytes(const _Elem *__wptr) { return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr)); }
98
+	byte_string to_bytes(const wide_string &__wstr) { return to_bytes(__wstr.data(), __wstr.data() + __wstr.size()); }
99
+	byte_string to_bytes(const _Elem *__frm, const _Elem *__frm_end)
100
+	{
101
+		this->__cvtcount_ = 0;
102
+		if (this->__cvtptr_)
103
+		{
104
+			byte_string __bs(2 * (__frm_end - __frm), char());
105
+			if (__frm != __frm_end)
106
+				__bs.resize(__bs.capacity());
107
+			auto __r = codecvt_base::ok;
108
+			auto __st = this->__cvtstate_;
109
+			if (__frm != __frm_end)
110
+			{
111
+				auto __to = &__bs[0];
112
+				auto __to_end = __to + __bs.size();
113
+				const _Elem *__frm_nxt;
114
+				do
115
+				{
116
+					char *__to_nxt;
117
+					__r = this->__cvtptr_->out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
118
+					this->__cvtcount_ += __frm_nxt - __frm;
119
+					if (__frm_nxt == __frm)
120
+						__r = codecvt_base::error;
121
+					else if (__r == codecvt_base::noconv)
122
+					{
123
+						__bs.resize(__to - &__bs[0]);
124
+						// This only gets executed if _Elem is char
125
+						__bs.append(reinterpret_cast<const char *>(__frm), reinterpret_cast<const char *>(__frm_end));
126
+						__frm = __frm_nxt;
127
+						__r = codecvt_base::ok;
128
+					}
129
+					else if (__r == codecvt_base::ok)
130
+					{
131
+						__bs.resize(__to_nxt - &__bs[0]);
132
+						__frm = __frm_nxt;
133
+					}
134
+					else if (__r == codecvt_base::partial)
135
+					{
136
+						ptrdiff_t __s = __to_nxt - &__bs[0];
137
+						__bs.resize(2 * __s);
138
+						__to = &__bs[0] + __s;
139
+						__to_end = &__bs[0] + __bs.size();
140
+						__frm = __frm_nxt;
141
+					}
142
+				} while (__r == codecvt_base::partial && __frm_nxt < __frm_end);
143
+			}
144
+			if (__r == codecvt_base::ok)
145
+			{
146
+				auto __s = __bs.size();
147
+				__bs.resize(__bs.capacity());
148
+				auto __to = &__bs[0] + __s;
149
+				auto __to_end = __to + __bs.size();
150
+				do
151
+				{
152
+					char *__to_nxt;
153
+					__r = this->__cvtptr_->unshift(__st, __to, __to_end, __to_nxt);
154
+					if (__r == codecvt_base::noconv)
155
+					{
156
+						__bs.resize(__to - &__bs[0]);
157
+						__r = codecvt_base::ok;
158
+					}
159
+					else if (__r == codecvt_base::ok)
160
+						__bs.resize(__to_nxt - &__bs[0]);
161
+					else if (__r == codecvt_base::partial)
162
+					{
163
+						ptrdiff_t __sp = __to_nxt - &__bs[0];
164
+						__bs.resize(2 * __sp);
165
+						__to = &__bs[0] + __sp;
166
+						__to_end = &__bs[0] + __bs.size();
167
+					}
168
+				} while (__r == codecvt_base::partial);
169
+				if (__r == codecvt_base::ok)
170
+					return __bs;
171
+			}
172
+		}
173
+		if (this->__byte_err_string_.empty())
174
+			throw range_error("wstring_convert: to_bytes error");
175
+		return this->__byte_err_string_;
176
+	}
177
+
178
+	size_t converted() const throw() { return this->__cvtcount_; }
179
+	state_type state() const { return this->__cvtstate_; }
180
+};
181
+
182
+};
183
+#endif