summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Poulain <benjamin.poulain@nokia.com>2010-03-06 18:05:53 (GMT)
committerBenjamin Poulain <benjamin.poulain@nokia.com>2010-03-07 16:30:53 (GMT)
commit19e1b32bdeeeb5c7865038cab97b40dbac0e6c42 (patch)
tree343140d3cd2e5b0a6e272d2ae55a7c27c177ace6
parent1bf5e9b3c328a80e71e7deed3419ff9d442db3cb (diff)
downloadQt-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.cpp51
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;