diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-04-27 15:08:50 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-05-14 07:48:42 +0200 |
commit | 3ce9162ab5b99594d59b654dcdf2009bc500d3d7 (patch) | |
tree | ac4b7f25d252ca1f68ce42d9803f0e3cc2b7ea61 | |
parent | 2d43f735b4768c9924f9f7ce97211043b22cd84c (diff) |
Construct a string converter by name
Add a constructor, that allows constructing a string converter by
name. This is required in some cases and also makes it possible to
(in the future) extend the API to 3rd party encodings.
Also add a name() accessor.
Change-Id: I606d6ce9405ee967f76197b803615e27c5b001cf
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/text/qstringconverter.cpp | 49 | ||||
-rw-r--r-- | src/corelib/text/qstringconverter.h | 20 | ||||
-rw-r--r-- | tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp | 27 |
3 files changed, 87 insertions, 9 deletions
diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp index dfd819e203..9322fcd35e 100644 --- a/src/corelib/text/qstringconverter.cpp +++ b/src/corelib/text/qstringconverter.cpp @@ -1441,15 +1441,46 @@ static qsizetype toLatin1Len(qsizetype l) { return l + 1; } const QStringConverter::Interface QStringConverter::encodingInterfaces[QStringConverter::LastEncoding + 1] = { - { QUtf8::convertToUnicode, fromUtf8Len, QUtf8::convertFromUnicode, toUtf8Len }, - { fromUtf16, fromUtf16Len, toUtf16, toUtf16Len }, - { fromUtf16LE, fromUtf16Len, toUtf16LE, toUtf16Len }, - { fromUtf16BE, fromUtf16Len, toUtf16BE, toUtf16Len }, - { fromUtf32, fromUtf32Len, toUtf32, toUtf32Len }, - { fromUtf32LE, fromUtf32Len, toUtf32LE, toUtf32Len }, - { fromUtf32BE, fromUtf32Len, toUtf32BE, toUtf32Len }, - { fromLatin1, fromLatin1Len, toLatin1, toLatin1Len }, - { fromLocal8Bit, fromUtf8Len, toLocal8Bit, toUtf8Len } + { "UTF-8", QUtf8::convertToUnicode, fromUtf8Len, QUtf8::convertFromUnicode, toUtf8Len }, + { "UTF-16", fromUtf16, fromUtf16Len, toUtf16, toUtf16Len }, + { "UTF-16LE", fromUtf16LE, fromUtf16Len, toUtf16LE, toUtf16Len }, + { "UTF-16BE", fromUtf16BE, fromUtf16Len, toUtf16BE, toUtf16Len }, + { "UTF-32", fromUtf32, fromUtf32Len, toUtf32, toUtf32Len }, + { "UTF-32LE", fromUtf32LE, fromUtf32Len, toUtf32LE, toUtf32Len }, + { "UTF-32BE", fromUtf32BE, fromUtf32Len, toUtf32BE, toUtf32Len }, + { "ISO-8859-1", fromLatin1, fromLatin1Len, toLatin1, toLatin1Len }, + { "Locale", fromLocal8Bit, fromUtf8Len, toLocal8Bit, toUtf8Len } }; +// match names case insensitive and skipping '-' and '_' +static bool nameMatch(const char *a, const char *b) +{ + while (*a && *b) { + if (*a == '-' || *a == '_') { + ++a; + continue; + } + if (*b == '-' || *b == '_') { + ++b; + continue; + } + if (toupper(*a) != toupper(*b)) + return false; + ++a; + ++b; + } + return !*a && !*b; +} + +QStringConverter::QStringConverter(const char *name) + : iface(nullptr) +{ + for (int i = 0; i < LastEncoding + 1; ++i) { + if (nameMatch(encodingInterfaces[i].name, name)) { + iface = encodingInterfaces + i; + break; + } + } +} + QT_END_NAMESPACE diff --git a/src/corelib/text/qstringconverter.h b/src/corelib/text/qstringconverter.h index 1e46cbe72e..73f9f4f9ba 100644 --- a/src/corelib/text/qstringconverter.h +++ b/src/corelib/text/qstringconverter.h @@ -132,18 +132,23 @@ protected: using DecoderFn = QChar * (*)(QChar *out, const char *in, qsizetype length, State *state); using LengthFn = qsizetype (*)(qsizetype inLength); using EncoderFn = char * (*)(char *out, QStringView in, State *state); + const char *name = nullptr; DecoderFn toUtf16 = nullptr; LengthFn toUtf16Len = nullptr; EncoderFn fromUtf16 = nullptr; LengthFn fromUtf16Len = nullptr; }; + QSTRINGCONVERTER_CONSTEXPR QStringConverter() + : iface(nullptr) + {} QSTRINGCONVERTER_CONSTEXPR QStringConverter(Encoding encoding, Flags f) : iface(&encodingInterfaces[int(encoding)]), state(f) {} QSTRINGCONVERTER_CONSTEXPR QStringConverter(const Interface *i) : iface(i) {} + QStringConverter(const char *name); public: bool isValid() const { return iface != nullptr; } @@ -154,6 +159,9 @@ public: } bool hasError() const { return state.invalidChars != 0; } + const char *name() const + { return isValid() ? iface->name : nullptr; } + protected: const Interface *iface; State state; @@ -168,9 +176,15 @@ protected: : QStringConverter(i) {} public: + QSTRINGCONVERTER_CONSTEXPR QStringEncoder() + : QStringConverter() + {} QSTRINGCONVERTER_CONSTEXPR QStringEncoder(Encoding encoding, Flags flags = Flag::Default) : QStringConverter(encoding, flags) {} + QStringEncoder(const char *name) + : QStringConverter(name) + {} #if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER) template<typename T> @@ -231,6 +245,12 @@ public: QSTRINGCONVERTER_CONSTEXPR QStringDecoder(Encoding encoding, Flags flags = Flag::Default) : QStringConverter(encoding, flags) {} + QSTRINGCONVERTER_CONSTEXPR QStringDecoder() + : QStringConverter() + {} + QStringDecoder(const char *name) + : QStringConverter(name) + {} #if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER) template<typename T> diff --git a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp index c3dc8a0383..1419321679 100644 --- a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp +++ b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp @@ -39,6 +39,8 @@ class tst_QStringConverter : public QObject private slots: void threadSafety(); + void constructByName(); + void convertUtf8(); void nonFlaggedCodepointFFFF() const; @@ -59,6 +61,31 @@ private slots: void utfHeaders(); }; +void tst_QStringConverter::constructByName() +{ + QStringDecoder decoder("UTF-8"); + QVERIFY(decoder.isValid()); + QVERIFY(!strcmp(decoder.name(), "UTF-8")); + decoder = QStringDecoder("XXX"); + QVERIFY(!decoder.isValid()); + decoder = QStringDecoder("ISO-8859-1"); + QVERIFY(decoder.isValid()); + QVERIFY(!strcmp(decoder.name(), "ISO-8859-1")); + decoder = QStringDecoder("UTF-16LE"); + QVERIFY(decoder.isValid()); + QVERIFY(!strcmp(decoder.name(), "UTF-16LE")); + + decoder = QStringDecoder("utf8"); + QVERIFY(decoder.isValid()); + QVERIFY(!strcmp(decoder.name(), "UTF-8")); + decoder = QStringDecoder("iso8859-1"); + QVERIFY(decoder.isValid()); + QVERIFY(!strcmp(decoder.name(), "ISO-8859-1")); + decoder = QStringDecoder("utf-16"); + QVERIFY(decoder.isValid()); + QVERIFY(!strcmp(decoder.name(), "UTF-16")); +} + void tst_QStringConverter::convertUtf8() { QFile file(QFINDTESTDATA("utf8.txt")); |