U_CAPI int32_t U_EXPORT2 udat_toPatternRelativeTime(const UDateFormat *fmt, UChar *result, int32_t resultLength, UErrorCode *status) { verifyIsRelativeDateFormat(fmt, status); if(U_FAILURE(*status)) return -1; UnicodeString timePattern; if(!(result==NULL && resultLength==0)) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer timePattern.setTo(result, 0, resultLength); } ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status); return timePattern.extract(result, resultLength, *status); }
void RuleBasedCollator::getRules(UColRuleOption delta, UnicodeString &buffer) { int32_t rulesize = ucol_getRulesEx(ucollator, delta, NULL, -1); if (rulesize > 0) { UChar *rules = (UChar*) uprv_malloc( sizeof(UChar) * (rulesize) ); if(rules != NULL) { ucol_getRulesEx(ucollator, delta, rules, rulesize); buffer.setTo(rules, rulesize); uprv_free(rules); } else { // couldn't allocate buffer.remove(); } } else { buffer.remove(); } }
UnicodeString& U_EXPORT2 TimeZoneNamesImpl::getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) { if (tzID.isEmpty() || tzID.startsWith(gEtcPrefix, gEtcPrefixLen) || tzID.startsWith(gSystemVPrefix, gSystemVPrefixLen) || tzID.indexOf(gRiyadh8, gRiyadh8Len, 0) > 0) { name.setToBogus(); return name; } int32_t sep = tzID.lastIndexOf((UChar)0x2F /* '/' */); if (sep > 0 && sep + 1 < tzID.length()) { name.setTo(tzID, sep + 1); name.findAndReplace(UnicodeString((UChar)0x5f /* _ */), UnicodeString((UChar)0x20 /* space */)); } else { name.setToBogus(); } return name; }
U_NAMESPACE_USE static TimeZone* _createTimeZone(const UChar* zoneID, int32_t len, UErrorCode* ec) { TimeZone* zone = NULL; if (ec!=NULL && U_SUCCESS(*ec)) { // Note that if zoneID is invalid, we get back GMT. This odd // behavior is by design and goes back to the JDK. The only // failure we will see is a memory allocation failure. int32_t l = (len<0 ? u_strlen(zoneID) : len); UnicodeString zoneStrID; zoneStrID.setTo((UBool)(len < 0), zoneID, l); /* temporary read-only alias */ zone = TimeZone::createTimeZone(zoneStrID); if (zone == NULL) { *ec = U_MEMORY_ALLOCATION_ERROR; } } return zone; }
UnicodeString& U_EXPORT2 ZoneMeta::getMetazoneID(const UnicodeString &tzid, UDate date, UnicodeString &result) { UBool isSet = FALSE; const UVector *mappings = getMetazoneMappings(tzid); if (mappings != NULL) { for (int32_t i = 0; i < mappings->size(); i++) { OlsonToMetaMappingEntry *mzm = (OlsonToMetaMappingEntry*)mappings->elementAt(i); if (mzm->from <= date && mzm->to > date) { result.setTo(mzm->mzid, -1); isSet = TRUE; break; } } } if (!isSet) { result.remove(); } return result; }
UnicodeString& U_EXPORT2 ZoneMeta::getZoneIdByMetazone(const UnicodeString &mzid, const UnicodeString ®ion, UnicodeString &result) { UErrorCode status = U_ZERO_ERROR; const UChar *tzid = NULL; int32_t tzidLen = 0; char keyBuf[ZID_KEY_MAX + 1]; int32_t keyLen = 0; if (mzid.length() >= ZID_KEY_MAX) { result.remove(); return result; } keyLen = mzid.extract(0, mzid.length(), keyBuf, ZID_KEY_MAX, US_INV); UResourceBundle *rb = ures_openDirect(NULL, gMetaZones, &status); ures_getByKey(rb, gMapTimezonesTag, rb, &status); ures_getByKey(rb, keyBuf, rb, &status); if (U_SUCCESS(status)) { // check region mapping if (region.length() == 2 || region.length() == 3) { region.extract(0, region.length(), keyBuf, ZID_KEY_MAX, US_INV); tzid = ures_getStringByKey(rb, keyBuf, &tzidLen, &status); if (status == U_MISSING_RESOURCE_ERROR) { status = U_ZERO_ERROR; } } if (U_SUCCESS(status) && tzid == NULL) { // try "001" tzid = ures_getStringByKey(rb, gWorldTag, &tzidLen, &status); } } ures_close(rb); if (tzid == NULL) { result.remove(); } else { result.setTo(tzid, tzidLen); } return result; }
/** * Parse an ID into pieces. Take IDs of the form T, T/V, S-T, * S-T/V, or S/V-T. If the source is missing, return a source of * ANY. * @param id the id string, in any of several forms * @return an array of 4 strings: source, target, variant, and * isSourcePresent. If the source is not present, ANY will be * given as the source, and isSourcePresent will be NULL. Otherwise * isSourcePresent will be non-NULL. The target may be empty if the * id is not well-formed. The variant may be empty. */ void TransliteratorIDParser::IDtoSTV(const UnicodeString& id, UnicodeString& source, UnicodeString& target, UnicodeString& variant, UBool& isSourcePresent) { source.setTo(ANY, 3); target.truncate(0); variant.truncate(0); int32_t sep = id.indexOf(TARGET_SEP); int32_t var = id.indexOf(VARIANT_SEP); if (var < 0) { var = id.length(); } isSourcePresent = FALSE; if (sep < 0) { // Form: T/V or T (or /V) id.extractBetween(0, var, target); id.extractBetween(var, id.length(), variant); } else if (sep < var) { // Form: S-T/V or S-T (or -T/V or -T) if (sep > 0) { id.extractBetween(0, sep, source); isSourcePresent = TRUE; } id.extractBetween(++sep, var, target); id.extractBetween(var, id.length(), variant); } else { // Form: (S/V-T or /V-T) if (var > 0) { id.extractBetween(0, var, source); isSourcePresent = TRUE; } id.extractBetween(var, sep++, variant); id.extractBetween(sep, id.length(), target); } if (variant.length() > 0) { variant.remove(0, 1); } }
static PyObject *t_canonicaliterator_getSource(t_canonicaliterator *self, PyObject *args) { UnicodeString *u; UnicodeString _u; switch (PyTuple_Size(args)) { case 0: _u = self->object->getSource(); return PyUnicode_FromUnicodeString(&_u); case 1: if (!parseArgs(args, "U", &u)) { u->setTo(self->object->getSource()); Py_RETURN_ARG(args, 0); } break; } return PyErr_SetArgsError((PyObject *) self, "getSource", args); }
static PyObject *t_resourcebundle_getNextString(t_resourcebundle *self, PyObject *args) { UnicodeString *u; UnicodeString _u; switch (PyTuple_Size(args)) { case 0: STATUS_CALL(_u = self->object->getNextString(status)); return PyUnicode_FromUnicodeString(&_u); case 1: if (!parseArgs(args, "U", &u)) { STATUS_CALL(u->setTo(self->object->getNextString(status))); Py_RETURN_ARG(args, 0); } break; } return PyErr_SetArgsError((PyObject *) self, "getNextString", args); }
static int32_t findInStringArray(UResourceBundle* array, const UnicodeString& id, UErrorCode &status) { UnicodeString copy; const UChar *u; int32_t len; int32_t start = 0; int32_t limit = ures_getSize(array); int32_t mid; int32_t lastMid = INT32_MAX; if(U_FAILURE(status) || (limit < 1)) { return -1; } U_DEBUG_TZ_MSG(("fisa: Looking for %s, between %d and %d\n", U_DEBUG_TZ_STR(UnicodeString(id).getTerminatedBuffer()), start, limit)); for (;;) { mid = (int32_t)((start + limit) / 2); if (lastMid == mid) { /* Have we moved? */ break; /* We haven't moved, and it wasn't found. */ } lastMid = mid; u = ures_getStringByIndex(array, mid, &len, &status); if (U_FAILURE(status)) { break; } U_DEBUG_TZ_MSG(("tz: compare to %s, %d .. [%d] .. %d\n", U_DEBUG_TZ_STR(u), start, mid, limit)); copy.setTo(TRUE, u, len); int r = id.compare(copy); if(r==0) { U_DEBUG_TZ_MSG(("fisa: found at %d\n", mid)); return mid; } else if(r<0) { limit = mid; } else { start = mid; } } U_DEBUG_TZ_MSG(("fisa: not found\n")); return -1; }
U_CAPI int32_t U_EXPORT2 unum_formatDecimal(const UNumberFormat* fmt, const char * number, int32_t length, UChar* result, int32_t resultLength, UFieldPosition *pos, /* 0 if ignore */ UErrorCode* status) { if(U_FAILURE(*status)) { return -1; } if ((result == NULL && resultLength != 0) || resultLength < 0) { *status = U_ILLEGAL_ARGUMENT_ERROR; return -1; } FieldPosition fp; if(pos != 0) { fp.setField(pos->field); } if (length < 0) { length = uprv_strlen(number); } StringPiece numSP(number, length); Formattable numFmtbl(numSP, *status); UnicodeString resultStr; if (resultLength > 0) { // Alias the destination buffer. resultStr.setTo(result, 0, resultLength); } ((const NumberFormat*)fmt)->format(numFmtbl, resultStr, fp, *status); if(pos != 0) { pos->beginIndex = fp.getBeginIndex(); pos->endIndex = fp.getEndIndex(); } return resultStr.extract(result, resultLength, *status); }
U_CAPI int32_t U_EXPORT2 ucal_getTimeZoneDisplayName(const UCalendar* cal, UCalendarDisplayNameType type, const char *locale, UChar* result, int32_t resultLength, UErrorCode* status) { if(U_FAILURE(*status)) return -1; const TimeZone& tz = ((Calendar*)cal)->getTimeZone(); UnicodeString id; if(!(result==NULL && resultLength==0)) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer id.setTo(result, 0, resultLength); } switch(type) { case UCAL_STANDARD: tz.getDisplayName(FALSE, TimeZone::LONG, Locale(locale), id); break; case UCAL_SHORT_STANDARD: tz.getDisplayName(FALSE, TimeZone::SHORT, Locale(locale), id); break; case UCAL_DST: tz.getDisplayName(TRUE, TimeZone::LONG, Locale(locale), id); break; case UCAL_SHORT_DST: tz.getDisplayName(TRUE, TimeZone::SHORT, Locale(locale), id); break; } return id.extract(result, resultLength, *status); }
static PyObject *t_rulebasedbreakiterator_getRules(t_rulebasedbreakiterator *self, PyObject *args) { switch (PyTuple_Size(args)) { case 0: { UnicodeString u = self->object->getRules(); return PyUnicode_FromUnicodeString(&u); } case 1: { UnicodeString *u; if (!parseArgs(args, "U", &u)) { u->setTo(self->object->getRules()); Py_RETURN_ARG(args, 0); } break; } } return PyErr_SetArgsError((PyObject *) self, "getRules", args); }
U_CAPI int32_t U_EXPORT2 udat_toPattern( const UDateFormat *fmt, UBool localized, UChar *result, int32_t resultLength, UErrorCode *status) { if(U_FAILURE(*status)) { return -1; } if (result == NULL ? resultLength != 0 : resultLength < 0) { *status = U_ILLEGAL_ARGUMENT_ERROR; return -1; } UnicodeString res; if (result != NULL) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer res.setTo(result, 0, resultLength); } const DateFormat *df=reinterpret_cast<const DateFormat *>(fmt); const SimpleDateFormat *sdtfmt=dynamic_cast<const SimpleDateFormat *>(df); const RelativeDateFormat *reldtfmt; if (sdtfmt!=NULL) { if(localized) sdtfmt->toLocalizedPattern(res, *status); else sdtfmt->toPattern(res); } else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(df))!=NULL) { reldtfmt->toPattern(res, *status); } else { *status = U_ILLEGAL_ARGUMENT_ERROR; return -1; } return res.extract(result, resultLength, *status); }
void RuleBasedNumberFormat::stripWhitespace(UnicodeString& description) { // iterate through the characters... UnicodeString result; int start = 0; while (start != -1 && start < description.length()) { // seek to the first non-whitespace character... while (start < description.length() && PatternProps::isWhiteSpace(description.charAt(start))) { ++start; } // locate the next semicolon in the text and copy the text from // our current position up to that semicolon into the result int32_t p = description.indexOf(gSemiColon, start); if (p == -1) { // or if we don't find a semicolon, just copy the rest of // the string into the result result.append(description, start, description.length() - start); start = -1; } else if (p < description.length()) { result.append(description, start, p + 1 - start); start = p + 1; } // when we get here, we've seeked off the end of the sring, and // we terminate the loop (we continue until *start* is -1 rather // than until *p* is -1, because otherwise we'd miss the last // rule in the description) else { start = -1; } } description.setTo(result); }
NumberingSystem* U_EXPORT2 NumberingSystem::createInstanceByName(const char *name, UErrorCode& status) { UResourceBundle *numberingSystemsInfo = NULL; UResourceBundle *nsTop, *nsCurrent; const UChar* description = NULL; int32_t radix = 10; int32_t algorithmic = 0; int32_t len; numberingSystemsInfo = ures_openDirect(NULL,gNumberingSystems, &status); nsCurrent = ures_getByKey(numberingSystemsInfo,gNumberingSystems,NULL,&status); nsTop = ures_getByKey(nsCurrent,name,NULL,&status); description = ures_getStringByKey(nsTop,gDesc,&len,&status); ures_getByKey(nsTop,gRadix,nsCurrent,&status); radix = ures_getInt(nsCurrent,&status); ures_getByKey(nsTop,gAlgorithmic,nsCurrent,&status); algorithmic = ures_getInt(nsCurrent,&status); UBool isAlgorithmic = ( algorithmic == 1 ); UnicodeString nsd; nsd.setTo(description); ures_close(nsCurrent); ures_close(nsTop); ures_close(numberingSystemsInfo); if (U_FAILURE(status)) { status = U_UNSUPPORTED_ERROR; return NULL; } NumberingSystem* ns = NumberingSystem::createInstance(radix,isAlgorithmic,nsd,status); ns->setName(name); return ns; }
U_CAPI int32_t U_EXPORT2 udat_toPattern( const UDateFormat *fmt, UBool localized, UChar *result, int32_t resultLength, UErrorCode *status) { if(U_FAILURE(*status)) return -1; UnicodeString res; if(!(result==NULL && resultLength==0)) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer res.setTo(result, 0, resultLength); } if(localized) ((SimpleDateFormat*)fmt)->toLocalizedPattern(res, *status); else ((SimpleDateFormat*)fmt)->toPattern(res); return res.extract(result, resultLength, *status); }
U_CAPI int32_t U_EXPORT2 udat_formatCalendar(const UDateFormat* format, UCalendar* calendar, UChar* result, int32_t resultLength, UFieldPosition* position, UErrorCode* status) { if(U_FAILURE(*status)) { return -1; } if (result == NULL ? resultLength != 0 : resultLength < 0) { *status = U_ILLEGAL_ARGUMENT_ERROR; return -1; } UnicodeString res; if (result != NULL) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer res.setTo(result, 0, resultLength); } FieldPosition fp; if(position != 0) fp.setField(position->field); ((DateFormat*)format)->format(*(Calendar*)calendar, res, fp); if(position != 0) { position->beginIndex = fp.getBeginIndex(); position->endIndex = fp.getEndIndex(); } return res.extract(result, resultLength, *status); }
U_CAPI int32_t U_EXPORT2 unum_formatDoubleCurrency(const UNumberFormat* fmt, double number, UChar* currency, UChar* result, int32_t resultLength, UFieldPosition* pos, /* ignored if 0 */ UErrorCode* status) { if (U_FAILURE(*status)) return -1; UnicodeString res; if (!(result==NULL && resultLength==0)) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer res.setTo(result, 0, resultLength); } FieldPosition fp; if (pos != 0) { fp.setField(pos->field); } CurrencyAmount *tempCurrAmnt = new CurrencyAmount(number, currency, *status); // Check for null pointer. if (tempCurrAmnt == NULL) { *status = U_MEMORY_ALLOCATION_ERROR; return -1; } Formattable n(tempCurrAmnt); ((const NumberFormat*)fmt)->format(n, res, fp, *status); if (pos != 0) { pos->beginIndex = fp.getBeginIndex(); pos->endIndex = fp.getEndIndex(); } return res.extract(result, resultLength, *status); }
U_CAPI int32_t U_EXPORT2 udat_toPatternRelativeDate(const UDateFormat *fmt, UChar *result, int32_t resultLength, UErrorCode *status) { verifyIsRelativeDateFormat(fmt, status); if(U_FAILURE(*status)) { return -1; } if (result == NULL ? resultLength != 0 : resultLength < 0) { *status = U_ILLEGAL_ARGUMENT_ERROR; return -1; } UnicodeString datePattern; if (result != NULL) { // NULL destination for pure preflighting: empty dummy string // otherwise, alias the destination buffer datePattern.setTo(result, 0, resultLength); } ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status); return datePattern.extract(result, resultLength, *status); }
void NFRuleSet::parseRules(UnicodeString& description, const RuleBasedNumberFormat* owner, UErrorCode& status) { // start by creating a Vector whose elements are Strings containing // the descriptions of the rules (one rule per element). The rules // are separated by semicolons (there's no escape facility: ALL // semicolons are rule delimiters) if (U_FAILURE(status)) { return; } // ensure we are starting with an empty rule list rules.deleteAll(); // dlf - the original code kept a separate description array for no reason, // so I got rid of it. The loop was too complex so I simplified it. UnicodeString currentDescription; int32_t oldP = 0; while (oldP < description.length()) { int32_t p = description.indexOf(gSemicolon, oldP); if (p == -1) { p = description.length(); } currentDescription.setTo(description, oldP, p - oldP); NFRule::makeRules(currentDescription, this, rules.last(), owner, rules, status); oldP = p + 1; } // for rules that didn't specify a base value, their base values // were initialized to 0. Make another pass through the list and // set all those rules' base values. We also remove any special // rules from the list and put them into their own member variables int64_t defaultBaseValue = 0; // (this isn't a for loop because we might be deleting items from // the vector-- we want to make sure we only increment i when // we _didn't_ delete aything from the vector) uint32_t i = 0; while (i < rules.size()) { NFRule* rule = rules[i]; switch (rule->getType()) { // if the rule's base value is 0, fill in a default // base value (this will be 1 plus the preceding // rule's base value for regular rule sets, and the // same as the preceding rule's base value in fraction // rule sets) case NFRule::kNoBase: rule->setBaseValue(defaultBaseValue, status); if (!isFractionRuleSet()) { ++defaultBaseValue; } ++i; break; // if it's the negative-number rule, copy it into its own // data member and delete it from the list case NFRule::kNegativeNumberRule: if (negativeNumberRule) { delete negativeNumberRule; } negativeNumberRule = rules.remove(i); break; // if it's the improper fraction rule, copy it into the // correct element of fractionRules case NFRule::kImproperFractionRule: if (fractionRules[0]) { delete fractionRules[0]; } fractionRules[0] = rules.remove(i); break; // if it's the proper fraction rule, copy it into the // correct element of fractionRules case NFRule::kProperFractionRule: if (fractionRules[1]) { delete fractionRules[1]; } fractionRules[1] = rules.remove(i); break; // if it's the master rule, copy it into the // correct element of fractionRules case NFRule::kMasterRule: if (fractionRules[2]) { delete fractionRules[2]; } fractionRules[2] = rules.remove(i); break; // if it's a regular rule that already knows its base value, // check to make sure the rules are in order, and update // the default base value for the next rule default: if (rule->getBaseValue() < defaultBaseValue) { // throw new IllegalArgumentException("Rules are not in order"); status = U_PARSE_ERROR; return; } defaultBaseValue = rule->getBaseValue(); if (!isFractionRuleSet()) { ++defaultBaseValue; } ++i; break; } } }
void LocaleDisplayNamesImpl::initialize(void) { LocaleDisplayNamesImpl *nonConstThis = (LocaleDisplayNamesImpl *)this; nonConstThis->locale = langData.getLocale() == Locale::getRoot() ? regionData.getLocale() : langData.getLocale(); UnicodeString sep; langData.getNoFallback("localeDisplayPattern", "separator", sep); if (sep.isBogus()) { sep = UnicodeString("{0}, {1}", -1, US_INV); } UErrorCode status = U_ZERO_ERROR; separatorFormat.applyPatternMinMaxArguments(sep, 2, 2, status); UnicodeString pattern; langData.getNoFallback("localeDisplayPattern", "pattern", pattern); if (pattern.isBogus()) { pattern = UnicodeString("{0} ({1})", -1, US_INV); } format.applyPatternMinMaxArguments(pattern, 2, 2, status); if (pattern.indexOf((UChar)0xFF08) >= 0) { formatOpenParen.setTo((UChar)0xFF08); // fullwidth ( formatReplaceOpenParen.setTo((UChar)0xFF3B); // fullwidth [ formatCloseParen.setTo((UChar)0xFF09); // fullwidth ) formatReplaceCloseParen.setTo((UChar)0xFF3D); // fullwidth ] } else { formatOpenParen.setTo((UChar)0x0028); // ( formatReplaceOpenParen.setTo((UChar)0x005B); // [ formatCloseParen.setTo((UChar)0x0029); // ) formatReplaceCloseParen.setTo((UChar)0x005D); // ] } UnicodeString ktPattern; langData.get("localeDisplayPattern", "keyTypePattern", ktPattern); if (ktPattern.isBogus()) { ktPattern = UnicodeString("{0}={1}", -1, US_INV); } keyTypeFormat.applyPatternMinMaxArguments(ktPattern, 2, 2, status); uprv_memset(fCapitalization, 0, sizeof(fCapitalization)); #if !UCONFIG_NO_BREAK_ITERATION // The following is basically copied from DateFormatSymbols::initializeData typedef struct { const char * usageName; LocaleDisplayNamesImpl::CapContextUsage usageEnum; } ContextUsageNameToEnum; const ContextUsageNameToEnum contextUsageTypeMap[] = { // Entries must be sorted by usageTypeName; entry with NULL name terminates list. { "key", kCapContextUsageKey }, { "keyValue", kCapContextUsageKeyValue }, { "languages", kCapContextUsageLanguage }, { "script", kCapContextUsageScript }, { "territory", kCapContextUsageTerritory }, { "variant", kCapContextUsageVariant }, { NULL, (CapContextUsage)0 }, }; // Only get the context data if we need it! This is a const object so we know now... // Also check whether we will need a break iterator (depends on the data) UBool needBrkIter = FALSE; if (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_STANDALONE) { int32_t len = 0; UResourceBundle *localeBundle = ures_open(NULL, locale.getName(), &status); if (U_SUCCESS(status)) { UResourceBundle *contextTransforms = ures_getByKeyWithFallback(localeBundle, "contextTransforms", NULL, &status); if (U_SUCCESS(status)) { UResourceBundle *contextTransformUsage; while ( (contextTransformUsage = ures_getNextResource(contextTransforms, NULL, &status)) != NULL ) { const int32_t * intVector = ures_getIntVector(contextTransformUsage, &len, &status); if (U_SUCCESS(status) && intVector != NULL && len >= 2) { const char* usageKey = ures_getKey(contextTransformUsage); if (usageKey != NULL) { const ContextUsageNameToEnum * typeMapPtr = contextUsageTypeMap; int32_t compResult = 0; // linear search; list is short and we cannot be sure that bsearch is available while ( typeMapPtr->usageName != NULL && (compResult = uprv_strcmp(usageKey, typeMapPtr->usageName)) > 0 ) { ++typeMapPtr; } if (typeMapPtr->usageName != NULL && compResult == 0) { int32_t titlecaseInt = (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU)? intVector[0]: intVector[1]; if (titlecaseInt != 0) { fCapitalization[typeMapPtr->usageEnum] = TRUE;; needBrkIter = TRUE; } } } } status = U_ZERO_ERROR; ures_close(contextTransformUsage); } ures_close(contextTransforms); } ures_close(localeBundle); } } // Get a sentence break iterator if we will need it if (needBrkIter || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE) { status = U_ZERO_ERROR; capitalizationBrkIter = BreakIterator::createSentenceInstance(locale, status); if (U_FAILURE(status)) { delete capitalizationBrkIter; capitalizationBrkIter = NULL; } } #endif }
// Convert a file from one encoding to another static UBool convertFile(const char *pname, const char *fromcpage, UConverterToUCallback toucallback, const void *touctxt, const char *tocpage, UConverterFromUCallback fromucallback, const void *fromuctxt, int fallback, size_t bufsz, const char *translit, const char *infilestr, FILE * outfile, int verbose) { FILE *infile; UBool ret = TRUE; UConverter *convfrom = 0; UConverter *convto = 0; UErrorCode err = U_ZERO_ERROR; UBool flush; const char *cbufp; char *bufp; char *buf = 0; uint32_t infoffset = 0, outfoffset = 0; /* Where we are in the file, for error reporting. */ const UChar *unibufbp; UChar *unibufp; UChar *unibuf = 0; int32_t *fromoffsets = 0, *tooffsets = 0; size_t rd, wr, tobufsz; #if !UCONFIG_NO_TRANSLITERATION Transliterator *t = 0; // Transliterator acting on Unicode data. #endif UnicodeString u; // String to do the transliteration. // Open the correct input file or connect to stdin for reading input if (infilestr != 0 && strcmp(infilestr, "-")) { infile = fopen(infilestr, "rb"); if (infile == 0) { UnicodeString str1(infilestr, ""); str1.append((UChar32) 0); UnicodeString str2(strerror(errno), ""); str2.append((UChar32) 0); initMsg(pname); u_wmsg(stderr, "cantOpenInputF", str1.getBuffer(), str2.getBuffer()); return FALSE; } } else { infilestr = "-"; infile = stdin; #ifdef WIN32 if (setmode(fileno(stdin), O_BINARY) == -1) { initMsg(pname); u_wmsg(stderr, "cantSetInBinMode"); return FALSE; } #endif } if (verbose) { fprintf(stderr, "%s:\n", infilestr); } #if !UCONFIG_NO_TRANSLITERATION // Create transliterator as needed. if (translit != NULL && *translit) { UParseError parse; UnicodeString str(translit), pestr; /* Create from rules or by ID as needed. */ parse.line = -1; if (uprv_strchr(translit, ':') || uprv_strchr(translit, '>') || uprv_strchr(translit, '<') || uprv_strchr(translit, '>')) { t = Transliterator::createFromRules("Uconv", str, UTRANS_FORWARD, parse, err); } else { t = Transliterator::createInstance(translit, UTRANS_FORWARD, err); } if (U_FAILURE(err)) { str.append((UChar32) 0); initMsg(pname); if (parse.line >= 0) { UChar linebuf[20], offsetbuf[20]; uprv_itou(linebuf, 20, parse.line, 10, 0); uprv_itou(offsetbuf, 20, parse.offset, 10, 0); u_wmsg(stderr, "cantCreateTranslitParseErr", str.getBuffer(), u_wmsg_errorName(err), linebuf, offsetbuf); } else { u_wmsg(stderr, "cantCreateTranslit", str.getBuffer(), u_wmsg_errorName(err)); } if (t) { delete t; t = 0; } goto error_exit; } } #endif // Create codepage converter. If the codepage or its aliases weren't // available, it returns NULL and a failure code. We also set the // callbacks, and return errors in the same way. convfrom = ucnv_open(fromcpage, &err); if (U_FAILURE(err)) { UnicodeString str(fromcpage, (int32_t)(uprv_strlen(fromcpage) + 1)); initMsg(pname); u_wmsg(stderr, "cantOpenFromCodeset", str.getBuffer(), u_wmsg_errorName(err)); goto error_exit; } ucnv_setToUCallBack(convfrom, toucallback, touctxt, 0, 0, &err); if (U_FAILURE(err)) { initMsg(pname); u_wmsg(stderr, "cantSetCallback", u_wmsg_errorName(err)); goto error_exit; } convto = ucnv_open(tocpage, &err); if (U_FAILURE(err)) { UnicodeString str(tocpage, (int32_t)(uprv_strlen(tocpage) + 1)); initMsg(pname); u_wmsg(stderr, "cantOpenToCodeset", str.getBuffer(), u_wmsg_errorName(err)); goto error_exit; } ucnv_setFromUCallBack(convto, fromucallback, fromuctxt, 0, 0, &err); if (U_FAILURE(err)) { initMsg(pname); u_wmsg(stderr, "cantSetCallback", u_wmsg_errorName(err)); goto error_exit; } ucnv_setFallback(convto, fallback); // To ensure that the buffer always is of enough size, we // must take the worst case scenario, that is the character in // the codepage that uses the most bytes and multiply it against // the buffer size. // use bufsz+1 to allow for additional BOM/signature character (U+FEFF) tobufsz = (bufsz+1) * ucnv_getMaxCharSize(convto); buf = new char[tobufsz]; unibuf = new UChar[bufsz]; fromoffsets = new int32_t[bufsz]; tooffsets = new int32_t[tobufsz]; // OK, we can convert now. do { char willexit = 0; rd = fread(buf, 1, bufsz, infile); if (ferror(infile) != 0) { UnicodeString str(strerror(errno)); str.append((UChar32) 0); initMsg(pname); u_wmsg(stderr, "cantRead", str.getBuffer()); goto error_exit; } // Convert the read buffer into the new coding // After the call 'unibufp' will be placed on the last // character that was converted in the 'unibuf'. // Also the 'cbufp' is positioned on the last converted // character. // At the last conversion in the file, flush should be set to // true so that we get all characters converted // // The converter must be flushed at the end of conversion so // that characters on hold also will be written. unibufp = unibuf; cbufp = buf; flush = rd != bufsz; ucnv_toUnicode(convfrom, &unibufp, unibufp + bufsz, &cbufp, cbufp + rd, fromoffsets, flush, &err); infoffset += (uint32_t)(cbufp - buf); if (U_FAILURE(err)) { char pos[32]; sprintf(pos, "%u", infoffset - 1); UnicodeString str(pos, (int32_t)(uprv_strlen(pos) + 1)); initMsg(pname); u_wmsg(stderr, "problemCvtToU", str.getBuffer(), u_wmsg_errorName(err)); willexit = 1; err = U_ZERO_ERROR; /* reset the error for the rest of the conversion. */ } // At the last conversion, the converted characters should be // equal to number of chars read. if (flush && !willexit && cbufp != (buf + rd)) { char pos[32]; sprintf(pos, "%u", infoffset); UnicodeString str(pos, (int32_t)(uprv_strlen(pos) + 1)); initMsg(pname); u_wmsg(stderr, "premEndInput", str.getBuffer()); willexit = 1; } // Prepare to transliterate and convert. Transliterate if needed. #if !UCONFIG_NO_TRANSLITERATION if (t) { u.setTo(unibuf, (int32_t)(unibufp - unibuf)); // Copy into string. t->transliterate(u); } else #endif { u.setTo(unibuf, (int32_t)(unibufp - unibuf), (int32_t)(bufsz)); // Share the buffer. } int32_t ulen = u.length(); // Convert the Unicode buffer into the destination codepage // Again 'bufp' will be placed on the last converted character // And 'unibufbp' will be placed on the last converted unicode character // At the last conversion flush should be set to true to ensure that // all characters left get converted const UChar *unibufu = unibufbp = u.getBuffer(); do { int32_t len = ulen > (int32_t)bufsz ? (int32_t)bufsz : ulen; bufp = buf; unibufp = (UChar *) (unibufbp + len); ucnv_fromUnicode(convto, &bufp, bufp + tobufsz, &unibufbp, unibufp, tooffsets, flush, &err); if (U_FAILURE(err)) { const char *errtag; char pos[32]; uint32_t erroffset = dataOffset((int32_t)(bufp - buf - 1), fromoffsets, (int32_t)(bufsz), tooffsets, (int32_t)(tobufsz)); int32_t ferroffset = (int32_t)(infoffset - (unibufp - unibufu) + erroffset); if ((int32_t) ferroffset < 0) { ferroffset = (int32_t)(outfoffset + (bufp - buf)); errtag = "problemCvtFromUOut"; } else { errtag = "problemCvtFromU"; } sprintf(pos, "%u", ferroffset); UnicodeString str(pos, (int32_t)(uprv_strlen(pos) + 1)); initMsg(pname); u_wmsg(stderr, errtag, str.getBuffer(), u_wmsg_errorName(err)); willexit = 1; } // At the last conversion, the converted characters should be equal to number // of consumed characters. if (flush && !willexit && unibufbp != (unibufu + (size_t) (unibufp - unibufu))) { char pos[32]; sprintf(pos, "%u", infoffset); UnicodeString str(pos, (int32_t)(uprv_strlen(pos) + 1)); initMsg(pname); u_wmsg(stderr, "premEnd", str.getBuffer()); willexit = 1; } // Finally, write the converted buffer to the output file rd = (size_t) (bufp - buf); outfoffset += (int32_t)(wr = fwrite(buf, 1, rd, outfile)); if (wr != rd) { UnicodeString str(strerror(errno), ""); initMsg(pname); u_wmsg(stderr, "cantWrite", str.getBuffer()); willexit = 1; } if (willexit) { goto error_exit; } } while ((ulen -= (int32_t)(bufsz)) > 0); } while (!flush); // Stop when we have flushed the // converters (this means that it's // the end of output) goto normal_exit; error_exit: ret = FALSE; normal_exit: // Cleanup. if (convfrom) ucnv_close(convfrom); if (convto) ucnv_close(convto); #if !UCONFIG_NO_TRANSLITERATION if (t) delete t; #endif if (buf) delete[] buf; if (unibuf) delete[] unibuf; if (fromoffsets) delete[] fromoffsets; if (tooffsets) delete[] tooffsets; if (infile != stdin) { fclose(infile); } return ret; }
int DoConvert ( char * lpInBuffer, int nInLen, char * lpOutBuffer, int& rnOutLen ) { #ifdef VERBOSE_DEBUGGING fprintf(stderr, "IcuTranslitEC.CppDoConvert() BEGIN\n"); #endif int hr = 0; UnicodeString sInOut; #ifdef _MSC_VER sInOut.setTo((UChar *)lpInBuffer, nInLen / 2); #else sInOut.setTo(lpInBuffer); #endif printUnicodeString("Will transliterate: ", sInOut); if( m_bLTR ) { if( m_pTForwards ) { #ifdef VERBOSE_DEBUGGING fprintf(stderr, "Doing forwards transliteration...\n"); #endif m_pTForwards->transliterate(sInOut); #ifdef VERBOSE_DEBUGGING fprintf(stderr, "Did forwards transliteration.\n"); #endif } else { #ifdef VERBOSE_DEBUGGING fprintf(stderr, "There is no forward transliterator.\n"); #endif hr = -1; } } else // !m_bLTR { if( m_pTBackwards ) { #ifdef VERBOSE_DEBUGGING fprintf(stderr, "Doing backwards transliteration...\n"); #endif m_pTBackwards->transliterate(sInOut); #ifdef VERBOSE_DEBUGGING fprintf(stderr, "Did backwards transliteration.\n"); #endif } else { #ifdef VERBOSE_DEBUGGING fprintf(stderr, "There is no backwards transliterator.\n"); #endif hr = -1; } } if (hr == 0) { printUnicodeString("Result of transliteration: ", sInOut); #ifdef VERBOSE_DEBUGGING fprintf(stderr, "sInOut.length %d\n", sInOut.length()); #endif #ifdef _MSC_VER UErrorCode err = U_ZERO_ERROR; int nLen = sInOut.extract((UChar *)lpOutBuffer, rnOutLen/sizeof(UChar) , err); if (nLen >= (int)rnOutLen || U_FAILURE(err)) #else int nLen = sInOut.extract(0, sInOut.length(), (char *)NULL); // "preflight" to get size if( nLen >= (int)rnOutLen ) #endif { #ifdef VERBOSE_DEBUGGING fprintf(stderr, "Length %d more than output buffer size %d\n", nLen, rnOutLen); #endif hr = -1; } else { #ifdef VERBOSE_DEBUGGING fprintf(stderr, "nLen %d < original rnOutLen %d\n", nLen, rnOutLen); #endif #ifdef _MSC_VER rnOutLen = nLen * sizeof(UChar); #else nLen = sInOut.extract(0, sInOut.length(), lpOutBuffer); rnOutLen = nLen; #endif #ifdef VERBOSE_DEBUGGING fprintf(stderr, "lpOutBuffer length = %u (should be %d)\n", (unsigned)strlen(lpOutBuffer), rnOutLen); fprintf(stderr, "lpOutBuffer: '%s'\n", lpOutBuffer); #endif } } return hr; }
UBool NewResourceBundleTest::testTag(const char* frag, UBool in_Root, UBool in_te, UBool in_te_IN) { int32_t failOrig = fail; // Make array from input params UBool is_in[] = { in_Root, in_te, in_te_IN }; const char* NAME[] = { "ROOT", "TE", "TE_IN" }; // Now try to load the desired items char tag[100]; UnicodeString action; int32_t i,j,row,col, actual_bundle; int32_t index; const char* testdatapath; UErrorCode status = U_ZERO_ERROR; testdatapath=loadTestData(status); if(U_FAILURE(status)) { dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(status))); return FALSE; } for (i=0; i<bundles_count; ++i) { action = "Constructor for "; action += param[i].name; status = U_ZERO_ERROR; ResourceBundle theBundle( testdatapath, *param[i].locale, status); //ResourceBundle theBundle( "c:\\icu\\icu\\source\\test\\testdata\\testdata", *param[i].locale, status); CONFIRM_UErrorCode(status,param[i].expected_constructor_status); if(i == 5) actual_bundle = 0; /* ne -> default */ else if(i == 3) actual_bundle = 1; /* te_NE -> te */ else if(i == 4) actual_bundle = 2; /* te_IN_NE -> te_IN */ else actual_bundle = i; UErrorCode expected_resource_status = U_MISSING_RESOURCE_ERROR; for (j=e_te_IN; j>=e_Root; --j) { if (is_in[j] && param[i].inherits[j]) { if(j == actual_bundle) /* it's in the same bundle OR it's a nonexistent=default bundle (5) */ expected_resource_status = U_ZERO_ERROR; else if(j == 0) expected_resource_status = U_USING_DEFAULT_WARNING; else expected_resource_status = U_USING_FALLBACK_WARNING; break; } } UErrorCode expected_status; UnicodeString base; for (j=param[i].where; j>=0; --j) { if (is_in[j]) { base = NAME[j]; break; } } //-------------------------------------------------------------------------- // string uprv_strcpy(tag, "string_"); uprv_strcat(tag, frag); action = param[i].name; action += ".getStringEx("; action += tag; action += ")"; status = U_ZERO_ERROR; UnicodeString string = theBundle.getStringEx(tag, status); if(U_FAILURE(status)) { string.setTo(TRUE, kErrorUChars, kErrorLength); } CONFIRM_UErrorCode(status, expected_resource_status); UnicodeString expected_string(kErrorUChars); if (U_SUCCESS(status)) { expected_string = base; } CONFIRM_EQ(string, expected_string); //-------------------------------------------------------------------------- // array ResourceBundle using the key uprv_strcpy(tag, "array_"); uprv_strcat(tag, frag); action = param[i].name; action += ".get("; action += tag; action += ")"; int32_t count = kERROR_COUNT; status = U_ZERO_ERROR; ResourceBundle array = theBundle.get(tag, status); CONFIRM_UErrorCode(status,expected_resource_status); if (U_SUCCESS(status)) { //confirm the resource type is an array UResType bundleType=array.getType(); CONFIRM_EQ(bundleType, URES_ARRAY); count=array.getSize(); CONFIRM_GE(count,1); for (j=0; j<count; ++j) { char buf[32]; expected_string = base; expected_string += itoa(j,buf); CONFIRM_EQ(array.getNextString(status),expected_string); } } else { CONFIRM_EQ(count,kERROR_COUNT); // CONFIRM_EQ((int32_t)(unsigned long)array,(int32_t)0); count = 0; } //-------------------------------------------------------------------------- // arrayItem ResourceBundle using the index for (j=0; j<100; ++j) { index = count ? (randi(count * 3) - count) : (randi(200) - 100); status = U_ZERO_ERROR; string = kErrorUChars; ResourceBundle array = theBundle.get(tag, status); if(!U_FAILURE(status)){ UnicodeString t = array.getStringEx(index, status); if(!U_FAILURE(status)) { string=t; } } expected_status = (index >= 0 && index < count) ? expected_resource_status : U_MISSING_RESOURCE_ERROR; CONFIRM_UErrorCode(status,expected_status); if (U_SUCCESS(status)){ char buf[32]; expected_string = base; expected_string += itoa(index,buf); } else { expected_string = kErrorUChars; } CONFIRM_EQ(string,expected_string); } //-------------------------------------------------------------------------- // 2dArray uprv_strcpy(tag, "array_2d_"); uprv_strcat(tag, frag); action = param[i].name; action += ".get("; action += tag; action += ")"; int32_t row_count = kERROR_COUNT, column_count = kERROR_COUNT; status = U_ZERO_ERROR; ResourceBundle array2d=theBundle.get(tag, status); //const UnicodeString** array2d = theBundle.get2dArray(tag, row_count, column_count, status); CONFIRM_UErrorCode(status,expected_resource_status); if (U_SUCCESS(status)) { //confirm the resource type is an 2darray UResType bundleType=array2d.getType(); CONFIRM_EQ(bundleType, URES_ARRAY); row_count=array2d.getSize(); CONFIRM_GE(row_count,1); for(row=0; row<row_count; ++row){ ResourceBundle tablerow=array2d.get(row, status); CONFIRM_UErrorCode(status, expected_resource_status); if(U_SUCCESS(status)){ //confirm the resourcetype of each table row is an array UResType rowType=tablerow.getType(); CONFIRM_EQ(rowType, URES_ARRAY); column_count=tablerow.getSize(); CONFIRM_GE(column_count,1); for (col=0; j<column_count; ++j) { char buf[32]; expected_string = base; expected_string += itoa(row,buf); expected_string += itoa(col,buf); CONFIRM_EQ(tablerow.getNextString(status),expected_string); } } } }else{ CONFIRM_EQ(row_count,kERROR_COUNT); CONFIRM_EQ(column_count,kERROR_COUNT); row_count=column_count=0; } //-------------------------------------------------------------------------- // 2dArrayItem for (j=0; j<200; ++j) { row = row_count ? (randi(row_count * 3) - row_count) : (randi(200) - 100); col = column_count ? (randi(column_count * 3) - column_count) : (randi(200) - 100); status = U_ZERO_ERROR; string = kErrorUChars; ResourceBundle array2d=theBundle.get(tag, status); if(U_SUCCESS(status)){ ResourceBundle tablerow=array2d.get(row, status); if(U_SUCCESS(status)) { UnicodeString t=tablerow.getStringEx(col, status); if(U_SUCCESS(status)){ string=t; } } } expected_status = (row >= 0 && row < row_count && col >= 0 && col < column_count) ? expected_resource_status: U_MISSING_RESOURCE_ERROR; CONFIRM_UErrorCode(status,expected_status); if (U_SUCCESS(status)){ char buf[32]; expected_string = base; expected_string += itoa(row,buf); expected_string += itoa(col,buf); } else { expected_string = kErrorUChars; } CONFIRM_EQ(string,expected_string); } //-------------------------------------------------------------------------- // taggedArray uprv_strcpy(tag, "tagged_array_"); uprv_strcat(tag, frag); action = param[i].name; action += ".get("; action += tag; action += ")"; int32_t tag_count; status = U_ZERO_ERROR; ResourceBundle tags=theBundle.get(tag, status); CONFIRM_UErrorCode(status, expected_resource_status); if (U_SUCCESS(status)) { UResType bundleType=tags.getType(); CONFIRM_EQ(bundleType, URES_TABLE); tag_count=tags.getSize(); CONFIRM_GE((int32_t)tag_count, (int32_t)0); for(index=0; index <tag_count; index++){ ResourceBundle tagelement=tags.get(index, status); UnicodeString key=tagelement.getKey(); UnicodeString value=tagelement.getNextString(status); logln("tag = " + key + ", value = " + value ); if(key.startsWith("tag") && value.startsWith(base)){ record_pass(); }else{ record_fail(); } } for(index=0; index <tag_count; index++){ ResourceBundle tagelement=tags.get(index, status); const char *tkey=NULL; UnicodeString value=tagelement.getNextString(&tkey, status); UnicodeString key(tkey); logln("tag = " + key + ", value = " + value ); if(value.startsWith(base)){ record_pass(); }else{ record_fail(); } } }else{ tag_count=0; } //-------------------------------------------------------------------------- // taggedArrayItem action = param[i].name; action += ".get("; action += tag; action += ")"; count = 0; for (index=-20; index<20; ++index) { char buf[32]; status = U_ZERO_ERROR; string = kErrorUChars; char item_tag[8]; uprv_strcpy(item_tag, "tag"); uprv_strcat(item_tag, itoa(index,buf)); ResourceBundle tags=theBundle.get(tag, status); if(U_SUCCESS(status)){ ResourceBundle tagelement=tags.get(item_tag, status); if(!U_FAILURE(status)){ UResType elementType=tagelement.getType(); CONFIRM_EQ(elementType, (int32_t)URES_STRING); const char* key=tagelement.getKey(); CONFIRM_EQ((UnicodeString)key, (UnicodeString)item_tag); UnicodeString t=tagelement.getString(status); if(!U_FAILURE(status)){ string=t; } } if (index < 0) { CONFIRM_UErrorCode(status,U_MISSING_RESOURCE_ERROR); } else{ if (status != U_MISSING_RESOURCE_ERROR) { count++; expected_string = base; expected_string += buf; CONFIRM_EQ(string,expected_string); } } } } CONFIRM_EQ(count, tag_count); } return (UBool)(failOrig == fail); }
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; }
UnicodeString& U_EXPORT2 ZoneMeta::getCanonicalSystemID(const UnicodeString &tzid, UnicodeString &systemID, UErrorCode& status) { int32_t len = tzid.length(); if ( len >= ZID_KEY_MAX ) { status = U_ILLEGAL_ARGUMENT_ERROR; systemID.remove(); return systemID; } char id[ZID_KEY_MAX]; const UChar* idChars = tzid.getBuffer(); u_UCharsToChars(idChars,id,len); id[len] = (char) 0; // Make sure it is null terminated. // replace '/' with ':' char *p = id; while (*p++) { if (*p == '/') { *p = ':'; } } UErrorCode tmpStatus = U_ZERO_ERROR; UResourceBundle *top = ures_openDirect(NULL, gTimeZoneTypes, &tmpStatus); UResourceBundle *rb = ures_getByKey(top, gTypeMapTag, NULL, &tmpStatus); ures_getByKey(rb, gTimezoneTag, rb, &tmpStatus); ures_getByKey(rb, id, rb, &tmpStatus); if (U_SUCCESS(tmpStatus)) { // direct map found systemID.setTo(tzid); ures_close(rb); ures_close(top); return systemID; } // If a map element not found, then look for an alias tmpStatus = U_ZERO_ERROR; ures_getByKey(top, gTypeAliasTag, rb, &tmpStatus); ures_getByKey(rb, gTimezoneTag, rb, &tmpStatus); const UChar *alias = ures_getStringByKey(rb,id,NULL,&tmpStatus); if (U_SUCCESS(tmpStatus)) { // alias found ures_close(rb); ures_close(top); systemID.setTo(alias); return systemID; } // Dereference the input ID using the tz data const UChar *derefer = TimeZone::dereferOlsonLink(tzid); if (derefer == NULL) { systemID.remove(); status = U_ILLEGAL_ARGUMENT_ERROR; } else { len = u_strlen(derefer); u_UCharsToChars(derefer,id,len); id[len] = (char) 0; // Make sure it is null terminated. // replace '/' with ':' char *p = id; while (*p++) { if (*p == '/') { *p = ':'; } } // If a dereference turned something up then look for an alias. // rb still points to the alias table, so we don't have to go looking // for it. tmpStatus = U_ZERO_ERROR; const UChar *alias = ures_getStringByKey(rb,id,NULL,&tmpStatus); if (U_SUCCESS(tmpStatus)) { // alias found systemID.setTo(alias); } else { systemID.setTo(derefer); } } ures_close(rb); ures_close(top); return systemID; }
UnicodeString& RelativeDateFormat::format( Calendar& cal, UnicodeString& appendTo, FieldPosition& pos) const { UErrorCode status = U_ZERO_ERROR; UnicodeString relativeDayString; UDisplayContext capitalizationContext = getContext(UDISPCTX_TYPE_CAPITALIZATION, status); // calculate the difference, in days, between 'cal' and now. int dayDiff = dayDifference(cal, status); // look up string int32_t len = 0; const UChar *theString = getStringForDay(dayDiff, len, status); if(U_SUCCESS(status) && (theString!=NULL)) { // found a relative string relativeDayString.setTo(theString, len); } if ( relativeDayString.length() > 0 && !fDatePattern.isEmpty() && (fTimePattern.isEmpty() || fCombinedFormat == NULL || fCombinedHasDateAtStart)) { #if !UCONFIG_NO_BREAK_ITERATION // capitalize relativeDayString according to context for relative, set formatter no context if ( u_islower(relativeDayString.char32At(0)) && fCapitalizationBrkIter!= NULL && ( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || (capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU && fCapitalizationOfRelativeUnitsForUIListMenu) || (capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_STANDALONE && fCapitalizationOfRelativeUnitsForStandAlone) ) ) { // titlecase first word of relativeDayString relativeDayString.toTitle(fCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT); } #endif fDateTimeFormatter->setContext(UDISPCTX_CAPITALIZATION_NONE, status); } else { // set our context for the formatter fDateTimeFormatter->setContext(capitalizationContext, status); } if (fDatePattern.isEmpty()) { fDateTimeFormatter->applyPattern(fTimePattern); fDateTimeFormatter->format(cal,appendTo,pos); } else if (fTimePattern.isEmpty() || fCombinedFormat == NULL) { if (relativeDayString.length() > 0) { appendTo.append(relativeDayString); } else { fDateTimeFormatter->applyPattern(fDatePattern); fDateTimeFormatter->format(cal,appendTo,pos); } } else { UnicodeString datePattern; if (relativeDayString.length() > 0) { // Need to quote the relativeDayString to make it a legal date pattern relativeDayString.findAndReplace(UNICODE_STRING("'", 1), UNICODE_STRING("''", 2)); // double any existing APOSTROPHE relativeDayString.insert(0, APOSTROPHE); // add APOSTROPHE at beginning... relativeDayString.append(APOSTROPHE); // and at end datePattern.setTo(relativeDayString); } else { datePattern.setTo(fDatePattern); } UnicodeString combinedPattern; fCombinedFormat->format(fTimePattern, datePattern, combinedPattern, status); fDateTimeFormatter->applyPattern(combinedPattern); fDateTimeFormatter->format(cal,appendTo,pos); } return appendTo; }
/** * Parse an ID into component pieces. Take IDs of the form T, * T/V, S-T, S-T/V, or S/V-T. If the source is missing, return a * source of ANY. * @param id the id string, in any of several forms * @param pos INPUT-OUTPUT parameter. On input, pos is the * offset of the first character to parse in id. On output, * pos is the offset after the last parsed character. If the * parse failed, pos will be unchanged. * @param allowFilter2 if TRUE, a UnicodeSet pattern is allowed * at any location between specs or delimiters, and is returned * as the fifth string in the array. * @return a Specs object, or NULL if the parse failed. If * neither source nor target was seen in the parsed id, then the * parse fails. If allowFilter is TRUE, then the parsed filter * pattern is returned in the Specs object, otherwise the returned * filter reference is NULL. If the parse fails for any reason * NULL is returned. */ TransliteratorIDParser::Specs* TransliteratorIDParser::parseFilterID(const UnicodeString& id, int32_t& pos, UBool allowFilter) { UnicodeString first; UnicodeString source; UnicodeString target; UnicodeString variant; UnicodeString filter; UChar delimiter = 0; int32_t specCount = 0; int32_t start = pos; // This loop parses one of the following things with each // pass: a filter, a delimiter character (either '-' or '/'), // or a spec (source, target, or variant). for (;;) { ICU_Utility::skipWhitespace(id, pos, TRUE); if (pos == id.length()) { break; } // Parse filters if (allowFilter && filter.length() == 0 && UnicodeSet::resemblesPattern(id, pos)) { ParsePosition ppos(pos); UErrorCode ec = U_ZERO_ERROR; UnicodeSet set(id, ppos, USET_IGNORE_SPACE, NULL, ec); if (U_FAILURE(ec)) { pos = start; return NULL; } id.extractBetween(pos, ppos.getIndex(), filter); pos = ppos.getIndex(); continue; } if (delimiter == 0) { UChar c = id.charAt(pos); if ((c == TARGET_SEP && target.length() == 0) || (c == VARIANT_SEP && variant.length() == 0)) { delimiter = c; ++pos; continue; } } // We are about to try to parse a spec with no delimiter // when we can no longer do so (we can only do so at the // start); break. if (delimiter == 0 && specCount > 0) { break; } UnicodeString spec = ICU_Utility::parseUnicodeIdentifier(id, pos); if (spec.length() == 0) { // Note that if there was a trailing delimiter, we // consume it. So Foo-, Foo/, Foo-Bar/, and Foo/Bar- // are legal. break; } switch (delimiter) { case 0: first = spec; break; case TARGET_SEP: target = spec; break; case VARIANT_SEP: variant = spec; break; } ++specCount; delimiter = 0; } // A spec with no prior character is either source or target, // depending on whether an explicit "-target" was seen. if (first.length() != 0) { if (target.length() == 0) { target = first; } else { source = first; } } // Must have either source or target if (source.length() == 0 && target.length() == 0) { pos = start; return NULL; } // Empty source or target defaults to ANY UBool sawSource = TRUE; if (source.length() == 0) { source.setTo(ANY, 3); sawSource = FALSE; } if (target.length() == 0) { target.setTo(ANY, 3); } return new Specs(source, target, variant, sawSource, filter); }
void LocaleDisplayNamesImpl::initialize(void) { LocaleDisplayNamesImpl *nonConstThis = (LocaleDisplayNamesImpl *)this; nonConstThis->locale = langData.getLocale() == Locale::getRoot() ? regionData.getLocale() : langData.getLocale(); UnicodeString sep; langData.getNoFallback("localeDisplayPattern", "separator", sep); if (sep.isBogus()) { sep = UnicodeString("{0}, {1}", -1, US_INV); } UErrorCode status = U_ZERO_ERROR; separatorFormat.applyPatternMinMaxArguments(sep, 2, 2, status); UnicodeString pattern; langData.getNoFallback("localeDisplayPattern", "pattern", pattern); if (pattern.isBogus()) { pattern = UnicodeString("{0} ({1})", -1, US_INV); } format.applyPatternMinMaxArguments(pattern, 2, 2, status); if (pattern.indexOf((UChar)0xFF08) >= 0) { formatOpenParen.setTo((UChar)0xFF08); // fullwidth ( formatReplaceOpenParen.setTo((UChar)0xFF3B); // fullwidth [ formatCloseParen.setTo((UChar)0xFF09); // fullwidth ) formatReplaceCloseParen.setTo((UChar)0xFF3D); // fullwidth ] } else { formatOpenParen.setTo((UChar)0x0028); // ( formatReplaceOpenParen.setTo((UChar)0x005B); // [ formatCloseParen.setTo((UChar)0x0029); // ) formatReplaceCloseParen.setTo((UChar)0x005D); // ] } UnicodeString ktPattern; langData.get("localeDisplayPattern", "keyTypePattern", ktPattern); if (ktPattern.isBogus()) { ktPattern = UnicodeString("{0}={1}", -1, US_INV); } keyTypeFormat.applyPatternMinMaxArguments(ktPattern, 2, 2, status); uprv_memset(fCapitalization, 0, sizeof(fCapitalization)); #if !UCONFIG_NO_BREAK_ITERATION // Only get the context data if we need it! This is a const object so we know now... // Also check whether we will need a break iterator (depends on the data) UBool needBrkIter = FALSE; if (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_STANDALONE) { LocalUResourceBundlePointer resource(ures_open(NULL, locale.getName(), &status)); if (U_FAILURE(status)) { return; } CapitalizationContextSink sink(*this); ures_getAllItemsWithFallback(resource.getAlias(), "contextTransforms", sink, status); if (status == U_MISSING_RESOURCE_ERROR) { // Silently ignore. Not every locale has contextTransforms. status = U_ZERO_ERROR; } else if (U_FAILURE(status)) { return; } needBrkIter = sink.hasCapitalizationUsage; } // Get a sentence break iterator if we will need it if (needBrkIter || capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE) { status = U_ZERO_ERROR; capitalizationBrkIter = BreakIterator::createSentenceInstance(locale, status); if (U_FAILURE(status)) { delete capitalizationBrkIter; capitalizationBrkIter = NULL; } } #endif }