int32_t Padder::padAndApply(const Modifier &mod1, const Modifier &mod2, NumberStringBuilder &string, int32_t leftIndex, int32_t rightIndex, UErrorCode &status) const { int32_t modLength = mod1.getCodePointCount(status) + mod2.getCodePointCount(status); int32_t requiredPadding = fWidth - modLength - string.codePointCount(); U_ASSERT(leftIndex == 0 && rightIndex == string.length()); // fix the previous line to remove this assertion int length = 0; if (requiredPadding <= 0) { // Padding is not required. length += mod1.apply(string, leftIndex, rightIndex, status); length += mod2.apply(string, leftIndex, rightIndex + length, status); return length; } PadPosition position = fUnion.padding.fPosition; UChar32 paddingCp = fUnion.padding.fCp; if (position == UNUM_PAD_AFTER_PREFIX) { length += addPaddingHelper(paddingCp, requiredPadding, string, leftIndex, status); } else if (position == UNUM_PAD_BEFORE_SUFFIX) { length += addPaddingHelper(paddingCp, requiredPadding, string, rightIndex + length, status); } length += mod1.apply(string, leftIndex, rightIndex + length, status); length += mod2.apply(string, leftIndex, rightIndex + length, status); if (position == UNUM_PAD_BEFORE_PREFIX) { length += addPaddingHelper(paddingCp, requiredPadding, string, leftIndex, status); } else if (position == UNUM_PAD_AFTER_SUFFIX) { length += addPaddingHelper(paddingCp, requiredPadding, string, rightIndex + length, status); } return length; }
bool NumberStringBuilder::contentEquals(const NumberStringBuilder &other) const { if (fLength != other.fLength) { return false; } for (int32_t i = 0; i < fLength; i++) { if (charAt(i) != other.charAt(i) || fieldAt(i) != other.fieldAt(i)) { return false; } } return true; }
void LocalizedNumberFormatter::getAffixImpl(bool isPrefix, bool isNegative, UnicodeString& result, UErrorCode& status) const { NumberStringBuilder string; auto signum = static_cast<int8_t>(isNegative ? -1 : 1); // Always return affixes for plural form OTHER. static const StandardPlural::Form plural = StandardPlural::OTHER; int32_t prefixLength; if (computeCompiled(status)) { prefixLength = fCompiled->getPrefixSuffix(signum, plural, string, status); } else { prefixLength = NumberFormatterImpl::getPrefixSuffixStatic(fMacros, signum, plural, string, status); } result.remove(); if (isPrefix) { result.append(string.toTempUnicodeString().tempSubStringBetween(0, prefixLength)); } else { result.append(string.toTempUnicodeString().tempSubStringBetween(prefixLength, string.length())); } }
int32_t AffixUtils::unescape(const CharSequence &affixPattern, NumberStringBuilder &output, int32_t position, const SymbolProvider &provider, UErrorCode &status) { int32_t length = 0; AffixTag tag; while (hasNext(tag, affixPattern)) { tag = nextToken(tag, affixPattern, status); if (U_FAILURE(status)) { return length; } if (tag.type == TYPE_CURRENCY_OVERFLOW) { // Don't go to the provider for this special case length += output.insertCodePoint(position + length, 0xFFFD, UNUM_CURRENCY_FIELD, status); } else if (tag.type < 0) { length += output.insert( position + length, provider.getSymbol(tag.type), getFieldForType(tag.type), status); } else { length += output.insertCodePoint(position + length, tag.codePoint, UNUM_FIELD_COUNT, status); } } return length; }
int32_t NumberFormatterImpl::writeFractionDigits(const MicroProps& micros, DecimalQuantity& quantity, NumberStringBuilder& string, UErrorCode& status) { int length = 0; int fractionCount = -quantity.getLowerDisplayMagnitude(); for (int i = 0; i < fractionCount; i++) { // Get and append the next digit value int8_t nextDigit = quantity.getDigit(-i - 1); length += utils::insertDigitFromSymbols( string, string.length(), nextDigit, *micros.symbols, UNUM_FRACTION_FIELD, status); } return length; }
int32_t NumberStringBuilder::insert(int32_t index, const NumberStringBuilder &other, UErrorCode &status) { if (this == &other) { status = U_ILLEGAL_ARGUMENT_ERROR; return 0; } int32_t count = other.fLength; if (count == 0) { // Nothing to insert. return 0; } int32_t position = prepareForInsert(index, count, status); if (U_FAILURE(status)) { return count; } for (int32_t i = 0; i < count; i++) { getCharPtr()[position + i] = other.charAt(i); getFieldPtr()[position + i] = other.fieldAt(i); } return count; }
int32_t NumberFormatterImpl::writeNumber(const MicroProps& micros, DecimalQuantity& quantity, NumberStringBuilder& string, UErrorCode& status) { int32_t length = 0; if (quantity.isInfinite()) { length += string.insert( length, micros.symbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kInfinitySymbol), UNUM_INTEGER_FIELD, status); } else if (quantity.isNaN()) { length += string.insert( length, micros.symbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kNaNSymbol), UNUM_INTEGER_FIELD, status); } else { // Add the integer digits length += writeIntegerDigits(micros, quantity, string, status); // Add the decimal point if (quantity.getLowerDisplayMagnitude() < 0 || micros.decimal == UNUM_DECIMAL_SEPARATOR_ALWAYS) { length += string.insert( length, micros.useCurrency ? micros.symbols->getSymbol( DecimalFormatSymbols::ENumberFormatSymbol::kMonetarySeparatorSymbol) : micros .symbols ->getSymbol( DecimalFormatSymbols::ENumberFormatSymbol::kDecimalSeparatorSymbol), UNUM_DECIMAL_SEPARATOR_FIELD, status); } // Add the fraction digits length += writeFractionDigits(micros, quantity, string, status); } return length; }
int32_t ScientificModifier::apply(NumberStringBuilder &output, int32_t /*leftIndex*/, int32_t rightIndex, UErrorCode &status) const { // FIXME: Localized exponent separator location. int i = rightIndex; // Append the exponent separator and sign i += output.insert( i, fHandler->fSymbols->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kExponentialSymbol), UNUM_EXPONENT_SYMBOL_FIELD, status); if (fExponent < 0 && fHandler->fSettings.fExponentSignDisplay != UNUM_SIGN_NEVER) { i += output.insert( i, fHandler->fSymbols ->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kMinusSignSymbol), UNUM_EXPONENT_SIGN_FIELD, status); } else if (fExponent >= 0 && fHandler->fSettings.fExponentSignDisplay == UNUM_SIGN_ALWAYS) { i += output.insert( i, fHandler->fSymbols ->getSymbol(DecimalFormatSymbols::ENumberFormatSymbol::kPlusSignSymbol), UNUM_EXPONENT_SIGN_FIELD, status); } // Append the exponent digits (using a simple inline algorithm) int32_t disp = std::abs(fExponent); for (int j = 0; j < fHandler->fSettings.fMinExponentDigits || disp > 0; j++, disp /= 10) { auto d = static_cast<int8_t>(disp % 10); i += utils::insertDigitFromSymbols( output, i - j, d, *fHandler->fSymbols, UNUM_EXPONENT_FIELD, status); } return i - rightIndex; }
int32_t NumberFormatterImpl::writeIntegerDigits(const MicroProps& micros, DecimalQuantity& quantity, NumberStringBuilder& string, UErrorCode& status) { int length = 0; int integerCount = quantity.getUpperDisplayMagnitude() + 1; for (int i = 0; i < integerCount; i++) { // Add grouping separator if (micros.grouping.groupAtPosition(i, quantity)) { length += string.insert( 0, micros.useCurrency ? micros.symbols->getSymbol( DecimalFormatSymbols::ENumberFormatSymbol::kMonetaryGroupingSeparatorSymbol) : micros.symbols->getSymbol( DecimalFormatSymbols::ENumberFormatSymbol::kGroupingSeparatorSymbol), UNUM_GROUPING_SEPARATOR_FIELD, status); } // Get and append the next digit value int8_t nextDigit = quantity.getDigit(i); length += utils::insertDigitFromSymbols( string, 0, nextDigit, *micros.symbols, UNUM_INTEGER_FIELD, status); } return length; }