Line | Source Code | Coverage |
---|
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | class QCollatorPrivate | - |
10 | { | - |
11 | public: | - |
12 | QAtomicInt ref; | - |
13 | QLocale locale; | - |
14 | QCollator::Collation collation; | - |
15 | | - |
16 | | - |
17 | UCollator *collator; | - |
18 | | - |
19 | | - |
20 | | - |
21 | | - |
22 | QStringList indexCharacters; | - |
23 | | - |
24 | void clear() { | - |
25 | | - |
26 | if (collator) partially evaluated: collator yes Evaluation Count:922098 | no Evaluation Count:0 |
| 0-922098 |
27 | ucol_close_44(collator); executed: ucol_close_44(collator); Execution Count:922098 | 922098 |
28 | | - |
29 | collator = 0; | - |
30 | indexCharacters.clear(); | - |
31 | } executed: } Execution Count:922098 | 922098 |
32 | | - |
33 | QCollatorPrivate() | - |
34 | : collation(QCollator::Default), | - |
35 | collator(0) | - |
36 | { ref.store(1); } executed: } Execution Count:922098 | 922098 |
37 | ~QCollatorPrivate(); | - |
38 | | - |
39 | private: | - |
40 | QCollatorPrivate(const QCollatorPrivate &) = delete; QCollatorPrivate &operator=(const QCollatorPrivate &) = delete; | - |
41 | }; | - |
42 | | - |
43 | | - |
44 | QCollatorPrivate::~QCollatorPrivate() | - |
45 | { | - |
46 | clear(); | - |
47 | } executed: } Execution Count:922098 | 922098 |
48 | | - |
49 | static const int collationStringsCount = 13; | - |
50 | static const char * const collationStrings[collationStringsCount] = { | - |
51 | "default", | - |
52 | "big5han", | - |
53 | "dictionary", | - |
54 | "direct", | - |
55 | "gb2312han", | - |
56 | "phonebook", | - |
57 | "pinyin", | - |
58 | "phonetic", | - |
59 | "reformed", | - |
60 | "standard", | - |
61 | "stroke", | - |
62 | "traditional", | - |
63 | "unihan" | - |
64 | }; | - |
65 | QCollator::QCollator(const QLocale &locale, QCollator::Collation collation) | - |
66 | : d(new QCollatorPrivate) | - |
67 | { | - |
68 | d->locale = locale; | - |
69 | if ((int)collation >= 0 && (int)collation < collationStringsCount) partially evaluated: (int)collation >= 0 yes Evaluation Count:922098 | no Evaluation Count:0 |
partially evaluated: (int)collation < collationStringsCount yes Evaluation Count:922098 | no Evaluation Count:0 |
| 0-922098 |
70 | d->collation = collation; executed: d->collation = collation; Execution Count:922098 | 922098 |
71 | | - |
72 | init(); | - |
73 | } executed: } Execution Count:922098 | 922098 |
74 | | - |
75 | | - |
76 | | - |
77 | | - |
78 | QCollator::QCollator(const QCollator &other) | - |
79 | : d(other.d) | - |
80 | { | - |
81 | d->ref.ref(); | - |
82 | } | 0 |
83 | | - |
84 | | - |
85 | | - |
86 | | - |
87 | QCollator::~QCollator() | - |
88 | { | - |
89 | if (!d->ref.deref()) partially evaluated: !d->ref.deref() yes Evaluation Count:922098 | no Evaluation Count:0 |
| 0-922098 |
90 | delete d; executed: delete d; Execution Count:922098 | 922098 |
91 | } executed: } Execution Count:922098 | 922098 |
92 | | - |
93 | | - |
94 | | - |
95 | | - |
96 | QCollator &QCollator::operator=(const QCollator &other) | - |
97 | { | - |
98 | if (this != &other) { never evaluated: this != &other | 0 |
99 | if (!d->ref.deref()) never evaluated: !d->ref.deref() | 0 |
100 | delete d; never executed: delete d; | 0 |
101 | d = other.d; | - |
102 | d->ref.ref(); | - |
103 | } | 0 |
104 | return *this; never executed: return *this; | 0 |
105 | } | - |
106 | | - |
107 | | - |
108 | | - |
109 | | - |
110 | | - |
111 | void QCollator::init() | - |
112 | { | - |
113 | qt_noop(); | - |
114 | | - |
115 | const char *collationString = collationStrings[(int)d->collation]; | - |
116 | UErrorCode status = U_ZERO_ERROR; | - |
117 | QByteArray name = (d->locale.bcp47Name().replace(QLatin1Char('-'), QLatin1Char('_')) + QLatin1String("@collation=") + QLatin1String(collationString)).toLatin1(); | - |
118 | d->collator = ucol_open_44(name.constData(), &status); | - |
119 | if (U_FAILURE(status)) partially evaluated: U_FAILURE(status) no Evaluation Count:0 | yes Evaluation Count:922098 |
| 0-922098 |
120 | QMessageLogger("tools/qcollator.cpp", 200, __PRETTY_FUNCTION__).warning("Could not create collator: %d", status); never executed: QMessageLogger("tools/qcollator.cpp", 200, __PRETTY_FUNCTION__).warning("Could not create collator: %d", status); | 0 |
121 | | - |
122 | | - |
123 | ucol_setAttribute_44(d->collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status); | - |
124 | | - |
125 | } executed: } Execution Count:922098 | 922098 |
126 | | - |
127 | | - |
128 | | - |
129 | | - |
130 | void QCollator::detach() | - |
131 | { | - |
132 | if (d->ref.load() != 1) { never evaluated: d->ref.load() != 1 | 0 |
133 | QCollatorPrivate *x = new QCollatorPrivate; | - |
134 | x->ref.store(1); | - |
135 | x->locale = d->locale; | - |
136 | x->collation = d->collation; | - |
137 | x->collator = 0; | - |
138 | if (!d->ref.deref()) never evaluated: !d->ref.deref() | 0 |
139 | delete d; never executed: delete d; | 0 |
140 | d = x; | - |
141 | } | 0 |
142 | } | 0 |
143 | | - |
144 | | - |
145 | | - |
146 | | - |
147 | | - |
148 | void QCollator::setLocale(const QLocale &locale) | - |
149 | { | - |
150 | if (d->ref.load() != 1) never evaluated: d->ref.load() != 1 | 0 |
151 | detach(); never executed: detach(); | 0 |
152 | d->clear(); | - |
153 | d->locale = locale; | - |
154 | | - |
155 | init(); | - |
156 | } | 0 |
157 | | - |
158 | | - |
159 | | - |
160 | | - |
161 | QLocale QCollator::locale() const | - |
162 | { | - |
163 | return d->locale; never executed: return d->locale; | 0 |
164 | } | - |
165 | void QCollator::setCollation(QCollator::Collation collation) | - |
166 | { | - |
167 | if ((int)collation < 0 || (int)collation >= collationStringsCount) never evaluated: (int)collation < 0 never evaluated: (int)collation >= collationStringsCount | 0 |
168 | return; | 0 |
169 | | - |
170 | if (d->ref.load() != 1) never evaluated: d->ref.load() != 1 | 0 |
171 | detach(); never executed: detach(); | 0 |
172 | d->clear(); | - |
173 | d->collation = collation; | - |
174 | | - |
175 | init(); | - |
176 | } | 0 |
177 | | - |
178 | | - |
179 | | - |
180 | | - |
181 | | - |
182 | QCollator::Collation QCollator::collation() const | - |
183 | { | - |
184 | return d->collation; never executed: return d->collation; | 0 |
185 | } | - |
186 | QString QCollator::identifier() const | - |
187 | { | - |
188 | QString id = d->locale.bcp47Name(); | - |
189 | if (d->collation != QCollator::Default) { never evaluated: d->collation != QCollator::Default | 0 |
190 | id += QLatin1String("@collation="); | - |
191 | id += QLatin1String(collationStrings[d->collation]); | - |
192 | } | 0 |
193 | | - |
194 | id.replace('-', '_'); | - |
195 | return id; never executed: return id; | 0 |
196 | } | - |
197 | | - |
198 | | - |
199 | | - |
200 | | - |
201 | | - |
202 | | - |
203 | QCollator QCollator::fromIdentifier(const QString &identifier) | - |
204 | { | - |
205 | QString localeString = identifier; | - |
206 | QString collationString; | - |
207 | int at = identifier.indexOf(QLatin1Char('@')); | - |
208 | if (at >= 0) { | 0 |
209 | localeString = identifier.left(at); | - |
210 | collationString = identifier.mid(at + strlen("@collation=")); | - |
211 | } | 0 |
212 | | - |
213 | QLocale locale(localeString); | - |
214 | Collation collation = Default; | - |
215 | if (!collationString.isEmpty()) { never evaluated: !collationString.isEmpty() | 0 |
216 | for (int i = 0; i < collationStringsCount; ++i) { never evaluated: i < collationStringsCount | 0 |
217 | if (QLatin1String(collationStrings[i]) == collationString) { never evaluated: QLatin1String(collationStrings[i]) == collationString | 0 |
218 | collation = Collation(i); | - |
219 | break; | 0 |
220 | } | - |
221 | } | 0 |
222 | } | 0 |
223 | return QCollator(locale, collation); never executed: return QCollator(locale, collation); | 0 |
224 | } | - |
225 | void QCollator::setCasePreference(CasePreference c) | - |
226 | { | - |
227 | if (d->ref.load() != 1) never evaluated: d->ref.load() != 1 | 0 |
228 | detach(); never executed: detach(); | 0 |
229 | | - |
230 | | - |
231 | UColAttributeValue val = UCOL_OFF; | - |
232 | if (c == QCollator::CasePreferenceUpper) never evaluated: c == QCollator::CasePreferenceUpper | 0 |
233 | val = UCOL_UPPER_FIRST; never executed: val = UCOL_UPPER_FIRST; | 0 |
234 | else if (c == QCollator::CasePreferenceLower) never evaluated: c == QCollator::CasePreferenceLower | 0 |
235 | val = UCOL_LOWER_FIRST; never executed: val = UCOL_LOWER_FIRST; | 0 |
236 | | - |
237 | UErrorCode status = U_ZERO_ERROR; | - |
238 | ucol_setAttribute_44(d->collator, UCOL_CASE_FIRST, val, &status); | - |
239 | if (U_FAILURE(status)) never evaluated: U_FAILURE(status) | 0 |
240 | QMessageLogger("tools/qcollator.cpp", 373, __PRETTY_FUNCTION__).warning("ucol_setAttribute: Case First failed: %d", status); never executed: QMessageLogger("tools/qcollator.cpp", 373, __PRETTY_FUNCTION__).warning("ucol_setAttribute: Case First failed: %d", status); | 0 |
241 | | - |
242 | | - |
243 | | - |
244 | } | 0 |
245 | | - |
246 | | - |
247 | | - |
248 | | - |
249 | | - |
250 | | - |
251 | QCollator::CasePreference QCollator::casePreference() const | - |
252 | { | - |
253 | | - |
254 | UErrorCode status = U_ZERO_ERROR; | - |
255 | switch (ucol_getAttribute_44(d->collator, UCOL_CASE_FIRST, &status)) { | - |
256 | case UCOL_UPPER_FIRST: | - |
257 | return QCollator::CasePreferenceUpper; never executed: return QCollator::CasePreferenceUpper; | 0 |
258 | case UCOL_LOWER_FIRST: | - |
259 | return QCollator::CasePreferenceLower; never executed: return QCollator::CasePreferenceLower; | 0 |
260 | case UCOL_OFF: | - |
261 | default: | - |
262 | break; | 0 |
263 | } | - |
264 | | - |
265 | return QCollator::CasePreferenceOff; never executed: return QCollator::CasePreferenceOff; | 0 |
266 | } | - |
267 | void QCollator::setNumericMode(bool on) | - |
268 | { | - |
269 | if (d->ref.load() != 1) never evaluated: d->ref.load() != 1 | 0 |
270 | detach(); never executed: detach(); | 0 |
271 | | - |
272 | | - |
273 | UErrorCode status = U_ZERO_ERROR; | - |
274 | ucol_setAttribute_44(d->collator, UCOL_NUMERIC_COLLATION, on ? UCOL_ON : UCOL_OFF, &status); | - |
275 | if (U_FAILURE(status)) never evaluated: U_FAILURE(status) | 0 |
276 | QMessageLogger("tools/qcollator.cpp", 417, __PRETTY_FUNCTION__).warning("ucol_setAttribute: numeric collation failed: %d", status); never executed: QMessageLogger("tools/qcollator.cpp", 417, __PRETTY_FUNCTION__).warning("ucol_setAttribute: numeric collation failed: %d", status); | 0 |
277 | | - |
278 | | - |
279 | | - |
280 | } | 0 |
281 | | - |
282 | | - |
283 | | - |
284 | | - |
285 | | - |
286 | | - |
287 | bool QCollator::numericMode() const | - |
288 | { | - |
289 | | - |
290 | UErrorCode status; | - |
291 | if (ucol_getAttribute_44(d->collator, UCOL_NUMERIC_COLLATION, &status) == UCOL_ON) never evaluated: ucol_getAttribute_44(d->collator, UCOL_NUMERIC_COLLATION, &status) == UCOL_ON | 0 |
292 | return true; never executed: return true; | 0 |
293 | | - |
294 | return false; never executed: return false; | 0 |
295 | } | - |
296 | | - |
297 | | - |
298 | | - |
299 | | - |
300 | | - |
301 | | - |
302 | void QCollator::setIgnorePunctuation(bool on) | - |
303 | { | - |
304 | if (d->ref.load() != 1) never evaluated: d->ref.load() != 1 | 0 |
305 | detach(); never executed: detach(); | 0 |
306 | | - |
307 | | - |
308 | UErrorCode status; | - |
309 | ucol_setAttribute_44(d->collator, UCOL_ALTERNATE_HANDLING, on ? UCOL_SHIFTED : UCOL_NON_IGNORABLE, &status); | - |
310 | if (U_FAILURE(status)) never evaluated: U_FAILURE(status) | 0 |
311 | QMessageLogger("tools/qcollator.cpp", 452, __PRETTY_FUNCTION__).warning("ucol_setAttribute: Alternate handling failed: %d", status); never executed: QMessageLogger("tools/qcollator.cpp", 452, __PRETTY_FUNCTION__).warning("ucol_setAttribute: Alternate handling failed: %d", status); | 0 |
312 | | - |
313 | | - |
314 | | - |
315 | } | 0 |
316 | | - |
317 | | - |
318 | | - |
319 | | - |
320 | | - |
321 | | - |
322 | bool QCollator::ignorePunctuation() const | - |
323 | { | - |
324 | | - |
325 | UErrorCode status; | - |
326 | if (ucol_getAttribute_44(d->collator, UCOL_ALTERNATE_HANDLING, &status) == UCOL_SHIFTED) never evaluated: ucol_getAttribute_44(d->collator, UCOL_ALTERNATE_HANDLING, &status) == UCOL_SHIFTED | 0 |
327 | return true; never executed: return true; | 0 |
328 | | - |
329 | return false; never executed: return false; | 0 |
330 | } | - |
331 | | - |
332 | | - |
333 | | - |
334 | | - |
335 | | - |
336 | int QCollator::compare(const QString &s1, const QString &s2) const | - |
337 | { | - |
338 | return compare(s1.constData(), s1.size(), s2.constData(), s2.size()); never executed: return compare(s1.constData(), s1.size(), s2.constData(), s2.size()); | 0 |
339 | } | - |
340 | | - |
341 | | - |
342 | | - |
343 | | - |
344 | | - |
345 | | - |
346 | | - |
347 | int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const | - |
348 | { | - |
349 | return compare(s1.constData(), s1.size(), s2.constData(), s2.size()); never executed: return compare(s1.constData(), s1.size(), s2.constData(), s2.size()); | 0 |
350 | } | - |
351 | int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const | - |
352 | { | - |
353 | | - |
354 | const UCollationResult result = | - |
355 | ucol_strcoll_44(d->collator, (const UChar *)s1, len1, (const UChar *)s2, len2); | - |
356 | return result; executed: return result; Execution Count:922098 | 922098 |
357 | | - |
358 | | - |
359 | | - |
360 | } | - |
361 | QByteArray QCollator::sortKey(const QString &string) const | - |
362 | { | - |
363 | | - |
364 | QByteArray result(16 + string.size() + (string.size() >> 2), Qt::Uninitialized); | - |
365 | int size = ucol_getSortKey_44(d->collator, (const UChar *)string.constData(), | - |
366 | string.size(), (uint8_t *)result.data(), result.size()); | - |
367 | if (size > result.size()) { never evaluated: size > result.size() | 0 |
368 | result.resize(size); | - |
369 | size = ucol_getSortKey_44(d->collator, (const UChar *)string.constData(), | - |
370 | string.size(), (uint8_t *)result.data(), result.size()); | - |
371 | } | 0 |
372 | result.truncate(size); | - |
373 | return result; never executed: return result; | 0 |
374 | | - |
375 | | - |
376 | | - |
377 | } | - |
378 | | - |
379 | static QStringList englishIndexCharacters() | - |
380 | { | - |
381 | QString chars = QString::fromLatin1("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"); | - |
382 | return chars.split(QLatin1Char(' '), QString::SkipEmptyParts); never executed: return chars.split(QLatin1Char(' '), QString::SkipEmptyParts); | 0 |
383 | } | - |
384 | | - |
385 | | - |
386 | | - |
387 | | - |
388 | | - |
389 | QStringList QCollator::indexCharacters() const | - |
390 | { | - |
391 | if (!d->indexCharacters.isEmpty()) never evaluated: !d->indexCharacters.isEmpty() | 0 |
392 | return d->indexCharacters; never executed: return d->indexCharacters; | 0 |
393 | | - |
394 | | - |
395 | QByteArray id = identifier().toLatin1(); | - |
396 | | - |
397 | UErrorCode status = U_ZERO_ERROR; | - |
398 | UResourceBundle *res = ures_open_44(__null, id, &status); | - |
399 | | - |
400 | if (U_FAILURE(status)) { never evaluated: U_FAILURE(status) | 0 |
401 | d->indexCharacters = englishIndexCharacters(); | - |
402 | } else { | 0 |
403 | | - |
404 | qint32 len = 0; | - |
405 | status = U_ZERO_ERROR; | - |
406 | const UChar *val = ures_getStringByKey_44(res, "ExemplarCharactersIndex", &len, &status); | - |
407 | if (U_FAILURE(status)) { never evaluated: U_FAILURE(status) | 0 |
408 | d->indexCharacters = englishIndexCharacters(); | - |
409 | } else { | 0 |
410 | QString chars(reinterpret_cast<const QChar *>(val), len); | - |
411 | chars.remove('['); | - |
412 | chars.remove(']'); | - |
413 | chars.remove('{'); | - |
414 | chars.remove('}'); | - |
415 | d->indexCharacters = chars.split(QLatin1Char(' '), QString::SkipEmptyParts); | - |
416 | } | 0 |
417 | } | - |
418 | | - |
419 | ures_close_44(res); | - |
420 | | - |
421 | | - |
422 | | - |
423 | | - |
424 | return d->indexCharacters; never executed: return d->indexCharacters; | 0 |
425 | } | - |
426 | | - |
427 | | - |
428 | | - |
| | |