void CalendarData::initData(const char *locale, const char *type, UErrorCode& status) { fOtherFillin = ures_open(U_CALENDAR_DATA, locale, &status); fFillin = ures_getByKey(fOtherFillin, U_CALENDAR_KEY, fFillin, &status); if((type != NULL) && (*type != '\0') && (uprv_strcmp(type, U_GREGORIAN_KEY))) { fBundle = ures_getByKeyWithFallback(fFillin, type, NULL, &status); fFallback = ures_getByKeyWithFallback(fFillin, U_GREGORIAN_KEY, NULL, &status); #if defined (U_DEBUG_CALDATA) fprintf(stderr, "%p: CalendarData(%s, %s, %s) -> main(%p, %s)=%s, fallback(%p, %s)=%s\n", this, locale, type, u_errorName(status), fBundle, type, fBundle?ures_getLocale(fBundle, &status):"", fFallback, U_GREGORIAN_KEY, fFallback?ures_getLocale(fFallback, &status):""); #endif } else { fBundle = ures_getByKeyWithFallback(fFillin, U_GREGORIAN_KEY, NULL, &status); #if defined (U_DEBUG_CALDATA) fprintf(stderr, "%p: CalendarData(%s, %s, %s) -> main(%p, %s)=%s, fallback = NULL\n", this, locale, type, u_errorName(status), fBundle, U_GREGORIAN_KEY, fBundle?ures_getLocale(fBundle, &status):"" ); #endif } }
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; }
static void TestOpenDirect(void) { UResourceBundle *idna_rules, *casing, *te_IN, *ne, *item; UErrorCode errorCode; /* * test that ures_openDirect() opens a resource bundle * where one can look up its own items but not fallback items * from root or similar */ errorCode=U_ZERO_ERROR; idna_rules=ures_openDirect(loadTestData(&errorCode), "idna_rules", &errorCode); if(U_FAILURE(errorCode)) { log_data_err("ures_openDirect(\"idna_rules\") failed: %s\n", u_errorName(errorCode)); return; } if(0!=uprv_strcmp("idna_rules", ures_getLocale(idna_rules, &errorCode))) { log_err("ures_openDirect(\"idna_rules\").getLocale()!=idna_rules\n"); } errorCode=U_ZERO_ERROR; /* try an item in idna_rules, must work */ item=ures_getByKey(idna_rules, "UnassignedSet", NULL, &errorCode); if(U_FAILURE(errorCode)) { log_err("translit_index.getByKey(local key) failed: %s\n", u_errorName(errorCode)); errorCode=U_ZERO_ERROR; } else { ures_close(item); } /* try an item in root, must fail */ item=ures_getByKey(idna_rules, "ShortLanguage", NULL, &errorCode); if(U_FAILURE(errorCode)) { errorCode=U_ZERO_ERROR; } else { log_err("idna_rules.getByKey(root key) succeeded!\n"); ures_close(item); } ures_close(idna_rules); /* now make sure that "idna_rules" will not work with ures_open() */ errorCode=U_ZERO_ERROR; idna_rules=ures_open("testdata", "idna_rules", &errorCode); if(U_FAILURE(errorCode) || errorCode==U_USING_DEFAULT_WARNING || errorCode==U_USING_FALLBACK_WARNING) { /* falling back to default or root is ok */ errorCode=U_ZERO_ERROR; } else if(0!=uprv_strcmp("idna_rules", ures_getLocale(idna_rules, &errorCode))) { /* Opening this file will work in "files mode" on Windows and the Mac, which have case insensitive file systems */ log_err("ures_open(\"idna_rules\") succeeded, should fail! Got: %s\n", u_errorName(errorCode)); } ures_close(idna_rules); /* ures_openDirect("translit_index_WronG") must fail */ idna_rules=ures_openDirect(NULL, "idna_rules_WronG", &errorCode); if(U_FAILURE(errorCode)) { errorCode=U_ZERO_ERROR; } else { log_err("ures_openDirect(\"idna_rules_WronG\") succeeded, should fail!\n"); } ures_close(idna_rules); errorCode = U_USING_FALLBACK_WARNING;; idna_rules=ures_openDirect("testdata", "idna_rules", &errorCode); if(U_FAILURE(errorCode)) { log_data_err("ures_openDirect(\"idna_rules\") failed when U_USING_FALLBACK_WARNING was set prior to call: %s\n", u_errorName(errorCode)); return; } ures_close(idna_rules); /* * ICU 3.6 has new resource bundle syntax and data for bundles that do not * participate in locale fallback. Now, * - ures_open() works like ures_openDirect() on a bundle with a top-level * type of ":table(nofallback)" _if_ the bundle exists * - ures_open() will continue to find a root bundle if the requested one * does not exist, unlike ures_openDirect() * * Test with a different bundle than above to avoid confusion in the cache. */ /* * verify that ures_open("casing"), which now has a nofallback declaration, * does not enable fallbacks */ errorCode=U_ZERO_ERROR; casing=ures_open("testdata", "casing", &errorCode); if(U_FAILURE(errorCode)) { log_data_err("ures_open(\"casing\") failed: %s\n", u_errorName(errorCode)); return; } errorCode=U_ZERO_ERROR; item=ures_getByKey(casing, "Info", NULL, &errorCode); if(U_FAILURE(errorCode)) { log_err("casing.getByKey(Info) failed - %s\n", u_errorName(errorCode)); } else { ures_close(item); } errorCode=U_ZERO_ERROR; item=ures_getByKey(casing, "ShortLanguage", NULL, &errorCode); if(U_SUCCESS(errorCode)) { log_err("casing.getByKey(root key) succeeded despite nofallback declaration - %s\n", u_errorName(errorCode)); ures_close(item); } ures_close(casing); /* * verify that ures_open("ne") finds the root bundle but * ures_openDirect("ne") does not */ errorCode=U_ZERO_ERROR; ne=ures_open("testdata", "ne", &errorCode); if(U_FAILURE(errorCode)) { log_data_err("ures_open(\"ne\") failed (expected to get root): %s\n", u_errorName(errorCode)); } if(errorCode!=U_USING_DEFAULT_WARNING || 0!=uprv_strcmp("root", ures_getLocale(ne, &errorCode))) { log_err("ures_open(\"ne\") found something other than \"root\" - %s\n", u_errorName(errorCode)); } ures_close(ne); errorCode=U_ZERO_ERROR; ne=ures_openDirect("testdata", "ne", &errorCode); if(U_SUCCESS(errorCode)) { log_data_err("ures_openDirect(\"ne\") succeeded unexpectedly\n"); ures_close(ne); } /* verify that ures_openDirect("te_IN") does not enable fallbacks */ errorCode=U_ZERO_ERROR; te_IN=ures_openDirect("testdata", "te_IN", &errorCode); if(U_FAILURE(errorCode)) { log_data_err("ures_open(\"te_IN\") failed: %s\n", u_errorName(errorCode)); return; } errorCode=U_ZERO_ERROR; item=ures_getByKey(te_IN, "ShortLanguage", NULL, &errorCode); if(U_SUCCESS(errorCode)) { log_err("te_IN.getByKey(root key) succeeded despite use of ures_openDirect() - %s\n", u_errorName(errorCode)); ures_close(item); } ures_close(te_IN); }
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; }
UResourceBundle* CalendarData::getByKey3(const char *key, const char *contextKey, const char *subKey, UErrorCode& status) { if(U_FAILURE(status)) { return NULL; } if(fBundle) { #if defined (U_DEBUG_CALDATA) fprintf(stderr, "%p: //\n"); #endif fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status); fOtherFillin = ures_getByKeyWithFallback(fFillin, contextKey, fOtherFillin, &status); fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); #if defined (U_DEBUG_CALDATA) fprintf(stderr, "%p: get %s/%s/%s -> %s - from MAIN %s\n", this, key, contextKey, subKey, u_errorName(status), ures_getLocale(fFillin, &status)); #endif } if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) { status = U_ZERO_ERROR; // retry with fallback (gregorian) fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status); fOtherFillin = ures_getByKeyWithFallback(fFillin, contextKey, fOtherFillin, &status); fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); #if defined (U_DEBUG_CALDATA) fprintf(stderr, "%p: get %s/%s/%s -> %s - from FALLBACK %s\n",this, key, contextKey, subKey, u_errorName(status), ures_getLocale(fFillin,&status)); #endif } return fFillin; }
UResourceBundle* CalendarData::getByKey2(const char *key, const char *subKey, UErrorCode& status) { if(U_FAILURE(status)) { return NULL; } if(fBundle) { #if defined (U_DEBUG_CALDATA) fprintf(stderr, "%p: //\n"); #endif fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status); fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status); fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); #if defined (U_DEBUG_CALDATA) fprintf(stderr, "%p: get %s/format/%s -> %s - from MAIN %s\n", this, key, subKey, u_errorName(status), ures_getLocale(fFillin, &status)); #endif } if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) { status = U_ZERO_ERROR; // retry with fallback (gregorian) fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status); fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status); fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); #if defined (U_DEBUG_CALDATA) fprintf(stderr, "%p: get %s/format/%s -> %s - from FALLBACK %s\n",this, key, subKey, u_errorName(status), ures_getLocale(fFillin,&status)); #endif } //// handling of 'default' keyword on failure: Commented out for 3.0. // if((status == U_MISSING_RESOURCE_ERROR) && // uprv_strcmp(subKey,U_DEFAULT_KEY)) { // avoid recursion // #if defined (U_DEBUG_CALDATA) // fprintf(stderr, "%p: - attempting fallback -\n", this); // fflush(stderr); // #endif // UErrorCode subStatus = U_ZERO_ERROR; // int32_t len; // char kwBuf[128] = ""; // const UChar *kw; // /* fFillin = */ getByKey2(key, U_DEFAULT_KEY, subStatus); // kw = ures_getString(fFillin, &len, &subStatus); // if(len>126) { // too big // len = 0; // } // if(U_SUCCESS(subStatus) && (len>0)) { // u_UCharsToChars(kw, kwBuf, len+1); // if(*kwBuf && uprv_strcmp(kwBuf,subKey)) { // #if defined (U_DEBUG_CALDATA) // fprintf(stderr, "%p: trying %s/format/default -> \"%s\"\n",this, key, kwBuf); // #endif // // now try again with the default // status = U_ZERO_ERROR; // /* fFillin = */ getByKey2(key, kwBuf, status); // } // #if defined (U_DEBUG_CALDATA) // } else { // fprintf(stderr, "%p: could not load %s/format/default - fail out (%s)\n",this, key, kwBuf, u_errorName(status)); // #endif // } // } return fFillin; }