X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/4388f060552cc537e71e957d32f35e9d75a61233..51004dcb01e06fef634b61be77ed73dd61cb6db9:/icuSources/i18n/plurrule.cpp diff --git a/icuSources/i18n/plurrule.cpp b/icuSources/i18n/plurrule.cpp index ba9b9bd4..2ceb511f 100644 --- a/icuSources/i18n/plurrule.cpp +++ b/icuSources/i18n/plurrule.cpp @@ -1,21 +1,16 @@ /* ******************************************************************************* -* Copyright (C) 2007-2011, International Business Machines Corporation and +* Copyright (C) 2007-2012, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * -* File PLURRULE.CPP -* -* Modification History: -* -* Date Name Description -******************************************************************************* +* File plurrule.cpp */ - #include "unicode/utypes.h" #include "unicode/localpointer.h" #include "unicode/plurrule.h" +#include "unicode/upluralrules.h" #include "unicode/ures.h" #include "cmemory.h" #include "cstring.h" @@ -34,7 +29,7 @@ U_NAMESPACE_BEGIN // shared by all instances when lazy-initializing samples -static UMTX pluralMutex; +static UMutex pluralMutex = U_MUTEX_INITIALIZER; #define ARRAY_SIZE(array) (int32_t)(sizeof array / sizeof array[0]) @@ -146,16 +141,25 @@ PluralRules::createDefaultRules(UErrorCode& status) { PluralRules* U_EXPORT2 PluralRules::forLocale(const Locale& locale, UErrorCode& status) { + return forLocale(locale, UPLURAL_TYPE_CARDINAL, status); +} + +PluralRules* U_EXPORT2 +PluralRules::forLocale(const Locale& locale, UPluralType type, UErrorCode& status) { RuleChain rChain; if (U_FAILURE(status)) { return NULL; } + if (type >= UPLURAL_TYPE_COUNT) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return NULL; + } PluralRules *newObj = new PluralRules(status); if (newObj==NULL || U_FAILURE(status)) { delete newObj; return NULL; } - UnicodeString locRule = newObj->getRuleFromResource(locale, status); + UnicodeString locRule = newObj->getRuleFromResource(locale, type, status); if ((locRule.length() != 0) && U_SUCCESS(status)) { newObj->parseDescription(locRule, rChain, status); if (U_SUCCESS(status)) { @@ -660,38 +664,48 @@ PluralRules::addRules(RuleChain& rules) { } UnicodeString -PluralRules::getRuleFromResource(const Locale& locale, UErrorCode& errCode) { +PluralRules::getRuleFromResource(const Locale& locale, UPluralType type, UErrorCode& errCode) { UnicodeString emptyStr; if (U_FAILURE(errCode)) { return emptyStr; } - UResourceBundle *rb=ures_openDirect(NULL, "plurals", &errCode); + LocalUResourceBundlePointer rb(ures_openDirect(NULL, "plurals", &errCode)); if(U_FAILURE(errCode)) { - /* total failure, not even root could be opened */ return emptyStr; } - UResourceBundle *locRes=ures_getByKey(rb, "locales", NULL, &errCode); + const char *typeKey; + switch (type) { + case UPLURAL_TYPE_CARDINAL: + typeKey = "locales"; + break; + case UPLURAL_TYPE_ORDINAL: + typeKey = "locales_ordinals"; + break; + default: + // Must not occur: The caller should have checked for valid types. + errCode = U_ILLEGAL_ARGUMENT_ERROR; + return emptyStr; + } + LocalUResourceBundlePointer locRes(ures_getByKey(rb.getAlias(), typeKey, NULL, &errCode)); if(U_FAILURE(errCode)) { - ures_close(rb); return emptyStr; } int32_t resLen=0; const char *curLocaleName=locale.getName(); - const UChar* s = ures_getStringByKey(locRes, curLocaleName, &resLen, &errCode); + const UChar* s = ures_getStringByKey(locRes.getAlias(), curLocaleName, &resLen, &errCode); if (s == NULL) { // Check parent locales. UErrorCode status = U_ZERO_ERROR; char parentLocaleName[ULOC_FULLNAME_CAPACITY]; const char *curLocaleName=locale.getName(); - int32_t localeNameLen=0; uprv_strcpy(parentLocaleName, curLocaleName); - while ((localeNameLen=uloc_getParent(parentLocaleName, parentLocaleName, - ULOC_FULLNAME_CAPACITY, &status)) > 0) { + while (uloc_getParent(parentLocaleName, parentLocaleName, + ULOC_FULLNAME_CAPACITY, &status) > 0) { resLen=0; - s = ures_getStringByKey(locRes, parentLocaleName, &resLen, &status); + s = ures_getStringByKey(locRes.getAlias(), parentLocaleName, &resLen, &status); if (s != NULL) { errCode = U_ZERO_ERROR; break; @@ -700,8 +714,6 @@ PluralRules::getRuleFromResource(const Locale& locale, UErrorCode& errCode) { } } if (s==NULL) { - ures_close(locRes); - ures_close(rb); return emptyStr; } @@ -711,28 +723,23 @@ PluralRules::getRuleFromResource(const Locale& locale, UErrorCode& errCode) { // printf("\n PluralRule: %s\n", setKey); - UResourceBundle *ruleRes=ures_getByKey(rb, "rules", NULL, &errCode); + LocalUResourceBundlePointer ruleRes(ures_getByKey(rb.getAlias(), "rules", NULL, &errCode)); if(U_FAILURE(errCode)) { - ures_close(locRes); - ures_close(rb); return emptyStr; } resLen=0; - UResourceBundle *setRes = ures_getByKey(ruleRes, setKey, NULL, &errCode); + LocalUResourceBundlePointer setRes(ures_getByKey(ruleRes.getAlias(), setKey, NULL, &errCode)); if (U_FAILURE(errCode)) { - ures_close(ruleRes); - ures_close(locRes); - ures_close(rb); return emptyStr; } - int32_t numberKeys = ures_getSize(setRes); + int32_t numberKeys = ures_getSize(setRes.getAlias()); char *key=NULL; int32_t len=0; for(int32_t i=0; i