예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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()));
    }
}
예제 #4
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
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;
}
예제 #8
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;
}
예제 #9
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;
}