]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/plurrule.cpp
ICU-511.25.tar.gz
[apple/icu.git] / icuSources / i18n / plurrule.cpp
index ba9b9bd4488e66ba7b30c1f2adde9d2246b27a9d..2ceb511f488da2204514c3c34b9c21c6e9cb82c0 100644 (file)
@@ -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<numberKeys; ++i) {
         int32_t keyLen;
         resLen=0;
-        s=ures_getNextString(setRes, &resLen, (const char**)&key, &errCode);
+        s=ures_getNextString(setRes.getAlias(), &resLen, (const char**)&key, &errCode);
         keyLen = (int32_t)uprv_strlen(key);
         u_charsToUChars(key, result+len, keyLen);
         len += keyLen;
@@ -745,10 +752,6 @@ PluralRules::getRuleFromResource(const Locale& locale, UErrorCode& errCode) {
     u_UCharsToChars(result, setKey, len);
     // printf(" Rule: %s\n", setKey);
 
-    ures_close(setRes);
-    ures_close(ruleRes);
-    ures_close(locRes);
-    ures_close(rb);
     return UnicodeString(result);
 }
 
@@ -1288,7 +1291,6 @@ RuleParser::getNextToken(const UnicodeString& ruleData,
                     return;
                  }
              }
-             break;
          default:
              status = U_UNEXPECTED_TOKEN;
              return;