|
|
bool headerdone = false; | bool headerdone = false; |
QChar replacement = QChar::ReplacementCharacter; | QChar replacement = QChar::ReplacementCharacter; |
int need = 0; | int need = 0; |
|
int error = -1; |
uint uc = 0; | uint uc = 0; |
|
uint min_uc = 0; |
if (state) { | if (state) { |
if (state->flags & IgnoreHeader) | if (state->flags & IgnoreHeader) |
headerdone = true; | headerdone = true; |
if (state->flags & ConvertInvalidToNull) | if (state->flags & ConvertInvalidToNull) |
replacement = QChar::Null; | replacement = QChar::Null; |
need = state->remainingChars; | need = state->remainingChars; |
if (need) |
if (need) { |
uc = state->state_data[0]; | uc = state->state_data[0]; |
|
min_uc = state->state_data[1]; |
|
} |
} | } |
if (!headerdone && len > 3 | if (!headerdone && len > 3 |
&& (uchar)chars[0] == 0xef && (uchar)chars[1] == 0xbb && (uchar)chars[2] == 0xbf) { | && (uchar)chars[0] == 0xef && (uchar)chars[1] == 0xbb && (uchar)chars[2] == 0xbf) { |
|
|
headerdone = true; | headerdone = true; |
} | } |
| |
|
int originalLength = target->length(); |
QString &result = *target; | QString &result = *target; |
result.resize(len); // worst case |
result.resize(originalLength + len); // worst case |
QChar *qch = result.data(); |
QChar *qch = result.data() + originalLength; |
uchar ch; | uchar ch; |
int invalid = 0; | int invalid = 0; |
| |
for (int i=0; i<len; i++) { | for (int i=0; i<len; i++) { |
ch = *chars++; |
ch = chars[i]; |
if (need) { | if (need) { |
if ((ch&0xc0) == 0x80) { | if ((ch&0xc0) == 0x80) { |
uc = (uc << 6) | (ch & 0x3f); | uc = (uc << 6) | (ch & 0x3f); |
|
|
uc -= 0x10000; | uc -= 0x10000; |
unsigned short high = uc/0x400 + 0xd800; | unsigned short high = uc/0x400 + 0xd800; |
unsigned short low = uc%0x400 + 0xdc00; | unsigned short low = uc%0x400 + 0xdc00; |
|
|
|
// resize if necessary |
|
long where = qch - result.unicode(); |
|
if (where + 2 >= result.length()) { |
|
result.resize(where + 2); |
|
qch = result.data() + where; |
|
} |
|
|
*qch++ = QChar(high); | *qch++ = QChar(high); |
*qch++ = QChar(low); | *qch++ = QChar(low); |
|
} else if ((uc < min_uc) || (uc >= 0xd800 && uc <= 0xdfff) || (uc >= 0xfffe)) { |
|
// error |
|
*qch++ = QChar::ReplacementCharacter; |
|
++invalid; |
} else { | } else { |
*qch++ = uc; | *qch++ = uc; |
} | } |
} | } |
} else { | } else { |
// error | // error |
|
i = error; |
*qch++ = QChar::ReplacementCharacter; | *qch++ = QChar::ReplacementCharacter; |
++invalid; | ++invalid; |
need = 0; | need = 0; |
|
|
} else if ((ch & 0xe0) == 0xc0) { | } else if ((ch & 0xe0) == 0xc0) { |
uc = ch & 0x1f; | uc = ch & 0x1f; |
need = 1; | need = 1; |
|
error = i; |
|
min_uc = 0x80; |
} else if ((ch & 0xf0) == 0xe0) { | } else if ((ch & 0xf0) == 0xe0) { |
uc = ch & 0x0f; | uc = ch & 0x0f; |
need = 2; | need = 2; |
|
error = i; |
|
min_uc = 0x800; |
} else if ((ch&0xf8) == 0xf0) { | } else if ((ch&0xf8) == 0xf0) { |
uc = ch & 0x07; | uc = ch & 0x07; |
need = 3; | need = 3; |
|
error = i; |
|
min_uc = 0x10000; |
|
} else { |
|
// error |
|
*qch++ = QChar::ReplacementCharacter; |
|
++invalid; |
} | } |
} | } |
} | } |
|
if (!state && need > 0) { |
|
// unterminated UTF sequence |
|
for (int i = error; i < len; ++i) { |
|
*qch++ = QChar::ReplacementCharacter; |
|
++invalid; |
|
} |
|
} |
result.truncate(qch - result.unicode()); | result.truncate(qch - result.unicode()); |
if (state) { | if (state) { |
state->invalidChars += invalid; | state->invalidChars += invalid; |
|
|
if (headerdone) | if (headerdone) |
state->flags |= IgnoreHeader; | state->flags |= IgnoreHeader; |
state->state_data[0] = need ? uc : 0; | state->state_data[0] = need ? uc : 0; |
|
state->state_data[1] = need ? min_uc : 0; |
} | } |
} | } |
| |
|
|
result.resize(size); // worst case | result.resize(size); // worst case |
ushort *qch = result.d->data; | ushort *qch = result.d->data; |
uint uc = 0; | uint uc = 0; |
|
uint min_uc = 0; |
int need = 0; | int need = 0; |
int error = -1; | int error = -1; |
uchar ch; | uchar ch; |
|
|
// surrogate pair | // surrogate pair |
*qch++ = QChar::highSurrogate(uc); | *qch++ = QChar::highSurrogate(uc); |
uc = QChar::lowSurrogate(uc); | uc = QChar::lowSurrogate(uc); |
|
} else if ((uc < min_uc) || (uc >= 0xd800 && uc <= 0xdfff) || (uc >= 0xfffe)) { |
|
// overlong seqence, UTF16 surrogate or BOM |
|
i = error; |
|
qch = addOne(qch, result); |
|
*qch++ = 0xdbff; |
|
uc = 0xde00 + ((uchar)str[i]); |
} | } |
*qch++ = uc; | *qch++ = uc; |
} | } |
|
|
uc = ch & 0x1f; | uc = ch & 0x1f; |
need = 1; | need = 1; |
error = i; | error = i; |
|
min_uc = 0x80; |
} else if ((ch & 0xf0) == 0xe0) { | } else if ((ch & 0xf0) == 0xe0) { |
uc = ch & 0x0f; | uc = ch & 0x0f; |
need = 2; | need = 2; |
error = i; | error = i; |
|
min_uc = 0x800; |
} else if ((ch&0xf8) == 0xf0) { | } else if ((ch&0xf8) == 0xf0) { |
uc = ch & 0x07; | uc = ch & 0x07; |
need = 3; | need = 3; |
error = i; | error = i; |
|
min_uc = 0x10000; |
} else { | } else { |
// Error | // Error |
qch = addOne(qch, result); | qch = addOne(qch, result); |
|
|
| |
| |
/*! \fn QString &QString::inline_append(QChar ch) | /*! \fn QString &QString::inline_append(QChar ch) |
|
\internal |
| |
An inlined version of append(). | An inlined version of append(). |
*/ | */ |