Preparation to use libiconv
parent
6d958c2274
commit
e219fd8896
|
@ -29,6 +29,8 @@ set(sources
|
||||||
main.cpp
|
main.cpp
|
||||||
CharEncodingConverter.cpp
|
CharEncodingConverter.cpp
|
||||||
CharEncodingConverter.h
|
CharEncodingConverter.h
|
||||||
|
CharEncodingConverterIConv.cpp
|
||||||
|
CharEncodingConverterIConv.h
|
||||||
PaintEngine.h
|
PaintEngine.h
|
||||||
PaintEngine_libgd.cpp
|
PaintEngine_libgd.cpp
|
||||||
PaintEngine_libgd.h
|
PaintEngine_libgd.h
|
||||||
|
|
|
@ -1,37 +1,26 @@
|
||||||
|
#include "CharEncodingConverter.h"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include "build_config.h"
|
#include "build_config.h"
|
||||||
|
|
||||||
#include "CharEncodingConverter.h"
|
#include <iostream>
|
||||||
#ifdef _WIN32
|
#ifdef USE_ICONV
|
||||||
#pragma message ("No standard charset converter defined for WIN32 - disabling conversion")
|
|
||||||
#else
|
|
||||||
#include "CharEncodingConverterIConv.h"
|
#include "CharEncodingConverterIConv.h"
|
||||||
#endif
|
#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
|
#ifdef USE_ICONV
|
||||||
return new CharEncodingConverterDummy(to, from);
|
|
||||||
#else
|
|
||||||
#if USE_ICONV
|
|
||||||
return new CharEncodingConverterIConv(to, from);
|
return new CharEncodingConverterIConv(to, from);
|
||||||
#else
|
#else
|
||||||
return new CharEncodingConverterDummy(to, from);
|
return new CharEncodingConverterDummy(to, from);
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CharEncodingConverter::getCurrentCharEncoding(void)
|
std::string CharEncodingConverter::getCurrentCharEncoding(void)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef USE_ICONV
|
||||||
return CharEncodingConverterDummy::getCurrentCharEncoding();
|
|
||||||
#else
|
|
||||||
#if USE_ICONV
|
|
||||||
return CharEncodingConverterIConv::getCurrentCharEncoding();
|
return CharEncodingConverterIConv::getCurrentCharEncoding();
|
||||||
#else
|
#else
|
||||||
return CharEncodingConverterDummy::getCurrentCharEncoding();
|
return CharEncodingConverterDummy::getCurrentCharEncoding();
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,29 @@
|
||||||
|
#pragma once
|
||||||
#ifndef _CHARENCODINGCONVERTER_H_INCLUDED_
|
|
||||||
#define _CHARENCODINGCONVERTER_H_INCLUDED_
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class CharEncodingConverter
|
class CharEncodingConverter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CharEncodingConverter(const std::string to, const std::string from)
|
CharEncodingConverter(const std::string &to, const std::string &from)
|
||||||
: m_toFormat(to), m_fromFormat(from) {
|
: m_toFormat(to), m_fromFormat(from)
|
||||||
if (m_toFormat == "") m_toFormat = getCurrentCharEncoding();
|
{
|
||||||
if (m_fromFormat == "") m_fromFormat = getCurrentCharEncoding();
|
if (m_toFormat.empty())
|
||||||
}
|
m_toFormat = getCurrentCharEncoding();
|
||||||
|
if (m_fromFormat.empty())
|
||||||
|
m_fromFormat = getCurrentCharEncoding();
|
||||||
|
}
|
||||||
virtual ~CharEncodingConverter(void) {}
|
virtual ~CharEncodingConverter(void) {}
|
||||||
|
|
||||||
// Create a converter with an unspecified but suitable backend.
|
// Create a converter with an unspecified but suitable backend.
|
||||||
// (for usage convenience)
|
// (for usage convenience)
|
||||||
static CharEncodingConverter *createStandardConverter(const std::string to, const std::string from = "");
|
static CharEncodingConverter *createStandardConverter(const std::string &to, const std::string &from = "");
|
||||||
static std::string getCurrentCharEncoding(void);
|
static std::string getCurrentCharEncoding();
|
||||||
|
|
||||||
virtual std::string convert(const std::string &src) = 0;
|
virtual std::string convert(const std::string &src) = 0;
|
||||||
virtual std::string fromFormat(void) { return m_fromFormat; }
|
virtual std::string fromFormat() { return m_fromFormat; }
|
||||||
virtual std::string toFormat(void) { return m_toFormat; }
|
virtual std::string toFormat() { return m_toFormat; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string m_toFormat;
|
std::string m_toFormat;
|
||||||
std::string m_fromFormat;
|
std::string m_fromFormat;
|
||||||
|
@ -30,13 +32,10 @@ protected:
|
||||||
class CharEncodingConverterDummy : public CharEncodingConverter
|
class CharEncodingConverterDummy : public CharEncodingConverter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CharEncodingConverterDummy(const std::string to, const std::string from = "")
|
CharEncodingConverterDummy(const std::string &to, const std::string &from = "")
|
||||||
: CharEncodingConverter(to, 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; }
|
std::string convert(const std::string &src) override { return src; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _CHARENCODINGCONVERTER_H_INCLUDED_
|
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
|
|
||||||
#include "CharEncodingConverterIConv.h"
|
#include "CharEncodingConverterIConv.h"
|
||||||
|
|
||||||
#include <cstring>
|
#ifdef USE_ICONV
|
||||||
#include <stdexcept>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <langinfo.h>
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <langinfo.h>
|
||||||
|
#endif
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#define ICONV_BUFSIZE 16
|
#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, "");
|
setlocale(LC_CTYPE, "");
|
||||||
char *enc = nl_langinfo(CODESET);
|
char *enc = nl_langinfo(CODESET);
|
||||||
std::string encoding;
|
std::string encoding;
|
||||||
|
@ -31,27 +36,31 @@ std::string CharEncodingConverterIConv::getCurrentCharEncoding(void)
|
||||||
// Alternative: modify conversion to replace unknown chars with '?' manually.
|
// Alternative: modify conversion to replace unknown chars with '?' manually.
|
||||||
setlocale(LC_CTYPE, "C");
|
setlocale(LC_CTYPE, "C");
|
||||||
return encoding;
|
return encoding;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CharEncodingConverterIConv::CharEncodingConverterIConv(std::string to, std::string from)
|
CharEncodingConverterIConv::CharEncodingConverterIConv(const std::string &to, const std::string &from)
|
||||||
: CharEncodingConverter(to, from)
|
: CharEncodingConverter(to, from)
|
||||||
{
|
{
|
||||||
to = m_toFormat + "//TRANSLIT";
|
std::string toFormat = m_toFormat + "//TRANSLIT";
|
||||||
from = m_fromFormat;
|
std::string fromFormat = m_fromFormat;
|
||||||
m_iconv = iconv_open(to.c_str(), from.c_str());
|
m_iconv = iconv_open(toFormat.c_str(), fromFormat.c_str());
|
||||||
if (m_iconv == (iconv_t) -1) {
|
if (m_iconv == (iconv_t)-1) {
|
||||||
int rno = errno;
|
int rno = errno;
|
||||||
std::string msg = std::string("Error initializing iconv charset converter (")
|
std::ostringstream oss;
|
||||||
+ (from=="" ? std::string("(default)") : from) + " --> "
|
oss << "Error initializing iconv charset converter ("
|
||||||
+ (to=="" ? std::string("(default)") : to) + "): " + strerror(rno);
|
<< (fromFormat.empty() ? "(default)" : from) << " --> "
|
||||||
throw std::runtime_error(msg);
|
<< (toFormat.empty() ? "(default)" : toFormat) << "): "
|
||||||
|
<< strerror(rno) << std::endl;
|
||||||
|
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CharEncodingConverterIConv::~CharEncodingConverterIConv(void)
|
CharEncodingConverterIConv::~CharEncodingConverterIConv(void)
|
||||||
{
|
{
|
||||||
if (m_iconv != (iconv_t) -1)
|
if (m_iconv != (iconv_t)-1)
|
||||||
iconv_close(m_iconv);
|
iconv_close(m_iconv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +81,7 @@ std::string CharEncodingConverterIConv::convert(const std::string &src)
|
||||||
size_t rv;
|
size_t rv;
|
||||||
do {
|
do {
|
||||||
rv = iconv(m_iconv, &fromBufP, &fromBufLen, &toBufP, &toBufLen);
|
rv = iconv(m_iconv, &fromBufP, &fromBufLen, &toBufP, &toBufLen);
|
||||||
if (rv == (size_t) -1) {
|
if (rv == (size_t)-1) {
|
||||||
int rno = errno;
|
int rno = errno;
|
||||||
if (rno != E2BIG) {
|
if (rno != E2BIG) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
@ -80,19 +89,19 @@ std::string CharEncodingConverterIConv::convert(const std::string &src)
|
||||||
<< fromFormat() << " to " << toFormat()
|
<< fromFormat() << " to " << toFormat()
|
||||||
<< " (text: '[" << std::string(src.c_str(), 0, fromBufP - src.c_str()) << "]" << std::string(fromBufP) << "'): "
|
<< " (text: '[" << std::string(src.c_str(), 0, fromBufP - src.c_str()) << "]" << std::string(fromBufP) << "'): "
|
||||||
<< strerror(rno);
|
<< strerror(rno);
|
||||||
// Note: strerror() can be misleading, e.g. complaining about invalid input
|
// Note: strerror() can be misleading, e.g. complaining about invalid input
|
||||||
// when really the character cannot be represented in the output...
|
// when really the character cannot be represented in the output...
|
||||||
// (but //TRANSLIT avoids (most of?) those kinds of errors...)
|
// (but //TRANSLIT avoids (most of?) those kinds of errors...)
|
||||||
throw std::runtime_error(oss.str());
|
throw std::runtime_error(oss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dst += std::string(toBuffer, ICONV_BUFSIZE - toBufLen);
|
dst += std::string(toBuffer, ICONV_BUFSIZE - toBufLen);
|
||||||
toBufLen = ICONV_BUFSIZE;
|
toBufLen = ICONV_BUFSIZE;
|
||||||
toBufP = toBuffer;
|
toBufP = toBuffer;
|
||||||
} while (rv == (size_t) -1);
|
} while (rv == (size_t)-1);
|
||||||
|
|
||||||
iconv(m_iconv, NULL, NULL, NULL, NULL);
|
iconv(m_iconv, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#ifndef _CHARENCODINGCONVERTERICONV_H_INCLUDED_
|
|
||||||
#define _CHARENCODINGCONVERTERICONV_H_INCLUDED_
|
|
||||||
|
|
||||||
#include <iconv.h>
|
|
||||||
#include "CharEncodingConverter.h"
|
#include "CharEncodingConverter.h"
|
||||||
|
#include "build_config.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_ICONV
|
||||||
|
#include <iconv.h>
|
||||||
|
|
||||||
class CharEncodingConverterIConv : public CharEncodingConverter
|
class CharEncodingConverterIConv : public CharEncodingConverter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CharEncodingConverterIConv(std::string to, std::string from = "");
|
CharEncodingConverterIConv(const std::string &to, const std::string &from = "");
|
||||||
virtual ~CharEncodingConverterIConv(void);
|
virtual ~CharEncodingConverterIConv();
|
||||||
|
|
||||||
static std::string getCurrentCharEncoding(void);
|
static std::string getCurrentCharEncoding();
|
||||||
std::string convert(const std::string &src) override;
|
std::string convert(const std::string &src) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
iconv_t m_iconv;
|
iconv_t m_iconv;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
#endif // _CHARENCODINGCONVERTERICONV_H_INCLUDED_
|
|
||||||
|
|
||||||
|
|
|
@ -7,3 +7,5 @@
|
||||||
#cmakedefine USE_LEVELDB
|
#cmakedefine USE_LEVELDB
|
||||||
|
|
||||||
#cmakedefine USE_REDIS
|
#cmakedefine USE_REDIS
|
||||||
|
|
||||||
|
#cmakedefine USE_ICONV
|
||||||
|
|
Loading…
Reference in New Issue