int32_t U_EXPORT2 TimeZone::countEquivalentIDs(const UnicodeString& id) { int32_t result = 0; UErrorCode ec = U_ZERO_ERROR; UResourceBundle res; ures_initStackObject(&res); U_DEBUG_TZ_MSG(("countEquivalentIDs..\n")); UResourceBundle *top = openOlsonResource(id, res, ec); if (U_SUCCESS(ec)) { int32_t size = ures_getSize(&res); U_DEBUG_TZ_MSG(("cEI: success (size %d, key %s)..\n", size, ures_getKey(&res))); if (size == 4 || size == 6) { UResourceBundle r; ures_initStackObject(&r); ures_getByIndex(&res, size-1, &r, &ec); //result = ures_getSize(&r); // doesn't work ures_getIntVector(&r, &result, &ec); U_DEBUG_TZ_MSG(("ceI: result %d, err %s\n", result, u_errorName(ec))); ures_close(&r); } } else { U_DEBUG_TZ_MSG(("cEI: fail, %s\n", u_errorName(ec))); } ures_close(&res); ures_close(top); return result; }
static void U_CALLCONV initAvailableLocaleList(UErrorCode &status) { U_ASSERT(availableLocaleListCount == 0); U_ASSERT(availableLocaleList == NULL); // for now, there is a hardcoded list, so just walk through that list and set it up. UResourceBundle *index = NULL; UResourceBundle installed; int32_t i = 0; ures_initStackObject(&installed); index = ures_openDirect(U_ICUDATA_COLL, "res_index", &status); ures_getByKey(index, "InstalledLocales", &installed, &status); if(U_SUCCESS(status)) { availableLocaleListCount = ures_getSize(&installed); availableLocaleList = new Locale[availableLocaleListCount]; if (availableLocaleList != NULL) { ures_resetIterator(&installed); while(ures_hasNext(&installed)) { const char *tempKey = NULL; ures_getNextString(&installed, NULL, &tempKey, &status); availableLocaleList[i++] = Locale(tempKey); } } U_ASSERT(availableLocaleListCount == i); ures_close(&installed); } ures_close(index); ucln_i18n_registerCleanup(UCLN_I18N_COLLATOR, collator_cleanup); }
TimeZone* TimeZone::createSystemTimeZone(const UnicodeString& id) { TimeZone* z = 0; UErrorCode ec = U_ZERO_ERROR; UResourceBundle res; ures_initStackObject(&res); U_DEBUG_TZ_MSG(("pre-err=%s\n", u_errorName(ec))); UResourceBundle *top = openOlsonResource(id, res, ec); U_DEBUG_TZ_MSG(("post-err=%s\n", u_errorName(ec))); if (U_SUCCESS(ec)) { z = new OlsonTimeZone(top, &res, ec); if (z) { z->setID(id); } else { U_DEBUG_TZ_MSG(("cstz: olson time zone failed to initialize - err %s\n", u_errorName(ec))); } } ures_close(&res); ures_close(top); if (U_FAILURE(ec)) { U_DEBUG_TZ_MSG(("cstz: failed to create, err %s\n", u_errorName(ec))); delete z; z = 0; } return z; }
static void U_CALLCONV initAvailableMetaZoneIDs () { U_ASSERT(gMetaZoneIDs == NULL); U_ASSERT(gMetaZoneIDTable == NULL); ucln_i18n_registerCleanup(UCLN_I18N_ZONEMETA, zoneMeta_cleanup); UErrorCode status = U_ZERO_ERROR; gMetaZoneIDTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status); if (U_FAILURE(status) || gMetaZoneIDTable == NULL) { gMetaZoneIDTable = NULL; return; } uhash_setKeyDeleter(gMetaZoneIDTable, uprv_deleteUObject); // No valueDeleter, because the vector maintain the value objects gMetaZoneIDs = new UVector(NULL, uhash_compareUChars, status); if (U_FAILURE(status) || gMetaZoneIDs == NULL) { gMetaZoneIDs = NULL; uhash_close(gMetaZoneIDTable); gMetaZoneIDTable = NULL; return; } gMetaZoneIDs->setDeleter(uprv_free); UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status); UResourceBundle *bundle = ures_getByKey(rb, gMapTimezonesTag, NULL, &status); UResourceBundle res; ures_initStackObject(&res); while (U_SUCCESS(status) && ures_hasNext(bundle)) { ures_getNextResource(bundle, &res, &status); if (U_FAILURE(status)) { break; } const char *mzID = ures_getKey(&res); int32_t len = uprv_strlen(mzID); UChar *uMzID = (UChar*)uprv_malloc(sizeof(UChar) * (len + 1)); if (uMzID == NULL) { status = U_MEMORY_ALLOCATION_ERROR; break; } u_charsToUChars(mzID, uMzID, len); uMzID[len] = 0; UnicodeString *usMzID = new UnicodeString(uMzID); if (uhash_get(gMetaZoneIDTable, usMzID) == NULL) { gMetaZoneIDs->addElement((void *)uMzID, status); uhash_put(gMetaZoneIDTable, (void *)usMzID, (void *)uMzID, &status); } else { uprv_free(uMzID); delete usMzID; } } ures_close(&res); ures_close(bundle); ures_close(rb); if (U_FAILURE(status)) { uhash_close(gMetaZoneIDTable); delete gMetaZoneIDs; gMetaZoneIDTable = NULL; gMetaZoneIDs = NULL; } }
ResourceBundle ResourceBundle::getWithFallback(const char* key, UErrorCode& status){ UResourceBundle r; ures_initStackObject(&r); ures_getByKeyWithFallback(fResource, key, &r, &status); ResourceBundle res(&r, status); if(U_SUCCESS(status)){ ures_close(&r); } return res; }
int32_t U_EXPORT2 TimeZone::countEquivalentIDs(const UnicodeString& id) { int32_t result = 0; UErrorCode ec = U_ZERO_ERROR; UResourceBundle res; ures_initStackObject(&res); U_DEBUG_TZ_MSG(("countEquivalentIDs..\n")); UResourceBundle *top = openOlsonResource(id, res, ec); if (U_SUCCESS(ec)) { UResourceBundle r; ures_initStackObject(&r); ures_getByKey(&res, kLINKS, &r, &ec); ures_getIntVector(&r, &result, &ec); ures_close(&r); } ures_close(&res); ures_close(top); return result; }
ResourceBundle ResourceBundle::get(int32_t indexR, UErrorCode& status) const { UResourceBundle r; ures_initStackObject(&r); ures_getByIndex(fResource, indexR, &r, &status); ResourceBundle res(&r, status); if (U_SUCCESS(status)) { ures_close(&r); } return res; }
ResourceBundle ResourceBundle::getNext(UErrorCode& status) { UResourceBundle r; ures_initStackObject(&r); ures_getNextResource(fResource, &r, &status); ResourceBundle res(&r, status); if (U_SUCCESS(status)) { ures_close(&r); } return res; }
const UnicodeString U_EXPORT2 TimeZone::getEquivalentID(const UnicodeString& id, int32_t index) { U_DEBUG_TZ_MSG(("gEI(%d)\n", index)); UnicodeString result; UErrorCode ec = U_ZERO_ERROR; UResourceBundle res; ures_initStackObject(&res); UResourceBundle *top = openOlsonResource(id, res, ec); int32_t zone = -1; if (U_SUCCESS(ec)) { int32_t size = ures_getSize(&res); if (size == 4 || size == 6) { UResourceBundle r; ures_initStackObject(&r); ures_getByIndex(&res, size-1, &r, &ec); const int32_t* v = ures_getIntVector(&r, &size, &ec); if (index >= 0 && index < size && getOlsonMeta()) { zone = v[index]; } ures_close(&r); } } ures_close(&res); if (zone >= 0) { UResourceBundle *ares = ures_getByKey(top, kNAMES, NULL, &ec); // dereference Zones section if (U_SUCCESS(ec)) { int32_t idLen = 0; const UChar* id = ures_getStringByIndex(ares, zone, &idLen, &ec); result.fastCopyFrom(UnicodeString(TRUE, id, idLen)); U_DEBUG_TZ_MSG(("gei(%d) -> %d, len%d, %s\n", index, zone, result.length(), u_errorName(ec))); } ures_close(ares); } ures_close(top); #if defined(U_DEBUG_TZ) if(result.length() ==0) { U_DEBUG_TZ_MSG(("equiv [__, #%d] -> 0 (%s)\n", index, u_errorName(ec))); } #endif return result; }
static UBool isAvailableLocaleListInitialized(UErrorCode &status) { // for now, there is a hardcoded list, so just walk through that list and set it up. UBool needInit; UMTX_CHECK(NULL, availableLocaleList == NULL, needInit); if (needInit) { UResourceBundle *index = NULL; UResourceBundle installed; Locale * temp; int32_t i = 0; int32_t localeCount; ures_initStackObject(&installed); index = ures_openDirect(U_ICUDATA_COLL, "res_index", &status); ures_getByKey(index, "InstalledLocales", &installed, &status); if(U_SUCCESS(status)) { localeCount = ures_getSize(&installed); temp = new Locale[localeCount]; if (temp != NULL) { ures_resetIterator(&installed); while(ures_hasNext(&installed)) { const char *tempKey = NULL; ures_getNextString(&installed, NULL, &tempKey, &status); temp[i++] = Locale(tempKey); } umtx_lock(NULL); if (availableLocaleList == NULL) { availableLocaleListCount = localeCount; availableLocaleList = temp; temp = NULL; ucln_i18n_registerCleanup(UCLN_I18N_COLLATOR, collator_cleanup); } umtx_unlock(NULL); needInit = FALSE; if (temp) { delete []temp; } } ures_close(&installed); } ures_close(index); } return !needInit; }
static UBool getOlsonMeta(const UResourceBundle* top) { if (OLSON_ZONE_COUNT == 0) { UErrorCode ec = U_ZERO_ERROR; UResourceBundle res; ures_initStackObject(&res); ures_getByKey(top, kZONES, &res, &ec); if(U_SUCCESS(ec)) { OLSON_ZONE_COUNT = ures_getSize(&res); U_DEBUG_TZ_MSG(("OZC%d\n",OLSON_ZONE_COUNT)); } ures_close(&res); } return (OLSON_ZONE_COUNT > 0); }
TZEnumeration(const char* country) : map(NULL), len(0), pos(0) { if (!getOlsonMeta()) { return; } char key[] = {0, 0, 0, 0,0, 0, 0,0, 0, 0,0}; // e.g., "US", or "Default" for no country if (country) { uprv_strncat(key, country, 2); } else { uprv_strcpy(key, kDEFAULT); } UErrorCode ec = U_ZERO_ERROR; UResourceBundle *top = ures_openDirect(0, kZONEINFO, &ec); top = ures_getByKey(top, kREGIONS, top, &ec); // dereference 'Regions' section if (U_SUCCESS(ec)) { UResourceBundle res; ures_initStackObject(&res); ures_getByKey(top, key, &res, &ec); // The list of zones is a list of integers, from 0..n-1, // where n is the total number of system zones. const int32_t* v = ures_getIntVector(&res, &len, &ec); if (U_SUCCESS(ec)) { U_ASSERT(len > 0); map = (int32_t*)uprv_malloc(sizeof(int32_t) * len); if (map != 0) { for (uint16_t i=0; i<len; ++i) { U_ASSERT(v[i] >= 0 && v[i] < OLSON_ZONE_COUNT); map[i] = v[i]; } } } else { U_DEBUG_TZ_MSG(("Failed to load tz for region %s: %s\n", country, u_errorName(ec))); } ures_close(&res); } ures_close(top); }
U_NAMESPACE_BEGIN // ------------------------------------- BreakIterator* BreakIterator::buildInstance(const Locale& loc, const char *type, int32_t kind, UErrorCode &status) { char fnbuff[256]; char ext[4]={'\0'}; char actualLocale[ULOC_FULLNAME_CAPACITY]; int32_t size; const UChar* brkfname = NULL; UResourceBundle brkRulesStack; UResourceBundle brkNameStack; UResourceBundle *brkRules = &brkRulesStack; UResourceBundle *brkName = &brkNameStack; RuleBasedBreakIterator *result = NULL; if (U_FAILURE(status)) return NULL; ures_initStackObject(brkRules); ures_initStackObject(brkName); // Get the locale UResourceBundle *b = ures_open(U_ICUDATA_BRKITR, loc.getName(), &status); /* this is a hack for now. Should be fixed when the data is fetched from brk_index.txt */ if(status==U_USING_DEFAULT_WARNING){ status=U_ZERO_ERROR; ures_openFillIn(b, U_ICUDATA_BRKITR, "", &status); } // Get the "boundaries" array. if (U_SUCCESS(status)) { brkRules = ures_getByKeyWithFallback(b, "boundaries", brkRules, &status); // Get the string object naming the rules file brkName = ures_getByKeyWithFallback(brkRules, type, brkName, &status); // Get the actual string brkfname = ures_getString(brkName, &size, &status); U_ASSERT((size_t)size<sizeof(fnbuff)); if ((size_t)size>=sizeof(fnbuff)) { size=0; if (U_SUCCESS(status)) { status = U_BUFFER_OVERFLOW_ERROR; } } // Use the string if we found it if (U_SUCCESS(status) && brkfname) { uprv_strncpy(actualLocale, ures_getLocale(brkName, &status), sizeof(actualLocale)/sizeof(actualLocale[0])); UChar* extStart=u_strchr(brkfname, 0x002e); int len = 0; if(extStart!=NULL){ len = (int)(extStart-brkfname); u_UCharsToChars(extStart+1, ext, sizeof(ext)); // nul terminates the buff u_UCharsToChars(brkfname, fnbuff, len); } fnbuff[len]=0; // nul terminate } } ures_close(brkRules); ures_close(brkName); UDataMemory* file = udata_open(U_ICUDATA_BRKITR, ext, fnbuff, &status); if (U_FAILURE(status)) { ures_close(b); return NULL; } // Create a RuleBasedBreakIterator result = new RuleBasedBreakIterator(file, status); // If there is a result, set the valid locale and actual locale, and the kind if (U_SUCCESS(status) && result != NULL) { U_LOCALE_BASED(locBased, *(BreakIterator*)result); locBased.setLocaleIDs(ures_getLocaleByType(b, ULOC_VALID_LOCALE, &status), actualLocale); result->setBreakType(kind); } ures_close(b); if (U_FAILURE(status) && result != NULL) { // Sometimes redundant check, but simple delete result; return NULL; } if (result == NULL) { udata_close(file); if (U_SUCCESS(status)) { status = U_MEMORY_ALLOCATION_ERROR; } } return result; }
/* * Lookup a resource bundle table item with fallback on the table level. * Regular resource bundle lookups perform fallback to parent locale bundles * and eventually the root bundle, but only for top-level items. * This function takes the name of a top-level table and of an item in that table * and performs a lookup of both, falling back until a bundle contains a table * with this item. * * Note: Only the opening of entire bundles falls back through the default locale * before root. Once a bundle is open, item lookups do not go through the * default locale because that would result in a mix of languages that is * unpredictable to the programmer and most likely useless. */ U_CAPI const UChar * U_EXPORT2 uloc_getTableStringWithFallback(const char *path, const char *locale, const char *tableKey, const char *subTableKey, const char *itemKey, int32_t *pLength, UErrorCode *pErrorCode) { /* char localeBuffer[ULOC_FULLNAME_CAPACITY*4];*/ UResourceBundle *rb=NULL, table, subTable; const UChar *item=NULL; UErrorCode errorCode; char explicitFallbackName[ULOC_FULLNAME_CAPACITY] = {0}; /* * open the bundle for the current locale * this falls back through the locale's chain to root */ errorCode=U_ZERO_ERROR; rb=ures_open(path, locale, &errorCode); if(U_FAILURE(errorCode)) { /* total failure, not even root could be opened */ *pErrorCode=errorCode; return NULL; } else if(errorCode==U_USING_DEFAULT_WARNING || (errorCode==U_USING_FALLBACK_WARNING && *pErrorCode!=U_USING_DEFAULT_WARNING) ) { /* set the "strongest" error code (success->fallback->default->failure) */ *pErrorCode=errorCode; } for(;;){ ures_initStackObject(&table); ures_initStackObject(&subTable); ures_getByKeyWithFallback(rb, tableKey, &table, &errorCode); if (subTableKey != NULL) { /* ures_getByKeyWithFallback(&table,subTableKey, &subTable, &errorCode); item = ures_getStringByKeyWithFallback(&subTable, itemKey, pLength, &errorCode); if(U_FAILURE(errorCode)){ *pErrorCode = errorCode; } break;*/ ures_getByKeyWithFallback(&table,subTableKey, &table, &errorCode); } if(U_SUCCESS(errorCode)){ item = ures_getStringByKeyWithFallback(&table, itemKey, pLength, &errorCode); if(U_FAILURE(errorCode)){ const char* replacement = NULL; *pErrorCode = errorCode; /*save the errorCode*/ errorCode = U_ZERO_ERROR; /* may be a deprecated code */ if(uprv_strcmp(tableKey, "Countries")==0){ replacement = uloc_getCurrentCountryID(itemKey); }else if(uprv_strcmp(tableKey, "Languages")==0){ replacement = uloc_getCurrentLanguageID(itemKey); } /*pointer comparison is ok since uloc_getCurrentCountryID & uloc_getCurrentLanguageID return the key itself is replacement is not found*/ if(replacement!=NULL && itemKey != replacement){ item = ures_getStringByKeyWithFallback(&table, replacement, pLength, &errorCode); if(U_SUCCESS(errorCode)){ *pErrorCode = errorCode; break; } } }else{ break; } } if(U_FAILURE(errorCode)){ /* still can't figure out ?.. try the fallback mechanism */ int32_t len = 0; const UChar* fallbackLocale = NULL; *pErrorCode = errorCode; errorCode = U_ZERO_ERROR; fallbackLocale = ures_getStringByKeyWithFallback(&table, "Fallback", &len, &errorCode); if(U_FAILURE(errorCode)){ *pErrorCode = errorCode; break; } u_UCharsToChars(fallbackLocale, explicitFallbackName, len); /* guard against recursive fallback */ if(uprv_strcmp(explicitFallbackName, locale)==0){ *pErrorCode = U_INTERNAL_PROGRAM_ERROR; break; } ures_close(rb); rb = ures_open(path, explicitFallbackName, &errorCode); if(U_FAILURE(errorCode)){ *pErrorCode = errorCode; break; } /* succeeded in opening the fallback bundle .. continue and try to fetch the item */ }else{ break; } } /* done with the locale string - ready to close table and rb */ ures_close(&subTable); ures_close(&table); ures_close(rb); return item; }
void ZoneMeta::initAvailableMetaZoneIDs () { UBool initialized; UMTX_CHECK(&gZoneMetaLock, gMetaZoneIDsInitialized, initialized); if (!initialized) { umtx_lock(&gZoneMetaLock); { if (!gMetaZoneIDsInitialized) { UErrorCode status = U_ZERO_ERROR; UHashtable *metaZoneIDTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status); uhash_setKeyDeleter(metaZoneIDTable, uprv_deleteUObject); // No valueDeleter, because the vector maintain the value objects UVector *metaZoneIDs = NULL; if (U_SUCCESS(status)) { metaZoneIDs = new UVector(NULL, uhash_compareUChars, status); if (metaZoneIDs == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } } else { uhash_close(metaZoneIDTable); } if (U_SUCCESS(status)) { U_ASSERT(metaZoneIDs != NULL); metaZoneIDs->setDeleter(uprv_free); UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status); UResourceBundle *bundle = ures_getByKey(rb, gMapTimezonesTag, NULL, &status); UResourceBundle res; ures_initStackObject(&res); while (U_SUCCESS(status) && ures_hasNext(bundle)) { ures_getNextResource(bundle, &res, &status); if (U_FAILURE(status)) { break; } const char *mzID = ures_getKey(&res); int32_t len = uprv_strlen(mzID); UChar *uMzID = (UChar*)uprv_malloc(sizeof(UChar) * (len + 1)); if (uMzID == NULL) { status = U_MEMORY_ALLOCATION_ERROR; break; } u_charsToUChars(mzID, uMzID, len); uMzID[len] = 0; UnicodeString *usMzID = new UnicodeString(uMzID); if (uhash_get(metaZoneIDTable, usMzID) == NULL) { metaZoneIDs->addElement((void *)uMzID, status); uhash_put(metaZoneIDTable, (void *)usMzID, (void *)uMzID, &status); } else { uprv_free(uMzID); delete usMzID; } } if (U_SUCCESS(status)) { gMetaZoneIDs = metaZoneIDs; gMetaZoneIDTable = metaZoneIDTable; gMetaZoneIDsInitialized = TRUE; } else { uhash_close(metaZoneIDTable); delete metaZoneIDs; } ures_close(&res); ures_close(bundle); ures_close(rb); } } } umtx_unlock(&gZoneMetaLock); } }