1818# include < unicode/ucsdet.h>
1919# include < unicode/ucnv.h>
2020#else
21- # ifdef _MSC_VER
22- # error MSVC builds require ICU
23- # endif
21+ # include < cstdint>
2422#endif
2523
2624#ifdef _WIN32
@@ -73,7 +71,6 @@ void Encoder::Decode(std::string& str) {
7371 Convert (str, _conv_storage, _conv_runtime);
7472}
7573
76- #if LCF_SUPPORT_ICU
7774void Encoder::Init () {
7875 if (_encoding.empty ()) {
7976 return ;
@@ -84,6 +81,7 @@ void Encoder::Init() {
8481 ? ReaderUtil::CodepageToEncoding (code_page)
8582 : _encoding;
8683
84+ #if LCF_SUPPORT_ICU
8785 auto status = U_ZERO_ERROR ;
8886 constexpr auto runtime_encoding = " UTF-8" ;
8987 auto conv_runtime = ucnv_open (runtime_encoding, &status);
@@ -106,8 +104,17 @@ void Encoder::Init() {
106104
107105 _conv_runtime = conv_runtime;
108106 _conv_storage = conv_storage;
107+ #else
108+ if (storage_encoding != " windows-1252" ) {
109+ return ;
110+ }
111+
112+ _conv_runtime = 65001 ;
113+ _conv_storage = 1252 ;
114+ #endif
109115}
110116
117+ #if LCF_SUPPORT_ICU
111118void Encoder::Reset () {
112119 if (_conv_runtime) {
113120 ucnv_close (_conv_runtime);
@@ -143,7 +150,64 @@ void Encoder::Convert(std::string& str, UConverter* conv_dst, UConverter* conv_s
143150
144151 str.assign (_buffer.data (), dst_p);
145152}
153+ #else
154+ void Encoder::Convert (std::string& str, int conv_dst, int ) {
155+ if (str.empty ()) {
156+ return ;
157+ }
158+
159+ size_t buf_idx = 0 ;
160+
161+ if (conv_dst == 65001 ) {
162+ // From 1252 to UTF-8
163+ // Based on https://stackoverflow.com/q/4059775/
164+ _buffer.resize (str.size () * 2 + 1 );
165+
166+ for (unsigned char ch: str) {
167+ if (ch < 0x80 ) {
168+ _buffer[buf_idx] = static_cast <char >(ch);
169+ } else {
170+ _buffer[buf_idx] = static_cast <char >(0xC0 | (ch >> 6 ));
171+ ++buf_idx;
172+ _buffer[buf_idx] = static_cast <char >(0x80 | (ch & 0x3F ));
173+ }
174+
175+ ++buf_idx;
176+ }
177+ } else {
178+ // From UTF-8 to 1252
179+ // Based on https://stackoverflow.com/q/23689733/
180+ _buffer.resize (str.size () + 1 );
181+ uint32_t codepoint;
182+
183+ for (size_t str_idx = 0 ; str_idx < str.size (); ++str_idx) {
184+ unsigned char ch = str[str_idx];
185+ if (ch <= 0x7F ) {
186+ codepoint = ch;
187+ } else if (ch <= 0xBF ) {
188+ codepoint = (codepoint << 6 ) | (ch & 0x3F );
189+ } else if (ch <= 0xDF ) {
190+ codepoint = ch & 0x1F ;
191+ } else if (ch <= 0xEF ) {
192+ codepoint = ch & 0x0F ;
193+ } else {
194+ codepoint = ch & 0x07 ;
195+ }
196+ ++str_idx;
197+ ch = str[str_idx];
198+ if (((ch & 0xC0 ) != 0x80 ) && (codepoint <= 0x10ffff )) {
199+ if (codepoint <= 255 ) {
200+ _buffer[buf_idx] = static_cast <char >(codepoint);
201+ } else {
202+ _buffer[buf_idx] = ' ?' ;
203+ }
204+ }
205+ ++buf_idx;
206+ }
207+ }
208+
209+ str.assign (_buffer.data (), buf_idx);
210+ }
146211#endif
147212
148213} // namespace lcf
149-
0 commit comments