libcore_icu_ICU.cpp revision e2377cdd707b830d07a5708216834f7ac76ee3e1
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License. 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17757a7942eed2b0aa457f8517a0259d2ac82c5b18Elliott Hughes#define LOG_TAG "ICU" 18c08f9fb2a3be82bb1a3f477ca1524ddcf7a1d4b8Elliott Hughes 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "JNIHelp.h" 20a9f5c16a864ff63ba63f810410f8a27c086d5d52Elliott Hughes#include "JniConstants.h" 21bef9ec33e1368f57c731fce63b6a8c61628c64b0Elliott Hughes#include "JniException.h" 22566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes#include "ScopedFd.h" 234e3714f7fe8ac7f6b20896038e491d378f4e6464Elliott Hughes#include "ScopedJavaUnicodeString.h" 24f281667712baf8e0721ceb2cc60e7eef19c2d859Elliott Hughes#include "ScopedLocalRef.h" 2552b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes#include "ScopedStringChars.h" 269de899cc3ffd3aa3f8f827201cbe14120609018bElliott Hughes#include "ScopedUtfChars.h" 27757a7942eed2b0aa457f8517a0259d2ac82c5b18Elliott Hughes#include "UniquePtr.h" 28f2d5062b67e57ef00ee81fec67480f0d58d66b50Elliott Hughes#include "cutils/log.h" 29ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes#include "toStringArray.h" 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "unicode/calendar.h" 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "unicode/datefmt.h" 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "unicode/dcfmtsym.h" 3394782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/decimfmt.h" 3494782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/dtfmtsym.h" 3594782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/gregocal.h" 3694782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/locid.h" 3794782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/numfmt.h" 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "unicode/strenum.h" 3994782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/ubrk.h" 4094782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/ucal.h" 4194782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/uclean.h" 4294782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/ucol.h" 4394782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/ucurr.h" 4494782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/udat.h" 4594782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "unicode/ustring.h" 46947eeb80f985827209c9500851e288504d58ec2eclaireho#include "ureslocs.h" 4794782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes#include "valueOf.h" 48ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes 49566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes#include <errno.h> 50566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes#include <fcntl.h> 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include <stdlib.h> 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include <string.h> 53ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes#include <string> 54566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes#include <sys/mman.h> 55566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes#include <sys/stat.h> 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include <sys/time.h> 57566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes#include <sys/types.h> 58566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes#include <time.h> 59566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes#include <unistd.h> 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6170fa193185427473999f1cda823c1ec408acd2baElliott Hughesclass ScopedResourceBundle { 6270fa193185427473999f1cda823c1ec408acd2baElliott Hughespublic: 6370fa193185427473999f1cda823c1ec408acd2baElliott Hughes ScopedResourceBundle(UResourceBundle* bundle) : mBundle(bundle) { 6470fa193185427473999f1cda823c1ec408acd2baElliott Hughes } 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6670fa193185427473999f1cda823c1ec408acd2baElliott Hughes ~ScopedResourceBundle() { 6770fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (mBundle != NULL) { 6870fa193185427473999f1cda823c1ec408acd2baElliott Hughes ures_close(mBundle); 6970fa193185427473999f1cda823c1ec408acd2baElliott Hughes } 7070fa193185427473999f1cda823c1ec408acd2baElliott Hughes } 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7270fa193185427473999f1cda823c1ec408acd2baElliott Hughes UResourceBundle* get() { 7370fa193185427473999f1cda823c1ec408acd2baElliott Hughes return mBundle; 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 7570fa193185427473999f1cda823c1ec408acd2baElliott Hughes 7670fa193185427473999f1cda823c1ec408acd2baElliott Hughesprivate: 7770fa193185427473999f1cda823c1ec408acd2baElliott Hughes UResourceBundle* mBundle; 787ca6fd0dca02f7abdd8808db78357743bbdd23a5Elliott Hughes 797ca6fd0dca02f7abdd8808db78357743bbdd23a5Elliott Hughes // Disallow copy and assignment. 807ca6fd0dca02f7abdd8808db78357743bbdd23a5Elliott Hughes ScopedResourceBundle(const ScopedResourceBundle&); 817ca6fd0dca02f7abdd8808db78357743bbdd23a5Elliott Hughes void operator=(const ScopedResourceBundle&); 8270fa193185427473999f1cda823c1ec408acd2baElliott Hughes}; 8370fa193185427473999f1cda823c1ec408acd2baElliott Hughes 8421557bb6a8f35a2f9889adba449cac950c9d41b9Elliott HughesLocale getLocale(JNIEnv* env, jstring localeName) { 850808cae1a2616ba9c708c7cc4489723b4060178eElliott Hughes return Locale::createFromName(ScopedUtfChars(env, localeName).c_str()); 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 8852b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughesstatic jint ICU_getCurrencyFractionDigits(JNIEnv* env, jclass, jstring javaCurrencyCode) { 894e3714f7fe8ac7f6b20896038e491d378f4e6464Elliott Hughes ScopedJavaUnicodeString currencyCode(env, javaCurrencyCode); 9052b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes UnicodeString icuCurrencyCode(currencyCode.unicodeString()); 9152b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes UErrorCode status = U_ZERO_ERROR; 9252b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes return ucurr_getDefaultFractionDigits(icuCurrencyCode.getTerminatedBuffer(), &status); 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 9552b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughesstatic jstring ICU_getCurrencyCode(JNIEnv* env, jclass, jstring javaCountryCode) { 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project UErrorCode status = U_ZERO_ERROR; 97947eeb80f985827209c9500851e288504d58ec2eclaireho ScopedResourceBundle supplData(ures_openDirect(U_ICUDATA_CURR, "supplementalData", &status)); 9870fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10270fa193185427473999f1cda823c1ec408acd2baElliott Hughes ScopedResourceBundle currencyMap(ures_getByKey(supplData.get(), "CurrencyMap", NULL, &status)); 10370fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10752b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes ScopedUtfChars countryCode(env, javaCountryCode); 10852b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes ScopedResourceBundle currency(ures_getByKey(currencyMap.get(), countryCode.c_str(), NULL, &status)); 10970fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 11370fa193185427473999f1cda823c1ec408acd2baElliott Hughes ScopedResourceBundle currencyElem(ures_getByIndex(currency.get(), 0, NULL, &status)); 11470fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return env->NewStringUTF("None"); 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 11852b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes // Check if there's a 'to' date. If there is, the currency isn't used anymore. 11967081ff5bcb8a2b3f7db2940f6e0cb3e459ab4b4Elliott Hughes ScopedResourceBundle currencyTo(ures_getByKey(currencyElem.get(), "to", NULL, &status)); 12067081ff5bcb8a2b3f7db2940f6e0cb3e459ab4b4Elliott Hughes if (!U_FAILURE(status)) { 12167081ff5bcb8a2b3f7db2940f6e0cb3e459ab4b4Elliott Hughes return NULL; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 12352b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes // Ignore the failure to find a 'to' date. 12467081ff5bcb8a2b3f7db2940f6e0cb3e459ab4b4Elliott Hughes status = U_ZERO_ERROR; 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 12670fa193185427473999f1cda823c1ec408acd2baElliott Hughes ScopedResourceBundle currencyId(ures_getByKey(currencyElem.get(), "id", NULL, &status)); 12770fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // No id defined for this country 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return env->NewStringUTF("None"); 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 13252b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes int32_t charCount; 13352b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes const jchar* chars = ures_getString(currencyId.get(), &charCount, &status); 13452b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes return (charCount == 0) ? env->NewStringUTF("None") : env->NewString(chars, charCount); 13552b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes} 13652b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes 13752b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughesstatic jstring ICU_getCurrencyDisplayName(JNIEnv* env, jclass, jstring javaLocaleName, jstring javaCurrencyCode) { 13852b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes ScopedUtfChars localeName(env, javaLocaleName); 13952b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes ScopedJavaUnicodeString currencyCode(env, javaCurrencyCode); 14052b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes UnicodeString icuCurrencyCode(currencyCode.unicodeString()); 14152b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes UErrorCode status = U_ZERO_ERROR; 14252b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes UBool isChoiceFormat; 14352b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes int32_t charCount; 14452b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes const UChar* chars = ucurr_getName(icuCurrencyCode.getTerminatedBuffer(), localeName.c_str(), 14552b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes UCURR_LONG_NAME, &isChoiceFormat, &charCount, &status); 14652b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes if (status == U_USING_DEFAULT_WARNING) { 14752b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes // ICU's default is English. We want the ISO 4217 currency code instead. 14852b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes chars = icuCurrencyCode.getBuffer(); 14952b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes charCount = icuCurrencyCode.length(); 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 15152b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes return (charCount == 0) ? NULL : env->NewString(chars, charCount); 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 15452b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughesstatic jstring ICU_getCurrencySymbol(JNIEnv* env, jclass, jstring locale, jstring currencyCode) { 15552b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes // We can't use ucurr_getName because it doesn't distinguish between using data root from 15652b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes // the root locale and parroting back the input because it's never heard of the currency code. 15705960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes ScopedUtfChars localeName(env, locale); 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project UErrorCode status = U_ZERO_ERROR; 159947eeb80f985827209c9500851e288504d58ec2eclaireho ScopedResourceBundle currLoc(ures_open(U_ICUDATA_CURR, localeName.c_str(), &status)); 16070fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 164947eeb80f985827209c9500851e288504d58ec2eclaireho ScopedResourceBundle currencies(ures_getByKey(currLoc.get(), "Currencies", NULL, &status)); 16570fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 16905960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes ScopedUtfChars currency(env, currencyCode); 17005960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes ScopedResourceBundle currencyElems(ures_getByKey(currencies.get(), currency.c_str(), NULL, &status)); 17170fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17552b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes int32_t charCount; 17652b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes const jchar* chars = ures_getStringByIndex(currencyElems.get(), 0, &charCount, &status); 17770fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 18052b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes return (charCount == 0) ? NULL : env->NewString(chars, charCount); 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 183e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jstring ICU_getDisplayCountryNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) { 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Locale loc = getLocale(env, locale); 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Locale targetLoc = getLocale(env, targetLocale); 18670fa193185427473999f1cda823c1ec408acd2baElliott Hughes UnicodeString str; 18770fa193185427473999f1cda823c1ec408acd2baElliott Hughes targetLoc.getDisplayCountry(loc, str); 18870fa193185427473999f1cda823c1ec408acd2baElliott Hughes return env->NewString(str.getBuffer(), str.length()); 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 191e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jstring ICU_getDisplayLanguageNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) { 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Locale loc = getLocale(env, locale); 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Locale targetLoc = getLocale(env, targetLocale); 19470fa193185427473999f1cda823c1ec408acd2baElliott Hughes UnicodeString str; 19570fa193185427473999f1cda823c1ec408acd2baElliott Hughes targetLoc.getDisplayLanguage(loc, str); 19670fa193185427473999f1cda823c1ec408acd2baElliott Hughes return env->NewString(str.getBuffer(), str.length()); 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 199e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jstring ICU_getDisplayVariantNative(JNIEnv* env, jclass, jstring targetLocale, jstring locale) { 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Locale loc = getLocale(env, locale); 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Locale targetLoc = getLocale(env, targetLocale); 20270fa193185427473999f1cda823c1ec408acd2baElliott Hughes UnicodeString str; 20370fa193185427473999f1cda823c1ec408acd2baElliott Hughes targetLoc.getDisplayVariant(loc, str); 20470fa193185427473999f1cda823c1ec408acd2baElliott Hughes return env->NewString(str.getBuffer(), str.length()); 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 207e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jstring ICU_getISO3CountryNative(JNIEnv* env, jclass, jstring locale) { 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Locale loc = getLocale(env, locale); 2092e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes return env->NewStringUTF(loc.getISO3Country()); 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 212e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jstring ICU_getISO3LanguageNative(JNIEnv* env, jclass, jstring locale) { 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Locale loc = getLocale(env, locale); 2142e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes return env->NewStringUTF(loc.getISO3Language()); 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 217e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jobjectArray ICU_getISOCountriesNative(JNIEnv* env, jclass) { 2182e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes return toStringArray(env, Locale::getISOCountries()); 2192e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes} 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 221e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jobjectArray ICU_getISOLanguagesNative(JNIEnv* env, jclass) { 2222e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes return toStringArray(env, Locale::getISOLanguages()); 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 225e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jobjectArray ICU_getAvailableLocalesNative(JNIEnv* env, jclass) { 226ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return toStringArray(env, uloc_countAvailable, uloc_getAvailable); 227f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes} 228f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes 229e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jobjectArray ICU_getAvailableBreakIteratorLocalesNative(JNIEnv* env, jclass) { 230ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return toStringArray(env, ubrk_countAvailable, ubrk_getAvailable); 231f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes} 232f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes 233e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jobjectArray ICU_getAvailableCalendarLocalesNative(JNIEnv* env, jclass) { 234ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return toStringArray(env, ucal_countAvailable, ucal_getAvailable); 235f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes} 236f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes 237e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jobjectArray ICU_getAvailableCollatorLocalesNative(JNIEnv* env, jclass) { 238ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return toStringArray(env, ucol_countAvailable, ucol_getAvailable); 239f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes} 240f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes 241e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jobjectArray ICU_getAvailableDateFormatLocalesNative(JNIEnv* env, jclass) { 242ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return toStringArray(env, udat_countAvailable, udat_getAvailable); 243f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes} 244f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes 245e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jobjectArray ICU_getAvailableNumberFormatLocalesNative(JNIEnv* env, jclass) { 246ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return toStringArray(env, unum_countAvailable, unum_getAvailable); 247f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes} 248f9157eaea53923d3dbe6a521b29427819052f176Elliott Hughes 24944e0e560c92338110953ce806df475fedcdf926eBrian Carlstromstatic bool getDayIntVector(JNIEnv*, UResourceBundle* gregorian, int* values) { 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // get the First day of week and the minimal days in first week numbers 2512e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes UErrorCode status = U_ZERO_ERROR; 25270fa193185427473999f1cda823c1ec408acd2baElliott Hughes ScopedResourceBundle gregorianElems(ures_getByKey(gregorian, "DateTimeElements", NULL, &status)); 2532e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes if (U_FAILURE(status)) { 25433aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes return false; 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int intVectSize; 25870fa193185427473999f1cda823c1ec408acd2baElliott Hughes const int* result = ures_getIntVector(gregorianElems.get(), &intVectSize, &status); 25970fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status) || intVectSize != 2) { 26033aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes return false; 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 26233aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes 26370fa193185427473999f1cda823c1ec408acd2baElliott Hughes values[0] = result[0]; 26470fa193185427473999f1cda823c1ec408acd2baElliott Hughes values[1] = result[1]; 26533aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes return true; 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 268ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes// This allows you to leave extra space at the beginning or end of the array to support the 269ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes// month names and day names arrays. 270ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughesstatic jobjectArray toStringArray(JNIEnv* env, UResourceBundle* rb, size_t size, int capacity, size_t offset) { 271ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes if (capacity == -1) { 272ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes capacity = size; 273ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes } 274ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes jobjectArray result = env->NewObjectArray(capacity, JniConstants::stringClass, NULL); 275ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes if (result == NULL) { 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 278ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes UErrorCode status = U_ZERO_ERROR; 279ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes for (size_t i = 0; i < size; ++i) { 280ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes int charCount; 281ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes const jchar* chars = ures_getStringByIndex(rb, i, &charCount, &status); 282ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes if (U_FAILURE(status)) { 283ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return NULL; 284ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes } 285ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes ScopedLocalRef<jstring> s(env, env->NewString(chars, charCount)); 286ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes if (env->ExceptionCheck()) { 287ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return NULL; 288ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes } 289ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes env->SetObjectArrayElement(result, offset + i, s.get()); 290ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes if (env->ExceptionCheck()) { 291ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return NULL; 292ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes } 293ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes } 294ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return result; 295ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes} 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 297ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughesstatic jobjectArray getAmPmMarkers(JNIEnv* env, UResourceBundle* gregorian) { 298ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes UErrorCode status = U_ZERO_ERROR; 299ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes ScopedResourceBundle amPmMarkers(ures_getByKey(gregorian, "AmPmMarkers", NULL, &status)); 3002e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes if (U_FAILURE(status)) { 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 303ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return toStringArray(env, amPmMarkers.get(), ures_getSize(amPmMarkers.get()), -1, 0); 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 30670fa193185427473999f1cda823c1ec408acd2baElliott Hughesstatic jobjectArray getEras(JNIEnv* env, UResourceBundle* gregorian) { 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project UErrorCode status = U_ZERO_ERROR; 308ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes ScopedResourceBundle eras(ures_getByKey(gregorian, "eras", NULL, &status)); 30970fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 312ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes ScopedResourceBundle abbreviatedEras(ures_getByKey(eras.get(), "abbreviated", NULL, &status)); 31370fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 316ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes return toStringArray(env, abbreviatedEras.get(), ures_getSize(abbreviatedEras.get()), -1, 0); 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 319143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughesenum NameType { REGULAR, STAND_ALONE }; 320143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughesenum NameWidth { LONG, SHORT }; 321143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughesstatic jobjectArray getNames(JNIEnv* env, UResourceBundle* namesBundle, bool months, NameType type, NameWidth width) { 322143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes const char* typeKey = (type == REGULAR) ? "format" : "stand-alone"; 323143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes const char* widthKey = (width == LONG) ? "wide" : "abbreviated"; 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project UErrorCode status = U_ZERO_ERROR; 325143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes ScopedResourceBundle formatBundle(ures_getByKey(namesBundle, typeKey, NULL, &status)); 326143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes ScopedResourceBundle valuesBundle(ures_getByKey(formatBundle.get(), widthKey, NULL, &status)); 32770fa193185427473999f1cda823c1ec408acd2baElliott Hughes if (U_FAILURE(status)) { 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return NULL; 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3308044bf6b446c93cd29c5753544246316f269064fElliott Hughes 331143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes // The months array has a trailing empty string. The days array has a leading empty string. 332143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes int count = ures_getSize(valuesBundle.get()); 333ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes int offset = months ? 0 : 1; 334ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes jobjectArray result = toStringArray(env, valuesBundle.get(), count, count + 1, offset); 335e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes ScopedLocalRef<jstring> emptyString(env, env->NewStringUTF("")); 336e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes env->SetObjectArrayElement(result, months ? count : 0, emptyString.get()); 337143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes return result; 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34033aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughesstatic void setIntegerField(JNIEnv* env, jobject obj, const char* fieldName, int value) { 34194782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes ScopedLocalRef<jobject> integerValue(env, integerValueOf(env, value)); 342a9f5c16a864ff63ba63f810410f8a27c086d5d52Elliott Hughes jfieldID fid = env->GetFieldID(JniConstants::localeDataClass, fieldName, "Ljava/lang/Integer;"); 34394782d07dd2d65b1a37fddca68eb9a9ac81ada4aElliott Hughes env->SetObjectField(obj, fid, integerValue.get()); 34433aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes} 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34633aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughesstatic void setStringField(JNIEnv* env, jobject obj, const char* fieldName, jstring value) { 347a9f5c16a864ff63ba63f810410f8a27c086d5d52Elliott Hughes jfieldID fid = env->GetFieldID(JniConstants::localeDataClass, fieldName, "Ljava/lang/String;"); 34833aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes env->SetObjectField(obj, fid, value); 349e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes env->DeleteLocalRef(value); 35033aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes} 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 35233aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughesstatic void setStringArrayField(JNIEnv* env, jobject obj, const char* fieldName, jobjectArray value) { 353a9f5c16a864ff63ba63f810410f8a27c086d5d52Elliott Hughes jfieldID fid = env->GetFieldID(JniConstants::localeDataClass, fieldName, "[Ljava/lang/String;"); 35433aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes env->SetObjectField(obj, fid, value); 35533aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes} 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 35733aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughesstatic void setStringField(JNIEnv* env, jobject obj, const char* fieldName, UResourceBundle* bundle, int index) { 35833aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes UErrorCode status = U_ZERO_ERROR; 35933aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes int charCount; 36033aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes const UChar* chars = ures_getStringByIndex(bundle, index, &charCount, &status); 36133aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes if (U_SUCCESS(status)) { 36233aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes setStringField(env, obj, fieldName, env->NewString(chars, charCount)); 36390aa512eb7b126deb8d752b7474c30d3f73507b2Elliott Hughes } else { 364b7e820b92c7345cdc0cd4fea50954289ae66eb67Elliott Hughes LOGE("Error setting String field %s from ICU resource: %s", fieldName, u_errorName(status)); 365b7e820b92c7345cdc0cd4fea50954289ae66eb67Elliott Hughes } 366b7e820b92c7345cdc0cd4fea50954289ae66eb67Elliott Hughes} 367b7e820b92c7345cdc0cd4fea50954289ae66eb67Elliott Hughes 3683be1277a4644a149c158f99febbab890fc7b708fclairehostatic bool setStringField(JNIEnv* env, jobject obj, const char* key, const char* fieldName, UResourceBundle* bundle) { 3693be1277a4644a149c158f99febbab890fc7b708fclaireho if (bundle == NULL) { 3703be1277a4644a149c158f99febbab890fc7b708fclaireho return false; 3713be1277a4644a149c158f99febbab890fc7b708fclaireho } 372b7e820b92c7345cdc0cd4fea50954289ae66eb67Elliott Hughes UErrorCode status = U_ZERO_ERROR; 373b7e820b92c7345cdc0cd4fea50954289ae66eb67Elliott Hughes int charCount; 3743be1277a4644a149c158f99febbab890fc7b708fclaireho const UChar* chars = ures_getStringByKey(bundle, key, &charCount, &status); 3753be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_SUCCESS(status)) { 3763be1277a4644a149c158f99febbab890fc7b708fclaireho setStringField(env, obj, fieldName, env->NewString(chars, charCount)); 3773be1277a4644a149c158f99febbab890fc7b708fclaireho return true; 3783be1277a4644a149c158f99febbab890fc7b708fclaireho } else { 3793be1277a4644a149c158f99febbab890fc7b708fclaireho // Missing item in current resource bundle but not an error. 3803be1277a4644a149c158f99febbab890fc7b708fclaireho return false; 3813be1277a4644a149c158f99febbab890fc7b708fclaireho } 3823be1277a4644a149c158f99febbab890fc7b708fclaireho} 3833be1277a4644a149c158f99febbab890fc7b708fclaireho 3843be1277a4644a149c158f99febbab890fc7b708fclairehostatic void setStringField(JNIEnv* env, jobject obj, const char* key, const char* fieldName, 3853be1277a4644a149c158f99febbab890fc7b708fclaireho UResourceBundle* bundle, UResourceBundle* fallbackBundle) { 3863be1277a4644a149c158f99febbab890fc7b708fclaireho if (!setStringField(env, obj, key, fieldName, bundle) && fallbackBundle != NULL) { 3873be1277a4644a149c158f99febbab890fc7b708fclaireho setStringField(env, obj, key, fieldName, fallbackBundle); 3883be1277a4644a149c158f99febbab890fc7b708fclaireho } 3893be1277a4644a149c158f99febbab890fc7b708fclaireho} 3903be1277a4644a149c158f99febbab890fc7b708fclaireho 3913be1277a4644a149c158f99febbab890fc7b708fclairehostatic bool setCharField(JNIEnv* env, jobject obj, const char* key, const char* fieldName, 3923be1277a4644a149c158f99febbab890fc7b708fclaireho UResourceBundle* bundle) { 3933be1277a4644a149c158f99febbab890fc7b708fclaireho if (bundle == NULL) { 3943be1277a4644a149c158f99febbab890fc7b708fclaireho return false; 3953be1277a4644a149c158f99febbab890fc7b708fclaireho } 3963be1277a4644a149c158f99febbab890fc7b708fclaireho UErrorCode status = U_ZERO_ERROR; 3973be1277a4644a149c158f99febbab890fc7b708fclaireho int charCount; 3983be1277a4644a149c158f99febbab890fc7b708fclaireho const UChar* chars = ures_getStringByKey(bundle, key, &charCount, &status); 399b7e820b92c7345cdc0cd4fea50954289ae66eb67Elliott Hughes if (U_SUCCESS(status)) { 400a9f5c16a864ff63ba63f810410f8a27c086d5d52Elliott Hughes jfieldID fid = env->GetFieldID(JniConstants::localeDataClass, fieldName, "C"); 401b7e820b92c7345cdc0cd4fea50954289ae66eb67Elliott Hughes env->SetCharField(obj, fid, chars[0]); 4023be1277a4644a149c158f99febbab890fc7b708fclaireho return true; 403b7e820b92c7345cdc0cd4fea50954289ae66eb67Elliott Hughes } else { 4043be1277a4644a149c158f99febbab890fc7b708fclaireho // Missing item in current resource bundle but not an error. 4053be1277a4644a149c158f99febbab890fc7b708fclaireho return false; 4063be1277a4644a149c158f99febbab890fc7b708fclaireho } 4073be1277a4644a149c158f99febbab890fc7b708fclaireho} 4083be1277a4644a149c158f99febbab890fc7b708fclaireho 4093be1277a4644a149c158f99febbab890fc7b708fclairehostatic void setCharField(JNIEnv* env, jobject obj, const char* key, const char* fieldName, 4103be1277a4644a149c158f99febbab890fc7b708fclaireho UResourceBundle* bundle, UResourceBundle* fallbackBundle) { 4113be1277a4644a149c158f99febbab890fc7b708fclaireho if (!setCharField(env, obj, key, fieldName, bundle) && fallbackBundle != NULL) { 4123be1277a4644a149c158f99febbab890fc7b708fclaireho setCharField(env, obj, key, fieldName, fallbackBundle); 4133be1277a4644a149c158f99febbab890fc7b708fclaireho } 4143be1277a4644a149c158f99febbab890fc7b708fclaireho} 4153be1277a4644a149c158f99febbab890fc7b708fclaireho 416e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughesstatic void setNumberSymbols(JNIEnv* env, jobject obj, UResourceBundle* numberSymbols, UResourceBundle* fallbackNumberSymbols) { 4173be1277a4644a149c158f99febbab890fc7b708fclaireho setCharField(env, obj, "decimal", "decimalSeparator", numberSymbols, fallbackNumberSymbols); 4183be1277a4644a149c158f99febbab890fc7b708fclaireho setCharField(env, obj, "group", "groupingSeparator", numberSymbols, fallbackNumberSymbols); 4193be1277a4644a149c158f99febbab890fc7b708fclaireho setCharField(env, obj, "list", "patternSeparator", numberSymbols, fallbackNumberSymbols); 4203be1277a4644a149c158f99febbab890fc7b708fclaireho setCharField(env, obj, "percentSign", "percent", numberSymbols, fallbackNumberSymbols); 4213be1277a4644a149c158f99febbab890fc7b708fclaireho setCharField(env, obj, "perMille", "perMill", numberSymbols, fallbackNumberSymbols); 4223be1277a4644a149c158f99febbab890fc7b708fclaireho setCharField(env, obj, "decimal", "monetarySeparator", numberSymbols, fallbackNumberSymbols); 4233be1277a4644a149c158f99febbab890fc7b708fclaireho setCharField(env, obj, "minusSign", "minusSign", numberSymbols, fallbackNumberSymbols); 4243be1277a4644a149c158f99febbab890fc7b708fclaireho setStringField(env, obj, "exponential", "exponentSeparator", numberSymbols, fallbackNumberSymbols); 4253be1277a4644a149c158f99febbab890fc7b708fclaireho setStringField(env, obj, "infinity", "infinity", numberSymbols, fallbackNumberSymbols); 4263be1277a4644a149c158f99febbab890fc7b708fclaireho setStringField(env, obj, "nan", "NaN", numberSymbols, fallbackNumberSymbols); 4273be1277a4644a149c158f99febbab890fc7b708fclaireho} 4283be1277a4644a149c158f99febbab890fc7b708fclaireho 4293be1277a4644a149c158f99febbab890fc7b708fclairehostatic void setZeroDigitToDefault(JNIEnv* env, jobject obj) { 430e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes static jfieldID fid = env->GetFieldID(JniConstants::localeDataClass, "zeroDigit", "C"); 4313be1277a4644a149c158f99febbab890fc7b708fclaireho env->SetCharField(obj, fid, '0'); 4323be1277a4644a149c158f99febbab890fc7b708fclaireho} 4333be1277a4644a149c158f99febbab890fc7b708fclaireho 4343be1277a4644a149c158f99febbab890fc7b708fclairehostatic void setZeroDigit(JNIEnv* env, jobject obj, bool isLatn, char* buffer) { 4353be1277a4644a149c158f99febbab890fc7b708fclaireho if (isLatn || buffer == NULL || buffer[0] == '\0') { 4363be1277a4644a149c158f99febbab890fc7b708fclaireho return setZeroDigitToDefault(env, obj); 4373be1277a4644a149c158f99febbab890fc7b708fclaireho } 4383be1277a4644a149c158f99febbab890fc7b708fclaireho UErrorCode status = U_ZERO_ERROR; 4393be1277a4644a149c158f99febbab890fc7b708fclaireho ScopedResourceBundle numSystemRoot(ures_openDirect(NULL, "numberingSystems", &status)); 4403be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_FAILURE(status)) { 4413be1277a4644a149c158f99febbab890fc7b708fclaireho return setZeroDigitToDefault(env, obj); 4423be1277a4644a149c158f99febbab890fc7b708fclaireho } 4433be1277a4644a149c158f99febbab890fc7b708fclaireho ScopedResourceBundle numSystem(ures_getByKey(numSystemRoot.get(), "numberingSystems", NULL, &status)); 4443be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_FAILURE(status)) { 4453be1277a4644a149c158f99febbab890fc7b708fclaireho return setZeroDigitToDefault(env, obj); 4463be1277a4644a149c158f99febbab890fc7b708fclaireho } 4473be1277a4644a149c158f99febbab890fc7b708fclaireho ScopedResourceBundle nonLatnSystem(ures_getByKey(numSystem.get(), buffer, NULL, &status)); 4483be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_FAILURE(status)) { 4493be1277a4644a149c158f99febbab890fc7b708fclaireho return setZeroDigitToDefault(env, obj); 4503be1277a4644a149c158f99febbab890fc7b708fclaireho } 4513be1277a4644a149c158f99febbab890fc7b708fclaireho int32_t charCount = 0; 4523be1277a4644a149c158f99febbab890fc7b708fclaireho const UChar* chars = ures_getStringByKey(nonLatnSystem.get(), "desc", &charCount, &status); 4533be1277a4644a149c158f99febbab890fc7b708fclaireho if (charCount == 0) { 4543be1277a4644a149c158f99febbab890fc7b708fclaireho setZeroDigitToDefault(env, obj); 4553be1277a4644a149c158f99febbab890fc7b708fclaireho } else { 456e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes static jfieldID fid = env->GetFieldID(JniConstants::localeDataClass, "zeroDigit", "C"); 4573be1277a4644a149c158f99febbab890fc7b708fclaireho env->SetCharField(obj, fid, chars[0]); 4583be1277a4644a149c158f99febbab890fc7b708fclaireho } 4593be1277a4644a149c158f99febbab890fc7b708fclaireho} 4603be1277a4644a149c158f99febbab890fc7b708fclaireho 4613be1277a4644a149c158f99febbab890fc7b708fclairehostatic void setNumberElements(JNIEnv* env, jobject obj, UResourceBundle* numberElements) { 4623be1277a4644a149c158f99febbab890fc7b708fclaireho UErrorCode status = U_ZERO_ERROR; 4633be1277a4644a149c158f99febbab890fc7b708fclaireho ScopedResourceBundle latnNumberRB(ures_getByKey(numberElements, "latn", NULL, &status)); 4643be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_FAILURE(status)) { 4653be1277a4644a149c158f99febbab890fc7b708fclaireho LOGW("Error getting ICU latn number elements system value: %s", u_errorName(status)); 4663be1277a4644a149c158f99febbab890fc7b708fclaireho return; 4673be1277a4644a149c158f99febbab890fc7b708fclaireho } 4683be1277a4644a149c158f99febbab890fc7b708fclaireho ScopedResourceBundle patternsRB(ures_getByKey(latnNumberRB.get(), "patterns", NULL, &status)); 4693be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_FAILURE(status)) { 4703be1277a4644a149c158f99febbab890fc7b708fclaireho LOGW("Error getting ICU latn number patterns value: %s", u_errorName(status)); 4713be1277a4644a149c158f99febbab890fc7b708fclaireho return; 4723be1277a4644a149c158f99febbab890fc7b708fclaireho } 4733be1277a4644a149c158f99febbab890fc7b708fclaireho // Get the patterns from the 'latn' numberElements 4743be1277a4644a149c158f99febbab890fc7b708fclaireho // This is a temporary workaround for ICU ticket#8611. 4753be1277a4644a149c158f99febbab890fc7b708fclaireho UResourceBundle* bundle = patternsRB.get(); 4763be1277a4644a149c158f99febbab890fc7b708fclaireho setStringField(env, obj, "currencyFormat", "currencyPattern", bundle); 4773be1277a4644a149c158f99febbab890fc7b708fclaireho setStringField(env, obj, "decimalFormat", "numberPattern", bundle); 4783be1277a4644a149c158f99febbab890fc7b708fclaireho setStringField(env, obj, "percentFormat", "percentPattern", bundle); 4793be1277a4644a149c158f99febbab890fc7b708fclaireho 4803be1277a4644a149c158f99febbab890fc7b708fclaireho status = U_ZERO_ERROR; 4813be1277a4644a149c158f99febbab890fc7b708fclaireho bool isLatn = false; 4823be1277a4644a149c158f99febbab890fc7b708fclaireho char buffer[256]; 4833be1277a4644a149c158f99febbab890fc7b708fclaireho buffer[0] = '\0'; 4843be1277a4644a149c158f99febbab890fc7b708fclaireho ScopedResourceBundle defaultNumberElem(ures_getByKey(numberElements, "default", NULL, &status)); 4853be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_SUCCESS(status)) { 4863be1277a4644a149c158f99febbab890fc7b708fclaireho int32_t charCount = 256; 4873be1277a4644a149c158f99febbab890fc7b708fclaireho ures_getUTF8String(defaultNumberElem.get(), buffer, &charCount, true, &status); 4883be1277a4644a149c158f99febbab890fc7b708fclaireho buffer[charCount] = '\0'; 4893be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_FAILURE(status)) { 4903be1277a4644a149c158f99febbab890fc7b708fclaireho LOGW("Error getting ICU default number element system value: %s", u_errorName(status)); 4913be1277a4644a149c158f99febbab890fc7b708fclaireho // Use latn number symbols instead. 4923be1277a4644a149c158f99febbab890fc7b708fclaireho isLatn = true; 4933be1277a4644a149c158f99febbab890fc7b708fclaireho } else { 4943be1277a4644a149c158f99febbab890fc7b708fclaireho isLatn = (strcmp(buffer, "latn") == 0); 4953be1277a4644a149c158f99febbab890fc7b708fclaireho } 4963be1277a4644a149c158f99febbab890fc7b708fclaireho } else { 4973be1277a4644a149c158f99febbab890fc7b708fclaireho // Not default data, fallback to latn number elements. 4983be1277a4644a149c158f99febbab890fc7b708fclaireho isLatn = true; 4993be1277a4644a149c158f99febbab890fc7b708fclaireho } 5003be1277a4644a149c158f99febbab890fc7b708fclaireho 5013be1277a4644a149c158f99febbab890fc7b708fclaireho status = U_ZERO_ERROR; 5023be1277a4644a149c158f99febbab890fc7b708fclaireho setZeroDigit(env, obj, isLatn, buffer); 5033be1277a4644a149c158f99febbab890fc7b708fclaireho if (isLatn) { 5043be1277a4644a149c158f99febbab890fc7b708fclaireho ScopedResourceBundle symbolsRB(ures_getByKey(latnNumberRB.get(), "symbols", NULL, &status)); 5053be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_SUCCESS(status)) { 5063be1277a4644a149c158f99febbab890fc7b708fclaireho setNumberSymbols(env, obj, symbolsRB.get(), NULL); 5073be1277a4644a149c158f99febbab890fc7b708fclaireho } else { 5083be1277a4644a149c158f99febbab890fc7b708fclaireho LOGW("Missing ICU latn symbols system value: %s", u_errorName(status)); 5093be1277a4644a149c158f99febbab890fc7b708fclaireho } 5103be1277a4644a149c158f99febbab890fc7b708fclaireho } else { 5113be1277a4644a149c158f99febbab890fc7b708fclaireho // Get every symbol item from default numbering system first. If it does not 5123be1277a4644a149c158f99febbab890fc7b708fclaireho // exist, get the symbol from latn numbering system. 5133be1277a4644a149c158f99febbab890fc7b708fclaireho ScopedResourceBundle defaultNumberRB(ures_getByKey(numberElements, (const char*)buffer, NULL, &status)); 5143be1277a4644a149c158f99febbab890fc7b708fclaireho ScopedResourceBundle defaultSymbolsRB(ures_getByKey(defaultNumberRB.get(), "symbols", NULL, &status)); 5153be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_FAILURE(status)) { 5163be1277a4644a149c158f99febbab890fc7b708fclaireho LOGW("Missing ICU %s symbols system value: %s", buffer, u_errorName(status)); 5173be1277a4644a149c158f99febbab890fc7b708fclaireho isLatn = true; // Fallback to latn symbols. 5183be1277a4644a149c158f99febbab890fc7b708fclaireho status = U_ZERO_ERROR; 5193be1277a4644a149c158f99febbab890fc7b708fclaireho } 5203be1277a4644a149c158f99febbab890fc7b708fclaireho ScopedResourceBundle latnSymbolsRB(ures_getByKey(latnNumberRB.get(), "symbols", NULL, &status)); 5213be1277a4644a149c158f99febbab890fc7b708fclaireho if (isLatn && U_FAILURE(status)) { 5223be1277a4644a149c158f99febbab890fc7b708fclaireho return; 5233be1277a4644a149c158f99febbab890fc7b708fclaireho } 5243be1277a4644a149c158f99febbab890fc7b708fclaireho setNumberSymbols(env, obj, defaultSymbolsRB.get(), latnSymbolsRB.get()); 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 52633aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes} 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 528e22935d3c7040c22b48d53bd18878844f381287cElliott Hughesstatic jboolean ICU_initLocaleDataImpl(JNIEnv* env, jclass, jstring locale, jobject localeData) { 52905960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes ScopedUtfChars localeName(env, locale); 530e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes if (localeName.c_str() == NULL) { 531e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes return JNI_FALSE; 532e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes } 533e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes 53433aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes UErrorCode status = U_ZERO_ERROR; 53521557bb6a8f35a2f9889adba449cac950c9d41b9Elliott Hughes ScopedResourceBundle root(ures_open(NULL, localeName.c_str(), &status)); 53633aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes if (U_FAILURE(status)) { 53733aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes LOGE("Error getting ICU resource bundle: %s", u_errorName(status)); 53833aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes return JNI_FALSE; 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54133aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes ScopedResourceBundle calendar(ures_getByKey(root.get(), "calendar", NULL, &status)); 54233aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes if (U_FAILURE(status)) { 5434722f161d49b5c483aa7aec0daad7bfee18578bbElliott Hughes LOGE("Error getting ICU calendar resource bundle: %s", u_errorName(status)); 54433aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes return JNI_FALSE; 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54733aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes ScopedResourceBundle gregorian(ures_getByKey(calendar.get(), "gregorian", NULL, &status)); 54833aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes if (U_FAILURE(status)) { 5494722f161d49b5c483aa7aec0daad7bfee18578bbElliott Hughes LOGE("Error getting ICU gregorian resource bundle: %s", u_errorName(status)); 55033aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes return JNI_FALSE; 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 553e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes int firstDayVals[] = { 0, 0 }; 55433aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes if (getDayIntVector(env, gregorian.get(), firstDayVals)) { 55533aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes setIntegerField(env, localeData, "firstDayOfWeek", firstDayVals[0]); 55633aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes setIntegerField(env, localeData, "minimalDaysInFirstWeek", firstDayVals[1]); 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 559e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes jobjectArray amPmMarkers = getAmPmMarkers(env, gregorian.get()); 560e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes setStringArrayField(env, localeData, "amPm", amPmMarkers); 561e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes env->DeleteLocalRef(amPmMarkers); 562e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes 563e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes jobjectArray eras = getEras(env, gregorian.get()); 564e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes setStringArrayField(env, localeData, "eras", eras); 565e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes env->DeleteLocalRef(eras); 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 567143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes ScopedResourceBundle dayNames(ures_getByKey(gregorian.get(), "dayNames", NULL, &status)); 568143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes ScopedResourceBundle monthNames(ures_getByKey(gregorian.get(), "monthNames", NULL, &status)); 569143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes 570143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes // Get the regular month and weekday names. 571143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes jobjectArray longMonthNames = getNames(env, monthNames.get(), true, REGULAR, LONG); 572143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes jobjectArray shortMonthNames = getNames(env, monthNames.get(), true, REGULAR, SHORT); 573143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes jobjectArray longWeekdayNames = getNames(env, dayNames.get(), false, REGULAR, LONG); 574143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes jobjectArray shortWeekdayNames = getNames(env, dayNames.get(), false, REGULAR, SHORT); 575143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringArrayField(env, localeData, "longMonthNames", longMonthNames); 576143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringArrayField(env, localeData, "shortMonthNames", shortMonthNames); 577143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringArrayField(env, localeData, "longWeekdayNames", longWeekdayNames); 578143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringArrayField(env, localeData, "shortWeekdayNames", shortWeekdayNames); 579143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes 580143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes // Get the stand-alone month and weekday names. If they're not available (as they aren't for 581143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes // English), we reuse the regular names. If we returned null to Java, the usual fallback 582143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes // mechanisms would come into play and we'd end up with the bogus stand-alone names from the 583143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes // root locale ("1" for January, and so on). 584143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes jobjectArray longStandAloneMonthNames = getNames(env, monthNames.get(), true, STAND_ALONE, LONG); 585143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes if (longStandAloneMonthNames == NULL) { 586143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes longStandAloneMonthNames = longMonthNames; 587143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes } 588143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes jobjectArray shortStandAloneMonthNames = getNames(env, monthNames.get(), true, STAND_ALONE, SHORT); 589143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes if (shortStandAloneMonthNames == NULL) { 590143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes shortStandAloneMonthNames = shortMonthNames; 591143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes } 592143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes jobjectArray longStandAloneWeekdayNames = getNames(env, dayNames.get(), false, STAND_ALONE, LONG); 593143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes if (longStandAloneWeekdayNames == NULL) { 594143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes longStandAloneWeekdayNames = longWeekdayNames; 595143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes } 596143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes jobjectArray shortStandAloneWeekdayNames = getNames(env, dayNames.get(), false, STAND_ALONE, SHORT); 597143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes if (shortStandAloneWeekdayNames == NULL) { 598143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes shortStandAloneWeekdayNames = shortWeekdayNames; 599143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes } 600143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringArrayField(env, localeData, "longStandAloneMonthNames", longStandAloneMonthNames); 601143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringArrayField(env, localeData, "shortStandAloneMonthNames", shortStandAloneMonthNames); 602143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringArrayField(env, localeData, "longStandAloneWeekdayNames", longStandAloneWeekdayNames); 603143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringArrayField(env, localeData, "shortStandAloneWeekdayNames", shortStandAloneWeekdayNames); 604143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes 605143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes ScopedResourceBundle dateTimePatterns(ures_getByKey(gregorian.get(), "DateTimePatterns", NULL, &status)); 60633aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes if (U_SUCCESS(status)) { 607143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringField(env, localeData, "fullTimeFormat", dateTimePatterns.get(), 0); 608143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringField(env, localeData, "longTimeFormat", dateTimePatterns.get(), 1); 609143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringField(env, localeData, "mediumTimeFormat", dateTimePatterns.get(), 2); 610143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringField(env, localeData, "shortTimeFormat", dateTimePatterns.get(), 3); 611143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringField(env, localeData, "fullDateFormat", dateTimePatterns.get(), 4); 612143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringField(env, localeData, "longDateFormat", dateTimePatterns.get(), 5); 613143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringField(env, localeData, "mediumDateFormat", dateTimePatterns.get(), 6); 614143e8c9cf91cfc01c3c91c8e93cad661ec7554eeElliott Hughes setStringField(env, localeData, "shortDateFormat", dateTimePatterns.get(), 7); 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 61633aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes status = U_ZERO_ERROR; 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6183be1277a4644a149c158f99febbab890fc7b708fclaireho // For numberPatterns and symbols. 61933aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes ScopedResourceBundle numberElements(ures_getByKey(root.get(), "NumberElements", NULL, &status)); 6203be1277a4644a149c158f99febbab890fc7b708fclaireho if (U_SUCCESS(status)) { 6213be1277a4644a149c158f99febbab890fc7b708fclaireho setNumberElements(env, localeData, numberElements.get()); 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 62333aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes status = U_ZERO_ERROR; 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6257ff7010c01a090dcbf992c7223fbc8fde54b3018Elliott Hughes jstring countryCode = env->NewStringUTF(Locale::createFromName(localeName.c_str()).getCountry()); 62652b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes jstring internationalCurrencySymbol = ICU_getCurrencyCode(env, NULL, countryCode); 627e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes env->DeleteLocalRef(countryCode); 628e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes countryCode = NULL; 629e2377cdd707b830d07a5708216834f7ac76ee3e1Elliott Hughes 63033aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes jstring currencySymbol = NULL; 63133aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes if (internationalCurrencySymbol != NULL) { 63252b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes currencySymbol = ICU_getCurrencySymbol(env, NULL, locale, internationalCurrencySymbol); 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 63433aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes internationalCurrencySymbol = env->NewStringUTF("XXX"); 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 63633aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes if (currencySymbol == NULL) { 63733aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes // This is the UTF-8 encoding of U+00A4 (CURRENCY SIGN). 638ad884a7b8cae7a1c3d973c8032d4f78ef7c96b80Hao Feng currencySymbol = env->NewStringUTF("\xc2\xa4"); 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 64033aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes setStringField(env, localeData, "currencySymbol", currencySymbol); 64133aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes setStringField(env, localeData, "internationalCurrencySymbol", internationalCurrencySymbol); 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 64333aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes return JNI_TRUE; 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 646dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughesstatic jstring ICU_toLowerCase(JNIEnv* env, jclass, jstring javaString, jstring localeName) { 647dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes ScopedJavaUnicodeString scopedString(env, javaString); 648dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes UnicodeString& s(scopedString.unicodeString()); 649dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes UnicodeString original(s); 650dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes s.toLower(Locale::createFromName(ScopedUtfChars(env, localeName).c_str())); 651dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes return s == original ? javaString : env->NewString(s.getBuffer(), s.length()); 652dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes} 653dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes 654dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughesstatic jstring ICU_toUpperCase(JNIEnv* env, jclass, jstring javaString, jstring localeName) { 655dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes ScopedJavaUnicodeString scopedString(env, javaString); 656dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes UnicodeString& s(scopedString.unicodeString()); 657dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes UnicodeString original(s); 658dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes s.toUpper(Locale::createFromName(ScopedUtfChars(env, localeName).c_str())); 659dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes return s == original ? javaString : env->NewString(s.getBuffer(), s.length()); 660dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes} 661dbbdffce5ac97a0e93ef495adaacca3660b9ab21Elliott Hughes 662e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughesstatic jstring versionString(JNIEnv* env, const UVersionInfo& version) { 663e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes char versionString[U_MAX_VERSION_STRING_LENGTH]; 664e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes u_versionToString(const_cast<UVersionInfo&>(version), &versionString[0]); 665e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes return env->NewStringUTF(versionString); 666e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes} 667e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes 668e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughesstatic jstring ICU_getIcuVersion(JNIEnv* env, jclass) { 669e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes UVersionInfo icuVersion; 670e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes u_getVersion(icuVersion); 671e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes return versionString(env, icuVersion); 672e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes} 673e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes 674e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughesstatic jstring ICU_getUnicodeVersion(JNIEnv* env, jclass) { 675e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes UVersionInfo unicodeVersion; 676e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes u_getUnicodeVersion(unicodeVersion); 677e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes return versionString(env, unicodeVersion); 678e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes} 679e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes 68052b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes 68152b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughesstruct EnumerationCounter { 68252b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes const size_t count; 68352b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes EnumerationCounter(size_t count) : count(count) {} 68452b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes size_t operator()() { return count; } 68552b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes}; 68652b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughesstruct EnumerationGetter { 68752b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes UEnumeration* e; 68852b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes UErrorCode* status; 68952b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes EnumerationGetter(UEnumeration* e, UErrorCode* status) : e(e), status(status) {} 69052b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes const UChar* operator()(int32_t* charCount) { return uenum_unext(e, charCount, status); } 69152b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes}; 69252b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughesstatic jobject ICU_getAvailableCurrencyCodes(JNIEnv* env, jclass) { 69352b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes UErrorCode status = U_ZERO_ERROR; 69452b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes UEnumeration* e(ucurr_openISOCurrencies(UCURR_COMMON|UCURR_NON_DEPRECATED, &status)); 69552b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes EnumerationCounter counter(uenum_count(e, &status)); 69652b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes EnumerationGetter getter(e, &status); 69752b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes jobject result = toStringArray16(env, &counter, &getter); 698bef9ec33e1368f57c731fce63b6a8c61628c64b0Elliott Hughes maybeThrowIcuException(env, status); 69952b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes uenum_close(e); 70052b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes return result; 70152b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes} 70252b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectstatic JNINativeMethod gMethods[] = { 704e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getAvailableBreakIteratorLocalesNative, "()[Ljava/lang/String;"), 705e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getAvailableCalendarLocalesNative, "()[Ljava/lang/String;"), 706e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getAvailableCollatorLocalesNative, "()[Ljava/lang/String;"), 70752b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes NATIVE_METHOD(ICU, getAvailableCurrencyCodes, "()[Ljava/lang/String;"), 708e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getAvailableDateFormatLocalesNative, "()[Ljava/lang/String;"), 709e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getAvailableLocalesNative, "()[Ljava/lang/String;"), 710e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getAvailableNumberFormatLocalesNative, "()[Ljava/lang/String;"), 71152b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes NATIVE_METHOD(ICU, getCurrencyCode, "(Ljava/lang/String;)Ljava/lang/String;"), 71252b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes NATIVE_METHOD(ICU, getCurrencyDisplayName, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), 71352b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes NATIVE_METHOD(ICU, getCurrencyFractionDigits, "(Ljava/lang/String;)I"), 71452b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes NATIVE_METHOD(ICU, getCurrencySymbol, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), 715e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getDisplayCountryNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), 716e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getDisplayLanguageNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), 717e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getDisplayVariantNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), 718e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getISO3CountryNative, "(Ljava/lang/String;)Ljava/lang/String;"), 719e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getISO3LanguageNative, "(Ljava/lang/String;)Ljava/lang/String;"), 720e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getISOCountriesNative, "()[Ljava/lang/String;"), 721e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, getISOLanguagesNative, "()[Ljava/lang/String;"), 722e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes NATIVE_METHOD(ICU, getIcuVersion, "()Ljava/lang/String;"), 723e0e567287e4392bebc5f5826b8ef3b1bd8ca166eElliott Hughes NATIVE_METHOD(ICU, getUnicodeVersion, "()Ljava/lang/String;"), 724c27a366a89e470690e99374b15270e7b9169ade1Elliott Hughes NATIVE_METHOD(ICU, initLocaleDataImpl, "(Ljava/lang/String;Llibcore/icu/LocaleData;)Z"), 725e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, toLowerCase, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), 726e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes NATIVE_METHOD(ICU, toUpperCase, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"), 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}; 728c27a366a89e470690e99374b15270e7b9169ade1Elliott Hughesint register_libcore_icu_ICU(JNIEnv* env) { 729566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes std::string path; 730566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes path = u_getDataDirectory(); 731566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes path += "/"; 732566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes path += U_ICUDATA_NAME; 733566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes path += ".dat"; 7349f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes 7359f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes #define FAIL_WITH_STRERROR(s) \ 7369f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes LOGE("Couldn't " s " '%s': %s", path.c_str(), strerror(errno)); \ 7379f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes return -1; 7389f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes #define MAYBE_FAIL_WITH_ICU_ERROR(s) \ 7399f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes if (status != U_ZERO_ERROR) {\ 7409f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes LOGE("Couldn't initialize ICU (" s "): %s (%s)", u_errorName(status), path.c_str()); \ 7419f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes return -1; \ 7429f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes } 743566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes 744566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes // Open the file and get its length. 745566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes ScopedFd fd(open(path.c_str(), O_RDONLY)); 746566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes if (fd.get() == -1) { 7479f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes FAIL_WITH_STRERROR("open"); 748566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes } 749566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes struct stat sb; 750566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes if (fstat(fd.get(), &sb) == -1) { 7519f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes FAIL_WITH_STRERROR("stat"); 752566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes } 753566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes 754566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes // Map it. 755566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes void* data = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd.get(), 0); 756566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes if (data == MAP_FAILED) { 7579f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes FAIL_WITH_STRERROR("mmap"); 758566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes } 759566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes 760566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes // Tell the kernel that accesses are likely to be random rather than sequential. 761566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes if (madvise(data, sb.st_size, MADV_RANDOM) == -1) { 7629f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes FAIL_WITH_STRERROR("madvise(MADV_RANDOM)"); 763566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes } 764566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes 765566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes // Tell ICU to use our memory-mapped data. 766566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes UErrorCode status = U_ZERO_ERROR; 767566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes udata_setCommonData(data, &status); 7689f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes MAYBE_FAIL_WITH_ICU_ERROR("udata_setCommonData"); 769566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes // Tell ICU it can *only* use our memory-mapped data. 770566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes udata_setFileAccess(UDATA_NO_FILES, &status); 7719f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes MAYBE_FAIL_WITH_ICU_ERROR("udata_setFileAccess"); 772566bbb1d5a0ffadfc07fa58176587d4bd0d0be13Elliott Hughes 773972d9be2dbbf6d467728b8ad44625f6574068bf8Elliott Hughes // Failures to find the ICU data tend to be somewhat obscure because ICU loads its data on first 774972d9be2dbbf6d467728b8ad44625f6574068bf8Elliott Hughes // use, which can be anywhere. Force initialization up front so we can report a nice clear error 775972d9be2dbbf6d467728b8ad44625f6574068bf8Elliott Hughes // and bail. 776972d9be2dbbf6d467728b8ad44625f6574068bf8Elliott Hughes u_init(&status); 7779f557fae5a751ba8de8c0bc9ba689ab23ad405f6Elliott Hughes MAYBE_FAIL_WITH_ICU_ERROR("u_init"); 778c27a366a89e470690e99374b15270e7b9169ade1Elliott Hughes return jniRegisterNativeMethods(env, "libcore/icu/ICU", gMethods, NELEM(gMethods)); 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 780