예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}