1/* 2 ****************************************************************************** 3 * Copyright (C) 1996-2014, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ****************************************************************************** 6 */ 7 8/** 9 * File coll.cpp 10 * 11 * Created by: Helena Shih 12 * 13 * Modification History: 14 * 15 * Date Name Description 16 * 2/5/97 aliu Modified createDefault to load collation data from 17 * binary files when possible. Added related methods 18 * createCollationFromFile, chopLocale, createPathName. 19 * 2/11/97 aliu Added methods addToCache, findInCache, which implement 20 * a Collation cache. Modified createDefault to look in 21 * cache first, and also to store newly created Collation 22 * objects in the cache. Modified to not use gLocPath. 23 * 2/12/97 aliu Modified to create objects from RuleBasedCollator cache. 24 * Moved cache out of Collation class. 25 * 2/13/97 aliu Moved several methods out of this class and into 26 * RuleBasedCollator, with modifications. Modified 27 * createDefault() to call new RuleBasedCollator(Locale&) 28 * constructor. General clean up and documentation. 29 * 2/20/97 helena Added clone, operator==, operator!=, operator=, and copy 30 * constructor. 31 * 05/06/97 helena Added memory allocation error detection. 32 * 05/08/97 helena Added createInstance(). 33 * 6/20/97 helena Java class name change. 34 * 04/23/99 stephen Removed EDecompositionMode, merged with 35 * Normalizer::EMode 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) 38 * 2012-2014 markus Rewritten in C++ again. 39 */ 40 41#include "utypeinfo.h" // for 'typeid' to work 42 43#include "unicode/utypes.h" 44 45#if !UCONFIG_NO_COLLATION 46 47#include "unicode/coll.h" 48#include "unicode/tblcoll.h" 49#include "collationdata.h" 50#include "collationroot.h" 51#include "collationtailoring.h" 52#include "ucol_imp.h" 53#include "cstring.h" 54#include "cmemory.h" 55#include "umutex.h" 56#include "servloc.h" 57#include "uassert.h" 58#include "ustrenum.h" 59#include "uresimp.h" 60#include "ucln_in.h" 61 62static icu::Locale* availableLocaleList = NULL; 63static int32_t availableLocaleListCount; 64static icu::ICULocaleService* gService = NULL; 65static icu::UInitOnce gServiceInitOnce = U_INITONCE_INITIALIZER; 66static icu::UInitOnce gAvailableLocaleListInitOnce; 67 68/** 69 * Release all static memory held by collator. 70 */ 71U_CDECL_BEGIN 72static UBool U_CALLCONV collator_cleanup(void) { 73#if !UCONFIG_NO_SERVICE 74 if (gService) { 75 delete gService; 76 gService = NULL; 77 } 78 gServiceInitOnce.reset(); 79#endif 80 if (availableLocaleList) { 81 delete []availableLocaleList; 82 availableLocaleList = NULL; 83 } 84 availableLocaleListCount = 0; 85 gAvailableLocaleListInitOnce.reset(); 86 return TRUE; 87} 88 89U_CDECL_END 90 91U_NAMESPACE_BEGIN 92 93#if !UCONFIG_NO_SERVICE 94 95// ------------------------------------------ 96// 97// Registration 98// 99 100//------------------------------------------- 101 102CollatorFactory::~CollatorFactory() {} 103 104//------------------------------------------- 105 106UBool 107CollatorFactory::visible(void) const { 108 return TRUE; 109} 110 111//------------------------------------------- 112 113UnicodeString& 114CollatorFactory::getDisplayName(const Locale& objectLocale, 115 const Locale& displayLocale, 116 UnicodeString& result) 117{ 118 return objectLocale.getDisplayName(displayLocale, result); 119} 120 121// ------------------------------------- 122 123class ICUCollatorFactory : public ICUResourceBundleFactory { 124 public: 125 ICUCollatorFactory() : ICUResourceBundleFactory(UnicodeString(U_ICUDATA_COLL, -1, US_INV)) { } 126 virtual ~ICUCollatorFactory(); 127 protected: 128 virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const; 129}; 130 131ICUCollatorFactory::~ICUCollatorFactory() {} 132 133UObject* 134ICUCollatorFactory::create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& status) const { 135 if (handlesKey(key, status)) { 136 const LocaleKey& lkey = (const LocaleKey&)key; 137 Locale loc; 138 // make sure the requested locale is correct 139 // default LocaleFactory uses currentLocale since that's the one vetted by handlesKey 140 // but for ICU rb resources we use the actual one since it will fallback again 141 lkey.canonicalLocale(loc); 142 143 return Collator::makeInstance(loc, status); 144 } 145 return NULL; 146} 147 148// ------------------------------------- 149 150class ICUCollatorService : public ICULocaleService { 151public: 152 ICUCollatorService() 153 : ICULocaleService(UNICODE_STRING_SIMPLE("Collator")) 154 { 155 UErrorCode status = U_ZERO_ERROR; 156 registerFactory(new ICUCollatorFactory(), status); 157 } 158 159 virtual ~ICUCollatorService(); 160 161 virtual UObject* cloneInstance(UObject* instance) const { 162 return ((Collator*)instance)->clone(); 163 } 164 165 virtual UObject* handleDefault(const ICUServiceKey& key, UnicodeString* actualID, UErrorCode& status) const { 166 LocaleKey& lkey = (LocaleKey&)key; 167 if (actualID) { 168 // Ugly Hack Alert! We return an empty actualID to signal 169 // to callers that this is a default object, not a "real" 170 // service-created object. (TODO remove in 3.0) [aliu] 171 actualID->truncate(0); 172 } 173 Locale loc(""); 174 lkey.canonicalLocale(loc); 175 return Collator::makeInstance(loc, status); 176 } 177 178 virtual UObject* getKey(ICUServiceKey& key, UnicodeString* actualReturn, UErrorCode& status) const { 179 UnicodeString ar; 180 if (actualReturn == NULL) { 181 actualReturn = &ar; 182 } 183 return (Collator*)ICULocaleService::getKey(key, actualReturn, status); 184 } 185 186 virtual UBool isDefault() const { 187 return countFactories() == 1; 188 } 189}; 190 191ICUCollatorService::~ICUCollatorService() {} 192 193// ------------------------------------- 194 195static void U_CALLCONV initService() { 196 gService = new ICUCollatorService(); 197 ucln_i18n_registerCleanup(UCLN_I18N_COLLATOR, collator_cleanup); 198} 199 200 201static ICULocaleService* 202getService(void) 203{ 204 umtx_initOnce(gServiceInitOnce, &initService); 205 return gService; 206} 207 208// ------------------------------------- 209 210static inline UBool 211hasService(void) 212{ 213 UBool retVal = !gServiceInitOnce.isReset() && (getService() != NULL); 214 return retVal; 215} 216 217#endif /* UCONFIG_NO_SERVICE */ 218 219static void U_CALLCONV 220initAvailableLocaleList(UErrorCode &status) { 221 U_ASSERT(availableLocaleListCount == 0); 222 U_ASSERT(availableLocaleList == NULL); 223 // for now, there is a hardcoded list, so just walk through that list and set it up. 224 UResourceBundle *index = NULL; 225 UResourceBundle installed; 226 int32_t i = 0; 227 228 ures_initStackObject(&installed); 229 index = ures_openDirect(U_ICUDATA_COLL, "res_index", &status); 230 ures_getByKey(index, "InstalledLocales", &installed, &status); 231 232 if(U_SUCCESS(status)) { 233 availableLocaleListCount = ures_getSize(&installed); 234 availableLocaleList = new Locale[availableLocaleListCount]; 235 236 if (availableLocaleList != NULL) { 237 ures_resetIterator(&installed); 238 while(ures_hasNext(&installed)) { 239 const char *tempKey = NULL; 240 ures_getNextString(&installed, NULL, &tempKey, &status); 241 availableLocaleList[i++] = Locale(tempKey); 242 } 243 } 244 U_ASSERT(availableLocaleListCount == i); 245 ures_close(&installed); 246 } 247 ures_close(index); 248 ucln_i18n_registerCleanup(UCLN_I18N_COLLATOR, collator_cleanup); 249} 250 251static UBool isAvailableLocaleListInitialized(UErrorCode &status) { 252 umtx_initOnce(gAvailableLocaleListInitOnce, &initAvailableLocaleList, status); 253 return U_SUCCESS(status); 254} 255 256 257// Collator public methods ----------------------------------------------- 258 259Collator* U_EXPORT2 Collator::createInstance(UErrorCode& success) 260{ 261 return createInstance(Locale::getDefault(), success); 262} 263 264Collator* U_EXPORT2 Collator::createInstance(const Locale& desiredLocale, 265 UErrorCode& status) 266{ 267 if (U_FAILURE(status)) 268 return 0; 269 270#if !UCONFIG_NO_SERVICE 271 if (hasService()) { 272 Locale actualLoc; 273 return (Collator*)gService->get(desiredLocale, &actualLoc, status); 274 } 275#endif 276 return makeInstance(desiredLocale, status); 277} 278 279 280Collator* Collator::makeInstance(const Locale& desiredLocale, 281 UErrorCode& status) 282{ 283 Locale validLocale(""); 284 const CollationTailoring *t = 285 CollationLoader::loadTailoring(desiredLocale, validLocale, status); 286 if (U_SUCCESS(status)) { 287 Collator *result = new RuleBasedCollator(t, validLocale); 288 if (result != NULL) { 289 return result; 290 } 291 status = U_MEMORY_ALLOCATION_ERROR; 292 } 293 if (t != NULL) { 294 t->deleteIfZeroRefCount(); 295 } 296 return NULL; 297} 298 299Collator * 300Collator::safeClone() const { 301 return clone(); 302} 303 304// implement deprecated, previously abstract method 305Collator::EComparisonResult Collator::compare(const UnicodeString& source, 306 const UnicodeString& target) const 307{ 308 UErrorCode ec = U_ZERO_ERROR; 309 return (EComparisonResult)compare(source, target, ec); 310} 311 312// implement deprecated, previously abstract method 313Collator::EComparisonResult Collator::compare(const UnicodeString& source, 314 const UnicodeString& target, 315 int32_t length) const 316{ 317 UErrorCode ec = U_ZERO_ERROR; 318 return (EComparisonResult)compare(source, target, length, ec); 319} 320 321// implement deprecated, previously abstract method 322Collator::EComparisonResult Collator::compare(const UChar* source, int32_t sourceLength, 323 const UChar* target, int32_t targetLength) 324 const 325{ 326 UErrorCode ec = U_ZERO_ERROR; 327 return (EComparisonResult)compare(source, sourceLength, target, targetLength, ec); 328} 329 330UCollationResult Collator::compare(UCharIterator &/*sIter*/, 331 UCharIterator &/*tIter*/, 332 UErrorCode &status) const { 333 if(U_SUCCESS(status)) { 334 // Not implemented in the base class. 335 status = U_UNSUPPORTED_ERROR; 336 } 337 return UCOL_EQUAL; 338} 339 340UCollationResult Collator::compareUTF8(const StringPiece &source, 341 const StringPiece &target, 342 UErrorCode &status) const { 343 if(U_FAILURE(status)) { 344 return UCOL_EQUAL; 345 } 346 UCharIterator sIter, tIter; 347 uiter_setUTF8(&sIter, source.data(), source.length()); 348 uiter_setUTF8(&tIter, target.data(), target.length()); 349 return compare(sIter, tIter, status); 350} 351 352UBool Collator::equals(const UnicodeString& source, 353 const UnicodeString& target) const 354{ 355 UErrorCode ec = U_ZERO_ERROR; 356 return (compare(source, target, ec) == UCOL_EQUAL); 357} 358 359UBool Collator::greaterOrEqual(const UnicodeString& source, 360 const UnicodeString& target) const 361{ 362 UErrorCode ec = U_ZERO_ERROR; 363 return (compare(source, target, ec) != UCOL_LESS); 364} 365 366UBool Collator::greater(const UnicodeString& source, 367 const UnicodeString& target) const 368{ 369 UErrorCode ec = U_ZERO_ERROR; 370 return (compare(source, target, ec) == UCOL_GREATER); 371} 372 373// this API ignores registered collators, since it returns an 374// array of indefinite lifetime 375const Locale* U_EXPORT2 Collator::getAvailableLocales(int32_t& count) 376{ 377 UErrorCode status = U_ZERO_ERROR; 378 Locale *result = NULL; 379 count = 0; 380 if (isAvailableLocaleListInitialized(status)) 381 { 382 result = availableLocaleList; 383 count = availableLocaleListCount; 384 } 385 return result; 386} 387 388UnicodeString& U_EXPORT2 Collator::getDisplayName(const Locale& objectLocale, 389 const Locale& displayLocale, 390 UnicodeString& name) 391{ 392#if !UCONFIG_NO_SERVICE 393 if (hasService()) { 394 UnicodeString locNameStr; 395 LocaleUtility::initNameFromLocale(objectLocale, locNameStr); 396 return gService->getDisplayName(locNameStr, name, displayLocale); 397 } 398#endif 399 return objectLocale.getDisplayName(displayLocale, name); 400} 401 402UnicodeString& U_EXPORT2 Collator::getDisplayName(const Locale& objectLocale, 403 UnicodeString& name) 404{ 405 return getDisplayName(objectLocale, Locale::getDefault(), name); 406} 407 408/* This is useless information */ 409/*void Collator::getVersion(UVersionInfo versionInfo) const 410{ 411 if (versionInfo!=NULL) 412 uprv_memcpy(versionInfo, fVersion, U_MAX_VERSION_LENGTH); 413} 414*/ 415 416// UCollator protected constructor destructor ---------------------------- 417 418/** 419* Default constructor. 420* Constructor is different from the old default Collator constructor. 421* The task for determing the default collation strength and normalization mode 422* is left to the child class. 423*/ 424Collator::Collator() 425: UObject() 426{ 427} 428 429/** 430* Constructor. 431* Empty constructor, does not handle the arguments. 432* This constructor is done for backward compatibility with 1.7 and 1.8. 433* The task for handling the argument collation strength and normalization 434* mode is left to the child class. 435* @param collationStrength collation strength 436* @param decompositionMode 437* @deprecated 2.4 use the default constructor instead 438*/ 439Collator::Collator(UCollationStrength, UNormalizationMode ) 440: UObject() 441{ 442} 443 444Collator::~Collator() 445{ 446} 447 448Collator::Collator(const Collator &other) 449 : UObject(other) 450{ 451} 452 453UBool Collator::operator==(const Collator& other) const 454{ 455 // Subclasses: Call this method and then add more specific checks. 456 return typeid(*this) == typeid(other); 457} 458 459UBool Collator::operator!=(const Collator& other) const 460{ 461 return (UBool)!(*this == other); 462} 463 464int32_t U_EXPORT2 Collator::getBound(const uint8_t *source, 465 int32_t sourceLength, 466 UColBoundMode boundType, 467 uint32_t noOfLevels, 468 uint8_t *result, 469 int32_t resultLength, 470 UErrorCode &status) 471{ 472 return ucol_getBound(source, sourceLength, boundType, noOfLevels, result, resultLength, &status); 473} 474 475void 476Collator::setLocales(const Locale& /* requestedLocale */, const Locale& /* validLocale */, const Locale& /*actualLocale*/) { 477} 478 479UnicodeSet *Collator::getTailoredSet(UErrorCode &status) const 480{ 481 if(U_FAILURE(status)) { 482 return NULL; 483 } 484 // everything can be changed 485 return new UnicodeSet(0, 0x10FFFF); 486} 487 488// ------------------------------------- 489 490#if !UCONFIG_NO_SERVICE 491URegistryKey U_EXPORT2 492Collator::registerInstance(Collator* toAdopt, const Locale& locale, UErrorCode& status) 493{ 494 if (U_SUCCESS(status)) { 495 // Set the collator locales while registering so that createInstance() 496 // need not guess whether the collator's locales are already set properly 497 // (as they are by the data loader). 498 toAdopt->setLocales(locale, locale, locale); 499 return getService()->registerInstance(toAdopt, locale, status); 500 } 501 return NULL; 502} 503 504// ------------------------------------- 505 506class CFactory : public LocaleKeyFactory { 507private: 508 CollatorFactory* _delegate; 509 Hashtable* _ids; 510 511public: 512 CFactory(CollatorFactory* delegate, UErrorCode& status) 513 : LocaleKeyFactory(delegate->visible() ? VISIBLE : INVISIBLE) 514 , _delegate(delegate) 515 , _ids(NULL) 516 { 517 if (U_SUCCESS(status)) { 518 int32_t count = 0; 519 _ids = new Hashtable(status); 520 if (_ids) { 521 const UnicodeString * idlist = _delegate->getSupportedIDs(count, status); 522 for (int i = 0; i < count; ++i) { 523 _ids->put(idlist[i], (void*)this, status); 524 if (U_FAILURE(status)) { 525 delete _ids; 526 _ids = NULL; 527 return; 528 } 529 } 530 } else { 531 status = U_MEMORY_ALLOCATION_ERROR; 532 } 533 } 534 } 535 536 virtual ~CFactory(); 537 538 virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const; 539 540protected: 541 virtual const Hashtable* getSupportedIDs(UErrorCode& status) const 542 { 543 if (U_SUCCESS(status)) { 544 return _ids; 545 } 546 return NULL; 547 } 548 549 virtual UnicodeString& 550 getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const; 551}; 552 553CFactory::~CFactory() 554{ 555 delete _delegate; 556 delete _ids; 557} 558 559UObject* 560CFactory::create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& status) const 561{ 562 if (handlesKey(key, status)) { 563 const LocaleKey& lkey = (const LocaleKey&)key; 564 Locale validLoc; 565 lkey.currentLocale(validLoc); 566 return _delegate->createCollator(validLoc); 567 } 568 return NULL; 569} 570 571UnicodeString& 572CFactory::getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const 573{ 574 if ((_coverage & 0x1) == 0) { 575 UErrorCode status = U_ZERO_ERROR; 576 const Hashtable* ids = getSupportedIDs(status); 577 if (ids && (ids->get(id) != NULL)) { 578 Locale loc; 579 LocaleUtility::initLocaleFromName(id, loc); 580 return _delegate->getDisplayName(loc, locale, result); 581 } 582 } 583 result.setToBogus(); 584 return result; 585} 586 587URegistryKey U_EXPORT2 588Collator::registerFactory(CollatorFactory* toAdopt, UErrorCode& status) 589{ 590 if (U_SUCCESS(status)) { 591 CFactory* f = new CFactory(toAdopt, status); 592 if (f) { 593 return getService()->registerFactory(f, status); 594 } 595 status = U_MEMORY_ALLOCATION_ERROR; 596 } 597 return NULL; 598} 599 600// ------------------------------------- 601 602UBool U_EXPORT2 603Collator::unregister(URegistryKey key, UErrorCode& status) 604{ 605 if (U_SUCCESS(status)) { 606 if (hasService()) { 607 return gService->unregister(key, status); 608 } 609 status = U_ILLEGAL_ARGUMENT_ERROR; 610 } 611 return FALSE; 612} 613#endif /* UCONFIG_NO_SERVICE */ 614 615class CollationLocaleListEnumeration : public StringEnumeration { 616private: 617 int32_t index; 618public: 619 static UClassID U_EXPORT2 getStaticClassID(void); 620 virtual UClassID getDynamicClassID(void) const; 621public: 622 CollationLocaleListEnumeration() 623 : index(0) 624 { 625 // The global variables should already be initialized. 626 //isAvailableLocaleListInitialized(status); 627 } 628 629 virtual ~CollationLocaleListEnumeration(); 630 631 virtual StringEnumeration * clone() const 632 { 633 CollationLocaleListEnumeration *result = new CollationLocaleListEnumeration(); 634 if (result) { 635 result->index = index; 636 } 637 return result; 638 } 639 640 virtual int32_t count(UErrorCode &/*status*/) const { 641 return availableLocaleListCount; 642 } 643 644 virtual const char* next(int32_t* resultLength, UErrorCode& /*status*/) { 645 const char* result; 646 if(index < availableLocaleListCount) { 647 result = availableLocaleList[index++].getName(); 648 if(resultLength != NULL) { 649 *resultLength = (int32_t)uprv_strlen(result); 650 } 651 } else { 652 if(resultLength != NULL) { 653 *resultLength = 0; 654 } 655 result = NULL; 656 } 657 return result; 658 } 659 660 virtual const UnicodeString* snext(UErrorCode& status) { 661 int32_t resultLength = 0; 662 const char *s = next(&resultLength, status); 663 return setChars(s, resultLength, status); 664 } 665 666 virtual void reset(UErrorCode& /*status*/) { 667 index = 0; 668 } 669}; 670 671CollationLocaleListEnumeration::~CollationLocaleListEnumeration() {} 672 673UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CollationLocaleListEnumeration) 674 675 676// ------------------------------------- 677 678StringEnumeration* U_EXPORT2 679Collator::getAvailableLocales(void) 680{ 681#if !UCONFIG_NO_SERVICE 682 if (hasService()) { 683 return getService()->getAvailableLocales(); 684 } 685#endif /* UCONFIG_NO_SERVICE */ 686 UErrorCode status = U_ZERO_ERROR; 687 if (isAvailableLocaleListInitialized(status)) { 688 return new CollationLocaleListEnumeration(); 689 } 690 return NULL; 691} 692 693StringEnumeration* U_EXPORT2 694Collator::getKeywords(UErrorCode& status) { 695 // This is a wrapper over ucol_getKeywords 696 UEnumeration* uenum = ucol_getKeywords(&status); 697 if (U_FAILURE(status)) { 698 uenum_close(uenum); 699 return NULL; 700 } 701 return new UStringEnumeration(uenum); 702} 703 704StringEnumeration* U_EXPORT2 705Collator::getKeywordValues(const char *keyword, UErrorCode& status) { 706 // This is a wrapper over ucol_getKeywordValues 707 UEnumeration* uenum = ucol_getKeywordValues(keyword, &status); 708 if (U_FAILURE(status)) { 709 uenum_close(uenum); 710 return NULL; 711 } 712 return new UStringEnumeration(uenum); 713} 714 715StringEnumeration* U_EXPORT2 716Collator::getKeywordValuesForLocale(const char* key, const Locale& locale, 717 UBool commonlyUsed, UErrorCode& status) { 718 // This is a wrapper over ucol_getKeywordValuesForLocale 719 UEnumeration *uenum = ucol_getKeywordValuesForLocale(key, locale.getName(), 720 commonlyUsed, &status); 721 if (U_FAILURE(status)) { 722 uenum_close(uenum); 723 return NULL; 724 } 725 return new UStringEnumeration(uenum); 726} 727 728Locale U_EXPORT2 729Collator::getFunctionalEquivalent(const char* keyword, const Locale& locale, 730 UBool& isAvailable, UErrorCode& status) { 731 // This is a wrapper over ucol_getFunctionalEquivalent 732 char loc[ULOC_FULLNAME_CAPACITY]; 733 /*int32_t len =*/ ucol_getFunctionalEquivalent(loc, sizeof(loc), 734 keyword, locale.getName(), &isAvailable, &status); 735 if (U_FAILURE(status)) { 736 *loc = 0; // root 737 } 738 return Locale::createFromName(loc); 739} 740 741Collator::ECollationStrength 742Collator::getStrength(void) const { 743 UErrorCode intStatus = U_ZERO_ERROR; 744 return (ECollationStrength)getAttribute(UCOL_STRENGTH, intStatus); 745} 746 747void 748Collator::setStrength(ECollationStrength newStrength) { 749 UErrorCode intStatus = U_ZERO_ERROR; 750 setAttribute(UCOL_STRENGTH, (UColAttributeValue)newStrength, intStatus); 751} 752 753Collator & 754Collator::setMaxVariable(UColReorderCode /*group*/, UErrorCode &errorCode) { 755 if (U_SUCCESS(errorCode)) { 756 errorCode = U_UNSUPPORTED_ERROR; 757 } 758 return *this; 759} 760 761UColReorderCode 762Collator::getMaxVariable() const { 763 return UCOL_REORDER_CODE_PUNCTUATION; 764} 765 766int32_t 767Collator::getReorderCodes(int32_t* /* dest*/, 768 int32_t /* destCapacity*/, 769 UErrorCode& status) const 770{ 771 if (U_SUCCESS(status)) { 772 status = U_UNSUPPORTED_ERROR; 773 } 774 return 0; 775} 776 777void 778Collator::setReorderCodes(const int32_t* /* reorderCodes */, 779 int32_t /* reorderCodesLength */, 780 UErrorCode& status) 781{ 782 if (U_SUCCESS(status)) { 783 status = U_UNSUPPORTED_ERROR; 784 } 785} 786 787int32_t 788Collator::getEquivalentReorderCodes(int32_t reorderCode, 789 int32_t *dest, int32_t capacity, 790 UErrorCode &errorCode) { 791 if(U_FAILURE(errorCode)) { return 0; } 792 if(capacity < 0 || (dest == NULL && capacity > 0)) { 793 errorCode = U_ILLEGAL_ARGUMENT_ERROR; 794 return 0; 795 } 796 const CollationData *baseData = CollationRoot::getData(errorCode); 797 if(U_FAILURE(errorCode)) { return 0; } 798 return baseData->getEquivalentScripts(reorderCode, dest, capacity, errorCode); 799} 800 801int32_t 802Collator::internalGetShortDefinitionString(const char * /*locale*/, 803 char * /*buffer*/, 804 int32_t /*capacity*/, 805 UErrorCode &status) const { 806 if(U_SUCCESS(status)) { 807 status = U_UNSUPPORTED_ERROR; /* Shouldn't happen, internal function */ 808 } 809 return 0; 810} 811 812UCollationResult 813Collator::internalCompareUTF8(const char *left, int32_t leftLength, 814 const char *right, int32_t rightLength, 815 UErrorCode &errorCode) const { 816 if(U_FAILURE(errorCode)) { return UCOL_EQUAL; } 817 if((left == NULL && leftLength != 0) || (right == NULL && rightLength != 0)) { 818 errorCode = U_ILLEGAL_ARGUMENT_ERROR; 819 return UCOL_EQUAL; 820 } 821 return compareUTF8( 822 StringPiece(left, (leftLength < 0) ? uprv_strlen(left) : leftLength), 823 StringPiece(right, (rightLength < 0) ? uprv_strlen(right) : rightLength), 824 errorCode); 825} 826 827int32_t 828Collator::internalNextSortKeyPart(UCharIterator * /*iter*/, uint32_t /*state*/[2], 829 uint8_t * /*dest*/, int32_t /*count*/, UErrorCode &errorCode) const { 830 if (U_SUCCESS(errorCode)) { 831 errorCode = U_UNSUPPORTED_ERROR; 832 } 833 return 0; 834} 835 836// UCollator private data members ---------------------------------------- 837 838/* This is useless information */ 839/*const UVersionInfo Collator::fVersion = {1, 1, 0, 0};*/ 840 841// ------------------------------------- 842 843U_NAMESPACE_END 844 845#endif /* #if !UCONFIG_NO_COLLATION */ 846 847/* eof */ 848