X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Futil.cpp;h=1c3d90583d17f733251edc79bb89061237a05036;hp=b86525325cc0808dff99d8de7df14a0bd282f5c4;hb=42ff71aaa8d3cee9e348a45758c56c380a4f1b45;hpb=077d44f36d2f5c730283ef6be839aea7dd073d56 diff --git a/src/common/util.cpp b/src/common/util.cpp index b8652532..1c3d9058 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -19,8 +19,8 @@ ***************************************************************************/ #include "util.h" - -#include +#include +#include QString nickFromMask(QString mask) { return mask.section('!', 0, 0); @@ -42,6 +42,39 @@ bool isChannelName(QString str) { return QString("#&!+").contains(str[0]); } +QString decodeString(QByteArray input, QString encoding) { + // First, we check if it's utf8. It is very improbable to encounter a string that looks like + // valid utf8, but in fact is not. This means that if the input string passes as valid utf8, it + // is safe to assume that it is. + Q_ASSERT(sizeof(const char) == sizeof(quint8)); // just to make sure + bool isUtf8 = true; + int cnt = 0; + for(int i = 0; i < input.size(); i++) { + if(cnt) { + // We check a part of a multibyte char. These need to be of the form 10yyyyyy. + if((input[i] & 0xc0) != 0x80) { isUtf8 = false; break; } + cnt--; + continue; + } + if((input[i] & 0x80) == 0x00) continue; // 7 bit is always ok + if((input[i] & 0xf8) == 0xf0) { cnt = 3; continue; } // 4-byte char 11110xxx 10yyyyyy 10zzzzzz 10vvvvvv + if((input[i] & 0xf0) == 0xe0) { cnt = 2; continue; } // 3-byte char 1110xxxx 10yyyyyy 10zzzzzz + if((input[i] & 0xe0) == 0xc0) { cnt = 1; continue; } // 2-byte char 110xxxxx 10yyyyyy + isUtf8 = false; break; // 8 bit char, but not utf8! + } + if(isUtf8 && cnt == 0) { + QString s = QString::fromUtf8(input); + //qDebug() << "Detected utf8:" << s; + return s; + } + QTextCodec *codec = QTextCodec::codecForName(encoding.toAscii()); + if(!codec) { + qWarning() << QString("Invalid encoding: %1").arg(encoding); + return QString::fromAscii(input); + } + return codec->toUnicode(input); +} + void writeDataToDevice(QIODevice *dev, const QVariant &item) { QByteArray block; QDataStream out(&block, QIODevice::WriteOnly);