Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/codecs/qutfcodec.cpp |
Switch to Source code | Preprocessed file |
Line | Source | Count | ||||||
---|---|---|---|---|---|---|---|---|
1 | - | |||||||
2 | - | |||||||
3 | - | |||||||
4 | - | |||||||
5 | enum { Endian = 0, Data = 1 }; | - | ||||||
6 | - | |||||||
7 | static const uchar utf8bom[] = { 0xef, 0xbb, 0xbf }; | - | ||||||
8 | - | |||||||
9 | - | |||||||
10 | static inline bool simdEncodeAscii(uchar *&dst, const ushort *&nextAscii, const ushort *&src, const ushort *end) | - | ||||||
11 | { | - | ||||||
12 | - | |||||||
13 | for ( ; end - src >= 16; src += 16, dst += 16) { | - | ||||||
14 | __m128i data1 = _mm_loadu_si128((const __m128i*)src); | - | ||||||
15 | __m128i data2 = _mm_loadu_si128(1+(const __m128i*)src); | - | ||||||
16 | __m128i packed = _mm_packus_epi16(data1, data2); | - | ||||||
17 | __m128i nonAscii = _mm_cmpgt_epi8(packed, _mm_setzero_si128()); | - | ||||||
18 | - | |||||||
19 | - | |||||||
20 | _mm_storeu_si128((__m128i*)dst, packed); | - | ||||||
21 | - | |||||||
22 | - | |||||||
23 | ushort n = ~_mm_movemask_epi8(nonAscii); | - | ||||||
24 | if (n) { | - | ||||||
25 | - | |||||||
26 | - | |||||||
27 | - | |||||||
28 | nextAscii = src + __bsrd(n) + 1; | - | ||||||
29 | - | |||||||
30 | n = __bsfd(n); | - | ||||||
31 | dst += n; | - | ||||||
32 | src += n; | - | ||||||
33 | return false; | - | ||||||
34 | } | - | ||||||
35 | } | - | ||||||
36 | return src == end; | - | ||||||
37 | } | - | ||||||
38 | - | |||||||
39 | static inline bool simdDecodeAscii(ushort *&dst, const uchar *&nextAscii, const uchar *&src, const uchar *end) | - | ||||||
40 | { | - | ||||||
41 | - | |||||||
42 | for ( ; end - src >= 16; src += 16, dst += 16) { | - | ||||||
43 | __m128i data = _mm_loadu_si128((const __m128i*)src); | - | ||||||
44 | const int BitSpacing = 1; | - | ||||||
45 | - | |||||||
46 | - | |||||||
47 | - | |||||||
48 | uint n = _mm_movemask_epi8(data); | - | ||||||
49 | if (!n) { | - | ||||||
50 | - | |||||||
51 | _mm_storeu_si128((__m128i*)dst, _mm_unpacklo_epi8(data, _mm_setzero_si128())); | - | ||||||
52 | _mm_storeu_si128(1+(__m128i*)dst, _mm_unpackhi_epi8(data, _mm_setzero_si128())); | - | ||||||
53 | continue; | - | ||||||
54 | } | - | ||||||
55 | - | |||||||
56 | - | |||||||
57 | - | |||||||
58 | while (!(n & 1)) { | - | ||||||
59 | *dst++ = *src++; | - | ||||||
60 | n >>= BitSpacing; | - | ||||||
61 | } | - | ||||||
62 | - | |||||||
63 | - | |||||||
64 | - | |||||||
65 | - | |||||||
66 | n = __bsrd(n); | - | ||||||
67 | nextAscii = src + (n / BitSpacing) + 1; | - | ||||||
68 | return false; | - | ||||||
69 | - | |||||||
70 | } | - | ||||||
71 | return src == end; | - | ||||||
72 | } | - | ||||||
73 | QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len) | - | ||||||
74 | { | - | ||||||
75 | - | |||||||
76 | QByteArray result(len * 3, Qt::Uninitialized); | - | ||||||
77 | uchar *dst = reinterpret_cast<uchar *>(const_cast<char *>(result.constData())); | - | ||||||
78 | const ushort *src = reinterpret_cast<const ushort *>(uc); | - | ||||||
79 | const ushort *const end = src + len; | - | ||||||
80 | - | |||||||
81 | while (src != end) { | - | ||||||
82 | const ushort *nextAscii = end; | - | ||||||
83 | if (simdEncodeAscii(dst, nextAscii, src, end)) | - | ||||||
84 | break; | - | ||||||
85 | - | |||||||
86 | do { | - | ||||||
87 | ushort uc = *src++; | - | ||||||
88 | int res = QUtf8Functions::toUtf8<QUtf8BaseTraits>(uc, dst, src, end); | - | ||||||
89 | if (res < 0) { | - | ||||||
90 | - | |||||||
91 | *dst++ = '?'; | - | ||||||
92 | } | - | ||||||
93 | } while (src < nextAscii); | - | ||||||
94 | } | - | ||||||
95 | - | |||||||
96 | result.truncate(dst - reinterpret_cast<uchar *>(const_cast<char *>(result.constData()))); | - | ||||||
97 | return result; | - | ||||||
98 | } | - | ||||||
99 | - | |||||||
100 | QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::ConverterState *state) | - | ||||||
101 | { | - | ||||||
102 | uchar replacement = '?'; | - | ||||||
103 | int rlen = 3*len; | - | ||||||
104 | int surrogate_high = -1; | - | ||||||
105 | if (state) { | - | ||||||
106 | if (state->flags & QTextCodec::ConvertInvalidToNull) | - | ||||||
107 | replacement = 0; | - | ||||||
108 | if (!(state->flags & QTextCodec::IgnoreHeader)) | - | ||||||
109 | rlen += 3; | - | ||||||
110 | if (state->remainingChars) | - | ||||||
111 | surrogate_high = state->state_data[0]; | - | ||||||
112 | } | - | ||||||
113 | - | |||||||
114 | - | |||||||
115 | QByteArray rstr(rlen, Qt::Uninitialized); | - | ||||||
116 | uchar *cursor = reinterpret_cast<uchar *>(const_cast<char *>(rstr.constData())); | - | ||||||
117 | const ushort *src = reinterpret_cast<const ushort *>(uc); | - | ||||||
118 | const ushort *const end = src + len; | - | ||||||
119 | - | |||||||
120 | int invalid = 0; | - | ||||||
121 | if (state && !(state->flags & QTextCodec::IgnoreHeader)) { | - | ||||||
122 | - | |||||||
123 | *cursor++ = utf8bom[0]; | - | ||||||
124 | *cursor++ = utf8bom[1]; | - | ||||||
125 | *cursor++ = utf8bom[2]; | - | ||||||
126 | } | - | ||||||
127 | - | |||||||
128 | const ushort *nextAscii = src; | - | ||||||
129 | while (src != end) { | - | ||||||
130 | int res; | - | ||||||
131 | ushort uc; | - | ||||||
132 | if (surrogate_high != -1) { | - | ||||||
133 | uc = surrogate_high; | - | ||||||
134 | surrogate_high = -1; | - | ||||||
135 | res = QUtf8Functions::toUtf8<QUtf8BaseTraits>(uc, cursor, src, end); | - | ||||||
136 | } else { | - | ||||||
137 | if (src >= nextAscii && simdEncodeAscii(cursor, nextAscii, src, end)) | - | ||||||
138 | break; | - | ||||||
139 | - | |||||||
140 | uc = *src++; | - | ||||||
141 | res = QUtf8Functions::toUtf8<QUtf8BaseTraits>(uc, cursor, src, end); | - | ||||||
142 | } | - | ||||||
143 | if (__builtin_expect(!!(res >= 0), true)) | - | ||||||
144 | continue; | - | ||||||
145 | - | |||||||
146 | if (res == QUtf8BaseTraits::Error) { | - | ||||||
147 | - | |||||||
148 | ++invalid; | - | ||||||
149 | *cursor++ = replacement; | - | ||||||
150 | } else if (res == QUtf8BaseTraits::EndOfString) { | - | ||||||
151 | surrogate_high = uc; | - | ||||||
152 | break; | - | ||||||
153 | } | - | ||||||
154 | } | - | ||||||
155 | - | |||||||
156 | rstr.resize(cursor - (const uchar*)rstr.constData()); | - | ||||||
157 | if (state) { | - | ||||||
158 | state->invalidChars += invalid; | - | ||||||
159 | state->flags |= QTextCodec::IgnoreHeader; | - | ||||||
160 | state->remainingChars = 0; | - | ||||||
161 | if (surrogate_high >= 0) { | - | ||||||
162 | state->remainingChars = 1; | - | ||||||
163 | state->state_data[0] = surrogate_high; | - | ||||||
164 | } | - | ||||||
165 | } | - | ||||||
166 | return rstr; | - | ||||||
167 | } | - | ||||||
168 | - | |||||||
169 | QString QUtf8::convertToUnicode(const char *chars, int len) | - | ||||||
170 | { | - | ||||||
171 | QString result(len, Qt::Uninitialized); | - | ||||||
172 | ushortQChar *dstdata = reinterpret_cast<ushort *>(const_cast<QChar*>(result.constData()));()); | - | ||||||
173 | const QChar *end = convertToUnicode(data, chars, len); | - | ||||||
174 | result.truncate(end - data); | - | ||||||
175 | return executed 3930821 times by 532 tests: result;return result; Executed by:
executed 3930821 times by 532 tests: return result; Executed by:
| 3930821 | ||||||
176 | } | - | ||||||
177 | QChar *QUtf8::convertToUnicode(QChar *buffer, const char *chars, int len) noexcept | - | ||||||
178 | { | - | ||||||
179 | ushort *dst = reinterpret_cast<ushort *>(buffer); | - | ||||||
180 | const uchar *src = reinterpret_cast<const uchar *>(chars); | - | ||||||
181 | const uchar *end = src + len; | - | ||||||
182 | - | |||||||
183 | - | |||||||
184 | const uchar *nextAscii = end; | - | ||||||
185 | if (!simdDecodeAscii(dst, nextAscii, src, end)
| 598854-4015432 | ||||||
186 | - | |||||||
187 | - | |||||||
188 | if (__builtin_expect(!!(src == reinterpret_cast<const uchar *>(chars)), false)
| 535942-3479490 | ||||||
189 | && end - src >= 3
| 1605604-1873886 | ||||||
190 | && __builtin_expect(!!(src[0] == utf8bom[0] && src[1] == utf8bom[1] && src[2] == utf8bom[2]), false)
| 5-1873881 | ||||||
191 | src += 3; | - | ||||||
192 | } executed 5 times by 2 tests: end of block Executed by:
| 5 | ||||||
193 | - | |||||||
194 | while (src < end
| 4015424-4064914 | ||||||
195 | nextAscii = end; | - | ||||||
196 | if (simdDecodeAscii(dst, nextAscii, src, end)
| 8-4064906 | ||||||
197 | break; executed 8 times by 1 test: break; Executed by:
| 8 | ||||||
198 | - | |||||||
199 | do { | - | ||||||
200 | uchar b = *src++; | - | ||||||
201 | int res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(b, dst, src, end); | - | ||||||
202 | if (res < 0
| 530-17941153 | ||||||
203 | - | |||||||
204 | *dst++ = QChar::ReplacementCharacter; | - | ||||||
205 | } executed 530 times by 5 tests: end of block Executed by:
| 530 | ||||||
206 | } executed 17941683 times by 546 tests: while (src < nextAsciiend of block Executed by:
| 4064906-17941683 | ||||||
207 | } executed 4064906 times by 546 tests: end of block Executed by:
| 4064906 | ||||||
208 | } executed 4015432 times by 546 tests: end of block Executed by:
| 4015432 | ||||||
209 | - | |||||||
210 | result.truncate(dst -return executed 4614286 times by 546 tests: return reinterpret_cast<QChar *>(dst); Executed by:
executed 4614286 times by 546 tests: reinterpret_cast<const ushortQChar *>(result.constData()));return reinterpret_cast<QChar *>(dst); Executed by:
executed 4614286 times by 546 tests: return reinterpret_cast<QChar *>(dst); Executed by:
| 4614286 | ||||||
return result; executed 4614286 times by 546 tests: return reinterpret_cast<QChar *>(dst); Executed by:
executed 4614286 times by 546 tests: dst);return reinterpret_cast<QChar *>(dst); Executed by:
executed 4614286 times by 546 tests: return reinterpret_cast<QChar *>(dst); Executed by:
| ||||||||
211 | } | - | ||||||
212 | - | |||||||
213 | QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::ConverterState *state) | - | ||||||
214 | { | - | ||||||
215 | bool headerdone = false; | - | ||||||
216 | ushort replacement = QChar::ReplacementCharacter; | - | ||||||
217 | int invalid = 0; | - | ||||||
218 | int res; | - | ||||||
219 | uchar ch = 0; | - | ||||||
220 | QString result(len + 1, Qt::Uninitialized); | - | ||||||
221 | - | |||||||
222 | ushort *dst = reinterpret_cast<ushort *>(const_cast<QChar *>(result.constData())); | - | ||||||
223 | const uchar *src = reinterpret_cast<const uchar *>(chars); | - | ||||||
224 | const uchar *end = src + len; | - | ||||||
225 | - | |||||||
226 | if (state) { | - | ||||||
227 | if (state->flags & QTextCodec::IgnoreHeader) | - | ||||||
228 | headerdone = true; | - | ||||||
229 | if (state->flags & QTextCodec::ConvertInvalidToNull) | - | ||||||
230 | replacement = QChar::Null; | - | ||||||
231 | if (state->remainingChars) { | - | ||||||
232 | - | |||||||
233 | uchar remainingCharsData[4]; | - | ||||||
234 | int remainingCharsCount = state->remainingChars; | - | ||||||
235 | int newCharsToCopy = qMin<int>(sizeof(remainingCharsData) - remainingCharsCount, end - src); | - | ||||||
236 | - | |||||||
237 | memset(remainingCharsData, 0, sizeof(remainingCharsData)); | - | ||||||
238 | memcpy(remainingCharsData, &state->state_data[0], remainingCharsCount); | - | ||||||
239 | memcpy(remainingCharsData + remainingCharsCount, src, newCharsToCopy); | - | ||||||
240 | - | |||||||
241 | const uchar *begin = &remainingCharsData[1]; | - | ||||||
242 | res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(remainingCharsData[0], dst, begin, | - | ||||||
243 | static_cast<const uchar *>(remainingCharsData) + remainingCharsCount + newCharsToCopy); | - | ||||||
244 | if (res == QUtf8BaseTraits::Error || (res == QUtf8BaseTraits::EndOfString && len == 0)) { | - | ||||||
245 | - | |||||||
246 | - | |||||||
247 | ++invalid; | - | ||||||
248 | *dst++ = replacement; | - | ||||||
249 | } else if (res == QUtf8BaseTraits::EndOfString) { | - | ||||||
250 | - | |||||||
251 | - | |||||||
252 | state->remainingChars = remainingCharsCount + newCharsToCopy; | - | ||||||
253 | memcpy(&state->state_data[0], remainingCharsData, state->remainingChars); | - | ||||||
254 | return QString(); | - | ||||||
255 | } else if (!headerdone && res >= 0) { | - | ||||||
256 | - | |||||||
257 | headerdone = true; | - | ||||||
258 | if (dst[-1] == 0xfeff) | - | ||||||
259 | --dst; | - | ||||||
260 | } | - | ||||||
261 | - | |||||||
262 | - | |||||||
263 | if (res >= 0) { | - | ||||||
264 | ((!(res > remainingCharsCount)) ? qt_assert("res > remainingCharsCount",__FILE__,357386) : qt_noop()); | - | ||||||
265 | src += res - remainingCharsCount; | - | ||||||
266 | } | - | ||||||
267 | } | - | ||||||
268 | } | - | ||||||
269 | - | |||||||
270 | - | |||||||
271 | res = 0; | - | ||||||
272 | const uchar *nextAscii = src; | - | ||||||
273 | const uchar *start = src; | - | ||||||
274 | while (res >= 0 && src < end) { | - | ||||||
275 | if (src >= nextAscii && simdDecodeAscii(dst, nextAscii, src, end)) | - | ||||||
276 | break; | - | ||||||
277 | - | |||||||
278 | ch = *src++; | - | ||||||
279 | res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(ch, dst, src, end); | - | ||||||
280 | if (!headerdone && res >= 0) { | - | ||||||
281 | headerdone = true; | - | ||||||
282 | if (src == start + 3) { | - | ||||||
283 | - | |||||||
284 | if (dst[-1] == 0xfeff) | - | ||||||
285 | --dst; | - | ||||||
286 | } | - | ||||||
287 | } | - | ||||||
288 | if (res == QUtf8BaseTraits::Error) { | - | ||||||
289 | res = 0; | - | ||||||
290 | ++invalid; | - | ||||||
291 | *dst++ = replacement; | - | ||||||
292 | } | - | ||||||
293 | } | - | ||||||
294 | - | |||||||
295 | if (!state && res == QUtf8BaseTraits::EndOfString) { | - | ||||||
296 | - | |||||||
297 | *dst++ = QChar::ReplacementCharacter; | - | ||||||
298 | while (src++ < end) | - | ||||||
299 | *dst++ = QChar::ReplacementCharacter; | - | ||||||
300 | } | - | ||||||
301 | - | |||||||
302 | result.truncate(dst - (const ushort *)result.unicode()); | - | ||||||
303 | if (state) { | - | ||||||
304 | state->invalidChars += invalid; | - | ||||||
305 | if (headerdone) | - | ||||||
306 | state->flags |= QTextCodec::IgnoreHeader; | - | ||||||
307 | if (res == QUtf8BaseTraits::EndOfString) { | - | ||||||
308 | --src; | - | ||||||
309 | state->remainingChars = end - src; | - | ||||||
310 | memcpy(&state->state_data[0], src, end - src); | - | ||||||
311 | } else { | - | ||||||
312 | state->remainingChars = 0; | - | ||||||
313 | } | - | ||||||
314 | } | - | ||||||
315 | return result; | - | ||||||
316 | } | - | ||||||
317 | - | |||||||
318 | QByteArray QUtf16::convertFromUnicode(const QChar *uc, int len, QTextCodec::ConverterState *state, DataEndianness e) | - | ||||||
319 | { | - | ||||||
320 | DataEndianness endian = e; | - | ||||||
321 | int length = 2*len; | - | ||||||
322 | if (!state || (!(state->flags & QTextCodec::IgnoreHeader))) { | - | ||||||
323 | length += 2; | - | ||||||
324 | } | - | ||||||
325 | if (e == DetectEndianness) { | - | ||||||
326 | endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? BigEndianness : LittleEndianness; | - | ||||||
327 | } | - | ||||||
328 | - | |||||||
329 | QByteArray d; | - | ||||||
330 | d.resize(length); | - | ||||||
331 | char *data = d.data(); | - | ||||||
332 | if (!state || !(state->flags & QTextCodec::IgnoreHeader)) { | - | ||||||
333 | QChar bom(QChar::ByteOrderMark); | - | ||||||
334 | if (endian == BigEndianness) { | - | ||||||
335 | data[0] = bom.row(); | - | ||||||
336 | data[1] = bom.cell(); | - | ||||||
337 | } else { | - | ||||||
338 | data[0] = bom.cell(); | - | ||||||
339 | data[1] = bom.row(); | - | ||||||
340 | } | - | ||||||
341 | data += 2; | - | ||||||
342 | } | - | ||||||
343 | if (endian == BigEndianness) { | - | ||||||
344 | for (int i = 0; i < len; ++i) { | - | ||||||
345 | *(data++) = uc[i].row(); | - | ||||||
346 | *(data++) = uc[i].cell(); | - | ||||||
347 | } | - | ||||||
348 | } else { | - | ||||||
349 | for (int i = 0; i < len; ++i) { | - | ||||||
350 | *(data++) = uc[i].cell(); | - | ||||||
351 | *(data++) = uc[i].row(); | - | ||||||
352 | } | - | ||||||
353 | } | - | ||||||
354 | - | |||||||
355 | if (state) { | - | ||||||
356 | state->remainingChars = 0; | - | ||||||
357 | state->flags |= QTextCodec::IgnoreHeader; | - | ||||||
358 | } | - | ||||||
359 | return d; | - | ||||||
360 | } | - | ||||||
361 | - | |||||||
362 | QString QUtf16::convertToUnicode(const char *chars, int len, QTextCodec::ConverterState *state, DataEndianness e) | - | ||||||
363 | { | - | ||||||
364 | DataEndianness endian = e; | - | ||||||
365 | bool half = false; | - | ||||||
366 | uchar buf = 0; | - | ||||||
367 | bool headerdone = false; | - | ||||||
368 | if (state) { | - | ||||||
369 | headerdone = state->flags & QTextCodec::IgnoreHeader; | - | ||||||
370 | if (endian == DetectEndianness) | - | ||||||
371 | endian = (DataEndianness)state->state_data[Endian]; | - | ||||||
372 | if (state->remainingChars) { | - | ||||||
373 | half = true; | - | ||||||
374 | buf = state->state_data[Data]; | - | ||||||
375 | } | - | ||||||
376 | } | - | ||||||
377 | if (headerdone && endian == DetectEndianness) | - | ||||||
378 | endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? BigEndianness : LittleEndianness; | - | ||||||
379 | - | |||||||
380 | QString result(len, Qt::Uninitialized); | - | ||||||
381 | QChar *qch = (QChar *)result.data(); | - | ||||||
382 | while (len--) { | - | ||||||
383 | if (half) { | - | ||||||
384 | QChar ch; | - | ||||||
385 | if (endian == LittleEndianness) { | - | ||||||
386 | ch.setRow(*chars++); | - | ||||||
387 | ch.setCell(buf); | - | ||||||
388 | } else { | - | ||||||
389 | ch.setRow(buf); | - | ||||||
390 | ch.setCell(*chars++); | - | ||||||
391 | } | - | ||||||
392 | if (!headerdone) { | - | ||||||
393 | headerdone = true; | - | ||||||
394 | if (endian == DetectEndianness) { | - | ||||||
395 | if (ch == QChar::ByteOrderSwapped) { | - | ||||||
396 | endian = LittleEndianness; | - | ||||||
397 | } else if (ch == QChar::ByteOrderMark) { | - | ||||||
398 | endian = BigEndianness; | - | ||||||
399 | } else { | - | ||||||
400 | if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { | - | ||||||
401 | endian = BigEndianness; | - | ||||||
402 | } else { | - | ||||||
403 | endian = LittleEndianness; | - | ||||||
404 | ch = QChar((ch.unicode() >> 8) | ((ch.unicode() & 0xff) << 8)); | - | ||||||
405 | } | - | ||||||
406 | *qch++ = ch; | - | ||||||
407 | } | - | ||||||
408 | } else if (ch != QChar::ByteOrderMark) { | - | ||||||
409 | *qch++ = ch; | - | ||||||
410 | } | - | ||||||
411 | } else { | - | ||||||
412 | *qch++ = ch; | - | ||||||
413 | } | - | ||||||
414 | half = false; | - | ||||||
415 | } else { | - | ||||||
416 | buf = *chars++; | - | ||||||
417 | half = true; | - | ||||||
418 | } | - | ||||||
419 | } | - | ||||||
420 | result.truncate(qch - result.unicode()); | - | ||||||
421 | - | |||||||
422 | if (state) { | - | ||||||
423 | if (headerdone) | - | ||||||
424 | state->flags |= QTextCodec::IgnoreHeader; | - | ||||||
425 | state->state_data[Endian] = endian; | - | ||||||
426 | if (half) { | - | ||||||
427 | state->remainingChars = 1; | - | ||||||
428 | state->state_data[Data] = buf; | - | ||||||
429 | } else { | - | ||||||
430 | state->remainingChars = 0; | - | ||||||
431 | state->state_data[Data] = 0; | - | ||||||
432 | } | - | ||||||
433 | } | - | ||||||
434 | return result; | - | ||||||
435 | } | - | ||||||
436 | - | |||||||
437 | QByteArray QUtf32::convertFromUnicode(const QChar *uc, int len, QTextCodec::ConverterState *state, DataEndianness e) | - | ||||||
438 | { | - | ||||||
439 | DataEndianness endian = e; | - | ||||||
440 | int length = 4*len; | - | ||||||
441 | if (!state || (!(state->flags & QTextCodec::IgnoreHeader))) { | - | ||||||
442 | length += 4; | - | ||||||
443 | } | - | ||||||
444 | if (e == DetectEndianness) { | - | ||||||
445 | endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? BigEndianness : LittleEndianness; | - | ||||||
446 | } | - | ||||||
447 | - | |||||||
448 | QByteArray d(length, Qt::Uninitialized); | - | ||||||
449 | char *data = d.data(); | - | ||||||
450 | if (!state || !(state->flags & QTextCodec::IgnoreHeader)) { | - | ||||||
451 | if (endian == BigEndianness) { | - | ||||||
452 | data[0] = 0; | - | ||||||
453 | data[1] = 0; | - | ||||||
454 | data[2] = (char)0xfe; | - | ||||||
455 | data[3] = (char)0xff; | - | ||||||
456 | } else { | - | ||||||
457 | data[0] = (char)0xff; | - | ||||||
458 | data[1] = (char)0xfe; | - | ||||||
459 | data[2] = 0; | - | ||||||
460 | data[3] = 0; | - | ||||||
461 | } | - | ||||||
462 | data += 4; | - | ||||||
463 | } | - | ||||||
464 | - | |||||||
465 | QStringIterator i(uc, uc + len); | - | ||||||
466 | if (endian == BigEndianness) { | - | ||||||
467 | while (i.hasNext()) { | - | ||||||
468 | uint cp = i.next(); | - | ||||||
469 | - | |||||||
470 | *(data++) = cp >> 24; | - | ||||||
471 | *(data++) = (cp >> 16) & 0xff; | - | ||||||
472 | *(data++) = (cp >> 8) & 0xff; | - | ||||||
473 | *(data++) = cp & 0xff; | - | ||||||
474 | } | - | ||||||
475 | } else { | - | ||||||
476 | while (i.hasNext()) { | - | ||||||
477 | uint cp = i.next(); | - | ||||||
478 | - | |||||||
479 | *(data++) = cp & 0xff; | - | ||||||
480 | *(data++) = (cp >> 8) & 0xff; | - | ||||||
481 | *(data++) = (cp >> 16) & 0xff; | - | ||||||
482 | *(data++) = cp >> 24; | - | ||||||
483 | } | - | ||||||
484 | } | - | ||||||
485 | - | |||||||
486 | if (state) { | - | ||||||
487 | state->remainingChars = 0; | - | ||||||
488 | state->flags |= QTextCodec::IgnoreHeader; | - | ||||||
489 | } | - | ||||||
490 | return d; | - | ||||||
491 | } | - | ||||||
492 | - | |||||||
493 | QString QUtf32::convertToUnicode(const char *chars, int len, QTextCodec::ConverterState *state, DataEndianness e) | - | ||||||
494 | { | - | ||||||
495 | DataEndianness endian = e; | - | ||||||
496 | uchar tuple[4]; | - | ||||||
497 | int num = 0; | - | ||||||
498 | bool headerdone = false; | - | ||||||
499 | if (state) { | - | ||||||
500 | headerdone = state->flags & QTextCodec::IgnoreHeader; | - | ||||||
501 | if (endian == DetectEndianness) { | - | ||||||
502 | endian = (DataEndianness)state->state_data[Endian]; | - | ||||||
503 | } | - | ||||||
504 | num = state->remainingChars; | - | ||||||
505 | memcpy(tuple, &state->state_data[Data], 4); | - | ||||||
506 | } | - | ||||||
507 | if (headerdone && endian == DetectEndianness) | - | ||||||
508 | endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? BigEndianness : LittleEndianness; | - | ||||||
509 | - | |||||||
510 | QString result; | - | ||||||
511 | result.resize((num + len) >> 2 << 1); | - | ||||||
512 | QChar *qch = (QChar *)result.data(); | - | ||||||
513 | - | |||||||
514 | const char *end = chars + len; | - | ||||||
515 | while (chars < end) { | - | ||||||
516 | tuple[num++] = *chars++; | - | ||||||
517 | if (num == 4) { | - | ||||||
518 | if (!headerdone) { | - | ||||||
519 | if (endian == DetectEndianness) { | - | ||||||
520 | if (tuple[0] == 0xff && tuple[1] == 0xfe && tuple[2] == 0 && tuple[3] == 0 && endian != BigEndianness) { | - | ||||||
521 | endian = LittleEndianness; | - | ||||||
522 | num = 0; | - | ||||||
523 | continue; | - | ||||||
524 | } else if (tuple[0] == 0 && tuple[1] == 0 && tuple[2] == 0xfe && tuple[3] == 0xff && endian != LittleEndianness) { | - | ||||||
525 | endian = BigEndianness; | - | ||||||
526 | num = 0; | - | ||||||
527 | continue; | - | ||||||
528 | } else if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { | - | ||||||
529 | endian = BigEndianness; | - | ||||||
530 | } else { | - | ||||||
531 | endian = LittleEndianness; | - | ||||||
532 | } | - | ||||||
533 | } else if (((endian == BigEndianness) ? qFromBigEndian<quint32>(tuple) : qFromLittleEndian<quint32>(tuple)) == QChar::ByteOrderMark) { | - | ||||||
534 | num = 0; | - | ||||||
535 | continue; | - | ||||||
536 | } | - | ||||||
537 | } | - | ||||||
538 | uint code = (endian == BigEndianness) ? qFromBigEndian<quint32>(tuple) : qFromLittleEndian<quint32>(tuple); | - | ||||||
539 | if (QChar::requiresSurrogates(code)) { | - | ||||||
540 | *qch++ = QChar::highSurrogate(code); | - | ||||||
541 | *qch++ = QChar::lowSurrogate(code); | - | ||||||
542 | } else { | - | ||||||
543 | *qch++ = code; | - | ||||||
544 | } | - | ||||||
545 | num = 0; | - | ||||||
546 | } | - | ||||||
547 | } | - | ||||||
548 | result.truncate(qch - result.unicode()); | - | ||||||
549 | - | |||||||
550 | if (state) { | - | ||||||
551 | if (headerdone) | - | ||||||
552 | state->flags |= QTextCodec::IgnoreHeader; | - | ||||||
553 | state->state_data[Endian] = endian; | - | ||||||
554 | state->remainingChars = num; | - | ||||||
555 | memcpy(&state->state_data[Data], tuple, 4); | - | ||||||
556 | } | - | ||||||
557 | return result; | - | ||||||
558 | } | - | ||||||
559 | - | |||||||
560 | - | |||||||
561 | - | |||||||
562 | - | |||||||
563 | QUtf8Codec::~QUtf8Codec() | - | ||||||
564 | { | - | ||||||
565 | } | - | ||||||
566 | - | |||||||
567 | QByteArray QUtf8Codec::convertFromUnicode(const QChar *uc, int len, ConverterState *state) const | - | ||||||
568 | { | - | ||||||
569 | return QUtf8::convertFromUnicode(uc, len, state); | - | ||||||
570 | } | - | ||||||
571 | - | |||||||
572 | void QUtf8Codec::convertToUnicode(QString *target, const char *chars, int len, ConverterState *state) const | - | ||||||
573 | { | - | ||||||
574 | *target += QUtf8::convertToUnicode(chars, len, state); | - | ||||||
575 | } | - | ||||||
576 | - | |||||||
577 | QString QUtf8Codec::convertToUnicode(const char *chars, int len, ConverterState *state) const | - | ||||||
578 | { | - | ||||||
579 | return QUtf8::convertToUnicode(chars, len, state); | - | ||||||
580 | } | - | ||||||
581 | - | |||||||
582 | QByteArray QUtf8Codec::name() const | - | ||||||
583 | { | - | ||||||
584 | return "UTF-8"; | - | ||||||
585 | } | - | ||||||
586 | - | |||||||
587 | int QUtf8Codec::mibEnum() const | - | ||||||
588 | { | - | ||||||
589 | return 106; | - | ||||||
590 | } | - | ||||||
591 | - | |||||||
592 | QUtf16Codec::~QUtf16Codec() | - | ||||||
593 | { | - | ||||||
594 | } | - | ||||||
595 | - | |||||||
596 | QByteArray QUtf16Codec::convertFromUnicode(const QChar *uc, int len, ConverterState *state) const | - | ||||||
597 | { | - | ||||||
598 | return QUtf16::convertFromUnicode(uc, len, state, e); | - | ||||||
599 | } | - | ||||||
600 | - | |||||||
601 | QString QUtf16Codec::convertToUnicode(const char *chars, int len, ConverterState *state) const | - | ||||||
602 | { | - | ||||||
603 | return QUtf16::convertToUnicode(chars, len, state, e); | - | ||||||
604 | } | - | ||||||
605 | - | |||||||
606 | int QUtf16Codec::mibEnum() const | - | ||||||
607 | { | - | ||||||
608 | return 1015; | - | ||||||
609 | } | - | ||||||
610 | - | |||||||
611 | QByteArray QUtf16Codec::name() const | - | ||||||
612 | { | - | ||||||
613 | return "UTF-16"; | - | ||||||
614 | } | - | ||||||
615 | - | |||||||
616 | QList<QByteArray> QUtf16Codec::aliases() const | - | ||||||
617 | { | - | ||||||
618 | return QList<QByteArray>(); | - | ||||||
619 | } | - | ||||||
620 | - | |||||||
621 | int QUtf16BECodec::mibEnum() const | - | ||||||
622 | { | - | ||||||
623 | return 1013; | - | ||||||
624 | } | - | ||||||
625 | - | |||||||
626 | QByteArray QUtf16BECodec::name() const | - | ||||||
627 | { | - | ||||||
628 | return "UTF-16BE"; | - | ||||||
629 | } | - | ||||||
630 | - | |||||||
631 | QList<QByteArray> QUtf16BECodec::aliases() const | - | ||||||
632 | { | - | ||||||
633 | QList<QByteArray> list; | - | ||||||
634 | return list; | - | ||||||
635 | } | - | ||||||
636 | - | |||||||
637 | int QUtf16LECodec::mibEnum() const | - | ||||||
638 | { | - | ||||||
639 | return 1014; | - | ||||||
640 | } | - | ||||||
641 | - | |||||||
642 | QByteArray QUtf16LECodec::name() const | - | ||||||
643 | { | - | ||||||
644 | return "UTF-16LE"; | - | ||||||
645 | } | - | ||||||
646 | - | |||||||
647 | QList<QByteArray> QUtf16LECodec::aliases() const | - | ||||||
648 | { | - | ||||||
649 | QList<QByteArray> list; | - | ||||||
650 | return list; | - | ||||||
651 | } | - | ||||||
652 | - | |||||||
653 | QUtf32Codec::~QUtf32Codec() | - | ||||||
654 | { | - | ||||||
655 | } | - | ||||||
656 | - | |||||||
657 | QByteArray QUtf32Codec::convertFromUnicode(const QChar *uc, int len, ConverterState *state) const | - | ||||||
658 | { | - | ||||||
659 | return QUtf32::convertFromUnicode(uc, len, state, e); | - | ||||||
660 | } | - | ||||||
661 | - | |||||||
662 | QString QUtf32Codec::convertToUnicode(const char *chars, int len, ConverterState *state) const | - | ||||||
663 | { | - | ||||||
664 | return QUtf32::convertToUnicode(chars, len, state, e); | - | ||||||
665 | } | - | ||||||
666 | - | |||||||
667 | int QUtf32Codec::mibEnum() const | - | ||||||
668 | { | - | ||||||
669 | return 1017; | - | ||||||
670 | } | - | ||||||
671 | - | |||||||
672 | QByteArray QUtf32Codec::name() const | - | ||||||
673 | { | - | ||||||
674 | return "UTF-32"; | - | ||||||
675 | } | - | ||||||
676 | - | |||||||
677 | QList<QByteArray> QUtf32Codec::aliases() const | - | ||||||
678 | { | - | ||||||
679 | QList<QByteArray> list; | - | ||||||
680 | return list; | - | ||||||
681 | } | - | ||||||
682 | - | |||||||
683 | int QUtf32BECodec::mibEnum() const | - | ||||||
684 | { | - | ||||||
685 | return 1018; | - | ||||||
686 | } | - | ||||||
687 | - | |||||||
688 | QByteArray QUtf32BECodec::name() const | - | ||||||
689 | { | - | ||||||
690 | return "UTF-32BE"; | - | ||||||
691 | } | - | ||||||
692 | - | |||||||
693 | QList<QByteArray> QUtf32BECodec::aliases() const | - | ||||||
694 | { | - | ||||||
695 | QList<QByteArray> list; | - | ||||||
696 | return list; | - | ||||||
697 | } | - | ||||||
698 | - | |||||||
699 | int QUtf32LECodec::mibEnum() const | - | ||||||
700 | { | - | ||||||
701 | return 1019; | - | ||||||
702 | } | - | ||||||
703 | - | |||||||
704 | QByteArray QUtf32LECodec::name() const | - | ||||||
705 | { | - | ||||||
706 | return "UTF-32LE"; | - | ||||||
707 | } | - | ||||||
708 | - | |||||||
709 | QList<QByteArray> QUtf32LECodec::aliases() const | - | ||||||
710 | { | - | ||||||
711 | QList<QByteArray> list; | - | ||||||
712 | return list; | - | ||||||
713 | } | - | ||||||
714 | - | |||||||
715 | - | |||||||
716 | - | |||||||
717 | - | |||||||
Switch to Source code | Preprocessed file |