diff --git a/icu4c/source/i18n/tblcoll.cpp b/icu4c/source/i18n/tblcoll.cpp index 08f7858cc4b..2ee507e57cc 100644 --- a/icu4c/source/i18n/tblcoll.cpp +++ b/icu4c/source/i18n/tblcoll.cpp @@ -482,6 +482,18 @@ int32_t RuleBasedCollator::hashCode() const return uhash_hashUCharsN(rules, length); } +/** +* return the locale of this collator +*/ +const Locale RuleBasedCollator::getLocale(UErrorCode &status) const { + const char *result = ucol_getLocale(ucollator, &status); + if(result == NULL) { + return Locale(""); + } else { + return Locale(result); + } +} + /** * Set the decomposition mode of the Collator object. * @param the new decomposition mode diff --git a/icu4c/source/i18n/ucol.cpp b/icu4c/source/i18n/ucol.cpp index b47c41233f3..6e3d77ca34c 100644 --- a/icu4c/source/i18n/ucol.cpp +++ b/icu4c/source/i18n/ucol.cpp @@ -23,6 +23,7 @@ #include "bocsu.h" #include "unormimp.h" +#include "uresimp.h" #include "cstring.h" #include "umutex.h" #include "uhash.h" @@ -280,7 +281,13 @@ ucol_open( const char *loc, if(*status == U_MISSING_RESOURCE_ERROR) { /* if we don't find tailoring, we'll fallback to UCA */ *status = U_USING_DEFAULT_ERROR; result = ucol_initCollator(UCA->image, result, status); - /*result = UCA;*/ + // if we use UCA, real locale is root + result->rb = ures_open(NULL, "", status); + if(U_FAILURE(*status)) { + goto clean; + } + ures_close(binary); + ures_close(b); result->hasRealData = FALSE; } else if(U_SUCCESS(*status)) { /* otherwise, we'll pick a collation data that exists */ int32_t len = 0; @@ -302,16 +309,25 @@ ucol_open( const char *loc, } result->hasRealData = FALSE; } + const char *realCollationDataLocale = ures_getLocale(binary, status); + ures_close(binary); + // if the real data came from the fallback, we want to drag around + // the real resource bundle + if(uprv_strcmp(ures_getLocale(b, status), realCollationDataLocale) != NULL) { + result->rb = ures_open(NULL, realCollationDataLocale, status); + if(U_FAILURE(*status)) { + goto clean; + } + ures_close(b); + } else { // otherwise, we'll keep the initial RB around + result->rb = b; + } } else { /* There is another error, and we're just gonna clean up */ clean: ures_close(b); ures_close(binary); return NULL; } - - result->rb = b; - ures_close(binary); - return result; } @@ -5640,3 +5656,16 @@ ucol_equal( const UCollator *coll, == UCOL_EQUAL); } +/* returns the locale name the collation data comes from */ +U_CAPI const char * U_EXPORT2 +ucol_getLocale(const UCollator *coll, UErrorCode *status) { + if(status == NULL || U_FAILURE(*status)) { + return NULL; + } + if(coll->rb != NULL) { + return ures_getLocale(coll->rb, status); + } else { + return NULL; + } +} + diff --git a/icu4c/source/i18n/unicode/coll.h b/icu4c/source/i18n/unicode/coll.h index 923f4ee1dfb..033c70fe5b2 100644 --- a/icu4c/source/i18n/unicode/coll.h +++ b/icu4c/source/i18n/unicode/coll.h @@ -399,6 +399,12 @@ public: */ virtual int32_t hashCode(void) const = 0; + /** + * Gets the locale of the Collator + * @draft ICU 2.1 + */ + virtual const Locale getLocale(UErrorCode& status) const = 0; + /** * Convenience method for comparing two strings based on the collation rules. * @param source the source string to be compared with. diff --git a/icu4c/source/i18n/unicode/tblcoll.h b/icu4c/source/i18n/unicode/tblcoll.h index bf7f148685e..dfe0c8fc3a0 100644 --- a/icu4c/source/i18n/unicode/tblcoll.h +++ b/icu4c/source/i18n/unicode/tblcoll.h @@ -335,6 +335,14 @@ public: */ virtual int32_t hashCode(void) const; + /** + * Gets the locale of the Collator + * @return locale where the collation data lives. If the collator + * was instantiated from rules, locale is empty. + * @draft ICU 2.1 + */ + virtual const Locale getLocale(UErrorCode& status) const; + /** * Gets the table-based rules for the collation object. * @return returns the collation rules that the table collation object was diff --git a/icu4c/source/i18n/unicode/ucol.h b/icu4c/source/i18n/unicode/ucol.h index 08d6cce2aa0..e3e9601d5d2 100644 --- a/icu4c/source/i18n/unicode/ucol.h +++ b/icu4c/source/i18n/unicode/ucol.h @@ -743,6 +743,19 @@ U_CAPI void U_EXPORT2 ucol_setNormalization( UCollator *coll, UNormalizationMode mode); +/** + * gets the locale name of the collator. If the collator + * is instantiated from the rules, then this function returns + * NULL. + * @param coll The UCollator for which the locale is needed + * @param status error code of the operation + * @return real locale name from which the collation data comes. + * If the collator was instantiated from rules, returns + * NULL. + */ +U_CAPI const char * U_EXPORT2 +ucol_getLocale(const UCollator *coll, UErrorCode *status); + /** *@deprecated Remove after Aug 2002 */