diff options
author | Benjamin Poulain <benjamin.poulain@nokia.com> | 2010-03-06 18:05:53 (GMT) |
---|---|---|
committer | Benjamin Poulain <benjamin.poulain@nokia.com> | 2010-03-07 16:30:53 (GMT) |
commit | 19e1b32bdeeeb5c7865038cab97b40dbac0e6c42 (patch) | |
tree | 343140d3cd2e5b0a6e272d2ae55a7c27c177ace6 | |
parent | 1bf5e9b3c328a80e71e7deed3419ff9d442db3cb (diff) | |
download | Qt-19e1b32bdeeeb5c7865038cab97b40dbac0e6c42.zip Qt-19e1b32bdeeeb5c7865038cab97b40dbac0e6c42.tar.gz Qt-19e1b32bdeeeb5c7865038cab97b40dbac0e6c42.tar.bz2 |
Avoid memory allocations in conversion from Gb2312/Gb18030 to unicode
The previous implementation was using QString::operator+=() for
every converted character. This was resulting in thousands of
malloc, making those conversions slow.
Reviewed-by: Andreas Kling
-rw-r--r-- | src/plugins/codecs/cn/qgb18030codec.cpp | 51 |
1 files changed, 37 insertions, 14 deletions
diff --git a/src/plugins/codecs/cn/qgb18030codec.cpp b/src/plugins/codecs/cn/qgb18030codec.cpp index 5537cf7..e683fc0 100644 --- a/src/plugins/codecs/cn/qgb18030codec.cpp +++ b/src/plugins/codecs/cn/qgb18030codec.cpp @@ -173,6 +173,9 @@ QString QGb18030Codec::convertToUnicode(const char* chars, int len, ConverterSta int invalid = 0; QString result; + result.resize(len); + int unicodeLen = 0; + QChar *const resultData = result.data(); //qDebug("QGb18030Decoder::toUnicode(const char* chars, int len = %d)", len); for (int i = 0; i < len; i++) { uchar ch = chars[i]; @@ -180,14 +183,16 @@ QString QGb18030Codec::convertToUnicode(const char* chars, int len, ConverterSta case 0: if (ch < 0x80) { // ASCII - result += QLatin1Char(ch); + resultData[unicodeLen] = QChar(ch); + ++unicodeLen; } else if (Is1stByte(ch)) { // GB18030? buf[0] = ch; nbuf = 1; } else { // Invalid - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; } break; @@ -198,9 +203,11 @@ QString QGb18030Codec::convertToUnicode(const char* chars, int len, ConverterSta int clen = 2; uint u = qt_Gb18030ToUnicode(buf, clen); if (clen == 2) { - result += QValidChar(u); + resultData[unicodeLen] = QValidChar(u); + ++unicodeLen; } else { - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; } nbuf = 0; @@ -209,7 +216,8 @@ QString QGb18030Codec::convertToUnicode(const char* chars, int len, ConverterSta nbuf = 2; } else { // Error - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; nbuf = 0; } @@ -220,7 +228,8 @@ QString QGb18030Codec::convertToUnicode(const char* chars, int len, ConverterSta buf[2] = ch; nbuf = 3; } else { - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; nbuf = 0; } @@ -232,19 +241,24 @@ QString QGb18030Codec::convertToUnicode(const char* chars, int len, ConverterSta int clen = 4; uint u = qt_Gb18030ToUnicode(buf, clen); if (clen == 4) { - result += QValidChar(u); + resultData[unicodeLen] = QValidChar(u); + ++unicodeLen; } else { - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; } } else { - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; } nbuf = 0; break; } } + result.resize(unicodeLen); + if (state) { state->remainingChars = nbuf; state->state_data[0] = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]; @@ -456,6 +470,9 @@ QString QGb2312Codec::convertToUnicode(const char* chars, int len, ConverterStat int invalid = 0; QString result; + result.resize(len); + int unicodeLen = 0; + QChar *const resultData = result.data(); //qDebug("QGb2312Decoder::toUnicode(const char* chars, int len = %d)", len); for (int i=0; i<len; i++) { uchar ch = chars[i]; @@ -463,14 +480,16 @@ QString QGb2312Codec::convertToUnicode(const char* chars, int len, ConverterStat case 0: if (ch < 0x80) { // ASCII - result += QLatin1Char(ch); + resultData[unicodeLen] = QChar(ch); + ++unicodeLen; } else if (IsByteInGb2312(ch)) { // GB2312 1st byte? buf[0] = ch; nbuf = 1; } else { // Invalid - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; } break; @@ -481,21 +500,25 @@ QString QGb2312Codec::convertToUnicode(const char* chars, int len, ConverterStat int clen = 2; uint u = qt_Gb18030ToUnicode(buf, clen); if (clen == 2) { - result += QValidChar(u); + resultData[unicodeLen] = QValidChar(u); + ++unicodeLen; } else { - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; } nbuf = 0; } else { // Error - result += replacement; + resultData[unicodeLen] = replacement; + ++unicodeLen; ++invalid; nbuf = 0; } break; } } + result.resize(unicodeLen); if (state) { state->remainingChars = nbuf; |