diff --git a/src/common/textcodec.cpp b/src/common/textcodec.cpp index dc0865a1..28db0683 100644 --- a/src/common/textcodec.cpp +++ b/src/common/textcodec.cpp @@ -1,56 +1,48 @@ #include #include "textcodec.h" -TextCodec::TextCodec() +/* When Qt is compiled with ICU support, QTextCodec::codecForName() is very + slow due to broken codec name caching (the function does dozens of + comparisons and only then asks the cache...), so we use our own map. */ +static QMap initCodecs() { - _codec = QTextCodec::codecForName("Windows-1252"); + QMap map; + + map.insert(65001, 0); + map.insert(874, QTextCodec::codecForName("Windows-874")); + map.insert(932, QTextCodec::codecForName("Shift-JIS")); + map.insert(936, QTextCodec::codecForName("GB18030")); + map.insert(949, QTextCodec::codecForName("EUC-KR")); + map.insert(950, QTextCodec::codecForName("Big5")); + map.insert(1250, QTextCodec::codecForName("Windows-1250")); + map.insert(1251, QTextCodec::codecForName("Windows-1251")); + map.insert(1252, QTextCodec::codecForName("Windows-1252")); + map.insert(1253, QTextCodec::codecForName("Windows-1253")); + map.insert(1254, QTextCodec::codecForName("Windows-1254")); + map.insert(1255, QTextCodec::codecForName("Windows-1255")); + map.insert(1256, QTextCodec::codecForName("Windows-1256")); + map.insert(1257, QTextCodec::codecForName("Windows-1257")); + map.insert(1258, QTextCodec::codecForName("Windows-1258")); + + return map; +} + +const QMap &TextCodec::codecs() +{ + static QMap map = initCodecs(); + return map; } TextCodec::TextCodec(int codepage) { - switch (codepage) { - case 65001: - _codec = 0; - break; - case 932: - _codec = QTextCodec::codecForName("Shift-JIS"); - break; - case 936: - _codec = QTextCodec::codecForName("GB18030"); - break; - case 949: - _codec = QTextCodec::codecForName("EUC-KR"); - break; - case 950: - _codec = QTextCodec::codecForName("Big5"); - break; - case 1250: - _codec = QTextCodec::codecForName("Windows-1250"); - break; - case 1251: - _codec = QTextCodec::codecForName("Windows-1251"); - break; - case 1253: - _codec = QTextCodec::codecForName("Windows-1253"); - break; - case 1254: - _codec = QTextCodec::codecForName("Windows-1254"); - break; - case 1255: - _codec = QTextCodec::codecForName("Windows-1255"); - break; - case 1256: - _codec = QTextCodec::codecForName("Windows-1256"); - break; - case 1257: - _codec = QTextCodec::codecForName("Windows-1257"); - break; - case 1258: - _codec = QTextCodec::codecForName("Windows-1258"); - break; - default: - _codec = QTextCodec::codecForName("Windows-1252"); - } + const QMap &map = codecs(); + + QMap::const_iterator it(map.find(codepage)); + if (it == map.cend()) { + qWarning("%d: Unsupported codepage, using UTF-8", codepage); + _codec = 0; + } else + _codec = *it; } QString TextCodec::toString(const QByteArray &ba) const diff --git a/src/common/textcodec.h b/src/common/textcodec.h index c014d9c1..a5279ce7 100644 --- a/src/common/textcodec.h +++ b/src/common/textcodec.h @@ -2,19 +2,22 @@ #define TEXTCODEC_H #include +#include class QTextCodec; class TextCodec { public: - TextCodec(); + TextCodec() : _codec(0) {} TextCodec(int codepage); QString toString(const QByteArray &ba) const; private: QTextCodec *_codec; + + static const QMap &codecs(); }; #endif // TEXTCODEC_H diff --git a/src/data/gpiparser.cpp b/src/data/gpiparser.cpp index 47c2ea91..6755abae 100644 --- a/src/data/gpiparser.cpp +++ b/src/data/gpiparser.cpp @@ -128,7 +128,7 @@ qint64 CryptDevice::readData(char *data, qint64 maxSize) class DataStream : public QDataStream { public: - DataStream(QIODevice *d) : QDataStream(d) {} + DataStream(QIODevice *d) : QDataStream(d), _codec(1252) {} void setCodepage(quint16 codepage) {_codec = TextCodec(codepage);} diff --git a/src/data/twonavparser.cpp b/src/data/twonavparser.cpp index 76c91c0d..57206176 100644 --- a/src/data/twonavparser.cpp +++ b/src/data/twonavparser.cpp @@ -75,7 +75,7 @@ bool TwoNavParser::parse(QFile *file, QList &tracks, QVector &waypoints) { Q_UNUSED(polygons); - TextCodec codec; + TextCodec codec(1252); GCS gcs; bool ok, route = false, track = false, waypoint = false; diff --git a/src/map/IMG/lblfile.h b/src/map/IMG/lblfile.h index e3a01201..3a361b97 100644 --- a/src/map/IMG/lblfile.h +++ b/src/map/IMG/lblfile.h @@ -16,14 +16,14 @@ class LBLFile : public SubFile { public: LBLFile(const IMGData *img) - : SubFile(img), _huffmanText(0), _table(0), _rasters(0), _imgIdSize(0), - _poiShift(0), _shift(0), _encoding(0) {} + : SubFile(img), _huffmanText(0), _table(0), _rasters(0), _codec(1252), + _imgIdSize(0), _poiShift(0), _shift(0), _encoding(0) {} LBLFile(const QString *path) - : SubFile(path), _huffmanText(0), _table(0), _rasters(0), _imgIdSize(0), - _poiShift(0), _shift(0), _encoding(0) {} + : SubFile(path), _huffmanText(0), _table(0), _rasters(0), _codec(1252), + _imgIdSize(0), _poiShift(0), _shift(0), _encoding(0) {} LBLFile(const SubFile *gmp, quint32 offset) : SubFile(gmp, offset), _huffmanText(0), _table(0), _rasters(0), - _imgIdSize(0), _poiShift(0), _shift(0), _encoding(0) {} + _codec(1252), _imgIdSize(0), _poiShift(0), _shift(0), _encoding(0) {} ~LBLFile(); bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);