U_CAPI void U_EXPORT2 ucol_prepareShortStringOpen( const char *definition, UBool, UParseError *parseError, UErrorCode *status) { if(U_FAILURE(*status)) return; UParseError internalParseError; if(!parseError) { parseError = &internalParseError; } parseError->line = 0; parseError->offset = 0; parseError->preContext[0] = 0; parseError->postContext[0] = 0; // first we want to pick stuff out of short string. // we'll end up with an UCA version, locale and a bunch of // settings // analyse the string in order to get everything we need. CollatorSpec s; ucol_sit_initCollatorSpecs(&s); ucol_sit_readSpecs(&s, definition, parseError, status); ucol_sit_calculateWholeLocale(&s); char buffer[internalBufferSize]; uprv_memset(buffer, 0, internalBufferSize); uloc_canonicalize(s.locale, buffer, internalBufferSize, status); UResourceBundle *b = ures_open(U_ICUDATA_COLL, buffer, status); /* we try to find stuff from keyword */ UResourceBundle *collations = ures_getByKey(b, "collations", NULL, status); UResourceBundle *collElem = NULL; char keyBuffer[256]; // if there is a keyword, we pick it up and try to get elements if(!uloc_getKeywordValue(buffer, "collation", keyBuffer, 256, status)) { // no keyword. we try to find the default setting, which will give us the keyword value UResourceBundle *defaultColl = ures_getByKeyWithFallback(collations, "default", NULL, status); if(U_SUCCESS(*status)) { int32_t defaultKeyLen = 0; const UChar *defaultKey = ures_getString(defaultColl, &defaultKeyLen, status); u_UCharsToChars(defaultKey, keyBuffer, defaultKeyLen); keyBuffer[defaultKeyLen] = 0; } else { *status = U_INTERNAL_PROGRAM_ERROR; return; } ures_close(defaultColl); } collElem = ures_getByKeyWithFallback(collations, keyBuffer, collElem, status); ures_close(collElem); ures_close(collations); ures_close(b); }
/* {{{ ResourceBundle_extract_value */ void resourcebundle_extract_value( zval *return_value, ResourceBundle_object *source ) { UResType restype; const UChar* ufield; const uint8_t* bfield; const int32_t* vfield; int32_t ilen; int i; zend_long lfield; ResourceBundle_object* newrb; restype = ures_getType( source->child ); switch (restype) { case URES_STRING: ufield = ures_getString( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) ); INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve string value"); INTL_METHOD_RETVAL_UTF8(source, (UChar *)ufield, ilen, 0); break; case URES_BINARY: bfield = ures_getBinary( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) ); INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve binary value"); ZVAL_STRINGL( return_value, (char *) bfield, ilen ); break; case URES_INT: lfield = ures_getInt( source->child, &INTL_DATA_ERROR_CODE(source) ); INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve integer value"); ZVAL_LONG( return_value, lfield ); break; case URES_INT_VECTOR: vfield = ures_getIntVector( source->child, &ilen, &INTL_DATA_ERROR_CODE(source) ); INTL_METHOD_CHECK_STATUS(source, "Failed to retrieve vector value"); array_init( return_value ); for (i=0; i<ilen; i++) { add_next_index_long( return_value, vfield[i] ); } break; case URES_ARRAY: case URES_TABLE: object_init_ex( return_value, ResourceBundle_ce_ptr ); newrb = Z_INTL_RESOURCEBUNDLE_P(return_value); newrb->me = source->child; source->child = NULL; intl_errors_reset(INTL_DATA_ERROR_P(source)); break; default: intl_errors_set(INTL_DATA_ERROR_P(source), U_ILLEGAL_ARGUMENT_ERROR, "Unknown resource type", 0); RETURN_FALSE; break; } }
static UBool getString( const UResourceBundle *resource, UnicodeString &result, UErrorCode &status) { int32_t len = 0; const UChar *resStr = ures_getString(resource, &len, &status); if (U_FAILURE(status)) { return FALSE; } result.setTo(TRUE, resStr, len); return TRUE; }
const CompactTrieDictionary * ICULanguageBreakFactory::loadDictionaryFor(UScriptCode script, int32_t /*breakType*/) { UErrorCode status = U_ZERO_ERROR; // Open root from brkitr tree. char dictnbuff[256]; char ext[4]={'\0'}; UResourceBundle *b = ures_open(U_ICUDATA_BRKITR, "", &status); b = ures_getByKeyWithFallback(b, "dictionaries", b, &status); b = ures_getByKeyWithFallback(b, uscript_getShortName(script), b, &status); int32_t dictnlength = 0; const UChar *dictfname = ures_getString(b, &dictnlength, &status); if (U_SUCCESS(status) && (size_t)dictnlength >= sizeof(dictnbuff)) { dictnlength = 0; status = U_BUFFER_OVERFLOW_ERROR; } if (U_SUCCESS(status) && dictfname) { UChar* extStart=u_strchr(dictfname, 0x002e); int len = 0; if(extStart!=NULL){ len = extStart-dictfname; u_UCharsToChars(extStart+1, ext, sizeof(ext)); // nul terminates the buff u_UCharsToChars(dictfname, dictnbuff, len); } dictnbuff[len]=0; // nul terminate } ures_close(b); UDataMemory *file = udata_open(U_ICUDATA_BRKITR, ext, dictnbuff, &status); if (U_SUCCESS(status)) { const CompactTrieDictionary *dict = new CompactTrieDictionary( file, status); if (U_SUCCESS(status) && dict == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } if (U_FAILURE(status)) { delete dict; dict = NULL; } return dict; } else if (dictfname != NULL){ //create dummy dict if dictionary filename not valid UChar c = 0x0020; status = U_ZERO_ERROR; MutableTrieDictionary *mtd = new MutableTrieDictionary(c, status, TRUE); mtd->addWord(&c, 1, status, 1); return new CompactTrieDictionary(*mtd, status); } return NULL; }
static jstring getCurrencyCodeNative(JNIEnv* env, jclass clazz, jstring key) { UErrorCode status = U_ZERO_ERROR; ScopedResourceBundle supplData(ures_openDirect(NULL, "supplementalData", &status)); if (U_FAILURE(status)) { return NULL; } ScopedResourceBundle currencyMap(ures_getByKey(supplData.get(), "CurrencyMap", NULL, &status)); if (U_FAILURE(status)) { return NULL; } const char* keyChars = env->GetStringUTFChars(key, NULL); ScopedResourceBundle currency(ures_getByKey(currencyMap.get(), keyChars, NULL, &status)); env->ReleaseStringUTFChars(key, keyChars); if (U_FAILURE(status)) { return NULL; } ScopedResourceBundle currencyElem(ures_getByIndex(currency.get(), 0, NULL, &status)); if (U_FAILURE(status)) { return env->NewStringUTF("None"); } // check if there is a 'to' date. If there is, the currency isn't used anymore. ScopedResourceBundle currencyTo(ures_getByKey(currencyElem.get(), "to", NULL, &status)); if (!U_FAILURE(status)) { // return and let the caller throw an exception return NULL; } // We need to reset 'status'. It works like errno in that ICU doesn't set it // to U_ZERO_ERROR on success: it only touches it on error, and the test // above means it now holds a failure code. status = U_ZERO_ERROR; ScopedResourceBundle currencyId(ures_getByKey(currencyElem.get(), "id", NULL, &status)); if (U_FAILURE(status)) { // No id defined for this country return env->NewStringUTF("None"); } int length; const jchar* id = ures_getString(currencyId.get(), &length, &status); if (U_FAILURE(status) || length == 0) { return env->NewStringUTF("None"); } return env->NewString(id, length); }
// TODO: rewrite this with int32_t ucurr_forLocale(const char* locale, UChar* buff, int32_t buffCapacity, UErrorCode* ec)... static jstring ICU_getCurrencyCode(JNIEnv* env, jclass, jstring javaCountryCode) { UErrorCode status = U_ZERO_ERROR; ScopedResourceBundle supplData(ures_openDirect(U_ICUDATA_CURR, "supplementalData", &status)); if (U_FAILURE(status)) { return NULL; } ScopedResourceBundle currencyMap(ures_getByKey(supplData.get(), "CurrencyMap", NULL, &status)); if (U_FAILURE(status)) { return NULL; } ScopedUtfChars countryCode(env, javaCountryCode); ScopedResourceBundle currency(ures_getByKey(currencyMap.get(), countryCode.c_str(), NULL, &status)); if (U_FAILURE(status)) { return NULL; } ScopedResourceBundle currencyElem(ures_getByIndex(currency.get(), 0, NULL, &status)); if (U_FAILURE(status)) { return env->NewStringUTF("XXX"); } // Check if there's a 'to' date. If there is, the currency isn't used anymore. ScopedResourceBundle currencyTo(ures_getByKey(currencyElem.get(), "to", NULL, &status)); if (!U_FAILURE(status)) { return NULL; } // Ignore the failure to find a 'to' date. status = U_ZERO_ERROR; ScopedResourceBundle currencyId(ures_getByKey(currencyElem.get(), "id", NULL, &status)); if (U_FAILURE(status)) { // No id defined for this country return env->NewStringUTF("XXX"); } int32_t charCount; const jchar* chars = ures_getString(currencyId.get(), &charCount, &status); return (charCount == 0) ? env->NewStringUTF("XXX") : env->NewString(chars, charCount); }
void RelativeDateFormat::loadDates(UErrorCode &status) { CalendarData calData(fLocale, "gregorian", status); UErrorCode tempStatus = status; UResourceBundle *dateTimePatterns = calData.getByKey(DT_DateTimePatternsTag, tempStatus); if(U_SUCCESS(tempStatus)) { int32_t patternsSize = ures_getSize(dateTimePatterns); if (patternsSize > kDateTime) { int32_t resStrLen = 0; int32_t glueIndex = kDateTime; if (patternsSize >= (DateFormat::kDateTimeOffset + DateFormat::kShort + 1)) { // Get proper date time format switch (fDateStyle) { case kFullRelative: case kFull: glueIndex = kDateTimeOffset + kFull; break; case kLongRelative: case kLong: glueIndex = kDateTimeOffset + kLong; break; case kMediumRelative: case kMedium: glueIndex = kDateTimeOffset + kMedium; break; case kShortRelative: case kShort: glueIndex = kDateTimeOffset + kShort; break; default: break; } } const UChar *resStr = ures_getStringByIndex(dateTimePatterns, glueIndex, &resStrLen, &tempStatus); fCombinedFormat = new MessageFormat(UnicodeString(TRUE, resStr, resStrLen), fLocale, tempStatus); } } UResourceBundle *strings = calData.getByKey3("fields", "day", "relative", status); // set up min/max fDayMin=-1; fDayMax=1; if(U_FAILURE(status)) { fDatesLen=0; return; } fDatesLen = ures_getSize(strings); fDates = (URelativeString*) uprv_malloc(sizeof(fDates[0])*fDatesLen); // Load in each item into the array... int n = 0; UResourceBundle *subString = NULL; while(ures_hasNext(strings) && U_SUCCESS(status)) { // iterate over items subString = ures_getNextResource(strings, subString, &status); if(U_FAILURE(status) || (subString==NULL)) break; // key = offset # const char *key = ures_getKey(subString); // load the string and length int32_t aLen; const UChar* aString = ures_getString(subString, &aLen, &status); if(U_FAILURE(status) || aString == NULL) break; // calculate the offset int32_t offset = atoi(key); // set min/max if(offset < fDayMin) { fDayMin = offset; } if(offset > fDayMax) { fDayMax = offset; } // copy the string pointer fDates[n].offset = offset; fDates[n].string = aString; fDates[n].len = aLen; n++; } ures_close(subString); // the fDates[] array could be sorted here, for direct access. }
static void TestTable32(void) { static const struct { const char *key; int32_t number; } testcases[]={ { "ooooooooooooooooo", 0 }, { "oooooooooooooooo1", 1 }, { "ooooooooooooooo1o", 2 }, { "oo11ooo1ooo11111o", 25150 }, { "oo11ooo1ooo111111", 25151 }, { "o1111111111111111", 65535 }, { "1oooooooooooooooo", 65536 }, { "1ooooooo11o11ooo1", 65969 }, { "1ooooooo11o11oo1o", 65970 }, { "1ooooooo111oo1111", 65999 } }; /* ### TODO UResourceBundle staticItem={ 0 }; - need to know the size */ UResourceBundle *res, *item; const UChar *s; const char *key; UErrorCode errorCode; int32_t i, j, number, parsedNumber, length, count; errorCode=U_ZERO_ERROR; res=ures_open(loadTestData(&errorCode), "testtable32", &errorCode); if(U_FAILURE(errorCode)) { log_data_err("unable to open testdata/testtable32.res - %s\n", u_errorName(errorCode)); return; } if(ures_getType(res)!=URES_TABLE) { log_data_err("testdata/testtable32.res has type %d instead of URES_TABLE\n", ures_getType(res)); } count=ures_getSize(res); if(count!=66000) { log_err("testdata/testtable32.res should have 66000 entries but has %d\n", count); } /* get the items by index */ item=NULL; for(i=0; i<count; ++i) { item=ures_getByIndex(res, i, item, &errorCode); if(U_FAILURE(errorCode)) { log_err("unable to get item %d of %d in testdata/testtable32.res - %s\n", i, count, u_errorName(errorCode)); break; } key=ures_getKey(item); parsedNumber=parseTable32Key(key); switch(ures_getType(item)) { case URES_STRING: s=ures_getString(item, &length, &errorCode); if(U_FAILURE(errorCode) || s==NULL) { log_err("unable to access the string \"%s\" at %d in testdata/testtable32.res - %s\n", key, i, u_errorName(errorCode)); number=-1; } else { j=0; U16_NEXT(s, j, length, number); } break; case URES_INT: number=ures_getInt(item, &errorCode); if(U_FAILURE(errorCode)) { log_err("unable to access the integer \"%s\" at %d in testdata/testtable32.res - %s\n", key, i, u_errorName(errorCode)); number=-1; } break; default: log_err("unexpected resource type %d for \"%s\" at %d in testdata/testtable32.res - %s\n", ures_getType(item), key, i, u_errorName(errorCode)); number=-1; break; } if(number>=0 && number!=parsedNumber) { log_err("\"%s\" at %d in testdata/testtable32.res has a string/int value of %d, expected %d\n", key, i, number, parsedNumber); } } /* search for some items by key */ for(i=0; i<UPRV_LENGTHOF(testcases); ++i) { item=ures_getByKey(res, testcases[i].key, item, &errorCode); if(U_FAILURE(errorCode)) { log_err("unable to find the key \"%s\" in testdata/testtable32.res - %s\n", testcases[i].key, u_errorName(errorCode)); continue; } switch(ures_getType(item)) { case URES_STRING: s=ures_getString(item, &length, &errorCode); if(U_FAILURE(errorCode) || s==NULL) { log_err("unable to access the string \"%s\" in testdata/testtable32.res - %s\n", testcases[i].key, u_errorName(errorCode)); number=-1; } else { j=0; U16_NEXT(s, j, length, number); } break; case URES_INT: number=ures_getInt(item, &errorCode); if(U_FAILURE(errorCode)) { log_err("unable to access the integer \"%s\" in testdata/testtable32.res - %s\n", testcases[i].key, u_errorName(errorCode)); number=-1; } break; default: log_err("unexpected resource type %d for \"%s\" in testdata/testtable32.res - %s\n", ures_getType(item), testcases[i].key, u_errorName(errorCode)); number=-1; break; } if(number>=0 && number!=testcases[i].number) { log_err("\"%s\" in testdata/testtable32.res has a string/int value of %d, expected %d\n", testcases[i].key, number, testcases[i].number); } key=ures_getKey(item); if(0!=uprv_strcmp(key, testcases[i].key)) { log_err("\"%s\" in testdata/testtable32.res claims to have the key \"%s\"\n", testcases[i].key, key); } } ures_close(item); ures_close(res); }
void printOutBundle(UFILE *out, UResourceBundle *resource, int32_t indent, UErrorCode *status) { int32_t i = 0; const char *key = ures_getKey(resource); switch(ures_getType(resource)) { case URES_STRING : { int32_t len=0; const UChar*thestr = ures_getString(resource, &len, status); UChar *string = quotedString(thestr); /* TODO: String truncation */ /* if(trunc && len > truncsize) { printIndent(out, indent); u_fprintf(out, "// WARNING: this string, size %d is truncated to %d\n", len, truncsize/2); len = truncsize/2; } */ printIndent(out, indent); if(key != NULL) { u_fprintf(out, "%s { \"%S\" } ", key, string); } else { u_fprintf(out, "\"%S\",", string); } if(VERBOSE) { u_fprintf(out, " // STRING"); } u_fprintf(out, "\n"); free(string); } break; case URES_INT : printIndent(out, indent); if(key != NULL) { u_fprintf(out, "%s", key); } u_fprintf(out, ":int { %li } ", ures_getInt(resource, status)); if(VERBOSE) { u_fprintf(out, " // INT"); } u_fprintf(out, "\n"); break; case URES_BINARY : { int32_t len = 0; const int8_t *data = (const int8_t *)ures_getBinary(resource, &len, status); if(trunc && len > truncsize) { printIndent(out, indent); u_fprintf(out, "// WARNING: this resource, size %li is truncated to %li\n", len, truncsize/2); len = truncsize/2; } if(U_SUCCESS(*status)) { printIndent(out, indent); if(key != NULL) { u_fprintf(out, "%s", key); } u_fprintf(out, ":binary { "); for(i = 0; i<len; i++) { printHex(out, data++); } u_fprintf(out, " }"); if(VERBOSE) { u_fprintf(out, " // BINARY"); } u_fprintf(out, "\n"); } else { reportError(status); } } break; case URES_INT_VECTOR : { int32_t len = 0; const int32_t *data = ures_getIntVector(resource, &len, status); if(U_SUCCESS(*status)) { printIndent(out, indent); if(key != NULL) { u_fprintf(out, "%s", key); } u_fprintf(out, ":intvector { "); for(i = 0; i<len-1; i++) { u_fprintf(out, "%d, ", data[i]); } if(len > 0) { u_fprintf(out, "%d ", data[len-1]); } u_fprintf(out, "}"); if(VERBOSE) { u_fprintf(out, " // INTVECTOR"); } u_fprintf(out, "\n"); } else { reportError(status); } } break; case URES_TABLE : case URES_ARRAY : { UResourceBundle *t = NULL; ures_resetIterator(resource); printIndent(out, indent); if(key != NULL) { u_fprintf(out, "%s ", key); } u_fprintf(out, "{"); if(VERBOSE) { if(ures_getType(resource) == URES_TABLE) { u_fprintf(out, " // TABLE"); } else { u_fprintf(out, " // ARRAY"); } } u_fprintf(out, "\n"); while(ures_hasNext(resource)) { t = ures_getNextResource(resource, t, status); printOutBundle(out, t, indent+indentsize, status); } printIndent(out, indent); u_fprintf(out, "}\n"); ures_close(t); } break; default: break; } }
U_CDECL_END static void U_CALLCONV initFromResourceBundle(UErrorCode& sts) { U_NAMESPACE_USE ucln_common_registerCleanup(UCLN_COMMON_LOCALE_KEY_TYPE, uloc_key_type_cleanup); gLocExtKeyMap = uhash_open(uhash_hashIChars, uhash_compareIChars, NULL, &sts); LocalUResourceBundlePointer keyTypeDataRes(ures_openDirect(NULL, "keyTypeData", &sts)); LocalUResourceBundlePointer keyMapRes(ures_getByKey(keyTypeDataRes.getAlias(), "keyMap", NULL, &sts)); LocalUResourceBundlePointer typeMapRes(ures_getByKey(keyTypeDataRes.getAlias(), "typeMap", NULL, &sts)); if (U_FAILURE(sts)) { return; } UErrorCode tmpSts = U_ZERO_ERROR; LocalUResourceBundlePointer typeAliasRes(ures_getByKey(keyTypeDataRes.getAlias(), "typeAlias", NULL, &tmpSts)); tmpSts = U_ZERO_ERROR; LocalUResourceBundlePointer bcpTypeAliasRes(ures_getByKey(keyTypeDataRes.getAlias(), "bcpTypeAlias", NULL, &tmpSts)); // initialize vectors storing dynamically allocated objects gKeyTypeStringPool = new UVector(uloc_deleteKeyTypeStringPoolEntry, NULL, sts); if (gKeyTypeStringPool == NULL) { if (U_SUCCESS(sts)) { sts = U_MEMORY_ALLOCATION_ERROR; } } if (U_FAILURE(sts)) { return; } gLocExtKeyDataEntries = new UVector(uloc_deleteKeyDataEntry, NULL, sts); if (gLocExtKeyDataEntries == NULL) { if (U_SUCCESS(sts)) { sts = U_MEMORY_ALLOCATION_ERROR; } } if (U_FAILURE(sts)) { return; } gLocExtTypeEntries = new UVector(uloc_deleteTypeEntry, NULL, sts); if (gLocExtTypeEntries == NULL) { if (U_SUCCESS(sts)) { sts = U_MEMORY_ALLOCATION_ERROR; } } if (U_FAILURE(sts)) { return; } // iterate through keyMap resource LocalUResourceBundlePointer keyMapEntry; while (ures_hasNext(keyMapRes.getAlias())) { keyMapEntry.adoptInstead(ures_getNextResource(keyMapRes.getAlias(), keyMapEntry.orphan(), &sts)); if (U_FAILURE(sts)) { break; } const char* legacyKeyId = ures_getKey(keyMapEntry.getAlias()); int32_t bcpKeyIdLen = 0; const UChar* uBcpKeyId = ures_getString(keyMapEntry.getAlias(), &bcpKeyIdLen, &sts); if (U_FAILURE(sts)) { break; } // empty value indicates that BCP key is same with the legacy key. const char* bcpKeyId = legacyKeyId; if (bcpKeyIdLen > 0) { char* bcpKeyIdBuf = (char*)uprv_malloc(bcpKeyIdLen + 1); if (bcpKeyIdBuf == NULL) { sts = U_MEMORY_ALLOCATION_ERROR; break; } u_UCharsToChars(uBcpKeyId, bcpKeyIdBuf, bcpKeyIdLen); bcpKeyIdBuf[bcpKeyIdLen] = 0; gKeyTypeStringPool->addElement(bcpKeyIdBuf, sts); if (U_FAILURE(sts)) { break; } bcpKeyId = bcpKeyIdBuf; } UBool isTZ = uprv_strcmp(legacyKeyId, "timezone") == 0; UHashtable* typeDataMap = uhash_open(uhash_hashIChars, uhash_compareIChars, NULL, &sts); if (U_FAILURE(sts)) { break; } uint32_t specialTypes = SPECIALTYPE_NONE; LocalUResourceBundlePointer typeAliasResByKey; LocalUResourceBundlePointer bcpTypeAliasResByKey; if (typeAliasRes.isValid()) { tmpSts = U_ZERO_ERROR; typeAliasResByKey.adoptInstead(ures_getByKey(typeAliasRes.getAlias(), legacyKeyId, NULL, &tmpSts)); if (U_FAILURE(tmpSts)) { typeAliasResByKey.orphan(); } } if (bcpTypeAliasRes.isValid()) { tmpSts = U_ZERO_ERROR; bcpTypeAliasResByKey.adoptInstead(ures_getByKey(bcpTypeAliasRes.getAlias(), bcpKeyId, NULL, &tmpSts)); if (U_FAILURE(tmpSts)) { bcpTypeAliasResByKey.orphan(); } } // look up type map for the key, and walk through the mapping data tmpSts = U_ZERO_ERROR; LocalUResourceBundlePointer typeMapResByKey(ures_getByKey(typeMapRes.getAlias(), legacyKeyId, NULL, &tmpSts)); if (U_FAILURE(tmpSts)) { // type map for each key must exist U_ASSERT(FALSE); } else { LocalUResourceBundlePointer typeMapEntry; while (ures_hasNext(typeMapResByKey.getAlias())) { typeMapEntry.adoptInstead(ures_getNextResource(typeMapResByKey.getAlias(), typeMapEntry.orphan(), &sts)); if (U_FAILURE(sts)) { break; } const char* legacyTypeId = ures_getKey(typeMapEntry.getAlias()); // special types if (uprv_strcmp(legacyTypeId, "CODEPOINTS") == 0) { specialTypes |= SPECIALTYPE_CODEPOINTS; continue; } if (uprv_strcmp(legacyTypeId, "REORDER_CODE") == 0) { specialTypes |= SPECIALTYPE_REORDER_CODE; continue; } if (uprv_strcmp(legacyTypeId, "RG_KEY_VALUE") == 0) { specialTypes |= SPECIALTYPE_RG_KEY_VALUE; continue; } if (isTZ) { // a timezone key uses a colon instead of a slash in the resource. // e.g. America:Los_Angeles if (uprv_strchr(legacyTypeId, ':') != NULL) { int32_t legacyTypeIdLen = uprv_strlen(legacyTypeId); char* legacyTypeIdBuf = (char*)uprv_malloc(legacyTypeIdLen + 1); if (legacyTypeIdBuf == NULL) { sts = U_MEMORY_ALLOCATION_ERROR; break; } const char* p = legacyTypeId; char* q = legacyTypeIdBuf; while (*p) { if (*p == ':') { *q++ = '/'; } else { *q++ = *p; } p++; } *q = 0; gKeyTypeStringPool->addElement(legacyTypeIdBuf, sts); if (U_FAILURE(sts)) { break; } legacyTypeId = legacyTypeIdBuf; } } int32_t bcpTypeIdLen = 0; const UChar* uBcpTypeId = ures_getString(typeMapEntry.getAlias(), &bcpTypeIdLen, &sts); if (U_FAILURE(sts)) { break; } // empty value indicates that BCP type is same with the legacy type. const char* bcpTypeId = legacyTypeId; if (bcpTypeIdLen > 0) { char* bcpTypeIdBuf = (char*)uprv_malloc(bcpTypeIdLen + 1); if (bcpTypeIdBuf == NULL) { sts = U_MEMORY_ALLOCATION_ERROR; break; } u_UCharsToChars(uBcpTypeId, bcpTypeIdBuf, bcpTypeIdLen); bcpTypeIdBuf[bcpTypeIdLen] = 0; gKeyTypeStringPool->addElement(bcpTypeIdBuf, sts); if (U_FAILURE(sts)) { break; } bcpTypeId = bcpTypeIdBuf; } // Note: legacy type value should never be // equivalent to bcp type value of a different // type under the same key. So we use a single // map for lookup. LocExtType* t = (LocExtType*)uprv_malloc(sizeof(LocExtType)); if (t == NULL) { sts = U_MEMORY_ALLOCATION_ERROR; break; } t->bcpId = bcpTypeId; t->legacyId = legacyTypeId; gLocExtTypeEntries->addElement((void*)t, sts); if (U_FAILURE(sts)) { break; } uhash_put(typeDataMap, (void*)legacyTypeId, t, &sts); if (bcpTypeId != legacyTypeId) { // different type value uhash_put(typeDataMap, (void*)bcpTypeId, t, &sts); } if (U_FAILURE(sts)) { break; } // also put aliases in the map if (typeAliasResByKey.isValid()) { LocalUResourceBundlePointer typeAliasDataEntry; ures_resetIterator(typeAliasResByKey.getAlias()); while (ures_hasNext(typeAliasResByKey.getAlias()) && U_SUCCESS(sts)) { int32_t toLen; typeAliasDataEntry.adoptInstead(ures_getNextResource(typeAliasResByKey.getAlias(), typeAliasDataEntry.orphan(), &sts)); const UChar* to = ures_getString(typeAliasDataEntry.getAlias(), &toLen, &sts); if (U_FAILURE(sts)) { break; } // check if this is an alias of canoncal legacy type if (uprv_compareInvWithUChar(NULL, legacyTypeId, -1, to, toLen) == 0) { const char* from = ures_getKey(typeAliasDataEntry.getAlias()); if (isTZ) { // replace colon with slash if necessary if (uprv_strchr(from, ':') != NULL) { int32_t fromLen = uprv_strlen(from); char* fromBuf = (char*)uprv_malloc(fromLen + 1); if (fromBuf == NULL) { sts = U_MEMORY_ALLOCATION_ERROR; break; } const char* p = from; char* q = fromBuf; while (*p) { if (*p == ':') { *q++ = '/'; } else { *q++ = *p; } p++; } *q = 0; gKeyTypeStringPool->addElement(fromBuf, sts); if (U_FAILURE(sts)) { break; } from = fromBuf; } } uhash_put(typeDataMap, (void*)from, t, &sts); } } if (U_FAILURE(sts)) { break; } } if (bcpTypeAliasResByKey.isValid()) { LocalUResourceBundlePointer bcpTypeAliasDataEntry; ures_resetIterator(bcpTypeAliasResByKey.getAlias()); while (ures_hasNext(bcpTypeAliasResByKey.getAlias()) && U_SUCCESS(sts)) { int32_t toLen; bcpTypeAliasDataEntry.adoptInstead(ures_getNextResource(bcpTypeAliasResByKey.getAlias(), bcpTypeAliasDataEntry.orphan(), &sts)); const UChar* to = ures_getString(bcpTypeAliasDataEntry.getAlias(), &toLen, &sts); if (U_FAILURE(sts)) { break; } // check if this is an alias of bcp type if (uprv_compareInvWithUChar(NULL, bcpTypeId, -1, to, toLen) == 0) { const char* from = ures_getKey(bcpTypeAliasDataEntry.getAlias()); uhash_put(typeDataMap, (void*)from, t, &sts); } } if (U_FAILURE(sts)) { break; } } } } if (U_FAILURE(sts)) { break; } LocExtKeyData* keyData = (LocExtKeyData*)uprv_malloc(sizeof(LocExtKeyData)); if (keyData == NULL) { sts = U_MEMORY_ALLOCATION_ERROR; break; } keyData->bcpId = bcpKeyId; keyData->legacyId = legacyKeyId; keyData->specialTypes = specialTypes; keyData->typeMap = typeDataMap; gLocExtKeyDataEntries->addElement((void*)keyData, sts); if (U_FAILURE(sts)) { break; } uhash_put(gLocExtKeyMap, (void*)legacyKeyId, keyData, &sts); if (legacyKeyId != bcpKeyId) { // different key value uhash_put(gLocExtKeyMap, (void*)bcpKeyId, keyData, &sts); } if (U_FAILURE(sts)) { break; } } }
U_CFUNC UCollator* ucol_open_internal(const char *loc, UErrorCode *status) { const UCollator* UCA = ucol_initUCA(status); /* New version */ if(U_FAILURE(*status)) return 0; UCollator *result = NULL; UResourceBundle *b = ures_open(U_ICUDATA_COLL, loc, status); /* we try to find stuff from keyword */ UResourceBundle *collations = ures_getByKey(b, "collations", NULL, status); UResourceBundle *collElem = NULL; char keyBuffer[256]; // if there is a keyword, we pick it up and try to get elements if(!uloc_getKeywordValue(loc, "collation", keyBuffer, 256, status)) { // no keyword. we try to find the default setting, which will give us the keyword value UErrorCode intStatus = U_ZERO_ERROR; // finding default value does not affect collation fallback status UResourceBundle *defaultColl = ures_getByKeyWithFallback(collations, "default", NULL, &intStatus); if(U_SUCCESS(intStatus)) { int32_t defaultKeyLen = 0; const UChar *defaultKey = ures_getString(defaultColl, &defaultKeyLen, &intStatus); u_UCharsToChars(defaultKey, keyBuffer, defaultKeyLen); keyBuffer[defaultKeyLen] = 0; } else { *status = U_INTERNAL_PROGRAM_ERROR; return NULL; } ures_close(defaultColl); } collElem = ures_getByKeyWithFallback(collations, keyBuffer, collElem, status); UResourceBundle *binary = NULL; if(*status == U_MISSING_RESOURCE_ERROR) { /* We didn't find the tailoring data, we fallback to the UCA */ *status = U_USING_DEFAULT_WARNING; result = ucol_initCollator(UCA->image, result, UCA, status); // if we use UCA, real locale is root result->rb = ures_open(U_ICUDATA_COLL, "", status); result->elements = ures_open(U_ICUDATA_COLL, "", status); if(U_FAILURE(*status)) { goto clean; } ures_close(b); result->hasRealData = FALSE; } else if(U_SUCCESS(*status)) { int32_t len = 0; UErrorCode binaryStatus = U_ZERO_ERROR; binary = ures_getByKey(collElem, "%%CollationBin", NULL, &binaryStatus); if(binaryStatus == U_MISSING_RESOURCE_ERROR) { /* we didn't find the binary image, we should use the rules */ binary = NULL; result = tryOpeningFromRules(collElem, status); if(U_FAILURE(*status)) { goto clean; } } else if(U_SUCCESS(*status)) { /* otherwise, we'll pick a collation data that exists */ const uint8_t *inData = ures_getBinary(binary, &len, status); UCATableHeader *colData = (UCATableHeader *)inData; if(uprv_memcmp(colData->UCAVersion, UCA->image->UCAVersion, sizeof(UVersionInfo)) != 0 || uprv_memcmp(colData->UCDVersion, UCA->image->UCDVersion, sizeof(UVersionInfo)) != 0 || colData->version[0] != UCOL_BUILDER_VERSION) { *status = U_DIFFERENT_UCA_VERSION; result = tryOpeningFromRules(collElem, status); } else { if(U_FAILURE(*status)){ goto clean; } if((uint32_t)len > (paddedsize(sizeof(UCATableHeader)) + paddedsize(sizeof(UColOptionSet)))) { result = ucol_initCollator((const UCATableHeader *)inData, result, UCA, status); if(U_FAILURE(*status)){ goto clean; } result->hasRealData = TRUE; } else { result = ucol_initCollator(UCA->image, result, UCA, status); ucol_setOptionsFromHeader(result, (UColOptionSet *)(inData+((const UCATableHeader *)inData)->options), status); if(U_FAILURE(*status)){ goto clean; } result->hasRealData = FALSE; } result->freeImageOnClose = FALSE; } } result->rb = b; result->elements = collElem; len = 0; binaryStatus = U_ZERO_ERROR; result->rules = ures_getStringByKey(result->elements, "Sequence", &len, &binaryStatus); result->rulesLength = len; result->freeRulesOnClose = FALSE; } else { /* There is another error, and we're just gonna clean up */ goto clean; } result->validLocale = NULL; // default is to use rb info if(loc == NULL) { loc = ures_getLocale(result->rb, status); } result->requestedLocale = (char *)uprv_malloc((uprv_strlen(loc)+1)*sizeof(char)); /* test for NULL */ if (result->requestedLocale == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; goto clean; } uprv_strcpy(result->requestedLocale, loc); ures_close(binary); ures_close(collations); //??? we have to decide on that. Probably affects something :) result->resCleaner = ucol_prv_closeResources; return result; clean: ures_close(b); ures_close(collElem); ures_close(collations); ures_close(binary); return NULL; }
EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEra, UErrorCode& status) { if(U_FAILURE(status)) { return nullptr; } LocalUResourceBundlePointer rb(ures_openDirect(nullptr, "supplementalData", &status)); ures_getByKey(rb.getAlias(), "calendarData", rb.getAlias(), &status); ures_getByKey(rb.getAlias(), calType, rb.getAlias(), &status); ures_getByKey(rb.getAlias(), "eras", rb.getAlias(), &status); if (U_FAILURE(status)) { return nullptr; } int32_t numEras = ures_getSize(rb.getAlias()); int32_t firstTentativeIdx = MAX_INT32; LocalMemory<int32_t> startDates(static_cast<int32_t *>(uprv_malloc(numEras * sizeof(int32_t)))); if (startDates.isNull()) { status = U_MEMORY_ALLOCATION_ERROR; return nullptr; } uprv_memset(startDates.getAlias(), 0 , numEras * sizeof(int32_t)); while (ures_hasNext(rb.getAlias())) { LocalUResourceBundlePointer eraRuleRes(ures_getNextResource(rb.getAlias(), nullptr, &status)); if (U_FAILURE(status)) { return nullptr; } const char *eraIdxStr = ures_getKey(eraRuleRes.getAlias()); char *endp; int32_t eraIdx = (int32_t)strtol(eraIdxStr, &endp, 10); if ((size_t)(endp - eraIdxStr) != uprv_strlen(eraIdxStr)) { status = U_INVALID_FORMAT_ERROR; return nullptr; } if (eraIdx < 0 || eraIdx >= numEras) { status = U_INVALID_FORMAT_ERROR; return nullptr; } if (isSet(startDates[eraIdx])) { // start date of the index was already set status = U_INVALID_FORMAT_ERROR; return nullptr; } UBool hasName = TRUE; UBool hasEnd = TRUE; int32_t len; while (ures_hasNext(eraRuleRes.getAlias())) { LocalUResourceBundlePointer res(ures_getNextResource(eraRuleRes.getAlias(), nullptr, &status)); if (U_FAILURE(status)) { return nullptr; } const char *key = ures_getKey(res.getAlias()); if (uprv_strcmp(key, "start") == 0) { const int32_t *fields = ures_getIntVector(res.getAlias(), &len, &status); if (U_FAILURE(status)) { return nullptr; } if (len != 3 || !isValidRuleStartDate(fields[0], fields[1], fields[2])) { status = U_INVALID_FORMAT_ERROR; return nullptr; } startDates[eraIdx] = encodeDate(fields[0], fields[1], fields[2]); } else if (uprv_strcmp(key, "named") == 0) { const UChar *val = ures_getString(res.getAlias(), &len, &status); if (u_strncmp(val, VAL_FALSE, VAL_FALSE_LEN) == 0) { hasName = FALSE; } } else if (uprv_strcmp(key, "end") == 0) { hasEnd = TRUE; } } if (isSet(startDates[eraIdx])) { if (hasEnd) { // This implementation assumes either start or end is available, not both. // For now, just ignore the end rule. } } else { if (hasEnd) { if (eraIdx != 0) { // This implementation does not support end only rule for eras other than // the first one. status = U_INVALID_FORMAT_ERROR; return nullptr; } U_ASSERT(eraIdx == 0); startDates[eraIdx] = MIN_ENCODED_START; } else { status = U_INVALID_FORMAT_ERROR; return nullptr; } } if (hasName) { if (eraIdx >= firstTentativeIdx) { status = U_INVALID_FORMAT_ERROR; return nullptr; } } else { if (eraIdx < firstTentativeIdx) { firstTentativeIdx = eraIdx; } } } EraRules *result; if (firstTentativeIdx < MAX_INT32 && !includeTentativeEra) { result = new EraRules(startDates, firstTentativeIdx); } else { result = new EraRules(startDates, numEras); } if (result == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; } return result; }
static void printOutBundle(FILE *out, UConverter *converter, UResourceBundle *resource, int32_t indent, const char *pname, UErrorCode *status) { static const UChar cr[] = { '\n' }; /* int32_t noOfElements = ures_getSize(resource);*/ int32_t i = 0; const char *key = ures_getKey(resource); switch(ures_getType(resource)) { case RES_STRING : { int32_t len=0; const UChar* thestr = ures_getString(resource, &len, status); UChar *string = quotedString(thestr); /* TODO: String truncation */ if(trunc && len > truncsize) { char msg[128]; printIndent(out, converter, indent); sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n", (long)len, (long)(truncsize/2)); printCString(out, converter, msg, -1); len = truncsize/2; } printIndent(out, converter, indent); if(key != NULL) { static const UChar openStr[] = { 0x0020, 0x007B, 0x0020, 0x0022 }; /* " { \"" */ static const UChar closeStr[] = { 0x0022, 0x0020, 0x007D }; /* "\" }" */ printCString(out, converter, key, (int32_t)uprv_strlen(key)); printString(out, converter, openStr, (int32_t)(sizeof(openStr)/sizeof(*openStr))); printString(out, converter, string, len); printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); } else { static const UChar openStr[] = { 0x0022 }; /* "\"" */ static const UChar closeStr[] = { 0x0022, 0x002C }; /* "\"," */ printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); printString(out, converter, string, (int32_t)(u_strlen(string))); printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); } if(verbose) { printCString(out, converter, "// STRING", -1); } printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); uprv_free(string); } break; case RES_INT : { static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0020, 0x007B, 0x0020 }; /* ":int { " */ static const UChar closeStr[] = { 0x0020, 0x007D }; /* " }" */ UChar num[20]; printIndent(out, converter, indent); if(key != NULL) { printCString(out, converter, key, -1); } printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); uprv_itou(num, 20, ures_getInt(resource, status), 10, 0); printString(out, converter, num, u_strlen(num)); printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); if(verbose) { printCString(out, converter, "// INT", -1); } printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); break; } case RES_BINARY : { int32_t len = 0; const int8_t *data = (const int8_t *)ures_getBinary(resource, &len, status); if(trunc && len > truncsize) { char msg[128]; printIndent(out, converter, indent); sprintf(msg, "// WARNING: this resource, size %li is truncated to %li\n", (long)len, (long)(truncsize/2)); printCString(out, converter, msg, -1); len = truncsize; } if(U_SUCCESS(*status)) { static const UChar openStr[] = { 0x003A, 0x0062, 0x0069, 0x006E, 0x0061, 0x0072, 0x0079, 0x0020, 0x007B, 0x0020 }; /* ":binary { " */ static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */ printIndent(out, converter, indent); if(key != NULL) { printCString(out, converter, key, -1); } printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); for(i = 0; i<len; i++) { printHex(out, converter, *data++); } printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); if(verbose) { printCString(out, converter, " // BINARY", -1); } printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); } else { reportError(pname, status, "getting binary value"); } } break; case RES_INT_VECTOR : { int32_t len = 0; const int32_t *data = ures_getIntVector(resource, &len, status); if(U_SUCCESS(*status)) { static const UChar openStr[] = { 0x003A, 0x0069, 0x006E, 0x0074, 0x0076, 0x0065, 0x0063, 0x0074, 0x006F, 0x0072, 0x0020, 0x007B, 0x0020 }; /* ":intvector { " */ static const UChar closeStr[] = { 0x0020, 0x007D, 0x0020 }; /* " } " */ UChar num[20]; printIndent(out, converter, indent); if(key != NULL) { printCString(out, converter, key, -1); } printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); for(i = 0; i < len - 1; i++) { int32_t numLen = uprv_itou(num, 20, data[i], 10, 0); num[numLen++] = 0x002C; /* ',' */ num[numLen++] = 0x0020; /* ' ' */ num[numLen] = 0; printString(out, converter, num, u_strlen(num)); } if(len > 0) { uprv_itou(num, 20, data[len - 1], 10, 0); printString(out, converter, num, u_strlen(num)); } printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); if(verbose) { printCString(out, converter, "// INTVECTOR", -1); } printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); } else { reportError(pname, status, "getting int vector"); } } break; case RES_TABLE : case RES_ARRAY : { static const UChar openStr[] = { 0x007B }; /* "{" */ static const UChar closeStr[] = { 0x007D, '\n' }; /* "}\n" */ UResourceBundle *t = NULL; ures_resetIterator(resource); printIndent(out, converter, indent); if(key != NULL) { printCString(out, converter, key, -1); } printString(out, converter, openStr, (int32_t)(sizeof(openStr) / sizeof(*openStr))); if(verbose) { if(ures_getType(resource) == RES_TABLE) { printCString(out, converter, "// TABLE", -1); } else { printCString(out, converter, "// ARRAY", -1); } } printString(out, converter, cr, (int32_t)(sizeof(cr) / sizeof(*cr))); if(suppressAliases == FALSE) { while(U_SUCCESS(*status) && ures_hasNext(resource)) { t = ures_getNextResource(resource, t, status); if(U_SUCCESS(*status)) { printOutBundle(out, converter, t, indent+indentsize, pname, status); } else { reportError(pname, status, "While processing table"); *status = U_ZERO_ERROR; } } } else { /* we have to use low level access to do this */ Resource r = RES_BOGUS; for(i = 0; i < ures_getSize(resource); i++) { /* need to know if it's an alias */ if(ures_getType(resource) == RES_TABLE) { r = derb_getTableItem(resource->fResData.pRoot, resource->fRes, (int16_t)i); key = derb_getTableKey(resource->fResData.pRoot, resource->fRes, (int16_t)i); } else { r = derb_getArrayItem(resource->fResData.pRoot, resource->fRes, i); } if(U_SUCCESS(*status)) { if(RES_GET_TYPE(r) == RES_ALIAS) { printOutAlias(out, converter, resource, r, key, indent+indentsize, pname, status); } else { t = ures_getByIndex(resource, i, t, status); printOutBundle(out, converter, t, indent+indentsize, pname, status); } } else { reportError(pname, status, "While processing table"); *status = U_ZERO_ERROR; } } } printIndent(out, converter, indent); printString(out, converter, closeStr, (int32_t)(sizeof(closeStr) / sizeof(*closeStr))); ures_close(t); } break; default: break; } }
UBool Transliterator::initializeRegistry(UErrorCode &status) { if (registry != 0) { return TRUE; } registry = new TransliteratorRegistry(status); if (registry == 0 || U_FAILURE(status)) { delete registry; registry = 0; return FALSE; // can't create registry, no recovery } /* The following code parses the index table located in * icu/data/translit/root.txt. The index is an n x 4 table * that follows this format: * <id>{ * file{ * resource{"<resource>"} * direction{"<direction>"} * } * } * <id>{ * internal{ * resource{"<resource>"} * direction{"<direction"} * } * } * <id>{ * alias{"<getInstanceArg"} * } * <id> is the ID of the system transliterator being defined. These * are public IDs enumerated by Transliterator.getAvailableIDs(), * unless the second field is "internal". * * <resource> is a ResourceReader resource name. Currently these refer * to file names under com/ibm/text/resources. This string is passed * directly to ResourceReader, together with <encoding>. * * <direction> is either "FORWARD" or "REVERSE". * * <getInstanceArg> is a string to be passed directly to * Transliterator.getInstance(). The returned Transliterator object * then has its ID changed to <id> and is returned. * * The extra blank field on "alias" lines is to make the array square. */ //static const char translit_index[] = "translit_index"; UResourceBundle *bundle, *transIDs, *colBund; bundle = ures_open(U_ICUDATA_TRANSLIT, NULL/*open default locale*/, &status); transIDs = ures_getByKey(bundle, RB_RULE_BASED_IDS, 0, &status); int32_t row, maxRows; if (U_SUCCESS(status)) { maxRows = ures_getSize(transIDs); for (row = 0; row < maxRows; row++) { colBund = ures_getByIndex(transIDs, row, 0, &status); if (U_SUCCESS(status)) { UnicodeString id(ures_getKey(colBund), -1, US_INV); UResourceBundle* res = ures_getNextResource(colBund, NULL, &status); const char* typeStr = ures_getKey(res); UChar type; u_charsToUChars(typeStr, &type, 1); if (U_SUCCESS(status)) { int32_t len = 0; const UChar *resString; switch (type) { case 0x66: // 'f' case 0x69: // 'i' // 'file' or 'internal'; // row[2]=resource, row[3]=direction { resString = ures_getStringByKey(res, "resource", &len, &status); UBool visible = (type == 0x0066 /*f*/); UTransDirection dir = (ures_getUnicodeStringByKey(res, "direction", &status).charAt(0) == 0x0046 /*F*/) ? UTRANS_FORWARD : UTRANS_REVERSE; registry->put(id, UnicodeString(TRUE, resString, len), dir, TRUE, visible, status); } break; case 0x61: // 'a' // 'alias'; row[2]=createInstance argument resString = ures_getString(res, &len, &status); registry->put(id, UnicodeString(TRUE, resString, len), TRUE, TRUE, status); break; } } ures_close(res); } ures_close(colBund); } } ures_close(transIDs); ures_close(bundle); // Manually add prototypes that the system knows about to the // cache. This is how new non-rule-based transliterators are // added to the system. // This is to allow for null pointer check NullTransliterator* tempNullTranslit = new NullTransliterator(); LowercaseTransliterator* tempLowercaseTranslit = new LowercaseTransliterator(); UppercaseTransliterator* tempUppercaseTranslit = new UppercaseTransliterator(); TitlecaseTransliterator* tempTitlecaseTranslit = new TitlecaseTransliterator(); UnicodeNameTransliterator* tempUnicodeTranslit = new UnicodeNameTransliterator(); NameUnicodeTransliterator* tempNameUnicodeTranslit = new NameUnicodeTransliterator(); #if !UCONFIG_NO_BREAK_ITERATION // TODO: could or should these transliterators be referenced polymorphically once constructed? BreakTransliterator* tempBreakTranslit = new BreakTransliterator(); #endif // Check for null pointers if (tempNullTranslit == NULL || tempLowercaseTranslit == NULL || tempUppercaseTranslit == NULL || tempTitlecaseTranslit == NULL || tempUnicodeTranslit == NULL || #if !UCONFIG_NO_BREAK_ITERATION tempBreakTranslit == NULL || #endif tempNameUnicodeTranslit == NULL ) { delete tempNullTranslit; delete tempLowercaseTranslit; delete tempUppercaseTranslit; delete tempTitlecaseTranslit; delete tempUnicodeTranslit; delete tempNameUnicodeTranslit; #if !UCONFIG_NO_BREAK_ITERATION delete tempBreakTranslit; #endif // Since there was an error, remove registry delete registry; registry = NULL; status = U_MEMORY_ALLOCATION_ERROR; return 0; } registry->put(tempNullTranslit, TRUE, status); registry->put(tempLowercaseTranslit, TRUE, status); registry->put(tempUppercaseTranslit, TRUE, status); registry->put(tempTitlecaseTranslit, TRUE, status); registry->put(tempUnicodeTranslit, TRUE, status); registry->put(tempNameUnicodeTranslit, TRUE, status); #if !UCONFIG_NO_BREAK_ITERATION registry->put(tempBreakTranslit, FALSE, status); // FALSE means invisible. #endif RemoveTransliterator::registerIDs(); // Must be within mutex EscapeTransliterator::registerIDs(); UnescapeTransliterator::registerIDs(); NormalizationTransliterator::registerIDs(); AnyTransliterator::registerIDs(); _registerSpecialInverse(UNICODE_STRING_SIMPLE("Null"), UNICODE_STRING_SIMPLE("Null"), FALSE); _registerSpecialInverse(UNICODE_STRING_SIMPLE("Upper"), UNICODE_STRING_SIMPLE("Lower"), TRUE); _registerSpecialInverse(UNICODE_STRING_SIMPLE("Title"), UNICODE_STRING_SIMPLE("Lower"), FALSE); ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, utrans_transliterator_cleanup); return TRUE; }
U_CFUNC const char* U_EXPORT2 uprv_detectWindowsTimeZone() { UErrorCode status = U_ZERO_ERROR; UResourceBundle* bundle = NULL; char* icuid = NULL; LONG result; TZI tziKey; TZI tziReg; TIME_ZONE_INFORMATION apiTZI; /* Obtain TIME_ZONE_INFORMATION from the API, and then convert it to TZI. We could also interrogate the registry directly; we do this below if needed. */ uprv_memset(&apiTZI, 0, sizeof(apiTZI)); uprv_memset(&tziKey, 0, sizeof(tziKey)); uprv_memset(&tziReg, 0, sizeof(tziReg)); GetTimeZoneInformation(&apiTZI); tziKey.bias = apiTZI.Bias; uprv_memcpy((char *)&tziKey.standardDate, (char*)&apiTZI.StandardDate, sizeof(apiTZI.StandardDate)); uprv_memcpy((char *)&tziKey.daylightDate, (char*)&apiTZI.DaylightDate, sizeof(apiTZI.DaylightDate)); bundle = ures_openDirect(NULL, "supplementalData", &status); bundle = ures_getByKey(bundle, "mapTimezones", bundle, &status); bundle = ures_getByKey(bundle, "windows", bundle, &status); /* Note: We get the winid not from static tables but from resource bundle. */ while (U_SUCCESS(status) && ures_hasNext(bundle)) { const char* winid; int32_t len; UResourceBundle* winTZ = ures_getNextResource(bundle, NULL, &status); if (U_FAILURE(status)) { break; } winid = ures_getKey(winTZ); result = getTZI(winid, &tziReg); if (result == ERROR_SUCCESS) { /* Windows alters the DaylightBias in some situations. Using the bias and the rules suffices, so overwrite these unreliable fields. */ tziKey.standardBias = tziReg.standardBias; tziKey.daylightBias = tziReg.daylightBias; if (uprv_memcmp((char *)&tziKey, (char*)&tziReg, sizeof(tziKey)) == 0) { const UChar* icuTZ = ures_getString(winTZ, &len, &status); if (U_SUCCESS(status)) { icuid = (char*)uprv_malloc(sizeof(char) * (len + 1)); uprv_memset(icuid, 0, len + 1); u_austrncpy(icuid, icuTZ, len); } } } ures_close(winTZ); if (icuid != NULL) { break; } } ures_close(bundle); return icuid; }
// populatePower10 grabs data for a particular power of 10 from CLDR. // The loaded data is stored in result. static void populatePower10(const UResourceBundle* power10Bundle, CDFLocaleStyleData* result, UErrorCode& status) { if (U_FAILURE(status)) { return; } char* endPtr = NULL; double power10 = uprv_strtod(ures_getKey(power10Bundle), &endPtr); if (*endPtr != 0) { status = U_INTERNAL_PROGRAM_ERROR; return; } int32_t log10Value = computeLog10(power10, FALSE); // Silently ignore divisors that are too big. if (log10Value == MAX_DIGITS) { return; } int32_t size = ures_getSize(power10Bundle); int32_t numZeros = 0; UBool otherVariantDefined = FALSE; UResourceBundle* variantBundle = NULL; // Iterate over all the plural variants for the power of 10 for (int32_t i = 0; i < size; ++i) { variantBundle = ures_getByIndex(power10Bundle, i, variantBundle, &status); if (U_FAILURE(status)) { ures_close(variantBundle); return; } const char* variant = ures_getKey(variantBundle); int32_t resLen; const UChar* formatStrP = ures_getString(variantBundle, &resLen, &status); if (U_FAILURE(status)) { ures_close(variantBundle); return; } UnicodeString formatStr(false, formatStrP, resLen); if (uprv_strcmp(variant, gOther) == 0) { otherVariantDefined = TRUE; } int32_t nz = populatePrefixSuffix( variant, log10Value, formatStr, result->unitsByVariant, status); if (U_FAILURE(status)) { ures_close(variantBundle); return; } if (nz != numZeros) { // We expect all format strings to have the same number of 0's // left of the decimal point. if (numZeros != 0) { status = U_INTERNAL_PROGRAM_ERROR; ures_close(variantBundle); return; } numZeros = nz; } } ures_close(variantBundle); // We expect to find an OTHER variant for each power of 10. if (!otherVariantDefined) { status = U_INTERNAL_PROGRAM_ERROR; return; } double divisor = power10; for (int32_t i = 1; i < numZeros; ++i) { divisor /= 10.0; } result->divisors[log10Value] = divisor; }
/* Test whether apps and ICU can each have their own root.res */ static void TestAppData() { UResourceBundle *icu, *app; UResourceBundle *tmp = NULL; UResourceBundle *tmp2 = NULL; const UChar *appString; const UChar *icuString; int32_t len; UErrorCode status = U_ZERO_ERROR; char testMsgBuf[256]; const char* testPath=loadTestData(&status); icu = ures_open(NULL, "root", &status); if(U_FAILURE(status)) { log_err("%s:%d: Couldn't open root ICU bundle- %s", __FILE__, __LINE__, u_errorName(status)); return; } /* log_info("Open icu root: %s size_%d\n", u_errorName(status), ures_getSize(icu)); */ status = U_ZERO_ERROR; app = ures_open(testPath, "root", &status); if(U_FAILURE(status)) { log_err("%s:%d: Couldn't open app ICU bundle [%s]- %s", __FILE__, __LINE__, testPath, u_errorName(status)); return; } /* log_info("Open app: %s, size %d\n", u_errorName(status), ures_getSize(app)); */ tmp = ures_getByKey(icu, "Version", tmp, &status); if(U_FAILURE(status)) { log_err("%s:%d: Couldn't get Version string from ICU root bundle- %s", __FILE__, __LINE__, u_errorName(status)); return; } icuString = ures_getString(tmp, &len, &status); if(U_FAILURE(status)) { log_err("%s:%d: Couldn't get string from Version string from ICU root bundle- %s", __FILE__, __LINE__, u_errorName(status)); return; } /* log_info("icuString=%p - %s\n", icuString, austrdup(icuString)); */ tmp2 = ures_getByKey(app, "Version", tmp2, &status); if(U_FAILURE(status)) { log_err("%s:%d: Couldn't get Version string from App root bundle- %s", __FILE__, __LINE__, u_errorName(status)); return; } appString = ures_getString(tmp2, &len, &status); if(U_FAILURE(status)) { log_err("%s:%d: Couldn't get string from Version string from App root bundle- %s", __FILE__, __LINE__, u_errorName(status)); return; } /* log_info("appString=%p - %s\n", appString, austrdup(appString)); */ if(!u_strcmp(icuString, appString)) { log_err("%s:%d: Error! Expected ICU and App root version strings to be DIFFERENT but they are both %s and %s\n", __FILE__, __LINE__, austrdup(icuString), austrdup(appString)); } else { log_verbose("%s:%d: appstr=%s, icustr=%s\n", __FILE__, __LINE__, u_austrcpy(testMsgBuf, appString), u_austrcpy(testMsgBuf, icuString)); } ures_close(tmp); ures_close(tmp2); ures_close(icu); ures_close(app); }
static jstring getCurrencyCodeNative(JNIEnv* env, jclass clazz, jstring key) { // LOGI("ENTER getCurrencyCodeNative"); UErrorCode status = U_ZERO_ERROR; UResourceBundle *supplData = ures_openDirect(NULL, "supplementalData", &status); if(U_FAILURE(status)) { return NULL; } UResourceBundle *currencyMap = ures_getByKey(supplData, "CurrencyMap", NULL, &status); if(U_FAILURE(status)) { ures_close(supplData); return NULL; } const char *keyChars = env->GetStringUTFChars(key, NULL); UResourceBundle *currency = ures_getByKey(currencyMap, keyChars, NULL, &status); env->ReleaseStringUTFChars(key, keyChars); if(U_FAILURE(status)) { ures_close(currencyMap); ures_close(supplData); return NULL; } UResourceBundle *currencyElem = ures_getByIndex(currency, 0, NULL, &status); if(U_FAILURE(status)) { ures_close(currency); ures_close(currencyMap); ures_close(supplData); return NULL; } UResourceBundle *currencyId = ures_getByKey(currencyElem, "id", NULL, &status); if(U_FAILURE(status)) { ures_close(currencyElem); ures_close(currency); ures_close(currencyMap); ures_close(supplData); return NULL; } int length; const jchar *id = ures_getString(currencyId, &length, &status); if(U_FAILURE(status)) { ures_close(currencyId); ures_close(currencyElem); ures_close(currency); ures_close(currencyMap); ures_close(supplData); return NULL; } ures_close(currencyId); ures_close(currencyElem); ures_close(currency); ures_close(currencyMap); ures_close(supplData); if(length == 0) { return NULL; } return env->NewString(id, length); }
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; }
UnicodeString ResourceBundle::getString(UErrorCode& status) const { int32_t len = 0; const UChar *r = ures_getString(fResource, &len, &status); return UnicodeString(TRUE, r, len); }