OLD | NEW |
1 /* | 1 /* |
2 ****************************************************************************** | 2 ****************************************************************************** |
3 * Copyright (C) 1996-2013, International Business Machines Corporation and | 3 * Copyright (C) 1996-2014, International Business Machines Corporation and |
4 * others. All Rights Reserved. | 4 * others. All Rights Reserved. |
5 ****************************************************************************** | 5 ****************************************************************************** |
6 */ | 6 */ |
7 | 7 |
8 /** | 8 /** |
9 * File coll.cpp | 9 * File coll.cpp |
10 * | 10 * |
11 * Created by: Helena Shih | 11 * Created by: Helena Shih |
12 * | 12 * |
13 * Modification History: | 13 * Modification History: |
(...skipping 14 matching lines...) Expand all Loading... |
28 * constructor. General clean up and documentation. | 28 * constructor. General clean up and documentation. |
29 * 2/20/97 helena Added clone, operator==, operator!=, operator=, and
copy | 29 * 2/20/97 helena Added clone, operator==, operator!=, operator=, and
copy |
30 * constructor. | 30 * constructor. |
31 * 05/06/97 helena Added memory allocation error detection. | 31 * 05/06/97 helena Added memory allocation error detection. |
32 * 05/08/97 helena Added createInstance(). | 32 * 05/08/97 helena Added createInstance(). |
33 * 6/20/97 helena Java class name change. | 33 * 6/20/97 helena Java class name change. |
34 * 04/23/99 stephen Removed EDecompositionMode, merged with | 34 * 04/23/99 stephen Removed EDecompositionMode, merged with |
35 * Normalizer::EMode | 35 * Normalizer::EMode |
36 * 11/23/9 srl Inlining of some critical functions | 36 * 11/23/9 srl Inlining of some critical functions |
37 * 01/29/01 synwee Modified into a C++ wrapper calling C APIs (ucol.h) | 37 * 01/29/01 synwee Modified into a C++ wrapper calling C APIs (ucol.h) |
| 38 * 2012-2014 markus Rewritten in C++ again. |
38 */ | 39 */ |
39 | 40 |
40 #include "utypeinfo.h" // for 'typeid' to work | 41 #include "utypeinfo.h" // for 'typeid' to work |
41 | 42 |
42 #include "unicode/utypes.h" | 43 #include "unicode/utypes.h" |
43 | 44 |
44 #if !UCONFIG_NO_COLLATION | 45 #if !UCONFIG_NO_COLLATION |
45 | 46 |
46 #include "unicode/coll.h" | 47 #include "unicode/coll.h" |
47 #include "unicode/tblcoll.h" | 48 #include "unicode/tblcoll.h" |
| 49 #include "collationdata.h" |
| 50 #include "collationroot.h" |
| 51 #include "collationtailoring.h" |
48 #include "ucol_imp.h" | 52 #include "ucol_imp.h" |
49 #include "cstring.h" | 53 #include "cstring.h" |
50 #include "cmemory.h" | 54 #include "cmemory.h" |
51 #include "umutex.h" | 55 #include "umutex.h" |
52 #include "servloc.h" | 56 #include "servloc.h" |
53 #include "uassert.h" | 57 #include "uassert.h" |
54 #include "ustrenum.h" | 58 #include "ustrenum.h" |
55 #include "uresimp.h" | 59 #include "uresimp.h" |
56 #include "ucln_in.h" | 60 #include "ucln_in.h" |
57 | 61 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 Locale loc(""); | 173 Locale loc(""); |
170 lkey.canonicalLocale(loc); | 174 lkey.canonicalLocale(loc); |
171 return Collator::makeInstance(loc, status); | 175 return Collator::makeInstance(loc, status); |
172 } | 176 } |
173 | 177 |
174 virtual UObject* getKey(ICUServiceKey& key, UnicodeString* actualReturn, UEr
rorCode& status) const { | 178 virtual UObject* getKey(ICUServiceKey& key, UnicodeString* actualReturn, UEr
rorCode& status) const { |
175 UnicodeString ar; | 179 UnicodeString ar; |
176 if (actualReturn == NULL) { | 180 if (actualReturn == NULL) { |
177 actualReturn = &ar; | 181 actualReturn = &ar; |
178 } | 182 } |
179 Collator* result = (Collator*)ICULocaleService::getKey(key, actualReturn
, status); | 183 return (Collator*)ICULocaleService::getKey(key, actualReturn, status); |
180 // Ugly Hack Alert! If the actualReturn length is zero, this | |
181 // means we got a default object, not a "real" service-created | |
182 // object. We don't call setLocales() on a default object, | |
183 // because that will overwrite its correct built-in locale | |
184 // metadata (valid & actual) with our incorrect data (all we | |
185 // have is the requested locale). (TODO remove in 3.0) [aliu] | |
186 if (result && actualReturn->length() > 0) { | |
187 const LocaleKey& lkey = (const LocaleKey&)key; | |
188 Locale canonicalLocale(""); | |
189 Locale currentLocale(""); | |
190 | |
191 LocaleUtility::initLocaleFromName(*actualReturn, currentLocale); | |
192 result->setLocales(lkey.canonicalLocale(canonicalLocale), currentLoc
ale, currentLocale); | |
193 } | |
194 return result; | |
195 } | 184 } |
196 | 185 |
197 virtual UBool isDefault() const { | 186 virtual UBool isDefault() const { |
198 return countFactories() == 1; | 187 return countFactories() == 1; |
199 } | 188 } |
200 }; | 189 }; |
201 | 190 |
202 ICUCollatorService::~ICUCollatorService() {} | 191 ICUCollatorService::~ICUCollatorService() {} |
203 | 192 |
204 // ------------------------------------- | 193 // ------------------------------------- |
(...skipping 13 matching lines...) Expand all Loading... |
218 | 207 |
219 // ------------------------------------- | 208 // ------------------------------------- |
220 | 209 |
221 static inline UBool | 210 static inline UBool |
222 hasService(void) | 211 hasService(void) |
223 { | 212 { |
224 UBool retVal = !gServiceInitOnce.isReset() && (getService() != NULL); | 213 UBool retVal = !gServiceInitOnce.isReset() && (getService() != NULL); |
225 return retVal; | 214 return retVal; |
226 } | 215 } |
227 | 216 |
228 // ------------------------------------- | |
229 | |
230 UCollator* | |
231 Collator::createUCollator(const char *loc, | |
232 UErrorCode *status) | |
233 { | |
234 UCollator *result = 0; | |
235 if (status && U_SUCCESS(*status) && hasService()) { | |
236 Locale desiredLocale(loc); | |
237 Collator *col = (Collator*)gService->get(desiredLocale, *status); | |
238 RuleBasedCollator *rbc; | |
239 if (col && (rbc = dynamic_cast<RuleBasedCollator *>(col))) { | |
240 if (!rbc->dataIsOwned) { | |
241 result = ucol_safeClone(rbc->ucollator, NULL, NULL, status); | |
242 } else { | |
243 result = rbc->ucollator; | |
244 rbc->ucollator = NULL; // to prevent free on delete | |
245 } | |
246 } else { | |
247 // should go in a function- ucol_initDelegate(delegate) | |
248 result = (UCollator *)uprv_malloc(sizeof(UCollator)); | |
249 if(result == NULL) { | |
250 *status = U_MEMORY_ALLOCATION_ERROR; | |
251 } else { | |
252 uprv_memset(result, 0, sizeof(UCollator)); | |
253 result->delegate = col; | |
254 result->freeOnClose = TRUE; // do free on close. | |
255 col = NULL; // to prevent free on delete. | |
256 } | |
257 } | |
258 delete col; | |
259 } | |
260 return result; | |
261 } | |
262 #endif /* UCONFIG_NO_SERVICE */ | 217 #endif /* UCONFIG_NO_SERVICE */ |
263 | 218 |
264 static void U_CALLCONV | 219 static void U_CALLCONV |
265 initAvailableLocaleList(UErrorCode &status) { | 220 initAvailableLocaleList(UErrorCode &status) { |
266 U_ASSERT(availableLocaleListCount == 0); | 221 U_ASSERT(availableLocaleListCount == 0); |
267 U_ASSERT(availableLocaleList == NULL); | 222 U_ASSERT(availableLocaleList == NULL); |
268 // for now, there is a hardcoded list, so just walk through that list and se
t it up. | 223 // for now, there is a hardcoded list, so just walk through that list and se
t it up. |
269 UResourceBundle *index = NULL; | 224 UResourceBundle *index = NULL; |
270 UResourceBundle installed; | 225 UResourceBundle installed; |
271 int32_t i = 0; | 226 int32_t i = 0; |
(...skipping 22 matching lines...) Expand all Loading... |
294 } | 249 } |
295 | 250 |
296 static UBool isAvailableLocaleListInitialized(UErrorCode &status) { | 251 static UBool isAvailableLocaleListInitialized(UErrorCode &status) { |
297 umtx_initOnce(gAvailableLocaleListInitOnce, &initAvailableLocaleList, status
); | 252 umtx_initOnce(gAvailableLocaleListInitOnce, &initAvailableLocaleList, status
); |
298 return U_SUCCESS(status); | 253 return U_SUCCESS(status); |
299 } | 254 } |
300 | 255 |
301 | 256 |
302 // Collator public methods ----------------------------------------------- | 257 // Collator public methods ----------------------------------------------- |
303 | 258 |
| 259 namespace { |
| 260 |
| 261 static const struct { |
| 262 const char *name; |
| 263 UColAttribute attr; |
| 264 } collAttributes[] = { |
| 265 { "colStrength", UCOL_STRENGTH }, |
| 266 { "colBackwards", UCOL_FRENCH_COLLATION }, |
| 267 { "colCaseLevel", UCOL_CASE_LEVEL }, |
| 268 { "colCaseFirst", UCOL_CASE_FIRST }, |
| 269 { "colAlternate", UCOL_ALTERNATE_HANDLING }, |
| 270 { "colNormalization", UCOL_NORMALIZATION_MODE }, |
| 271 { "colNumeric", UCOL_NUMERIC_COLLATION } |
| 272 }; |
| 273 |
| 274 static const struct { |
| 275 const char *name; |
| 276 UColAttributeValue value; |
| 277 } collAttributeValues[] = { |
| 278 { "primary", UCOL_PRIMARY }, |
| 279 { "secondary", UCOL_SECONDARY }, |
| 280 { "tertiary", UCOL_TERTIARY }, |
| 281 { "quaternary", UCOL_QUATERNARY }, |
| 282 // Note: Not supporting typo "quarternary" because it was never supported in
locale IDs. |
| 283 { "identical", UCOL_IDENTICAL }, |
| 284 { "no", UCOL_OFF }, |
| 285 { "yes", UCOL_ON }, |
| 286 { "shifted", UCOL_SHIFTED }, |
| 287 { "non-ignorable", UCOL_NON_IGNORABLE }, |
| 288 { "lower", UCOL_LOWER_FIRST }, |
| 289 { "upper", UCOL_UPPER_FIRST } |
| 290 }; |
| 291 |
| 292 static const char *collReorderCodes[UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_
FIRST] = { |
| 293 "space", "punct", "symbol", "currency", "digit" |
| 294 }; |
| 295 |
| 296 int32_t getReorderCode(const char *s) { |
| 297 for (int32_t i = 0; i < UPRV_LENGTHOF(collReorderCodes); ++i) { |
| 298 if (uprv_stricmp(s, collReorderCodes[i]) == 0) { |
| 299 return UCOL_REORDER_CODE_FIRST + i; |
| 300 } |
| 301 } |
| 302 // Not supporting "others" = UCOL_REORDER_CODE_OTHERS |
| 303 // as a synonym for Zzzz = USCRIPT_UNKNOWN for now: |
| 304 // Avoid introducing synonyms/aliases. |
| 305 return -1; |
| 306 } |
| 307 |
| 308 /** |
| 309 * Sets collation attributes according to locale keywords. See |
| 310 * http://www.unicode.org/reports/tr35/tr35-collation.html#Collation_Settings |
| 311 * |
| 312 * Using "alias" keywords and values where defined: |
| 313 * http://www.unicode.org/reports/tr35/tr35.html#Old_Locale_Extension_Syntax |
| 314 * http://unicode.org/repos/cldr/trunk/common/bcp47/collation.xml |
| 315 */ |
| 316 void setAttributesFromKeywords(const Locale &loc, Collator &coll, UErrorCode &er
rorCode) { |
| 317 if (U_FAILURE(errorCode)) { |
| 318 return; |
| 319 } |
| 320 if (uprv_strcmp(loc.getName(), loc.getBaseName()) == 0) { |
| 321 // No keywords. |
| 322 return; |
| 323 } |
| 324 char value[1024]; // The reordering value could be long. |
| 325 // Check for collation keywords that were already deprecated |
| 326 // before any were supported in createInstance() (except for "collation"). |
| 327 int32_t length = loc.getKeywordValue("colHiraganaQuaternary", value, UPRV_LE
NGTHOF(value), errorCode); |
| 328 if (U_FAILURE(errorCode)) { |
| 329 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 330 return; |
| 331 } |
| 332 if (length != 0) { |
| 333 errorCode = U_UNSUPPORTED_ERROR; |
| 334 return; |
| 335 } |
| 336 length = loc.getKeywordValue("variableTop", value, UPRV_LENGTHOF(value), err
orCode); |
| 337 if (U_FAILURE(errorCode)) { |
| 338 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 339 return; |
| 340 } |
| 341 if (length != 0) { |
| 342 errorCode = U_UNSUPPORTED_ERROR; |
| 343 return; |
| 344 } |
| 345 // Parse known collation keywords, ignore others. |
| 346 if (errorCode == U_STRING_NOT_TERMINATED_WARNING) { |
| 347 errorCode = U_ZERO_ERROR; |
| 348 } |
| 349 for (int32_t i = 0; i < UPRV_LENGTHOF(collAttributes); ++i) { |
| 350 length = loc.getKeywordValue(collAttributes[i].name, value, UPRV_LENGTHO
F(value), errorCode); |
| 351 if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING
) { |
| 352 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 353 return; |
| 354 } |
| 355 if (length == 0) { continue; } |
| 356 for (int32_t j = 0;; ++j) { |
| 357 if (j == UPRV_LENGTHOF(collAttributeValues)) { |
| 358 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 359 return; |
| 360 } |
| 361 if (uprv_stricmp(value, collAttributeValues[j].name) == 0) { |
| 362 coll.setAttribute(collAttributes[i].attr, collAttributeValues[j]
.value, errorCode); |
| 363 break; |
| 364 } |
| 365 } |
| 366 } |
| 367 length = loc.getKeywordValue("colReorder", value, UPRV_LENGTHOF(value), erro
rCode); |
| 368 if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING) { |
| 369 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 370 return; |
| 371 } |
| 372 if (length != 0) { |
| 373 int32_t codes[USCRIPT_CODE_LIMIT + UCOL_REORDER_CODE_LIMIT - UCOL_REORDE
R_CODE_FIRST]; |
| 374 int32_t codesLength = 0; |
| 375 char *scriptName = value; |
| 376 for (;;) { |
| 377 if (codesLength == UPRV_LENGTHOF(codes)) { |
| 378 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 379 return; |
| 380 } |
| 381 char *limit = scriptName; |
| 382 char c; |
| 383 while ((c = *limit) != 0 && c != '-') { ++limit; } |
| 384 *limit = 0; |
| 385 int32_t code; |
| 386 if ((limit - scriptName) == 4) { |
| 387 // Strict parsing, accept only 4-letter script codes, not long n
ames. |
| 388 code = u_getPropertyValueEnum(UCHAR_SCRIPT, scriptName); |
| 389 } else { |
| 390 code = getReorderCode(scriptName); |
| 391 } |
| 392 if (code < 0) { |
| 393 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 394 return; |
| 395 } |
| 396 codes[codesLength++] = code; |
| 397 if (c == 0) { break; } |
| 398 scriptName = limit + 1; |
| 399 } |
| 400 coll.setReorderCodes(codes, codesLength, errorCode); |
| 401 } |
| 402 length = loc.getKeywordValue("kv", value, UPRV_LENGTHOF(value), errorCode); |
| 403 if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING) { |
| 404 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 405 return; |
| 406 } |
| 407 if (length != 0) { |
| 408 int32_t code = getReorderCode(value); |
| 409 if (code < 0) { |
| 410 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 411 return; |
| 412 } |
| 413 coll.setMaxVariable((UColReorderCode)code, errorCode); |
| 414 } |
| 415 if (U_FAILURE(errorCode)) { |
| 416 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 417 } |
| 418 } |
| 419 |
| 420 } // namespace |
| 421 |
304 Collator* U_EXPORT2 Collator::createInstance(UErrorCode& success) | 422 Collator* U_EXPORT2 Collator::createInstance(UErrorCode& success) |
305 { | 423 { |
306 return createInstance(Locale::getDefault(), success); | 424 return createInstance(Locale::getDefault(), success); |
307 } | 425 } |
308 | 426 |
309 Collator* U_EXPORT2 Collator::createInstance(const Locale& desiredLocale, | 427 Collator* U_EXPORT2 Collator::createInstance(const Locale& desiredLocale, |
310 UErrorCode& status) | 428 UErrorCode& status) |
311 { | 429 { |
312 if (U_FAILURE(status)) | 430 if (U_FAILURE(status)) |
313 return 0; | 431 return 0; |
314 | 432 if (desiredLocale.isBogus()) { |
| 433 // Locale constructed from malformed locale ID or language tag. |
| 434 status = U_ILLEGAL_ARGUMENT_ERROR; |
| 435 return NULL; |
| 436 } |
| 437 |
| 438 Collator* coll; |
315 #if !UCONFIG_NO_SERVICE | 439 #if !UCONFIG_NO_SERVICE |
316 if (hasService()) { | 440 if (hasService()) { |
317 Locale actualLoc; | 441 Locale actualLoc; |
318 Collator *result = | 442 coll = (Collator*)gService->get(desiredLocale, &actualLoc, status); |
319 (Collator*)gService->get(desiredLocale, &actualLoc, status); | 443 } else |
320 | 444 #endif |
321 // Ugly Hack Alert! If the returned locale is empty (not root, | 445 { |
322 // but empty -- getName() == "") then that means the service | 446 coll = makeInstance(desiredLocale, status); |
323 // returned a default object, not a "real" service object. In | |
324 // that case, the locale metadata (valid & actual) is setup | |
325 // correctly already, and we don't want to overwrite it. (TODO | |
326 // remove in 3.0) [aliu] | |
327 if (*actualLoc.getName() != 0) { | |
328 result->setLocales(desiredLocale, actualLoc, actualLoc); | |
329 } | |
330 return result; | |
331 } | 447 } |
332 #endif | 448 setAttributesFromKeywords(desiredLocale, *coll, status); |
333 return makeInstance(desiredLocale, status); | 449 if (U_FAILURE(status)) { |
| 450 delete coll; |
| 451 return NULL; |
| 452 } |
| 453 return coll; |
334 } | 454 } |
335 | 455 |
336 | 456 |
337 Collator* Collator::makeInstance(const Locale& desiredLocale, | 457 Collator* Collator::makeInstance(const Locale& desiredLocale, UErrorCode& statu
s) { |
338 UErrorCode& status) | 458 const CollationCacheEntry *entry = CollationLoader::loadTailoring(desiredLoc
ale, status); |
339 { | 459 if (U_SUCCESS(status)) { |
340 // A bit of explanation is required here. Although in the current | 460 Collator *result = new RuleBasedCollator(entry); |
341 // implementation | 461 if (result != NULL) { |
342 // Collator::createInstance() is just turning around and calling | 462 // Both the unified cache's get() and the RBC constructor |
343 // RuleBasedCollator(Locale&), this will not necessarily always be the | 463 // did addRef(). Undo one of them. |
344 // case. For example, suppose we modify this code to handle a | 464 entry->removeRef(); |
345 // non-table-based Collator, such as that for Thai. In this case, | 465 return result; |
346 // createInstance() will have to be modified to somehow determine this fact | 466 } |
347 // (perhaps a field in the resource bundle). Then it can construct the | |
348 // non-table-based Collator in some other way, when it sees that it needs | |
349 // to. | |
350 // The specific caution is this: RuleBasedCollator(Locale&) will ALWAYS | |
351 // return a valid collation object, if the system is functioning properly. | |
352 // The reason is that it will fall back, use the default locale, and even | |
353 // use the built-in default collation rules. THEREFORE, createInstance() | |
354 // should in general ONLY CALL RuleBasedCollator(Locale&) IF IT KNOWS IN | |
355 // ADVANCE that the given locale's collation is properly implemented as a | |
356 // RuleBasedCollator. | |
357 // Currently, we don't do this...we always return a RuleBasedCollator, | |
358 // whether it is strictly correct to do so or not, without checking, because
| |
359 // we currently have no way of checking. | |
360 | |
361 RuleBasedCollator* collation = new RuleBasedCollator(desiredLocale, | |
362 status); | |
363 /* test for NULL */ | |
364 if (collation == 0) { | |
365 status = U_MEMORY_ALLOCATION_ERROR; | 467 status = U_MEMORY_ALLOCATION_ERROR; |
366 return 0; | |
367 } | 468 } |
368 if (U_FAILURE(status)) | 469 if (entry != NULL) { |
369 { | 470 // Undo the addRef() from the cache.get(). |
370 delete collation; | 471 entry->removeRef(); |
371 collation = 0; | |
372 } | 472 } |
373 return collation; | 473 return NULL; |
374 } | 474 } |
375 | 475 |
376 #ifdef U_USE_COLLATION_OBSOLETE_2_6 | |
377 // !!! dlf the following is obsolete, ignore registration for this | |
378 | |
379 Collator * | |
380 Collator::createInstance(const Locale &loc, | |
381 UVersionInfo version, | |
382 UErrorCode &status) | |
383 { | |
384 Collator *collator; | |
385 UVersionInfo info; | |
386 | |
387 collator=new RuleBasedCollator(loc, status); | |
388 /* test for NULL */ | |
389 if (collator == 0) { | |
390 status = U_MEMORY_ALLOCATION_ERROR; | |
391 return 0; | |
392 } | |
393 | |
394 if(U_SUCCESS(status)) { | |
395 collator->getVersion(info); | |
396 if(0!=uprv_memcmp(version, info, sizeof(UVersionInfo))) { | |
397 delete collator; | |
398 status=U_MISSING_RESOURCE_ERROR; | |
399 return 0; | |
400 } | |
401 } | |
402 return collator; | |
403 } | |
404 #endif | |
405 | |
406 Collator * | 476 Collator * |
407 Collator::safeClone() const { | 477 Collator::safeClone() const { |
408 return clone(); | 478 return clone(); |
409 } | 479 } |
410 | 480 |
411 // implement deprecated, previously abstract method | 481 // implement deprecated, previously abstract method |
412 Collator::EComparisonResult Collator::compare(const UnicodeString& source, | 482 Collator::EComparisonResult Collator::compare(const UnicodeString& source, |
413 const UnicodeString& target) const | 483 const UnicodeString& target) const |
414 { | 484 { |
415 UErrorCode ec = U_ZERO_ERROR; | 485 UErrorCode ec = U_ZERO_ERROR; |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 return new UnicodeSet(0, 0x10FFFF); | 662 return new UnicodeSet(0, 0x10FFFF); |
593 } | 663 } |
594 | 664 |
595 // ------------------------------------- | 665 // ------------------------------------- |
596 | 666 |
597 #if !UCONFIG_NO_SERVICE | 667 #if !UCONFIG_NO_SERVICE |
598 URegistryKey U_EXPORT2 | 668 URegistryKey U_EXPORT2 |
599 Collator::registerInstance(Collator* toAdopt, const Locale& locale, UErrorCode&
status) | 669 Collator::registerInstance(Collator* toAdopt, const Locale& locale, UErrorCode&
status) |
600 { | 670 { |
601 if (U_SUCCESS(status)) { | 671 if (U_SUCCESS(status)) { |
| 672 // Set the collator locales while registering so that createInstance() |
| 673 // need not guess whether the collator's locales are already set properl
y |
| 674 // (as they are by the data loader). |
| 675 toAdopt->setLocales(locale, locale, locale); |
602 return getService()->registerInstance(toAdopt, locale, status); | 676 return getService()->registerInstance(toAdopt, locale, status); |
603 } | 677 } |
604 return NULL; | 678 return NULL; |
605 } | 679 } |
606 | 680 |
607 // ------------------------------------- | 681 // ------------------------------------- |
608 | 682 |
609 class CFactory : public LocaleKeyFactory { | 683 class CFactory : public LocaleKeyFactory { |
610 private: | 684 private: |
611 CollatorFactory* _delegate; | 685 CollatorFactory* _delegate; |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
846 UErrorCode intStatus = U_ZERO_ERROR; | 920 UErrorCode intStatus = U_ZERO_ERROR; |
847 return (ECollationStrength)getAttribute(UCOL_STRENGTH, intStatus); | 921 return (ECollationStrength)getAttribute(UCOL_STRENGTH, intStatus); |
848 } | 922 } |
849 | 923 |
850 void | 924 void |
851 Collator::setStrength(ECollationStrength newStrength) { | 925 Collator::setStrength(ECollationStrength newStrength) { |
852 UErrorCode intStatus = U_ZERO_ERROR; | 926 UErrorCode intStatus = U_ZERO_ERROR; |
853 setAttribute(UCOL_STRENGTH, (UColAttributeValue)newStrength, intStatus); | 927 setAttribute(UCOL_STRENGTH, (UColAttributeValue)newStrength, intStatus); |
854 } | 928 } |
855 | 929 |
| 930 Collator & |
| 931 Collator::setMaxVariable(UColReorderCode /*group*/, UErrorCode &errorCode) { |
| 932 if (U_SUCCESS(errorCode)) { |
| 933 errorCode = U_UNSUPPORTED_ERROR; |
| 934 } |
| 935 return *this; |
| 936 } |
| 937 |
| 938 UColReorderCode |
| 939 Collator::getMaxVariable() const { |
| 940 return UCOL_REORDER_CODE_PUNCTUATION; |
| 941 } |
| 942 |
856 int32_t | 943 int32_t |
857 Collator::getReorderCodes(int32_t* /* dest*/, | 944 Collator::getReorderCodes(int32_t* /* dest*/, |
858 int32_t /* destCapacity*/, | 945 int32_t /* destCapacity*/, |
859 UErrorCode& status) const | 946 UErrorCode& status) const |
860 { | 947 { |
861 if (U_SUCCESS(status)) { | 948 if (U_SUCCESS(status)) { |
862 status = U_UNSUPPORTED_ERROR; | 949 status = U_UNSUPPORTED_ERROR; |
863 } | 950 } |
864 return 0; | 951 return 0; |
865 } | 952 } |
866 | 953 |
867 void | 954 void |
868 Collator::setReorderCodes(const int32_t* /* reorderCodes */, | 955 Collator::setReorderCodes(const int32_t* /* reorderCodes */, |
869 int32_t /* reorderCodesLength */, | 956 int32_t /* reorderCodesLength */, |
870 UErrorCode& status) | 957 UErrorCode& status) |
871 { | 958 { |
872 if (U_SUCCESS(status)) { | 959 if (U_SUCCESS(status)) { |
873 status = U_UNSUPPORTED_ERROR; | 960 status = U_UNSUPPORTED_ERROR; |
874 } | 961 } |
875 } | 962 } |
876 | 963 |
877 int32_t U_EXPORT2 | 964 int32_t |
878 Collator::getEquivalentReorderCodes(int32_t /* reorderCode */, | 965 Collator::getEquivalentReorderCodes(int32_t reorderCode, |
879 int32_t* /* dest */, | 966 int32_t *dest, int32_t capacity, |
880 int32_t /* destCapacity */, | 967 UErrorCode &errorCode) { |
881 UErrorCode& status) | 968 if(U_FAILURE(errorCode)) { return 0; } |
882 { | 969 if(capacity < 0 || (dest == NULL && capacity > 0)) { |
883 if (U_SUCCESS(status)) { | 970 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
884 status = U_UNSUPPORTED_ERROR; | 971 return 0; |
885 } | 972 } |
886 return 0; | 973 const CollationData *baseData = CollationRoot::getData(errorCode); |
| 974 if(U_FAILURE(errorCode)) { return 0; } |
| 975 return baseData->getEquivalentScripts(reorderCode, dest, capacity, errorCode
); |
887 } | 976 } |
888 | 977 |
889 int32_t | 978 int32_t |
890 Collator::internalGetShortDefinitionString(const char * /*locale*/, | 979 Collator::internalGetShortDefinitionString(const char * /*locale*/, |
891 char * /*buffer*/, | 980 char * /*buffer*/, |
892 int32_t /*capacity*
/, | 981 int32_t /*capacity*
/, |
893 UErrorCode &status)
const { | 982 UErrorCode &status)
const { |
894 if(U_SUCCESS(status)) { | 983 if(U_SUCCESS(status)) { |
895 status = U_UNSUPPORTED_ERROR; /* Shouldn't happen, internal function */ | 984 status = U_UNSUPPORTED_ERROR; /* Shouldn't happen, internal function */ |
896 } | 985 } |
897 return 0; | 986 return 0; |
898 } | 987 } |
899 | 988 |
| 989 UCollationResult |
| 990 Collator::internalCompareUTF8(const char *left, int32_t leftLength, |
| 991 const char *right, int32_t rightLength, |
| 992 UErrorCode &errorCode) const { |
| 993 if(U_FAILURE(errorCode)) { return UCOL_EQUAL; } |
| 994 if((left == NULL && leftLength != 0) || (right == NULL && rightLength != 0))
{ |
| 995 errorCode = U_ILLEGAL_ARGUMENT_ERROR; |
| 996 return UCOL_EQUAL; |
| 997 } |
| 998 return compareUTF8( |
| 999 StringPiece(left, (leftLength < 0) ? uprv_strlen(left) : leftLength)
, |
| 1000 StringPiece(right, (rightLength < 0) ? uprv_strlen(right) : rightLen
gth), |
| 1001 errorCode); |
| 1002 } |
| 1003 |
| 1004 int32_t |
| 1005 Collator::internalNextSortKeyPart(UCharIterator * /*iter*/, uint32_t /*state*/[2
], |
| 1006 uint8_t * /*dest*/, int32_t /*count*/, UErrorC
ode &errorCode) const { |
| 1007 if (U_SUCCESS(errorCode)) { |
| 1008 errorCode = U_UNSUPPORTED_ERROR; |
| 1009 } |
| 1010 return 0; |
| 1011 } |
| 1012 |
900 // UCollator private data members ---------------------------------------- | 1013 // UCollator private data members ---------------------------------------- |
901 | 1014 |
902 /* This is useless information */ | 1015 /* This is useless information */ |
903 /*const UVersionInfo Collator::fVersion = {1, 1, 0, 0};*/ | 1016 /*const UVersionInfo Collator::fVersion = {1, 1, 0, 0};*/ |
904 | 1017 |
905 // ------------------------------------- | 1018 // ------------------------------------- |
906 | 1019 |
907 U_NAMESPACE_END | 1020 U_NAMESPACE_END |
908 | 1021 |
909 #endif /* #if !UCONFIG_NO_COLLATION */ | 1022 #endif /* #if !UCONFIG_NO_COLLATION */ |
910 | 1023 |
911 /* eof */ | 1024 /* eof */ |
OLD | NEW |