diff --git a/Minetestmapper/CMakeLists.txt b/Minetestmapper/CMakeLists.txt index 3d8406a..4f64c83 100644 --- a/Minetestmapper/CMakeLists.txt +++ b/Minetestmapper/CMakeLists.txt @@ -29,6 +29,8 @@ set(sources main.cpp CharEncodingConverter.cpp CharEncodingConverter.h + CharEncodingConverterIConv.cpp + CharEncodingConverterIConv.h PaintEngine.h PaintEngine_libgd.cpp PaintEngine_libgd.h diff --git a/Minetestmapper/CharEncodingConverter.cpp b/Minetestmapper/CharEncodingConverter.cpp index 1f88360..38a9da1 100644 --- a/Minetestmapper/CharEncodingConverter.cpp +++ b/Minetestmapper/CharEncodingConverter.cpp @@ -1,37 +1,26 @@ +#include "CharEncodingConverter.h" -#include #include "build_config.h" -#include "CharEncodingConverter.h" -#ifdef _WIN32 -#pragma message ("No standard charset converter defined for WIN32 - disabling conversion") -#else +#include +#ifdef USE_ICONV #include "CharEncodingConverterIConv.h" #endif -CharEncodingConverter *CharEncodingConverter::createStandardConverter(const std::string to, const std::string from) +CharEncodingConverter *CharEncodingConverter::createStandardConverter(const std::string &to, const std::string &from) { -#ifdef _WIN32 - return new CharEncodingConverterDummy(to, from); -#else - #if USE_ICONV +#ifdef USE_ICONV return new CharEncodingConverterIConv(to, from); - #else +#else return new CharEncodingConverterDummy(to, from); - #endif #endif } std::string CharEncodingConverter::getCurrentCharEncoding(void) { -#ifdef _WIN32 - return CharEncodingConverterDummy::getCurrentCharEncoding(); -#else - #if USE_ICONV +#ifdef USE_ICONV return CharEncodingConverterIConv::getCurrentCharEncoding(); - #else +#else return CharEncodingConverterDummy::getCurrentCharEncoding(); - #endif #endif } - diff --git a/Minetestmapper/CharEncodingConverter.h b/Minetestmapper/CharEncodingConverter.h index 658cad5..1e31f31 100644 --- a/Minetestmapper/CharEncodingConverter.h +++ b/Minetestmapper/CharEncodingConverter.h @@ -1,27 +1,29 @@ - -#ifndef _CHARENCODINGCONVERTER_H_INCLUDED_ -#define _CHARENCODINGCONVERTER_H_INCLUDED_ +#pragma once #include class CharEncodingConverter { public: - CharEncodingConverter(const std::string to, const std::string from) - : m_toFormat(to), m_fromFormat(from) { - if (m_toFormat == "") m_toFormat = getCurrentCharEncoding(); - if (m_fromFormat == "") m_fromFormat = getCurrentCharEncoding(); - } + CharEncodingConverter(const std::string &to, const std::string &from) + : m_toFormat(to), m_fromFormat(from) + { + if (m_toFormat.empty()) + m_toFormat = getCurrentCharEncoding(); + if (m_fromFormat.empty()) + m_fromFormat = getCurrentCharEncoding(); + } virtual ~CharEncodingConverter(void) {} // Create a converter with an unspecified but suitable backend. // (for usage convenience) - static CharEncodingConverter *createStandardConverter(const std::string to, const std::string from = ""); - static std::string getCurrentCharEncoding(void); + static CharEncodingConverter *createStandardConverter(const std::string &to, const std::string &from = ""); + static std::string getCurrentCharEncoding(); virtual std::string convert(const std::string &src) = 0; - virtual std::string fromFormat(void) { return m_fromFormat; } - virtual std::string toFormat(void) { return m_toFormat; } + virtual std::string fromFormat() { return m_fromFormat; } + virtual std::string toFormat() { return m_toFormat; } + protected: std::string m_toFormat; std::string m_fromFormat; @@ -30,13 +32,10 @@ protected: class CharEncodingConverterDummy : public CharEncodingConverter { public: - CharEncodingConverterDummy(const std::string to, const std::string from = "") + CharEncodingConverterDummy(const std::string &to, const std::string &from = "") : CharEncodingConverter(to, from) {} - virtual ~CharEncodingConverterDummy(void) {} + virtual ~CharEncodingConverterDummy() {} - static std::string getCurrentCharEncoding(void) { return "UTF-8"; } + static std::string getCurrentCharEncoding() { return "UTF-8"; } std::string convert(const std::string &src) override { return src; } }; - -#endif // _CHARENCODINGCONVERTER_H_INCLUDED_ - diff --git a/Minetestmapper/CharEncodingConverterIConv.cpp b/Minetestmapper/CharEncodingConverterIConv.cpp index 0602acb..6351757 100644 --- a/Minetestmapper/CharEncodingConverterIConv.cpp +++ b/Minetestmapper/CharEncodingConverterIConv.cpp @@ -1,17 +1,22 @@ - #include "CharEncodingConverterIConv.h" -#include -#include -#include -#include -#include +#ifdef USE_ICONV #include +#include +#include +#ifndef _WIN32 +#include +#endif +#include +#include #define ICONV_BUFSIZE 16 -std::string CharEncodingConverterIConv::getCurrentCharEncoding(void) +std::string CharEncodingConverterIConv::getCurrentCharEncoding() { +#ifdef _WIN32 + return "UTF-8"; // TODO: Get the correct codepage on Windows and convert it to something that iconv can use +#else setlocale(LC_CTYPE, ""); char *enc = nl_langinfo(CODESET); std::string encoding; @@ -31,27 +36,31 @@ std::string CharEncodingConverterIConv::getCurrentCharEncoding(void) // Alternative: modify conversion to replace unknown chars with '?' manually. setlocale(LC_CTYPE, "C"); return encoding; +#endif } -CharEncodingConverterIConv::CharEncodingConverterIConv(std::string to, std::string from) +CharEncodingConverterIConv::CharEncodingConverterIConv(const std::string &to, const std::string &from) : CharEncodingConverter(to, from) { - to = m_toFormat + "//TRANSLIT"; - from = m_fromFormat; - m_iconv = iconv_open(to.c_str(), from.c_str()); - if (m_iconv == (iconv_t) -1) { + std::string toFormat = m_toFormat + "//TRANSLIT"; + std::string fromFormat = m_fromFormat; + m_iconv = iconv_open(toFormat.c_str(), fromFormat.c_str()); + if (m_iconv == (iconv_t)-1) { int rno = errno; - std::string msg = std::string("Error initializing iconv charset converter (") - + (from=="" ? std::string("(default)") : from) + " --> " - + (to=="" ? std::string("(default)") : to) + "): " + strerror(rno); - throw std::runtime_error(msg); + std::ostringstream oss; + oss << "Error initializing iconv charset converter (" + << (fromFormat.empty() ? "(default)" : from) << " --> " + << (toFormat.empty() ? "(default)" : toFormat) << "): " + << strerror(rno) << std::endl; + + throw std::runtime_error(oss.str()); } } CharEncodingConverterIConv::~CharEncodingConverterIConv(void) { - if (m_iconv != (iconv_t) -1) + if (m_iconv != (iconv_t)-1) iconv_close(m_iconv); } @@ -72,7 +81,7 @@ std::string CharEncodingConverterIConv::convert(const std::string &src) size_t rv; do { rv = iconv(m_iconv, &fromBufP, &fromBufLen, &toBufP, &toBufLen); - if (rv == (size_t) -1) { + if (rv == (size_t)-1) { int rno = errno; if (rno != E2BIG) { std::ostringstream oss; @@ -80,19 +89,19 @@ std::string CharEncodingConverterIConv::convert(const std::string &src) << fromFormat() << " to " << toFormat() << " (text: '[" << std::string(src.c_str(), 0, fromBufP - src.c_str()) << "]" << std::string(fromBufP) << "'): " << strerror(rno); - // Note: strerror() can be misleading, e.g. complaining about invalid input - // when really the character cannot be represented in the output... - // (but //TRANSLIT avoids (most of?) those kinds of errors...) + // Note: strerror() can be misleading, e.g. complaining about invalid input + // when really the character cannot be represented in the output... + // (but //TRANSLIT avoids (most of?) those kinds of errors...) throw std::runtime_error(oss.str()); } } dst += std::string(toBuffer, ICONV_BUFSIZE - toBufLen); toBufLen = ICONV_BUFSIZE; toBufP = toBuffer; - } while (rv == (size_t) -1); + } while (rv == (size_t)-1); iconv(m_iconv, NULL, NULL, NULL, NULL); return dst; } - +#endif diff --git a/Minetestmapper/CharEncodingConverterIConv.h b/Minetestmapper/CharEncodingConverterIConv.h index 40edb48..7517da6 100644 --- a/Minetestmapper/CharEncodingConverterIConv.h +++ b/Minetestmapper/CharEncodingConverterIConv.h @@ -1,21 +1,22 @@ +#pragma once -#ifndef _CHARENCODINGCONVERTERICONV_H_INCLUDED_ -#define _CHARENCODINGCONVERTERICONV_H_INCLUDED_ - -#include #include "CharEncodingConverter.h" +#include "build_config.h" + + +#ifdef USE_ICONV +#include class CharEncodingConverterIConv : public CharEncodingConverter { public: - CharEncodingConverterIConv(std::string to, std::string from = ""); - virtual ~CharEncodingConverterIConv(void); + CharEncodingConverterIConv(const std::string &to, const std::string &from = ""); + virtual ~CharEncodingConverterIConv(); - static std::string getCurrentCharEncoding(void); + static std::string getCurrentCharEncoding(); std::string convert(const std::string &src) override; + private: iconv_t m_iconv; }; - -#endif // _CHARENCODINGCONVERTERICONV_H_INCLUDED_ - +#endif diff --git a/build_config.h.in b/build_config.h.in index 3906f45..7e81991 100644 --- a/build_config.h.in +++ b/build_config.h.in @@ -7,3 +7,5 @@ #cmakedefine USE_LEVELDB #cmakedefine USE_REDIS + +#cmakedefine USE_ICONV