• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "NativePluralRules"
18 
19 #include "IcuUtilities.h"
20 #include "JNIHelp.h"
21 #include "JniConstants.h"
22 #include "JniException.h"
23 #include "ScopedUtfChars.h"
24 #include "unicode/plurrule.h"
25 
26 #include <string>
27 
toPluralRules(jlong address)28 static icu::PluralRules* toPluralRules(jlong address) {
29     return reinterpret_cast<icu::PluralRules*>(static_cast<uintptr_t>(address));
30 }
31 
NativePluralRules_finalizeImpl(JNIEnv *,jclass,jlong address)32 static void NativePluralRules_finalizeImpl(JNIEnv*, jclass, jlong address) {
33     delete toPluralRules(address);
34 }
35 
NativePluralRules_forLocaleImpl(JNIEnv * env,jclass,jstring javaLocaleName)36 static jlong NativePluralRules_forLocaleImpl(JNIEnv* env, jclass, jstring javaLocaleName) {
37     // The icu4c PluralRules returns a "other: n" default rule for the deprecated locales Java uses.
38     // Work around this by translating back to the current language codes.
39     std::string localeName(ScopedUtfChars(env, javaLocaleName).c_str());
40     if (localeName[0] == 'i' && localeName[1] == 'w') {
41         localeName[0] = 'h';
42         localeName[1] = 'e';
43     } else if (localeName[0] == 'i' && localeName[1] == 'n') {
44         localeName[0] = 'i';
45         localeName[1] = 'd';
46     } else if (localeName[0] == 'j' && localeName[1] == 'i') {
47         localeName[0] = 'y';
48         localeName[1] = 'i';
49     }
50 
51     icu::Locale locale = icu::Locale::createFromName(localeName.c_str());
52     UErrorCode status = U_ZERO_ERROR;
53     icu::PluralRules* result = icu::PluralRules::forLocale(locale, status);
54     maybeThrowIcuException(env, "PluralRules::forLocale", status);
55     return reinterpret_cast<uintptr_t>(result);
56 }
57 
NativePluralRules_quantityForIntImpl(JNIEnv *,jclass,jlong address,jint value)58 static jint NativePluralRules_quantityForIntImpl(JNIEnv*, jclass, jlong address, jint value) {
59     icu::UnicodeString keyword = toPluralRules(address)->select(value);
60     if (keyword == "zero") {
61         return 0;
62     } else if (keyword == "one") {
63         return 1;
64     } else if (keyword == "two") {
65         return 2;
66     } else if (keyword == "few") {
67         return 3;
68     } else if (keyword == "many") {
69         return 4;
70     } else {
71         return 5;
72     }
73 }
74 
75 static JNINativeMethod gMethods[] = {
76     NATIVE_METHOD(NativePluralRules, finalizeImpl, "(J)V"),
77     NATIVE_METHOD(NativePluralRules, forLocaleImpl, "(Ljava/lang/String;)J"),
78     NATIVE_METHOD(NativePluralRules, quantityForIntImpl, "(JI)I"),
79 };
register_libcore_icu_NativePluralRules(JNIEnv * env)80 void register_libcore_icu_NativePluralRules(JNIEnv* env) {
81     jniRegisterNativeMethods(env, "libcore/icu/NativePluralRules", gMethods, NELEM(gMethods));
82 }
83