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>
This commit is contained in:
parent
2d43f735b4
commit
3ce9162ab5
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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"));
|
||||
|
Loading…
Reference in New Issue
Block a user