UnicodeString& GLUE_SYM (DateFormat ) :: format( Calendar& cal, UnicodeString& appendTo, FieldPosition& pos) const { #if DATE_FE_DEBUG fprintf(stderr, "VCF " ICUGLUE_VER_STR " - formatting. \n"); #endif int32_t len = appendTo.length(); UChar junk[200]; UErrorCode status = U_ZERO_ERROR; UFieldPosition pos2; int32_t nlen = OICU_udat_format(_this, cal.getTime(status), junk, 200, &pos2, &status); // todo: use pos2 pos.setBeginIndex(len); pos.setEndIndex(len += nlen); appendTo.append(junk, nlen); return appendTo; }
bool NumberStringBuilder::nextFieldPosition(FieldPosition& fp, UErrorCode& status) const { int32_t rawField = fp.getField(); if (rawField == FieldPosition::DONT_CARE) { return FALSE; } if (rawField < 0 || rawField >= UNUM_FIELD_COUNT) { status = U_ILLEGAL_ARGUMENT_ERROR; return FALSE; } auto field = static_cast<Field>(rawField); bool seenStart = false; int32_t fractionStart = -1; int32_t startIndex = fp.getEndIndex(); for (int i = fZero + startIndex; i <= fZero + fLength; i++) { Field _field = UNUM_FIELD_COUNT; if (i < fZero + fLength) { _field = getFieldPtr()[i]; } if (seenStart && field != _field) { // Special case: GROUPING_SEPARATOR counts as an INTEGER. if (field == UNUM_INTEGER_FIELD && _field == UNUM_GROUPING_SEPARATOR_FIELD) { continue; } fp.setEndIndex(i - fZero); break; } else if (!seenStart && field == _field) { fp.setBeginIndex(i - fZero); seenStart = true; } if (_field == UNUM_INTEGER_FIELD || _field == UNUM_DECIMAL_SEPARATOR_FIELD) { fractionStart = i - fZero + 1; } } // Backwards compatibility: FRACTION needs to start after INTEGER if empty. // Do not return that a field was found, though, since there is not actually a fraction part. if (field == UNUM_FRACTION_FIELD && !seenStart && fractionStart != -1) { fp.setBeginIndex(fractionStart); fp.setEndIndex(fractionStart); } return seenStart; }
void NumberStringBuilder::populateFieldPosition(FieldPosition &fp, int32_t offset, UErrorCode &status) const { int32_t rawField = fp.getField(); if (rawField == FieldPosition::DONT_CARE) { return; } if (rawField < 0 || rawField >= UNUM_FIELD_COUNT) { status = U_ILLEGAL_ARGUMENT_ERROR; return; } auto field = static_cast<Field>(rawField); bool seenStart = false; int32_t fractionStart = -1; for (int i = fZero; i <= fZero + fLength; i++) { Field _field = UNUM_FIELD_COUNT; if (i < fZero + fLength) { _field = getFieldPtr()[i]; } if (seenStart && field != _field) { // Special case: GROUPING_SEPARATOR counts as an INTEGER. if (field == UNUM_INTEGER_FIELD && _field == UNUM_GROUPING_SEPARATOR_FIELD) { continue; } fp.setEndIndex(i - fZero + offset); break; } else if (!seenStart && field == _field) { fp.setBeginIndex(i - fZero + offset); seenStart = true; } if (_field == UNUM_INTEGER_FIELD || _field == UNUM_DECIMAL_SEPARATOR_FIELD) { fractionStart = i - fZero + 1; } } // Backwards compatibility: FRACTION needs to start after INTEGER if empty if (field == UNUM_FRACTION_FIELD && !seenStart) { fp.setBeginIndex(fractionStart + offset); fp.setEndIndex(fractionStart + offset); } }
void FormattedNumber::populateFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) { if (U_FAILURE(status)) { return; } if (fResults == nullptr) { status = fErrorCode; return; } // in case any users were depending on the old behavior: fieldPosition.setBeginIndex(0); fieldPosition.setEndIndex(0); fResults->string.nextFieldPosition(fieldPosition, status); }
UBool FieldPositionIterator::next(FieldPosition& fp) { if (pos == -1) { return FALSE; } fp.setField(data->elementAti(pos++)); fp.setBeginIndex(data->elementAti(pos++)); fp.setEndIndex(data->elementAti(pos++)); if (pos == data->size()) { pos = -1; } return TRUE; }
void PluralFormat::parseType(const UnicodeString& source, const NFRule *rbnfLenientScanner, Formattable& result, FieldPosition& pos) const { // If no pattern was applied, return null. if (msgPattern.countParts() == 0) { pos.setBeginIndex(-1); pos.setEndIndex(-1); return; } int partIndex = 0; int currMatchIndex; int count=msgPattern.countParts(); int startingAt = pos.getBeginIndex(); if (startingAt < 0) { startingAt = 0; } // The keyword is null until we need to match against a non-explicit, not-"other" value. // Then we get the keyword from the selector. // (In other words, we never call the selector if we match against an explicit value, // or if the only non-explicit keyword is "other".) UnicodeString keyword; UnicodeString matchedWord; const UnicodeString& pattern = msgPattern.getPatternString(); int matchedIndex = -1; // Iterate over (ARG_SELECTOR ARG_START message ARG_LIMIT) tuples // until the end of the plural-only pattern. while (partIndex < count) { const MessagePattern::Part* partSelector = &msgPattern.getPart(partIndex++); if (partSelector->getType() != UMSGPAT_PART_TYPE_ARG_SELECTOR) { // Bad format continue; } const MessagePattern::Part* partStart = &msgPattern.getPart(partIndex++); if (partStart->getType() != UMSGPAT_PART_TYPE_MSG_START) { // Bad format continue; } const MessagePattern::Part* partLimit = &msgPattern.getPart(partIndex++); if (partLimit->getType() != UMSGPAT_PART_TYPE_MSG_LIMIT) { // Bad format continue; } UnicodeString currArg = pattern.tempSubString(partStart->getLimit(), partLimit->getIndex() - partStart->getLimit()); if (rbnfLenientScanner != NULL) { // If lenient parsing is turned ON, we've got some time consuming parsing ahead of us. int32_t length = -1; currMatchIndex = rbnfLenientScanner->findTextLenient(source, currArg, startingAt, &length); } else { currMatchIndex = source.indexOf(currArg, startingAt); } if (currMatchIndex >= 0 && currMatchIndex >= matchedIndex && currArg.length() > matchedWord.length()) { matchedIndex = currMatchIndex; matchedWord = currArg; keyword = pattern.tempSubString(partStart->getLimit(), partLimit->getIndex() - partStart->getLimit()); } } if (matchedIndex >= 0) { pos.setBeginIndex(matchedIndex); pos.setEndIndex(matchedIndex + matchedWord.length()); result.setString(keyword); return; } // Not found! pos.setBeginIndex(-1); pos.setEndIndex(-1); }