13c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep/*
23c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep**********************************************************************
33c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep* Copyright (c) 2014, International Business Machines
43c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep* Corporation and others.  All Rights Reserved.
53c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep**********************************************************************
63c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep*/
73c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep#include "unicode/utypes.h"
83c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
93c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep#if !UCONFIG_NO_FORMATTING
103c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
113c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep#include "unicode/scientificnumberformatter.h"
123c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep#include "unicode/dcfmtsym.h"
133c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep#include "unicode/fpositer.h"
143c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep#include "unicode/utf16.h"
153c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep#include "unicode/uniset.h"
163c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep#include "decfmtst.h"
173c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep#include "unicode/decimfmt.h"
183c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
193c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepU_NAMESPACE_BEGIN
203c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
213c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keepstatic const UChar kSuperscriptDigits[] = {
223c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        0x2070,
233c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        0xB9,
243c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        0xB2,
253c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        0xB3,
263c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        0x2074,
273c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        0x2075,
283c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        0x2076,
293c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        0x2077,
303c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        0x2078,
313c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        0x2079};
323c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
333c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keepstatic const UChar kSuperscriptPlusSign = 0x207A;
343c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keepstatic const UChar kSuperscriptMinusSign = 0x207B;
353c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
363c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keepstatic UBool copyAsSuperscript(
373c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const UnicodeString &s,
383c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        int32_t beginIndex,
393c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        int32_t endIndex,
403c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UnicodeString &result,
413c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UErrorCode &status) {
423c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    if (U_FAILURE(status)) {
433c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        return FALSE;
443c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
453c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    for (int32_t i = beginIndex; i < endIndex;) {
463c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UChar32 c = s.char32At(i);
473c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        int32_t digit = u_charDigitValue(c);
483c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        if (digit < 0) {
493c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            status = U_INVALID_CHAR_FOUND;
503c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            return FALSE;
513c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        }
523c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        result.append(kSuperscriptDigits[digit]);
533c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        i += U16_LENGTH(c);
543c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
553c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return TRUE;
563c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
573c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
583c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepScientificNumberFormatter *ScientificNumberFormatter::createSuperscriptInstance(
593c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            DecimalFormat *fmtToAdopt, UErrorCode &status) {
603c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return createInstance(fmtToAdopt, new SuperscriptStyle(), status);
613c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
623c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
633c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepScientificNumberFormatter *ScientificNumberFormatter::createSuperscriptInstance(
643c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            const Locale &locale, UErrorCode &status) {
653c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return createInstance(
663c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            static_cast<DecimalFormat *>(
673c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    DecimalFormat::createScientificInstance(locale, status)),
683c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            new SuperscriptStyle(),
693c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            status);
703c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
713c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
723c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepScientificNumberFormatter *ScientificNumberFormatter::createMarkupInstance(
733c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        DecimalFormat *fmtToAdopt,
743c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const UnicodeString &beginMarkup,
753c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const UnicodeString &endMarkup,
763c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UErrorCode &status) {
773c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return createInstance(
783c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            fmtToAdopt,
793c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            new MarkupStyle(beginMarkup, endMarkup),
803c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            status);
813c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
823c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
833c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepScientificNumberFormatter *ScientificNumberFormatter::createMarkupInstance(
843c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const Locale &locale,
853c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const UnicodeString &beginMarkup,
863c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const UnicodeString &endMarkup,
873c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UErrorCode &status) {
883c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return createInstance(
893c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            static_cast<DecimalFormat *>(
903c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    DecimalFormat::createScientificInstance(locale, status)),
913c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            new MarkupStyle(beginMarkup, endMarkup),
923c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            status);
933c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
943c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
953c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepScientificNumberFormatter *ScientificNumberFormatter::createInstance(
963c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            DecimalFormat *fmtToAdopt,
973c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            Style *styleToAdopt,
983c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            UErrorCode &status) {
993c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    LocalPointer<DecimalFormat> fmt(fmtToAdopt);
1003c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    LocalPointer<Style> style(styleToAdopt);
1013c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    if (U_FAILURE(status)) {
1023c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        return NULL;
1033c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
1043c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    ScientificNumberFormatter *result =
1053c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            new ScientificNumberFormatter(
1063c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    fmt.getAlias(),
1073c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    style.getAlias(),
1083c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    status);
1093c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    if (result == NULL) {
1103c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        status = U_MEMORY_ALLOCATION_ERROR;
1113c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        return NULL;
1123c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
1133c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    fmt.orphan();
1143c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    style.orphan();
1153c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    if (U_FAILURE(status)) {
1163c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        delete result;
1173c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        return NULL;
1183c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
1193c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return result;
1203c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
1213c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
1223c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepScientificNumberFormatter::Style *ScientificNumberFormatter::SuperscriptStyle::clone() const {
1233c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return new ScientificNumberFormatter::SuperscriptStyle(*this);
1243c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
1253c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
1263c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepUnicodeString &ScientificNumberFormatter::SuperscriptStyle::format(
1273c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const UnicodeString &original,
1283c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        FieldPositionIterator &fpi,
1293c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const UnicodeString &preExponent,
1303c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const DecimalFormatStaticSets &staticSets,
1313c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UnicodeString &appendTo,
1323c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UErrorCode &status) const {
1333c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    if (U_FAILURE(status)) {
1343c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        return appendTo;
1353c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
1363c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    FieldPosition fp;
1373c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    int32_t copyFromOffset = 0;
1383c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    while (fpi.next(fp)) {
1393c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        switch (fp.getField()) {
1403c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        case UNUM_EXPONENT_SYMBOL_FIELD:
1413c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            appendTo.append(
1423c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    original,
1433c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    copyFromOffset,
1443c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    fp.getBeginIndex() - copyFromOffset);
1453c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            copyFromOffset = fp.getEndIndex();
1463c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            appendTo.append(preExponent);
1473c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            break;
1483c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        case UNUM_EXPONENT_SIGN_FIELD:
1493c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            {
1503c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                int32_t beginIndex = fp.getBeginIndex();
1513c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                int32_t endIndex = fp.getEndIndex();
1523c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                UChar32 aChar = original.char32At(beginIndex);
1533c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                if (staticSets.fMinusSigns->contains(aChar)) {
1543c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    appendTo.append(
1553c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                            original,
1563c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                            copyFromOffset,
1573c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                            beginIndex - copyFromOffset);
1583c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    appendTo.append(kSuperscriptMinusSign);
1593c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                } else if (staticSets.fPlusSigns->contains(aChar)) {
1603c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    appendTo.append(
1613c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                           original,
1623c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                           copyFromOffset,
1633c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                           beginIndex - copyFromOffset);
1643c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    appendTo.append(kSuperscriptPlusSign);
1653c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                } else {
1663c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    status = U_INVALID_CHAR_FOUND;
1673c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    return appendTo;
1683c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                }
1693c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                copyFromOffset = endIndex;
1703c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            }
1713c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            break;
1723c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        case UNUM_EXPONENT_FIELD:
1733c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            appendTo.append(
1743c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    original,
1753c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    copyFromOffset,
1763c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    fp.getBeginIndex() - copyFromOffset);
1773c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            if (!copyAsSuperscript(
1783c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    original,
1793c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    fp.getBeginIndex(),
1803c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    fp.getEndIndex(),
1813c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    appendTo,
1823c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    status)) {
1833c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep              return appendTo;
1843c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            }
1853c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            copyFromOffset = fp.getEndIndex();
1863c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            break;
1873c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        default:
1883c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            break;
1893c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        }
1903c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
1913c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    appendTo.append(
1923c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            original, copyFromOffset, original.length() - copyFromOffset);
1933c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return appendTo;
1943c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
1953c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
1963c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepScientificNumberFormatter::Style *ScientificNumberFormatter::MarkupStyle::clone() const {
1973c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return new ScientificNumberFormatter::MarkupStyle(*this);
1983c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
1993c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
2003c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepUnicodeString &ScientificNumberFormatter::MarkupStyle::format(
2013c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const UnicodeString &original,
2023c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        FieldPositionIterator &fpi,
2033c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const UnicodeString &preExponent,
2041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert        const DecimalFormatStaticSets & /*unusedDecimalFormatSets*/,
2053c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UnicodeString &appendTo,
2063c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UErrorCode &status) const {
2073c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    if (U_FAILURE(status)) {
2083c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        return appendTo;
2093c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
2103c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    FieldPosition fp;
2113c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    int32_t copyFromOffset = 0;
2123c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    while (fpi.next(fp)) {
2133c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        switch (fp.getField()) {
2143c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        case UNUM_EXPONENT_SYMBOL_FIELD:
2153c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            appendTo.append(
2163c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    original,
2173c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    copyFromOffset,
2183c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    fp.getBeginIndex() - copyFromOffset);
2193c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            copyFromOffset = fp.getEndIndex();
2203c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            appendTo.append(preExponent);
2213c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            appendTo.append(fBeginMarkup);
2223c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            break;
2233c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        case UNUM_EXPONENT_FIELD:
2243c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            appendTo.append(
2253c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    original,
2263c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    copyFromOffset,
2273c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep                    fp.getEndIndex() - copyFromOffset);
2283c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            copyFromOffset = fp.getEndIndex();
2293c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            appendTo.append(fEndMarkup);
2303c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            break;
2313c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        default:
2323c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            break;
2333c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        }
2343c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
2353c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    appendTo.append(
2363c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            original, copyFromOffset, original.length() - copyFromOffset);
2373c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return appendTo;
2383c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
2393c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
2403c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepScientificNumberFormatter::ScientificNumberFormatter(
2413c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        DecimalFormat *fmtToAdopt, Style *styleToAdopt, UErrorCode &status)
2423c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        : fPreExponent(),
2433c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep          fDecimalFormat(fmtToAdopt),
2443c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep          fStyle(styleToAdopt),
2453c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep          fStaticSets(NULL) {
2463c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    if (U_FAILURE(status)) {
2473c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        return;
2483c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
2493c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    if (fDecimalFormat == NULL || fStyle == NULL) {
2503c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        status = U_ILLEGAL_ARGUMENT_ERROR;
2513c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        return;
2523c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
2533c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    const DecimalFormatSymbols *sym = fDecimalFormat->getDecimalFormatSymbols();
2543c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    if (sym == NULL) {
2553c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        status = U_ILLEGAL_ARGUMENT_ERROR;
2563c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        return;
2573c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
2583c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    getPreExponent(*sym, fPreExponent);
2593c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    fStaticSets = DecimalFormatStaticSets::getStaticSets(status);
2603c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
2613c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
2623c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepScientificNumberFormatter::ScientificNumberFormatter(
2633c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const ScientificNumberFormatter &other)
2643c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        : UObject(other),
2653c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep          fPreExponent(other.fPreExponent),
2663c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep          fDecimalFormat(NULL),
2673c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep          fStyle(NULL),
2683c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep          fStaticSets(other.fStaticSets) {
2693c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    fDecimalFormat = static_cast<DecimalFormat *>(
2703c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            other.fDecimalFormat->clone());
2713c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    fStyle = other.fStyle->clone();
2723c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
2733c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
2743c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepScientificNumberFormatter::~ScientificNumberFormatter() {
2753c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    delete fDecimalFormat;
2763c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    delete fStyle;
2773c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
2783c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
2793c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepUnicodeString &ScientificNumberFormatter::format(
2803c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const Formattable &number,
2813c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UnicodeString &appendTo,
2823c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        UErrorCode &status) const {
2833c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    if (U_FAILURE(status)) {
2843c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        return appendTo;
2853c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    }
2863c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    UnicodeString original;
2873c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    FieldPositionIterator fpi;
2883c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    fDecimalFormat->format(number, original, &fpi, status);
2893c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    return fStyle->format(
2903c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            original,
2913c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            fpi,
2923c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            fPreExponent,
2933c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            *fStaticSets,
2943c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            appendTo,
2953c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            status);
2963c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
2973c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
2983c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keepvoid ScientificNumberFormatter::getPreExponent(
2993c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep        const DecimalFormatSymbols &dfs, UnicodeString &preExponent) {
3003c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    preExponent.append(dfs.getConstSymbol(
3013c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep            DecimalFormatSymbols::kExponentMultiplicationSymbol));
3023c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    preExponent.append(dfs.getConstSymbol(DecimalFormatSymbols::kOneDigitSymbol));
3033c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep    preExponent.append(dfs.getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol));
3043c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep}
3053c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
3063c580527bbfaf374a2a2d15ccc16363d36e6e803Travis KeepU_NAMESPACE_END
3073c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep
3083c580527bbfaf374a2a2d15ccc16363d36e6e803Travis Keep#endif /* !UCONFIG_NO_FORMATTING */
309