int32_t FieldsSet::parseFrom(const UnicodeString& str, const FieldsSet* inheritFrom, UErrorCode& status) { int goodFields = 0; if(U_FAILURE(status)) { return -1; } int32_t destCount = 0; UnicodeString *dest = split(str, 0x002C /* ',' */, destCount); for(int i = 0; i < destCount; i += 1) { int32_t dc = 0; UnicodeString *kv = split(dest[i], 0x003D /* '=' */, dc); if(dc != 2) { it_errln(UnicodeString("dc == ") + dc + UnicodeString("?")); } int32_t field = handleParseName(inheritFrom, kv[0], kv[1], status); if(U_FAILURE(status)) { char ch[256]; const UChar *u = kv[0].getBuffer(); int32_t len = kv[0].length(); u_UCharsToChars(u, ch, len); ch[len] = 0; /* include terminating \0 */ it_errln(UnicodeString("Parse Failed: Field ") + UnicodeString(ch) + UnicodeString(", err ") + UnicodeString(u_errorName(status))); return -1; } if(field != -1) { handleParseValue(inheritFrom, field, kv[1], status); if(U_FAILURE(status)) { char ch[256]; const UChar *u = kv[1].getBuffer(); int32_t len = kv[1].length(); u_UCharsToChars(u, ch, len); ch[len] = 0; /* include terminating \0 */ it_errln(UnicodeString("Parse Failed: Value ") + UnicodeString(ch) + UnicodeString(", err ") + UnicodeString(u_errorName(status))); return -1; } goodFields += 1; } delete[] kv; } delete[] dest; return goodFields; }
static void TestJitterbug1098(){ UChar rule[1000]; UCollator* c1 = NULL; UErrorCode status = U_ZERO_ERROR; UParseError parseError; char preContext[200]={0}; char postContext[200]={0}; int i=0; const char* rules[] = { "&''<\\\\", "&\\'<\\\\", "&\\\"<'\\'", "&'\"'<\\'", '\0' }; const UCollationResult results1098[] = { UCOL_LESS, UCOL_LESS, UCOL_LESS, UCOL_LESS, }; const UChar input[][2]= { {0x0027,0x005c}, {0x0027,0x005c}, {0x0022,0x005c}, {0x0022,0x0027}, }; UChar X[2] ={0}; UChar Y[2] ={0}; u_memset(parseError.preContext,0x0000,U_PARSE_CONTEXT_LEN); u_memset(parseError.postContext,0x0000,U_PARSE_CONTEXT_LEN); for(;rules[i]!=0;i++){ u_uastrcpy(rule, rules[i]); c1 = ucol_openRules(rule, u_strlen(rule), UCOL_OFF, UCOL_DEFAULT_STRENGTH, &parseError, &status); if(U_FAILURE(status)){ log_err("Could not parse the rules syntax. Error: %s ", u_errorName(status)); if (status == U_PARSE_ERROR) { u_UCharsToChars(parseError.preContext,preContext,20); u_UCharsToChars(parseError.postContext,postContext,20); log_verbose("\n\tPre-Context: %s \n\tPost-Context:%s \n",preContext,postContext); } return; } X[0] = input[i][0]; Y[0] = input[i][1]; doTest(c1,X,Y,results1098[i]); ucol_close(c1); } }
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; }
const UChar* ZoneMeta::getShortIDFromCanonical(const UChar* canonicalID) { const UChar* shortID = NULL; int32_t len = u_strlen(canonicalID); char tzidKey[ZID_KEY_MAX + 1]; u_UCharsToChars(canonicalID, tzidKey, len); tzidKey[len] = (char) 0; // Make sure it is null terminated. // replace '/' with ':' char *p = tzidKey; while (*p++) { if (*p == '/') { *p = ':'; } } UErrorCode status = U_ZERO_ERROR; UResourceBundle *rb = ures_openDirect(NULL, gKeyTypeData, &status); ures_getByKey(rb, gTypeMapTag, rb, &status); ures_getByKey(rb, gTimezoneTag, rb, &status); shortID = ures_getStringByKey(rb, tzidKey, NULL, &status); ures_close(rb); return shortID; }
NumberingSystem* U_EXPORT2 NumberingSystem::createInstance(const Locale & inLocale, UErrorCode& status) { char buffer[ULOC_KEYWORDS_CAPACITY]; int32_t count = inLocale.getKeywordValue("numbers",buffer, sizeof(buffer),status); if ( count > 0 ) { // @numbers keyword was specified in the locale buffer[count] = '\0'; // Make sure it is null terminated. return NumberingSystem::createInstanceByName(buffer,status); } else { // Find the default numbering system for this locale. LocalUResourceBundlePointer resource(ures_open(NULL, inLocale.getName(), &status)); if (U_FAILURE(status)) { status = U_USING_FALLBACK_WARNING; NumberingSystem *ns = new NumberingSystem(); return ns; } const UChar *defaultNSName = ures_getStringByKeyWithFallback(resource.getAlias(), gDefaultNumberingSystem, &count, &status); if (U_FAILURE(status)) { return NULL; } if ( count > 0 && count < ULOC_KEYWORDS_CAPACITY ) { // Default numbering system found u_UCharsToChars(defaultNSName,buffer,count); buffer[count] = '\0'; // Make sure it is null terminated. return NumberingSystem::createInstanceByName(buffer,status); } else { status = U_USING_FALLBACK_WARNING; NumberingSystem *ns = new NumberingSystem(); return ns; } } }
/* This only works for invariant BMP chars */ static char oneUCharToChar(UChar32 c) { UChar ubuf[1]; char buf[1]; ubuf[0] = (UChar) c; u_UCharsToChars(ubuf, buf, 1); return buf[0]; }
virtual UObject* create(const ICUServiceKey& key, const ICUService* /*service*/, UErrorCode& status) const { LocaleKey &lkey = (LocaleKey&)key; Locale loc; lkey.currentLocale(loc); #ifdef U_DEBUG_CALSVC fprintf(stderr, "DefaultCalendar factory %p: looking up %s\n", this, (const char*)loc.getName()); #endif UErrorCode resStatus = U_ZERO_ERROR; UResourceBundle *rb = ures_open(NULL, (const char*)loc.getName(), &resStatus); #ifdef U_DEBUG_CALSVC fprintf(stderr, "... ures_open -> %s\n", u_errorName(resStatus)); #endif if(U_FAILURE(resStatus) || (resStatus == U_USING_DEFAULT_WARNING) || (resStatus==U_USING_FALLBACK_WARNING)) { //Don't want to handle fallback data. ures_close(rb); status = resStatus; // propagate err back to caller #ifdef U_DEBUG_CALSVC fprintf(stderr, "... exitting (NULL)\n"); #endif return NULL; } int32_t len = 0; UnicodeString myString = ures_getUnicodeStringByKey(rb, Calendar::kDefaultCalendar, &status); #ifdef U_DEBUG_CALSVC UErrorCode debugStatus = U_ZERO_ERROR; const UChar *defCal = ures_getStringByKey(rb, Calendar::kDefaultCalendar, &len, &debugStatus); fprintf(stderr, "... get string(%d) -> %s\n", len, u_errorName(debugStatus)); #endif ures_close(rb); if(U_FAILURE(status)) { return NULL; } #ifdef U_DEBUG_CALSVC { char defCalStr[200]; if(len > 199) { len = 199; } u_UCharsToChars(defCal, defCalStr, len); defCalStr[len]=0; fprintf(stderr, "DefaultCalendarFactory: looked up %s, got DefaultCalendar= %s\n", (const char*)loc.getName(), defCalStr); } #endif return myString.clone(); }
const char* TimeZone::getTZDataVersion(UErrorCode& status) { /* This is here to prevent race conditions. */ UBool needsInit; UMTX_CHECK(&LOCK, !TZDataVersionInitialized, needsInit); if (needsInit) { int32_t len = 0; UResourceBundle *bundle = ures_openDirect(NULL, "zoneinfo", &status); const UChar *tzver = ures_getStringByKey(bundle, "TZVersion", &len, &status); if (U_SUCCESS(status)) { if (len >= (int32_t)sizeof(TZDATA_VERSION)) { // Ensure that there is always space for a trailing nul in TZDATA_VERSION len = sizeof(TZDATA_VERSION) - 1; } umtx_lock(&LOCK); if (!TZDataVersionInitialized) { u_UCharsToChars(tzver, TZDATA_VERSION, len); TZDataVersionInitialized = TRUE; } umtx_unlock(&LOCK); ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup); } ures_close(bundle); } if (U_FAILURE(status)) { return NULL; } return (const char*)TZDATA_VERSION; }
U_NAMESPACE_BEGIN CStr::CStr(const UnicodeString &in) { UErrorCode status = U_ZERO_ERROR; #if !UCONFIG_NO_CONVERSION || U_CHARSET_IS_UTF8 int32_t length = in.extract(0, in.length(), static_cast<char *>(NULL), static_cast<uint32_t>(0)); int32_t resultCapacity = 0; char *buf = s.getAppendBuffer(length, length, resultCapacity, status); if (U_SUCCESS(status)) { in.extract(0, in.length(), buf, resultCapacity); s.append(buf, length, status); } #else // No conversion available. Convert any invariant characters; substitute '?' for the rest. // Note: can't just call u_UCharsToChars() or CharString.appendInvariantChars() on the // whole string because they require that the entire input be invariant. char buf[2]; for (int i=0; i<in.length(); i = in.moveIndex32(i, 1)) { if (uprv_isInvariantUString(in.getBuffer()+i, 1)) { u_UCharsToChars(in.getBuffer()+i, buf, 1); } else { buf[0] = '?'; } s.append(buf, 1, status); } #endif }
static void demoUnicodeStringInit() { // *** Make sure to read about invariant characters in utypes.h! *** // Initialization of Unicode strings from C literals works _only_ for // invariant characters! printf("\n* demoUnicodeStringInit() ---------- ***\n\n"); // the string literal is 32 chars long - this must be counted for the macro UnicodeString invariantOnly=UNICODE_STRING("such characters are safe 123 %-.", 32); /* * In C, we need two macros: one to declare the UChar[] array, and * one to populate it; the second one is a noop on platforms where * wchar_t is compatible with UChar and ASCII-based. * The length of the string literal must be counted for both macros. */ /* declare the invString array for the string */ U_STRING_DECL(invString, "such characters are safe 123 %-.", 32); /* populate it with the characters */ U_STRING_INIT(invString, "such characters are safe 123 %-.", 32); // compare the C and C++ strings printf("C and C++ Unicode strings are equal: %d\n", invariantOnly==UnicodeString(TRUE, invString, 32)); /* * convert between char * and UChar * strings that * contain only invariant characters */ static const char *cs1="such characters are safe 123 %-."; static UChar us1[40]; static char cs2[40]; u_charsToUChars(cs1, us1, 33); /* include the terminating NUL */ u_UCharsToChars(us1, cs2, 33); printf("char * -> UChar * -> char * with only " "invariant characters: \"%s\"\n", cs2); // initialize a UnicodeString from a string literal that contains // escape sequences written with invariant characters // do not forget to duplicate the backslashes for ICU to see them // then, count each double backslash only once! UnicodeString german=UNICODE_STRING( "Sch\\u00f6nes Auto: \\u20ac 11240.\\fPrivates Zeichen: \\U00102345\\n", 64). unescape(); printUnicodeString("german UnicodeString from unescaping:\n ", german); /* * C: convert and unescape a char * string with only invariant * characters to fill a UChar * string */ UChar buffer[200]; int32_t length; length=u_unescape( "Sch\\u00f6nes Auto: \\u20ac 11240.\\fPrivates Zeichen: \\U00102345\\n", buffer, UPRV_LENGTHOF(buffer)); printf("german C Unicode string from char * unescaping: (length %d)\n ", length); printUnicodeString("", UnicodeString(buffer)); }
NumberingSystem* U_EXPORT2 NumberingSystem::createInstance(const Locale & inLocale, UErrorCode& status) { if (U_FAILURE(status)) { return NULL; } UBool nsResolved = TRUE; UBool usingFallback = FALSE; char buffer[ULOC_KEYWORDS_CAPACITY]; int32_t count = inLocale.getKeywordValue("numbers",buffer, sizeof(buffer),status); if ( count > 0 ) { // @numbers keyword was specified in the locale buffer[count] = '\0'; // Make sure it is null terminated. if ( !uprv_strcmp(buffer,gDefault) || !uprv_strcmp(buffer,gNative) || !uprv_strcmp(buffer,gTraditional) || !uprv_strcmp(buffer,gFinance)) { nsResolved = FALSE; } } else { uprv_strcpy(buffer,gDefault); nsResolved = FALSE; } if (!nsResolved) { // Resolve the numbering system ( default, native, traditional or finance ) into a "real" numbering system UErrorCode localStatus = U_ZERO_ERROR; UResourceBundle *resource = ures_open(NULL, inLocale.getName(), &localStatus); UResourceBundle *numberElementsRes = ures_getByKey(resource,gNumberElements,NULL,&localStatus); while (!nsResolved) { localStatus = U_ZERO_ERROR; count = 0; const UChar *nsName = ures_getStringByKeyWithFallback(numberElementsRes, buffer, &count, &localStatus); if ( count > 0 && count < ULOC_KEYWORDS_CAPACITY ) { // numbering system found u_UCharsToChars(nsName,buffer,count); buffer[count] = '\0'; // Make sure it is null terminated. nsResolved = TRUE; } if (!nsResolved) { // Fallback behavior per TR35 - traditional falls back to native, finance and native fall back to default if (!uprv_strcmp(buffer,gNative) || !uprv_strcmp(buffer,gFinance)) { uprv_strcpy(buffer,gDefault); } else if (!uprv_strcmp(buffer,gTraditional)) { uprv_strcpy(buffer,gNative); } else { // If we get here we couldn't find even the default numbering system usingFallback = TRUE; nsResolved = TRUE; } } } ures_close(numberElementsRes); ures_close(resource); } if (usingFallback) { status = U_USING_FALLBACK_WARNING; NumberingSystem *ns = new NumberingSystem(); return ns; } else { return NumberingSystem::createInstanceByName(buffer,status); } }
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); }
U_CAPI double udbg_stod(const UnicodeString &s) { char ch[256]; const UChar *u = s.getBuffer(); int32_t len = s.length(); u_UCharsToChars(u, ch, len); ch[len] = 0; /* include terminating \0 */ return atof(ch); }
int32_t DataMap::utoi(const UnicodeString &s) const { char ch[256]; const UChar *u = s.getBuffer(); int32_t len = s.length(); u_UCharsToChars(u, ch, len); ch[len] = 0; /* include terminating \0 */ return atoi(ch); }
/* * Check for the alias from the string or alias resource res. */ static void checkAlias(const char *itemName, Resource res, const UChar *alias, int32_t length, UBool useResSuffix, CheckDependency check, void *context, UErrorCode *pErrorCode) { int32_t i; if(!uprv_isInvariantUString(alias, length)) { fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) alias string contains non-invariant characters\n", itemName, res); *pErrorCode=U_INVALID_CHAR_FOUND; return; } // extract the locale ID from alias strings like // locale_ID/key1/key2/key3 // locale_ID // search for the first slash for(i=0; i<length && alias[i]!=SLASH; ++i) {} if(res_getPublicType(res)==URES_ALIAS) { // ignore aliases with an initial slash: // /ICUDATA/... and /pkgname/... go to a different package // /LOCALE/... are for dynamic sideways fallbacks and don't go to a fixed bundle if(i==0) { return; // initial slash ('/') } // ignore the intra-bundle path starting from the first slash ('/') length=i; } else /* URES_STRING */ { // the whole string should only consist of a locale ID if(i!=length) { fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) %%ALIAS contains a '/'\n", itemName, res); *pErrorCode=U_UNSUPPORTED_ERROR; return; } } // convert the Unicode string to char * char localeID[32]; if(length>=(int32_t)sizeof(localeID)) { fprintf(stderr, "icupkg/ures_enumDependencies(%s res=%08x) alias locale ID length %ld too long\n", itemName, res, (long)length); *pErrorCode=U_BUFFER_OVERFLOW_ERROR; return; } u_UCharsToChars(alias, localeID, length); localeID[length]=0; checkIDSuffix(itemName, localeID, -1, (useResSuffix ? ".res" : ""), check, context, pErrorCode); }
U_CAPI UResourceBundle * U_EXPORT2 ures_openU(const UChar *myPath, const char *localeID, UErrorCode *status) { char pathBuffer[1024]; int32_t length; char *path = pathBuffer; if(status==NULL || U_FAILURE(*status)) { return NULL; } if(myPath==NULL) { path = NULL; } else { length=u_strlen(myPath); if(length>=sizeof(pathBuffer)) { *status=U_ILLEGAL_ARGUMENT_ERROR; return NULL; } else if(uprv_isInvariantUString(myPath, length)) { /* * the invariant converter is sufficient for package and tree names * and is more efficient */ u_UCharsToChars(myPath, path, length+1); /* length+1 to include the NUL */ } else { #if !UCONFIG_NO_CONVERSION /* use the default converter to support variant-character paths */ UConverter *cnv=u_getDefaultConverter(status); length=ucnv_fromUChars(cnv, path, (int32_t)sizeof(pathBuffer), myPath, length, status); u_releaseDefaultConverter(cnv); if(U_FAILURE(*status)) { return NULL; } if(length>=sizeof(pathBuffer)) { /* not NUL-terminated - path too long */ *status=U_ILLEGAL_ARGUMENT_ERROR; return NULL; } #else /* the default converter is not available */ *status=U_UNSUPPORTED_ERROR; return NULL; #endif } } return ures_open(path, localeID, status); }
U_NAMESPACE_BEGIN CurrencyUnit::CurrencyUnit(ConstChar16Ptr _isoCode, UErrorCode& ec) { *isoCode = 0; if (U_SUCCESS(ec)) { if (_isoCode != nullptr && u_strlen(_isoCode)==3) { u_strcpy(isoCode, _isoCode); char simpleIsoCode[4]; u_UCharsToChars(isoCode, simpleIsoCode, 4); initCurrency(simpleIsoCode); } else { ec = U_ILLEGAL_ARGUMENT_ERROR; } } }
const GenderInfo* GenderInfo::loadInstance(const Locale& locale, UErrorCode& status) { LocalUResourceBundlePointer rb( ures_openDirect(NULL, "genderList", &status)); if (U_FAILURE(status)) { return NULL; } LocalUResourceBundlePointer locRes(ures_getByKey(rb.getAlias(), "genderList", NULL, &status)); if (U_FAILURE(status)) { return NULL; } int32_t resLen = 0; const char* curLocaleName = locale.getName(); UErrorCode key_status = U_ZERO_ERROR; const UChar* s = ures_getStringByKey(locRes.getAlias(), curLocaleName, &resLen, &key_status); if (s == NULL) { key_status = U_ZERO_ERROR; char parentLocaleName[ULOC_FULLNAME_CAPACITY]; uprv_strcpy(parentLocaleName, curLocaleName); while (s == NULL && uloc_getParent(parentLocaleName, parentLocaleName, ULOC_FULLNAME_CAPACITY, &key_status) > 0) { key_status = U_ZERO_ERROR; resLen = 0; s = ures_getStringByKey(locRes.getAlias(), parentLocaleName, &resLen, &key_status); key_status = U_ZERO_ERROR; } } if (s == NULL) { return &gObjs[NEUTRAL]; } char type_str[256]; u_UCharsToChars(s, type_str, resLen + 1); if (uprv_strcmp(type_str, gNeutralStr) == 0) { return &gObjs[NEUTRAL]; } if (uprv_strcmp(type_str, gMixedNeutralStr) == 0) { return &gObjs[MIXED_NEUTRAL]; } if (uprv_strcmp(type_str, gMailTaintsStr) == 0) { return &gObjs[MALE_TAINTS]; } return &gObjs[NEUTRAL]; }
/** * This function looks for the localeID in the likelySubtags resource. * * @param localeID The tag to find. * @param buffer A buffer to hold the matching entry * @param bufferLength The length of the output buffer * @return A pointer to "buffer" if found, or a null pointer if not. */ static const char* U_CALLCONV findLikelySubtags(const char* localeID, char* buffer, int32_t bufferLength, UErrorCode* err) { const char* result = NULL; if (!U_FAILURE(*err)) { int32_t resLen = 0; const UChar* s = NULL; UErrorCode tmpErr = U_ZERO_ERROR; UResourceBundle* subtags = ures_openDirect(NULL, "likelySubtags", &tmpErr); if (U_SUCCESS(tmpErr)) { s = ures_getStringByKey(subtags, localeID, &resLen, &tmpErr); if (U_FAILURE(tmpErr)) { /* * If a resource is missing, it's not really an error, it's * just that we don't have any data for that particular locale ID. */ if (tmpErr != U_MISSING_RESOURCE_ERROR) { *err = tmpErr; } } else if (resLen >= bufferLength) { /* The buffer should never overflow. */ *err = U_INTERNAL_PROGRAM_ERROR; } else { u_UCharsToChars(s, buffer, resLen + 1); result = buffer; } ures_close(subtags); } else { *err = tmpErr; } } return result; }
Locale GetLocale(const UChar* localeName, bool canonize) { char localeNameTemp[ULOC_FULLNAME_CAPACITY]; if (localeName != NULL) { int32_t len = u_strlen(localeName); u_UCharsToChars(localeName, localeNameTemp, len + 1); } Locale loc; if (canonize) { loc = Locale::createCanonical(localeName == NULL ? NULL : localeNameTemp); } else { loc = Locale::createFromName(localeName == NULL ? NULL : localeNameTemp); } return loc; }
/* Don't call this directly. Only uenum_next should be calling this. */ U_CAPI const char* U_EXPORT2 uenum_nextDefault(UEnumeration* en, int32_t* resultLength, UErrorCode* status) { if (en->uNext != NULL) { char *tempCharVal; const UChar *tempUCharVal = en->uNext(en, resultLength, status); if (tempUCharVal == NULL) { return NULL; } tempCharVal = (char*) _getBuffer(en, (*resultLength+1) * sizeof(char)); if (!tempCharVal) { *status = U_MEMORY_ALLOCATION_ERROR; return NULL; } u_UCharsToChars(tempUCharVal, tempCharVal, *resultLength + 1); return tempCharVal; } else { *status = U_UNSUPPORTED_ERROR; return NULL; } }
/* test invariant-character handling */ static void TestInvariant() { /* all invariant graphic chars and some control codes (not \n!) */ const char invariantChars[]= "\t\r \"%&'()*+,-./" "0123456789:;<=>?" "ABCDEFGHIJKLMNOPQRSTUVWXYZ_" "abcdefghijklmnopqrstuvwxyz"; const UChar invariantUChars[]={ 9, 0xd, 0x20, 0x22, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5f, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0 }; const char variantChars[]="\n!#$@[\\]^`{|}~"; const UChar variantUChars[]={ 0x0a, 0x21, 0x23, 0x24, 0x40, 0x5b, 0x5c, 0x5d, 0x5e, 0x60, 0x7b, 0x7c, 0x7d, 0x7e, 0 }; const UChar nonASCIIUChars[]={ 0x80, 0xa0, 0x900, 0xff51 }; UChar us[120]; char cs[120]; int32_t i, length; /* make sure that all invariant characters convert both ways */ length=sizeof(invariantChars); u_charsToUChars(invariantChars, us, length); if(u_strcmp(us, invariantUChars)!=0) { log_err("u_charsToUChars(invariantChars) failed\n"); } u_UCharsToChars(invariantUChars, cs, length); if(strcmp(cs, invariantChars)!=0) { log_err("u_UCharsToChars(invariantUChars) failed\n"); } /* * make sure that variant characters convert from source code literals to Unicode * but not back to char * */ length=sizeof(variantChars); u_charsToUChars(variantChars, us, length); if(u_strcmp(us, variantUChars)!=0) { log_err("u_charsToUChars(variantChars) failed\n"); } #ifdef NDEBUG /* * Test u_UCharsToChars(variantUChars) only in release mode because it will * cause an assertion failure in debug builds. */ u_UCharsToChars(variantUChars, cs, length); for(i=0; i<length; ++i) { if(cs[i]!=0) { log_err("u_UCharsToChars(variantUChars) converted the %d-th character to %02x instead of 00\n", i, cs[i]); } } #endif /* * Verify that invariant characters roundtrip from Unicode to the * default converter and back. */ { UConverter *cnv; UErrorCode errorCode; errorCode=U_ZERO_ERROR; cnv=ucnv_open(NULL, &errorCode); if(U_FAILURE(errorCode)) { log_err("unable to open the default converter\n"); } else { length=ucnv_fromUChars(cnv, cs, sizeof(cs), invariantUChars, -1, &errorCode); if(U_FAILURE(errorCode)) { log_err("ucnv_fromUChars(invariantUChars) failed - %s\n", u_errorName(errorCode)); } else if(length!=sizeof(invariantChars)-1 || strcmp(cs, invariantChars)!=0) { log_err("ucnv_fromUChars(invariantUChars) failed\n"); } errorCode=U_ZERO_ERROR; length=ucnv_toUChars(cnv, us, LENGTHOF(us), invariantChars, -1, &errorCode); if(U_FAILURE(errorCode)) { log_err("ucnv_toUChars(invariantChars) failed - %s\n", u_errorName(errorCode)); } else if(length!=LENGTHOF(invariantUChars)-1 || u_strcmp(us, invariantUChars)!=0) { log_err("ucnv_toUChars(invariantChars) failed\n"); } ucnv_close(cnv); } } /* API tests */ if(!uprv_isInvariantString(invariantChars, -1)) { log_err("uprv_isInvariantString(invariantChars) failed\n"); } if(!uprv_isInvariantUString(invariantUChars, -1)) { log_err("uprv_isInvariantUString(invariantUChars) failed\n"); } if(!uprv_isInvariantString(invariantChars+strlen(invariantChars), 1)) { log_err("uprv_isInvariantString(\"\\0\") failed\n"); } for(i=0; i<(sizeof(variantChars)-1); ++i) { if(uprv_isInvariantString(variantChars+i, 1)) { log_err("uprv_isInvariantString(variantChars[%d]) failed\n", i); } if(uprv_isInvariantUString(variantUChars+i, 1)) { log_err("uprv_isInvariantUString(variantUChars[%d]) failed\n", i); } } for(i=0; i<LENGTHOF(nonASCIIUChars); ++i) { if(uprv_isInvariantUString(nonASCIIUChars+i, 1)) { log_err("uprv_isInvariantUString(nonASCIIUChars[%d]) failed\n", i); } } }
U_CAPI int32_t U_EXPORT2 u_file_write_flush( const UChar *chars, int32_t count, UFILE *f, UBool flush) { /* Set up conversion parameters */ UErrorCode status = U_ZERO_ERROR; const UChar *mySource = chars; const UChar *sourceAlias = chars; const UChar *mySourceEnd = chars + count; char *myTarget = f->fCharBuffer; int32_t bufferSize = UFILE_CHARBUFFER_SIZE; int32_t written = 0; int32_t numConverted = 0; #if !UCONFIG_NO_TRANSLITERATION if((f->fTranslit) && (f->fTranslit->translit)) { /* Do the transliteration */ mySource = u_file_translit(f, chars, &count, flush); sourceAlias = mySource; mySourceEnd = mySource + count; } #endif /* Perform the conversion in a loop */ do { status = U_ZERO_ERROR; sourceAlias = mySource; if(f->fConverter != NULL) { /* We have a valid converter */ ucnv_fromUnicode(f->fConverter, &myTarget, f->fCharBuffer + bufferSize, &mySource, mySourceEnd, NULL, flush, &status); } else { /*weiv: do the invariant conversion */ u_UCharsToChars(mySource, myTarget, count); myTarget += count; } numConverted = (int32_t)(myTarget - f->fCharBuffer); if (numConverted > 0) { /* write the converted bytes */ fwrite(f->fCharBuffer, sizeof(char), numConverted, f->fFile); written += numConverted; } myTarget = f->fCharBuffer; } while(status == U_BUFFER_OVERFLOW_ERROR); /* return # of chars written */ return written; }
U_CAPI int32_t U_EXPORT2 udata_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, UErrorCode *pErrorCode) { char dataFormatChars[4]; const UDataInfo *pInfo; int32_t i, swappedLength; if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return 0; } /* * Preflight the header first; checks for illegal arguments, too. * Do not swap the header right away because the format-specific swapper * will swap it, get the headerSize again, and also use the header * information. Otherwise we would have to pass some of the information * and not be able to use the UDataSwapFn signature. */ udata_swapDataHeader(ds, inData, -1, NULL, pErrorCode); /* * If we wanted udata_swap() to also handle non-loadable data like a UTrie, * then we could check here for further known magic values and structures. */ if(U_FAILURE(*pErrorCode)) { return 0; /* the data format was not recognized */ } pInfo=(const UDataInfo *)((const char *)inData+4); { /* convert the data format from ASCII to Unicode to the system charset */ UChar u[4]={ pInfo->dataFormat[0], pInfo->dataFormat[1], pInfo->dataFormat[2], pInfo->dataFormat[3] }; if(uprv_isInvariantUString(u, 4)) { u_UCharsToChars(u, dataFormatChars, 4); } else { dataFormatChars[0]=dataFormatChars[1]=dataFormatChars[2]=dataFormatChars[3]='?'; } } /* dispatch to the swap function for the dataFormat */ for(i=0; i<UPRV_LENGTHOF(swapFns); ++i) { if(0==memcmp(swapFns[i].dataFormat, pInfo->dataFormat, 4)) { swappedLength=swapFns[i].swapFn(ds, inData, length, outData, pErrorCode); if(U_FAILURE(*pErrorCode)) { udata_printError(ds, "udata_swap(): failure swapping data format %02x.%02x.%02x.%02x (\"%c%c%c%c\") - %s\n", pInfo->dataFormat[0], pInfo->dataFormat[1], pInfo->dataFormat[2], pInfo->dataFormat[3], dataFormatChars[0], dataFormatChars[1], dataFormatChars[2], dataFormatChars[3], u_errorName(*pErrorCode)); } else if(swappedLength<(length-15)) { /* swapped less than expected */ udata_printError(ds, "udata_swap() warning: swapped only %d out of %d bytes - data format %02x.%02x.%02x.%02x (\"%c%c%c%c\")\n", swappedLength, length, pInfo->dataFormat[0], pInfo->dataFormat[1], pInfo->dataFormat[2], pInfo->dataFormat[3], dataFormatChars[0], dataFormatChars[1], dataFormatChars[2], dataFormatChars[3], u_errorName(*pErrorCode)); } return swappedLength; } } /* the dataFormat was not recognized */ udata_printError(ds, "udata_swap(): unknown data format %02x.%02x.%02x.%02x (\"%c%c%c%c\")\n", pInfo->dataFormat[0], pInfo->dataFormat[1], pInfo->dataFormat[2], pInfo->dataFormat[3], dataFormatChars[0], dataFormatChars[1], dataFormatChars[2], dataFormatChars[3]); *pErrorCode=U_UNSUPPORTED_ERROR; return 0; }
static void OpenMessageFormatTest(void) { UMessageFormat *f1, *f2, *f3; UChar pattern[256]; UChar result[256]; char cresult[256]; UParseError parseError; const char* locale = "hi_IN"; char* retLoc; const char* PAT = "Number {1,number,#0.000}, String {0}, Date {2,date,12:mm:ss.SSS}"; int32_t length=0; UErrorCode status = U_ZERO_ERROR; u_uastrncpy(pattern, PAT, sizeof(pattern)/sizeof(pattern[0])); /* Test umsg_open */ f1 = umsg_open(pattern,length,NULL,NULL,&status); if(U_FAILURE(status)) { log_err("umsg_open failed with pattern %s. Error: \n", PAT, u_errorName(status)); return; } /* Test umsg_open with parse error */ status = U_ZERO_ERROR; f2 = umsg_open(pattern,length,NULL,&parseError,&status); if(U_FAILURE(status)) { log_err("umsg_open with parseError failed with pattern %s. Error: %s\n", PAT, u_errorName(status)); return; } /* Test umsg_clone */ status = U_ZERO_ERROR; f3 = umsg_clone(f1,&status); if(U_FAILURE(status)) { log_err("umsg_clone failed. Error %s \n", u_errorName(status)); } /* Test umsg_setLocale */ umsg_setLocale(f1,locale); /* Test umsg_getLocale */ retLoc = (char*)umsg_getLocale(f1); if(strcmp(retLoc,locale)!=0) { log_err("umsg_setLocale and umsg_getLocale methods failed. Expected:%s Got: %s \n", locale, retLoc); } /* Test umsg_applyPattern */ status = U_ZERO_ERROR; umsg_applyPattern(f1,pattern,(int32_t)strlen(PAT),NULL,&status); if(U_FAILURE(status)) { log_data_err("umsg_applyPattern failed. Error %s (Are you missing data?)\n",u_errorName(status)); } /* Test umsg_toPattern */ umsg_toPattern(f1,result,256,&status); if(U_FAILURE(status) ){ log_data_err("umsg_toPattern method failed. Error: %s (Are you missing data?)\n",u_errorName(status)); } else { if(u_strcmp(result,pattern)!=0){ u_UCharsToChars(result,cresult,256); log_err("umsg_toPattern method failed. Expected: %s Got: %s \n",PAT,cresult); } } /* umsg_format umsg_parse */ umsg_close(f1); umsg_close(f2); umsg_close(f3); }
static void TestCaseDutchTitle(void) { static const UChar beforeTitle[]= { 0x69, 0x6A, 0x73, 0x73, 0x45, 0x6c, 0x20, 0x69, 0x67, 0x6c, 0x4f, 0x6f , 0x20 , 0x49, 0x4A, 0x53, 0x53, 0x45, 0x4C }, titleRoot[]= { 0x49, 0x6A, 0x73, 0x73, 0x65, 0x6c, 0x20, 0x49, 0x67, 0x6c, 0x6f, 0x6f , 0x20 , 0x49, 0x6A, 0x73, 0x73, 0x65, 0x6C }, titleDutch[]= { 0x49, 0x4A, 0x73, 0x73, 0x65, 0x6c, 0x20, 0x49, 0x67, 0x6c, 0x6f, 0x6f , 0x20 , 0x49, 0x4A, 0x73, 0x73, 0x65, 0x6C }; UChar buffer[32]; UBreakIterator *titleIterWord; int32_t length; UErrorCode errorCode; errorCode=U_ZERO_ERROR; titleIterWord=ubrk_open(UBRK_WORD, "", beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR, &errorCode); if(U_FAILURE(errorCode)) { log_err_status(errorCode, "error: ubrk_open(UBRK_WORD)->%s\n", u_errorName(errorCode)); return; } /* titlecase with default locale */ buffer[0]=0xabcd; errorCode=U_ZERO_ERROR; length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR, titleIterWord, "", &errorCode); if( U_FAILURE(errorCode) || length!=(sizeof(titleRoot)/U_SIZEOF_UCHAR) || uprv_memcmp(titleRoot, buffer, length*U_SIZEOF_UCHAR)!=0 || buffer[length]!=0 ) { char charsOut[21]; u_UCharsToChars(buffer,charsOut,sizeof(charsOut)); log_err("error in u_strToTitle(UBRK_CHARACTERS)=%ld error=%s root locale string matches: %s\noutput buffer is {%s}\n", length, u_errorName(errorCode), uprv_memcmp(titleRoot, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no", charsOut); } /* titlecase with Dutch locale */ buffer[0]=0xabcd; errorCode=U_ZERO_ERROR; length=u_strToTitle(buffer, sizeof(buffer)/U_SIZEOF_UCHAR, beforeTitle, sizeof(beforeTitle)/U_SIZEOF_UCHAR, titleIterWord, "nl", &errorCode); if( U_FAILURE(errorCode) || length!=(sizeof(titleDutch)/U_SIZEOF_UCHAR) || uprv_memcmp(titleDutch, buffer, length*U_SIZEOF_UCHAR)!=0 || buffer[length]!=0 ) { char charsOut[21]; u_UCharsToChars(buffer,charsOut,sizeof(charsOut)); log_err("error in u_strToTitle(UBRK_CHARACTERS)=%ld error=%s dutch locale string matches: %s\noutput buffer is {%s}\n", length, u_errorName(errorCode), uprv_memcmp(titleDutch, buffer, length*U_SIZEOF_UCHAR)==0 && buffer[length]==0 ? "yes" : "no", charsOut); } ubrk_close(titleIterWord); }
static char* quikU2C(const UChar* str, int32_t len) { u_UCharsToChars(str, quikBuf, len); quikBuf[len] = 0; return quikBuf; }
void DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool useLastResortData) { static const char *gNumberElementKeys[kFormatSymbolCount] = { "decimal", "group", "list", "percentSign", NULL, /* Native zero digit is deprecated from CLDR - get it from the numbering system */ NULL, /* Pattern digit character is deprecated from CLDR - use # by default always */ "minusSign", "plusSign", NULL, /* currency symbol - We don't really try to load this directly from CLDR until we know the currency */ NULL, /* intl currency symbol - We don't really try to load this directly from CLDR until we know the currency */ "currencyDecimal", "exponential", "perMille", NULL, /* Escape padding character - not in CLDR */ "infinity", "nan", NULL, /* Significant digit symbol - not in CLDR */ "currencyGroup", NULL, /* one digit - get it from the numbering system */ NULL, /* two digit - get it from the numbering system */ NULL, /* three digit - get it from the numbering system */ NULL, /* four digit - get it from the numbering system */ NULL, /* five digit - get it from the numbering system */ NULL, /* six digit - get it from the numbering system */ NULL, /* seven digit - get it from the numbering system */ NULL, /* eight digit - get it from the numbering system */ NULL, /* nine digit - get it from the numbering system */ "superscriptingExponent", /* Multiplication (x) symbol for exponents */ }; static const char *gLatn = "latn"; static const char *gSymbols = "symbols"; const char *nsName; const UChar *sym = NULL; int32_t len = 0; *validLocale = *actualLocale = 0; currPattern = NULL; if (U_FAILURE(status)) return; const char* locStr = loc.getName(); LocalUResourceBundlePointer resource(ures_open(NULL, locStr, &status)); LocalUResourceBundlePointer numberElementsRes( ures_getByKeyWithFallback(resource.getAlias(), gNumberElements, NULL, &status)); if (U_FAILURE(status)) { if ( useLastResortData ) { status = U_USING_DEFAULT_WARNING; initialize(); } return; } // First initialize all the symbols to the fallbacks for anything we can't find initialize(); // // Next get the numbering system for this locale and set zero digit // and the digit string based on the numbering system for the locale // LocalPointer<NumberingSystem> ns(NumberingSystem::createInstance(loc, status)); if (U_SUCCESS(status) && ns->getRadix() == 10 && !ns->isAlgorithmic()) { nsName = ns->getName(); UnicodeString digitString(ns->getDescription()); int32_t digitIndex = 0; UChar32 digit = digitString.char32At(0); fSymbols[kZeroDigitSymbol].setTo(digit); for (int32_t i = kOneDigitSymbol; i <= kNineDigitSymbol; ++i) { digitIndex += U16_LENGTH(digit); digit = digitString.char32At(digitIndex); fSymbols[i].setTo(digit); } } else { nsName = gLatn; } UBool isLatn = !uprv_strcmp(nsName,gLatn); UErrorCode nlStatus = U_ZERO_ERROR; LocalUResourceBundlePointer nonLatnSymbols; if ( !isLatn ) { nonLatnSymbols.adoptInstead( ures_getByKeyWithFallback(numberElementsRes.getAlias(), nsName, NULL, &nlStatus)); ures_getByKeyWithFallback(nonLatnSymbols.getAlias(), gSymbols, nonLatnSymbols.getAlias(), &nlStatus); } LocalUResourceBundlePointer latnSymbols( ures_getByKeyWithFallback(numberElementsRes.getAlias(), gLatn, NULL, &status)); ures_getByKeyWithFallback(latnSymbols.getAlias(), gSymbols, latnSymbols.getAlias(), &status); UBool kMonetaryDecimalSet = FALSE; UBool kMonetaryGroupingSet = FALSE; for(int32_t i = 0; i<kFormatSymbolCount; i++) { if ( gNumberElementKeys[i] != NULL ) { UErrorCode localStatus = U_ZERO_ERROR; if ( !isLatn ) { sym = ures_getStringByKeyWithFallback(nonLatnSymbols.getAlias(), gNumberElementKeys[i], &len, &localStatus); // If we can't find the symbol in the numbering system specific resources, // use the "latn" numbering system as the fallback. if ( U_FAILURE(localStatus) ) { localStatus = U_ZERO_ERROR; sym = ures_getStringByKeyWithFallback(latnSymbols.getAlias(), gNumberElementKeys[i], &len, &localStatus); } } else { sym = ures_getStringByKeyWithFallback(latnSymbols.getAlias(), gNumberElementKeys[i], &len, &localStatus); } if ( U_SUCCESS(localStatus) ) { setSymbol((ENumberFormatSymbol)i, UnicodeString(TRUE, sym, len)); if ( i == kMonetarySeparatorSymbol ) { kMonetaryDecimalSet = TRUE; } else if ( i == kMonetaryGroupingSeparatorSymbol ) { kMonetaryGroupingSet = TRUE; } } } } // If monetary decimal or grouping were not explicitly set, then set them to be the // same as their non-monetary counterparts. if ( !kMonetaryDecimalSet ) { setSymbol(kMonetarySeparatorSymbol,fSymbols[kDecimalSeparatorSymbol]); } if ( !kMonetaryGroupingSet ) { setSymbol(kMonetaryGroupingSeparatorSymbol,fSymbols[kGroupingSeparatorSymbol]); } // Obtain currency data from the currency API. This is strictly // for backward compatibility; we don't use DecimalFormatSymbols // for currency data anymore. UErrorCode internalStatus = U_ZERO_ERROR; // don't propagate failures out UChar curriso[4]; UnicodeString tempStr; ucurr_forLocale(locStr, curriso, 4, &internalStatus); uprv_getStaticCurrencyName(curriso, locStr, tempStr, internalStatus); if (U_SUCCESS(internalStatus)) { fSymbols[kIntlCurrencySymbol].setTo(curriso, -1); fSymbols[kCurrencySymbol] = tempStr; } /* else use the default values. */ U_LOCALE_BASED(locBased, *this); locBased.setLocaleIDs(ures_getLocaleByType(numberElementsRes.getAlias(), ULOC_VALID_LOCALE, &status), ures_getLocaleByType(numberElementsRes.getAlias(), ULOC_ACTUAL_LOCALE, &status)); //load the currency data UChar ucc[4]={0}; //Currency Codes are always 3 chars long int32_t uccLen = 4; const char* locName = loc.getName(); UErrorCode localStatus = U_ZERO_ERROR; uccLen = ucurr_forLocale(locName, ucc, uccLen, &localStatus); if(U_SUCCESS(localStatus) && uccLen > 0) { char cc[4]={0}; u_UCharsToChars(ucc, cc, uccLen); /* An explicit currency was requested */ LocalUResourceBundlePointer currencyResource(ures_open(U_ICUDATA_CURR, locStr, &localStatus)); LocalUResourceBundlePointer currency( ures_getByKeyWithFallback(currencyResource.getAlias(), "Currencies", NULL, &localStatus)); ures_getByKeyWithFallback(currency.getAlias(), cc, currency.getAlias(), &localStatus); if(U_SUCCESS(localStatus) && ures_getSize(currency.getAlias())>2) { // the length is 3 if more data is present ures_getByIndex(currency.getAlias(), 2, currency.getAlias(), &localStatus); int32_t currPatternLen = 0; currPattern = ures_getStringByIndex(currency.getAlias(), (int32_t)0, &currPatternLen, &localStatus); UnicodeString decimalSep = ures_getUnicodeStringByIndex(currency.getAlias(), (int32_t)1, &localStatus); UnicodeString groupingSep = ures_getUnicodeStringByIndex(currency.getAlias(), (int32_t)2, &localStatus); if(U_SUCCESS(localStatus)){ fSymbols[kMonetaryGroupingSeparatorSymbol] = groupingSep; fSymbols[kMonetarySeparatorSymbol] = decimalSep; //pattern.setTo(TRUE, currPattern, currPatternLen); status = localStatus; } } /* else An explicit currency was requested and is unknown or locale data is malformed. */ /* ucurr_* API will get the correct value later on. */ } // else ignore the error if no currency // Currency Spacing. localStatus = U_ZERO_ERROR; LocalUResourceBundlePointer currencyResource(ures_open(U_ICUDATA_CURR, locStr, &localStatus)); LocalUResourceBundlePointer currencySpcRes( ures_getByKeyWithFallback(currencyResource.getAlias(), gCurrencySpacingTag, NULL, &localStatus)); if (localStatus == U_USING_FALLBACK_WARNING || U_SUCCESS(localStatus)) { const char* keywords[UNUM_CURRENCY_SPACING_COUNT] = { gCurrencyMatchTag, gCurrencySudMatchTag, gCurrencyInsertBtnTag }; localStatus = U_ZERO_ERROR; LocalUResourceBundlePointer dataRes( ures_getByKeyWithFallback(currencySpcRes.getAlias(), gBeforeCurrencyTag, NULL, &localStatus)); if (localStatus == U_USING_FALLBACK_WARNING || U_SUCCESS(localStatus)) { localStatus = U_ZERO_ERROR; for (int32_t i = 0; i < UNUM_CURRENCY_SPACING_COUNT; i++) { currencySpcBeforeSym[i] = ures_getUnicodeStringByKey(dataRes.getAlias(), keywords[i], &localStatus); } } dataRes.adoptInstead( ures_getByKeyWithFallback(currencySpcRes.getAlias(), gAfterCurrencyTag, NULL, &localStatus)); if (localStatus == U_USING_FALLBACK_WARNING || U_SUCCESS(localStatus)) { localStatus = U_ZERO_ERROR; for (int32_t i = 0; i < UNUM_CURRENCY_SPACING_COUNT; i++) { currencySpcAfterSym[i] = ures_getUnicodeStringByKey(dataRes.getAlias(), keywords[i], &localStatus); } } } }
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& U_EXPORT2 ZoneMeta::getSingleCountry(const UnicodeString &tzid, UnicodeString &country) { // Get canonical country for the zone const UChar *region = TimeZone::getRegion(tzid); if (u_strcmp(gWorld, region) == 0) { // special case - "001" country.remove(); return country; } // Checking the cached results UErrorCode status = U_ZERO_ERROR; UBool initialized; UMTX_CHECK(&gZoneMetaLock, gCountryInfoVectorsInitialized, initialized); if (!initialized) { // Create empty vectors umtx_lock(&gZoneMetaLock); { if (!gCountryInfoVectorsInitialized) { // No deleters for these UVectors, it's a reference to a resource bundle string. gSingleZoneCountries = new UVector(NULL, uhash_compareUChars, status); if (gSingleZoneCountries == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } gMultiZonesCountries = new UVector(NULL, uhash_compareUChars, status); if (gMultiZonesCountries == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } if (U_SUCCESS(status)) { gCountryInfoVectorsInitialized = TRUE; } else { delete gSingleZoneCountries; delete gMultiZonesCountries; } } } umtx_unlock(&gZoneMetaLock); if (U_FAILURE(status)) { country.remove(); return country; } } // Check if it was already cached UBool cached = FALSE; UBool multiZones = FALSE; umtx_lock(&gZoneMetaLock); { multiZones = cached = gMultiZonesCountries->contains((void*)region); if (!multiZones) { cached = gSingleZoneCountries->contains((void*)region); } } umtx_unlock(&gZoneMetaLock); if (!cached) { // We need to go through all zones associated with the region. // This is relatively heavy operation. U_ASSERT(u_strlen(region) == 2); char buf[] = {0, 0, 0}; u_UCharsToChars(region, buf, 2); StringEnumeration *ids = TimeZone::createEnumeration(buf); int32_t idsLen = ids->count(status); if (U_SUCCESS(status) && idsLen > 1) { // multiple zones are available for the region UnicodeString canonical, tmp; const UnicodeString *id = ids->snext(status); getCanonicalSystemID(*id, canonical, status); if (U_SUCCESS(status)) { // check if there are any other canonical zone in the group while ((id = ids->snext(status))!=NULL) { getCanonicalSystemID(*id, tmp, status); if (U_FAILURE(status)) { break; } if (canonical != tmp) { // another canonical zone was found multiZones = TRUE; break; } } } } if (U_FAILURE(status)) { // no single country by default for any error cases multiZones = TRUE; } delete ids; // Cache the result umtx_lock(&gZoneMetaLock); { UErrorCode ec = U_ZERO_ERROR; if (multiZones) { if (!gMultiZonesCountries->contains((void*)region)) { gMultiZonesCountries->addElement((void*)region, ec); } } else { if (!gSingleZoneCountries->contains((void*)region)) { gSingleZoneCountries->addElement((void*)region, ec); } } } umtx_unlock(&gZoneMetaLock); } if (multiZones) { country.remove(); } else { country.setTo(region, -1); } return country; }