2 ******************************************************************************
3 * Copyright (C) 1996-2014, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ******************************************************************************
11 * Created by: Helena Shih
13 * Modification History:
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
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
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.
41 #include "utypeinfo.h" // for 'typeid' to work
43 #include "unicode/utypes.h"
45 #if !UCONFIG_NO_COLLATION
47 #include "unicode/coll.h"
48 #include "unicode/tblcoll.h"
49 #include "collationdata.h"
50 #include "collationroot.h"
51 #include "collationtailoring.h"
62 static icu::Locale
* availableLocaleList
= NULL
;
63 static int32_t availableLocaleListCount
;
64 static icu::ICULocaleService
* gService
= NULL
;
65 static icu::UInitOnce gServiceInitOnce
= U_INITONCE_INITIALIZER
;
66 static icu::UInitOnce gAvailableLocaleListInitOnce
;
69 * Release all static memory held by collator.
72 static UBool U_CALLCONV
collator_cleanup(void) {
73 #if !UCONFIG_NO_SERVICE
78 gServiceInitOnce
.reset();
80 if (availableLocaleList
) {
81 delete []availableLocaleList
;
82 availableLocaleList
= NULL
;
84 availableLocaleListCount
= 0;
85 gAvailableLocaleListInitOnce
.reset();
93 #if !UCONFIG_NO_SERVICE
95 // ------------------------------------------
100 //-------------------------------------------
102 CollatorFactory::~CollatorFactory() {}
104 //-------------------------------------------
107 CollatorFactory::visible(void) const {
111 //-------------------------------------------
114 CollatorFactory::getDisplayName(const Locale
& objectLocale
,
115 const Locale
& displayLocale
,
116 UnicodeString
& result
)
118 return objectLocale
.getDisplayName(displayLocale
, result
);
121 // -------------------------------------
123 class ICUCollatorFactory
: public ICUResourceBundleFactory
{
125 ICUCollatorFactory() : ICUResourceBundleFactory(UnicodeString(U_ICUDATA_COLL
, -1, US_INV
)) { }
126 virtual ~ICUCollatorFactory();
128 virtual UObject
* create(const ICUServiceKey
& key
, const ICUService
* service
, UErrorCode
& status
) const;
131 ICUCollatorFactory::~ICUCollatorFactory() {}
134 ICUCollatorFactory::create(const ICUServiceKey
& key
, const ICUService
* /* service */, UErrorCode
& status
) const {
135 if (handlesKey(key
, status
)) {
136 const LocaleKey
& lkey
= (const LocaleKey
&)key
;
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
);
143 return Collator::makeInstance(loc
, status
);
148 // -------------------------------------
150 class ICUCollatorService
: public ICULocaleService
{
153 : ICULocaleService(UNICODE_STRING_SIMPLE("Collator"))
155 UErrorCode status
= U_ZERO_ERROR
;
156 registerFactory(new ICUCollatorFactory(), status
);
159 virtual ~ICUCollatorService();
161 virtual UObject
* cloneInstance(UObject
* instance
) const {
162 return ((Collator
*)instance
)->clone();
165 virtual UObject
* handleDefault(const ICUServiceKey
& key
, UnicodeString
* actualID
, UErrorCode
& status
) const {
166 LocaleKey
& lkey
= (LocaleKey
&)key
;
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);
174 lkey
.canonicalLocale(loc
);
175 return Collator::makeInstance(loc
, status
);
178 virtual UObject
* getKey(ICUServiceKey
& key
, UnicodeString
* actualReturn
, UErrorCode
& status
) const {
180 if (actualReturn
== NULL
) {
183 return (Collator
*)ICULocaleService::getKey(key
, actualReturn
, status
);
186 virtual UBool
isDefault() const {
187 return countFactories() == 1;
191 ICUCollatorService::~ICUCollatorService() {}
193 // -------------------------------------
195 static void U_CALLCONV
initService() {
196 gService
= new ICUCollatorService();
197 ucln_i18n_registerCleanup(UCLN_I18N_COLLATOR
, collator_cleanup
);
201 static ICULocaleService
*
204 umtx_initOnce(gServiceInitOnce
, &initService
);
208 // -------------------------------------
213 UBool retVal
= !gServiceInitOnce
.isReset() && (getService() != NULL
);
217 #endif /* UCONFIG_NO_SERVICE */
219 static void U_CALLCONV
220 initAvailableLocaleList(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
;
228 ures_initStackObject(&installed
);
229 index
= ures_openDirect(U_ICUDATA_COLL
, "res_index", &status
);
230 ures_getByKey(index
, "InstalledLocales", &installed
, &status
);
232 if(U_SUCCESS(status
)) {
233 availableLocaleListCount
= ures_getSize(&installed
);
234 availableLocaleList
= new Locale
[availableLocaleListCount
];
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
);
244 U_ASSERT(availableLocaleListCount
== i
);
245 ures_close(&installed
);
248 ucln_i18n_registerCleanup(UCLN_I18N_COLLATOR
, collator_cleanup
);
251 static UBool
isAvailableLocaleListInitialized(UErrorCode
&status
) {
252 umtx_initOnce(gAvailableLocaleListInitOnce
, &initAvailableLocaleList
, status
);
253 return U_SUCCESS(status
);
257 // Collator public methods -----------------------------------------------
261 static const struct {
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
}
274 static const struct {
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
},
286 { "shifted", UCOL_SHIFTED
},
287 { "non-ignorable", UCOL_NON_IGNORABLE
},
288 { "lower", UCOL_LOWER_FIRST
},
289 { "upper", UCOL_UPPER_FIRST
}
292 static const char *collReorderCodes
[UCOL_REORDER_CODE_LIMIT
- UCOL_REORDER_CODE_FIRST
] = {
293 "space", "punct", "symbol", "currency", "digit"
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
;
302 // Not supporting "others" = UCOL_REORDER_CODE_OTHERS
303 // as a synonym for Zzzz = USCRIPT_UNKNOWN for now:
304 // Avoid introducing synonyms/aliases.
309 * Sets collation attributes according to locale keywords. See
310 * http://www.unicode.org/reports/tr35/tr35-collation.html#Collation_Settings
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
316 void setAttributesFromKeywords(const Locale
&loc
, Collator
&coll
, UErrorCode
&errorCode
) {
317 if (U_FAILURE(errorCode
)) {
320 if (uprv_strcmp(loc
.getName(), loc
.getBaseName()) == 0) {
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_LENGTHOF(value
), errorCode
);
328 if (U_FAILURE(errorCode
)) {
329 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
333 errorCode
= U_UNSUPPORTED_ERROR
;
336 length
= loc
.getKeywordValue("variableTop", value
, UPRV_LENGTHOF(value
), errorCode
);
337 if (U_FAILURE(errorCode
)) {
338 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
342 errorCode
= U_UNSUPPORTED_ERROR
;
345 // Parse known collation keywords, ignore others.
346 if (errorCode
== U_STRING_NOT_TERMINATED_WARNING
) {
347 errorCode
= U_ZERO_ERROR
;
349 for (int32_t i
= 0; i
< UPRV_LENGTHOF(collAttributes
); ++i
) {
350 length
= loc
.getKeywordValue(collAttributes
[i
].name
, value
, UPRV_LENGTHOF(value
), errorCode
);
351 if (U_FAILURE(errorCode
) || errorCode
== U_STRING_NOT_TERMINATED_WARNING
) {
352 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
355 if (length
== 0) { continue; }
356 for (int32_t j
= 0;; ++j
) {
357 if (j
== UPRV_LENGTHOF(collAttributeValues
)) {
358 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
361 if (uprv_stricmp(value
, collAttributeValues
[j
].name
) == 0) {
362 coll
.setAttribute(collAttributes
[i
].attr
, collAttributeValues
[j
].value
, errorCode
);
367 length
= loc
.getKeywordValue("colReorder", value
, UPRV_LENGTHOF(value
), errorCode
);
368 if (U_FAILURE(errorCode
) || errorCode
== U_STRING_NOT_TERMINATED_WARNING
) {
369 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
373 int32_t codes
[USCRIPT_CODE_LIMIT
+ UCOL_REORDER_CODE_LIMIT
- UCOL_REORDER_CODE_FIRST
];
374 int32_t codesLength
= 0;
375 char *scriptName
= value
;
377 if (codesLength
== UPRV_LENGTHOF(codes
)) {
378 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
381 char *limit
= scriptName
;
383 while ((c
= *limit
) != 0 && c
!= '-') { ++limit
; }
386 if ((limit
- scriptName
) == 4) {
387 // Strict parsing, accept only 4-letter script codes, not long names.
388 code
= u_getPropertyValueEnum(UCHAR_SCRIPT
, scriptName
);
390 code
= getReorderCode(scriptName
);
393 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
396 codes
[codesLength
++] = code
;
397 if (c
== 0) { break; }
398 scriptName
= limit
+ 1;
400 coll
.setReorderCodes(codes
, codesLength
, errorCode
);
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
;
408 int32_t code
= getReorderCode(value
);
410 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
413 coll
.setMaxVariable((UColReorderCode
)code
, errorCode
);
415 if (U_FAILURE(errorCode
)) {
416 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
422 Collator
* U_EXPORT2
Collator::createInstance(UErrorCode
& success
)
424 return createInstance(Locale::getDefault(), success
);
427 Collator
* U_EXPORT2
Collator::createInstance(const Locale
& desiredLocale
,
430 if (U_FAILURE(status
))
432 if (desiredLocale
.isBogus()) {
433 // Locale constructed from malformed locale ID or language tag.
434 status
= U_ILLEGAL_ARGUMENT_ERROR
;
439 #if !UCONFIG_NO_SERVICE
442 coll
= (Collator
*)gService
->get(desiredLocale
, &actualLoc
, status
);
446 coll
= makeInstance(desiredLocale
, status
);
448 setAttributesFromKeywords(desiredLocale
, *coll
, status
);
449 if (U_FAILURE(status
)) {
457 Collator
* Collator::makeInstance(const Locale
& desiredLocale
, UErrorCode
& status
) {
458 const CollationCacheEntry
*entry
= CollationLoader::loadTailoring(desiredLocale
, status
);
459 if (U_SUCCESS(status
)) {
460 Collator
*result
= new RuleBasedCollator(entry
);
461 if (result
!= NULL
) {
462 // Both the unified cache's get() and the RBC constructor
463 // did addRef(). Undo one of them.
467 status
= U_MEMORY_ALLOCATION_ERROR
;
470 // Undo the addRef() from the cache.get().
477 Collator::safeClone() const {
481 // implement deprecated, previously abstract method
482 Collator::EComparisonResult
Collator::compare(const UnicodeString
& source
,
483 const UnicodeString
& target
) const
485 UErrorCode ec
= U_ZERO_ERROR
;
486 return (EComparisonResult
)compare(source
, target
, ec
);
489 // implement deprecated, previously abstract method
490 Collator::EComparisonResult
Collator::compare(const UnicodeString
& source
,
491 const UnicodeString
& target
,
492 int32_t length
) const
494 UErrorCode ec
= U_ZERO_ERROR
;
495 return (EComparisonResult
)compare(source
, target
, length
, ec
);
498 // implement deprecated, previously abstract method
499 Collator::EComparisonResult
Collator::compare(const UChar
* source
, int32_t sourceLength
,
500 const UChar
* target
, int32_t targetLength
)
503 UErrorCode ec
= U_ZERO_ERROR
;
504 return (EComparisonResult
)compare(source
, sourceLength
, target
, targetLength
, ec
);
507 UCollationResult
Collator::compare(UCharIterator
&/*sIter*/,
508 UCharIterator
&/*tIter*/,
509 UErrorCode
&status
) const {
510 if(U_SUCCESS(status
)) {
511 // Not implemented in the base class.
512 status
= U_UNSUPPORTED_ERROR
;
517 UCollationResult
Collator::compareUTF8(const StringPiece
&source
,
518 const StringPiece
&target
,
519 UErrorCode
&status
) const {
520 if(U_FAILURE(status
)) {
523 UCharIterator sIter
, tIter
;
524 uiter_setUTF8(&sIter
, source
.data(), source
.length());
525 uiter_setUTF8(&tIter
, target
.data(), target
.length());
526 return compare(sIter
, tIter
, status
);
529 UBool
Collator::equals(const UnicodeString
& source
,
530 const UnicodeString
& target
) const
532 UErrorCode ec
= U_ZERO_ERROR
;
533 return (compare(source
, target
, ec
) == UCOL_EQUAL
);
536 UBool
Collator::greaterOrEqual(const UnicodeString
& source
,
537 const UnicodeString
& target
) const
539 UErrorCode ec
= U_ZERO_ERROR
;
540 return (compare(source
, target
, ec
) != UCOL_LESS
);
543 UBool
Collator::greater(const UnicodeString
& source
,
544 const UnicodeString
& target
) const
546 UErrorCode ec
= U_ZERO_ERROR
;
547 return (compare(source
, target
, ec
) == UCOL_GREATER
);
550 // this API ignores registered collators, since it returns an
551 // array of indefinite lifetime
552 const Locale
* U_EXPORT2
Collator::getAvailableLocales(int32_t& count
)
554 UErrorCode status
= U_ZERO_ERROR
;
555 Locale
*result
= NULL
;
557 if (isAvailableLocaleListInitialized(status
))
559 result
= availableLocaleList
;
560 count
= availableLocaleListCount
;
565 UnicodeString
& U_EXPORT2
Collator::getDisplayName(const Locale
& objectLocale
,
566 const Locale
& displayLocale
,
569 #if !UCONFIG_NO_SERVICE
571 UnicodeString locNameStr
;
572 LocaleUtility::initNameFromLocale(objectLocale
, locNameStr
);
573 return gService
->getDisplayName(locNameStr
, name
, displayLocale
);
576 return objectLocale
.getDisplayName(displayLocale
, name
);
579 UnicodeString
& U_EXPORT2
Collator::getDisplayName(const Locale
& objectLocale
,
582 return getDisplayName(objectLocale
, Locale::getDefault(), name
);
585 /* This is useless information */
586 /*void Collator::getVersion(UVersionInfo versionInfo) const
588 if (versionInfo!=NULL)
589 uprv_memcpy(versionInfo, fVersion, U_MAX_VERSION_LENGTH);
593 // UCollator protected constructor destructor ----------------------------
596 * Default constructor.
597 * Constructor is different from the old default Collator constructor.
598 * The task for determing the default collation strength and normalization mode
599 * is left to the child class.
608 * Empty constructor, does not handle the arguments.
609 * This constructor is done for backward compatibility with 1.7 and 1.8.
610 * The task for handling the argument collation strength and normalization
611 * mode is left to the child class.
612 * @param collationStrength collation strength
613 * @param decompositionMode
614 * @deprecated 2.4 use the default constructor instead
616 Collator::Collator(UCollationStrength
, UNormalizationMode
)
621 Collator::~Collator()
625 Collator::Collator(const Collator
&other
)
630 UBool
Collator::operator==(const Collator
& other
) const
632 // Subclasses: Call this method and then add more specific checks.
633 return typeid(*this) == typeid(other
);
636 UBool
Collator::operator!=(const Collator
& other
) const
638 return (UBool
)!(*this == other
);
641 int32_t U_EXPORT2
Collator::getBound(const uint8_t *source
,
642 int32_t sourceLength
,
643 UColBoundMode boundType
,
646 int32_t resultLength
,
649 return ucol_getBound(source
, sourceLength
, boundType
, noOfLevels
, result
, resultLength
, &status
);
653 Collator::setLocales(const Locale
& /* requestedLocale */, const Locale
& /* validLocale */, const Locale
& /*actualLocale*/) {
656 UnicodeSet
*Collator::getTailoredSet(UErrorCode
&status
) const
658 if(U_FAILURE(status
)) {
661 // everything can be changed
662 return new UnicodeSet(0, 0x10FFFF);
665 // -------------------------------------
667 #if !UCONFIG_NO_SERVICE
668 URegistryKey U_EXPORT2
669 Collator::registerInstance(Collator
* toAdopt
, const Locale
& locale
, UErrorCode
& 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 properly
674 // (as they are by the data loader).
675 toAdopt
->setLocales(locale
, locale
, locale
);
676 return getService()->registerInstance(toAdopt
, locale
, status
);
681 // -------------------------------------
683 class CFactory
: public LocaleKeyFactory
{
685 CollatorFactory
* _delegate
;
689 CFactory(CollatorFactory
* delegate
, UErrorCode
& status
)
690 : LocaleKeyFactory(delegate
->visible() ? VISIBLE
: INVISIBLE
)
691 , _delegate(delegate
)
694 if (U_SUCCESS(status
)) {
696 _ids
= new Hashtable(status
);
698 const UnicodeString
* idlist
= _delegate
->getSupportedIDs(count
, status
);
699 for (int i
= 0; i
< count
; ++i
) {
700 _ids
->put(idlist
[i
], (void*)this, status
);
701 if (U_FAILURE(status
)) {
708 status
= U_MEMORY_ALLOCATION_ERROR
;
715 virtual UObject
* create(const ICUServiceKey
& key
, const ICUService
* service
, UErrorCode
& status
) const;
718 virtual const Hashtable
* getSupportedIDs(UErrorCode
& status
) const
720 if (U_SUCCESS(status
)) {
726 virtual UnicodeString
&
727 getDisplayName(const UnicodeString
& id
, const Locale
& locale
, UnicodeString
& result
) const;
730 CFactory::~CFactory()
737 CFactory::create(const ICUServiceKey
& key
, const ICUService
* /* service */, UErrorCode
& status
) const
739 if (handlesKey(key
, status
)) {
740 const LocaleKey
& lkey
= (const LocaleKey
&)key
;
742 lkey
.currentLocale(validLoc
);
743 return _delegate
->createCollator(validLoc
);
749 CFactory::getDisplayName(const UnicodeString
& id
, const Locale
& locale
, UnicodeString
& result
) const
751 if ((_coverage
& 0x1) == 0) {
752 UErrorCode status
= U_ZERO_ERROR
;
753 const Hashtable
* ids
= getSupportedIDs(status
);
754 if (ids
&& (ids
->get(id
) != NULL
)) {
756 LocaleUtility::initLocaleFromName(id
, loc
);
757 return _delegate
->getDisplayName(loc
, locale
, result
);
764 URegistryKey U_EXPORT2
765 Collator::registerFactory(CollatorFactory
* toAdopt
, UErrorCode
& status
)
767 if (U_SUCCESS(status
)) {
768 CFactory
* f
= new CFactory(toAdopt
, status
);
770 return getService()->registerFactory(f
, status
);
772 status
= U_MEMORY_ALLOCATION_ERROR
;
777 // -------------------------------------
780 Collator::unregister(URegistryKey key
, UErrorCode
& status
)
782 if (U_SUCCESS(status
)) {
784 return gService
->unregister(key
, status
);
786 status
= U_ILLEGAL_ARGUMENT_ERROR
;
790 #endif /* UCONFIG_NO_SERVICE */
792 class CollationLocaleListEnumeration
: public StringEnumeration
{
796 static UClassID U_EXPORT2
getStaticClassID(void);
797 virtual UClassID
getDynamicClassID(void) const;
799 CollationLocaleListEnumeration()
802 // The global variables should already be initialized.
803 //isAvailableLocaleListInitialized(status);
806 virtual ~CollationLocaleListEnumeration();
808 virtual StringEnumeration
* clone() const
810 CollationLocaleListEnumeration
*result
= new CollationLocaleListEnumeration();
812 result
->index
= index
;
817 virtual int32_t count(UErrorCode
&/*status*/) const {
818 return availableLocaleListCount
;
821 virtual const char* next(int32_t* resultLength
, UErrorCode
& /*status*/) {
823 if(index
< availableLocaleListCount
) {
824 result
= availableLocaleList
[index
++].getName();
825 if(resultLength
!= NULL
) {
826 *resultLength
= (int32_t)uprv_strlen(result
);
829 if(resultLength
!= NULL
) {
837 virtual const UnicodeString
* snext(UErrorCode
& status
) {
838 int32_t resultLength
= 0;
839 const char *s
= next(&resultLength
, status
);
840 return setChars(s
, resultLength
, status
);
843 virtual void reset(UErrorCode
& /*status*/) {
848 CollationLocaleListEnumeration::~CollationLocaleListEnumeration() {}
850 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CollationLocaleListEnumeration
)
853 // -------------------------------------
855 StringEnumeration
* U_EXPORT2
856 Collator::getAvailableLocales(void)
858 #if !UCONFIG_NO_SERVICE
860 return getService()->getAvailableLocales();
862 #endif /* UCONFIG_NO_SERVICE */
863 UErrorCode status
= U_ZERO_ERROR
;
864 if (isAvailableLocaleListInitialized(status
)) {
865 return new CollationLocaleListEnumeration();
870 StringEnumeration
* U_EXPORT2
871 Collator::getKeywords(UErrorCode
& status
) {
872 return UStringEnumeration::fromUEnumeration(
873 ucol_getKeywords(&status
), status
);
876 StringEnumeration
* U_EXPORT2
877 Collator::getKeywordValues(const char *keyword
, UErrorCode
& status
) {
878 return UStringEnumeration::fromUEnumeration(
879 ucol_getKeywordValues(keyword
, &status
), status
);
882 StringEnumeration
* U_EXPORT2
883 Collator::getKeywordValuesForLocale(const char* key
, const Locale
& locale
,
884 UBool commonlyUsed
, UErrorCode
& status
) {
885 return UStringEnumeration::fromUEnumeration(
886 ucol_getKeywordValuesForLocale(
887 key
, locale
.getName(), commonlyUsed
, &status
),
892 Collator::getFunctionalEquivalent(const char* keyword
, const Locale
& locale
,
893 UBool
& isAvailable
, UErrorCode
& status
) {
894 // This is a wrapper over ucol_getFunctionalEquivalent
895 char loc
[ULOC_FULLNAME_CAPACITY
];
896 /*int32_t len =*/ ucol_getFunctionalEquivalent(loc
, sizeof(loc
),
897 keyword
, locale
.getName(), &isAvailable
, &status
);
898 if (U_FAILURE(status
)) {
901 return Locale::createFromName(loc
);
904 Collator::ECollationStrength
905 Collator::getStrength(void) const {
906 UErrorCode intStatus
= U_ZERO_ERROR
;
907 return (ECollationStrength
)getAttribute(UCOL_STRENGTH
, intStatus
);
911 Collator::setStrength(ECollationStrength newStrength
) {
912 UErrorCode intStatus
= U_ZERO_ERROR
;
913 setAttribute(UCOL_STRENGTH
, (UColAttributeValue
)newStrength
, intStatus
);
917 Collator::setMaxVariable(UColReorderCode
/*group*/, UErrorCode
&errorCode
) {
918 if (U_SUCCESS(errorCode
)) {
919 errorCode
= U_UNSUPPORTED_ERROR
;
925 Collator::getMaxVariable() const {
926 return UCOL_REORDER_CODE_PUNCTUATION
;
930 Collator::getReorderCodes(int32_t* /* dest*/,
931 int32_t /* destCapacity*/,
932 UErrorCode
& status
) const
934 if (U_SUCCESS(status
)) {
935 status
= U_UNSUPPORTED_ERROR
;
941 Collator::setReorderCodes(const int32_t* /* reorderCodes */,
942 int32_t /* reorderCodesLength */,
945 if (U_SUCCESS(status
)) {
946 status
= U_UNSUPPORTED_ERROR
;
951 Collator::getEquivalentReorderCodes(int32_t reorderCode
,
952 int32_t *dest
, int32_t capacity
,
953 UErrorCode
&errorCode
) {
954 if(U_FAILURE(errorCode
)) { return 0; }
955 if(capacity
< 0 || (dest
== NULL
&& capacity
> 0)) {
956 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
959 const CollationData
*baseData
= CollationRoot::getData(errorCode
);
960 if(U_FAILURE(errorCode
)) { return 0; }
961 return baseData
->getEquivalentScripts(reorderCode
, dest
, capacity
, errorCode
);
965 Collator::internalGetShortDefinitionString(const char * /*locale*/,
967 int32_t /*capacity*/,
968 UErrorCode
&status
) const {
969 if(U_SUCCESS(status
)) {
970 status
= U_UNSUPPORTED_ERROR
; /* Shouldn't happen, internal function */
976 Collator::internalCompareUTF8(const char *left
, int32_t leftLength
,
977 const char *right
, int32_t rightLength
,
978 UErrorCode
&errorCode
) const {
979 if(U_FAILURE(errorCode
)) { return UCOL_EQUAL
; }
980 if((left
== NULL
&& leftLength
!= 0) || (right
== NULL
&& rightLength
!= 0)) {
981 errorCode
= U_ILLEGAL_ARGUMENT_ERROR
;
985 StringPiece(left
, (leftLength
< 0) ? uprv_strlen(left
) : leftLength
),
986 StringPiece(right
, (rightLength
< 0) ? uprv_strlen(right
) : rightLength
),
991 Collator::internalNextSortKeyPart(UCharIterator
* /*iter*/, uint32_t /*state*/[2],
992 uint8_t * /*dest*/, int32_t /*count*/, UErrorCode
&errorCode
) const {
993 if (U_SUCCESS(errorCode
)) {
994 errorCode
= U_UNSUPPORTED_ERROR
;
999 // UCollator private data members ----------------------------------------
1001 /* This is useless information */
1002 /*const UVersionInfo Collator::fVersion = {1, 1, 0, 0};*/
1004 // -------------------------------------
1008 #endif /* #if !UCONFIG_NO_COLLATION */