| Index: source/i18n/scientificnumberformatter.cpp
|
| diff --git a/source/i18n/scientificnumberformatter.cpp b/source/i18n/scientificnumberformatter.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b3bc09939ceb9f13616990de01a336cdc7d39693
|
| --- /dev/null
|
| +++ b/source/i18n/scientificnumberformatter.cpp
|
| @@ -0,0 +1,308 @@
|
| +/*
|
| +**********************************************************************
|
| +* Copyright (c) 2014, International Business Machines
|
| +* Corporation and others. All Rights Reserved.
|
| +**********************************************************************
|
| +*/
|
| +#include "unicode/utypes.h"
|
| +
|
| +#if !UCONFIG_NO_FORMATTING
|
| +
|
| +#include "unicode/scientificnumberformatter.h"
|
| +#include "unicode/dcfmtsym.h"
|
| +#include "unicode/fpositer.h"
|
| +#include "unicode/utf16.h"
|
| +#include "unicode/uniset.h"
|
| +#include "decfmtst.h"
|
| +#include "unicode/decimfmt.h"
|
| +
|
| +U_NAMESPACE_BEGIN
|
| +
|
| +static const UChar kSuperscriptDigits[] = {
|
| + 0x2070,
|
| + 0xB9,
|
| + 0xB2,
|
| + 0xB3,
|
| + 0x2074,
|
| + 0x2075,
|
| + 0x2076,
|
| + 0x2077,
|
| + 0x2078,
|
| + 0x2079};
|
| +
|
| +static const UChar kSuperscriptPlusSign = 0x207A;
|
| +static const UChar kSuperscriptMinusSign = 0x207B;
|
| +
|
| +static UBool copyAsSuperscript(
|
| + const UnicodeString &s,
|
| + int32_t beginIndex,
|
| + int32_t endIndex,
|
| + UnicodeString &result,
|
| + UErrorCode &status) {
|
| + if (U_FAILURE(status)) {
|
| + return FALSE;
|
| + }
|
| + for (int32_t i = beginIndex; i < endIndex;) {
|
| + UChar32 c = s.char32At(i);
|
| + int32_t digit = u_charDigitValue(c);
|
| + if (digit < 0) {
|
| + status = U_INVALID_CHAR_FOUND;
|
| + return FALSE;
|
| + }
|
| + result.append(kSuperscriptDigits[digit]);
|
| + i += U16_LENGTH(c);
|
| + }
|
| + return TRUE;
|
| +}
|
| +
|
| +ScientificNumberFormatter *ScientificNumberFormatter::createSuperscriptInstance(
|
| + DecimalFormat *fmtToAdopt, UErrorCode &status) {
|
| + return createInstance(fmtToAdopt, new SuperscriptStyle(), status);
|
| +}
|
| +
|
| +ScientificNumberFormatter *ScientificNumberFormatter::createSuperscriptInstance(
|
| + const Locale &locale, UErrorCode &status) {
|
| + return createInstance(
|
| + static_cast<DecimalFormat *>(
|
| + DecimalFormat::createScientificInstance(locale, status)),
|
| + new SuperscriptStyle(),
|
| + status);
|
| +}
|
| +
|
| +ScientificNumberFormatter *ScientificNumberFormatter::createMarkupInstance(
|
| + DecimalFormat *fmtToAdopt,
|
| + const UnicodeString &beginMarkup,
|
| + const UnicodeString &endMarkup,
|
| + UErrorCode &status) {
|
| + return createInstance(
|
| + fmtToAdopt,
|
| + new MarkupStyle(beginMarkup, endMarkup),
|
| + status);
|
| +}
|
| +
|
| +ScientificNumberFormatter *ScientificNumberFormatter::createMarkupInstance(
|
| + const Locale &locale,
|
| + const UnicodeString &beginMarkup,
|
| + const UnicodeString &endMarkup,
|
| + UErrorCode &status) {
|
| + return createInstance(
|
| + static_cast<DecimalFormat *>(
|
| + DecimalFormat::createScientificInstance(locale, status)),
|
| + new MarkupStyle(beginMarkup, endMarkup),
|
| + status);
|
| +}
|
| +
|
| +ScientificNumberFormatter *ScientificNumberFormatter::createInstance(
|
| + DecimalFormat *fmtToAdopt,
|
| + Style *styleToAdopt,
|
| + UErrorCode &status) {
|
| + LocalPointer<DecimalFormat> fmt(fmtToAdopt);
|
| + LocalPointer<Style> style(styleToAdopt);
|
| + if (U_FAILURE(status)) {
|
| + return NULL;
|
| + }
|
| + ScientificNumberFormatter *result =
|
| + new ScientificNumberFormatter(
|
| + fmt.getAlias(),
|
| + style.getAlias(),
|
| + status);
|
| + if (result == NULL) {
|
| + status = U_MEMORY_ALLOCATION_ERROR;
|
| + return NULL;
|
| + }
|
| + fmt.orphan();
|
| + style.orphan();
|
| + if (U_FAILURE(status)) {
|
| + delete result;
|
| + return NULL;
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +ScientificNumberFormatter::Style *ScientificNumberFormatter::SuperscriptStyle::clone() const {
|
| + return new ScientificNumberFormatter::SuperscriptStyle(*this);
|
| +}
|
| +
|
| +UnicodeString &ScientificNumberFormatter::SuperscriptStyle::format(
|
| + const UnicodeString &original,
|
| + FieldPositionIterator &fpi,
|
| + const UnicodeString &preExponent,
|
| + const DecimalFormatStaticSets &staticSets,
|
| + UnicodeString &appendTo,
|
| + UErrorCode &status) const {
|
| + if (U_FAILURE(status)) {
|
| + return appendTo;
|
| + }
|
| + FieldPosition fp;
|
| + int32_t copyFromOffset = 0;
|
| + while (fpi.next(fp)) {
|
| + switch (fp.getField()) {
|
| + case UNUM_EXPONENT_SYMBOL_FIELD:
|
| + appendTo.append(
|
| + original,
|
| + copyFromOffset,
|
| + fp.getBeginIndex() - copyFromOffset);
|
| + copyFromOffset = fp.getEndIndex();
|
| + appendTo.append(preExponent);
|
| + break;
|
| + case UNUM_EXPONENT_SIGN_FIELD:
|
| + {
|
| + int32_t beginIndex = fp.getBeginIndex();
|
| + int32_t endIndex = fp.getEndIndex();
|
| + UChar32 aChar = original.char32At(beginIndex);
|
| + if (staticSets.fMinusSigns->contains(aChar)) {
|
| + appendTo.append(
|
| + original,
|
| + copyFromOffset,
|
| + beginIndex - copyFromOffset);
|
| + appendTo.append(kSuperscriptMinusSign);
|
| + } else if (staticSets.fPlusSigns->contains(aChar)) {
|
| + appendTo.append(
|
| + original,
|
| + copyFromOffset,
|
| + beginIndex - copyFromOffset);
|
| + appendTo.append(kSuperscriptPlusSign);
|
| + } else {
|
| + status = U_INVALID_CHAR_FOUND;
|
| + return appendTo;
|
| + }
|
| + copyFromOffset = endIndex;
|
| + }
|
| + break;
|
| + case UNUM_EXPONENT_FIELD:
|
| + appendTo.append(
|
| + original,
|
| + copyFromOffset,
|
| + fp.getBeginIndex() - copyFromOffset);
|
| + if (!copyAsSuperscript(
|
| + original,
|
| + fp.getBeginIndex(),
|
| + fp.getEndIndex(),
|
| + appendTo,
|
| + status)) {
|
| + return appendTo;
|
| + }
|
| + copyFromOffset = fp.getEndIndex();
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + }
|
| + appendTo.append(
|
| + original, copyFromOffset, original.length() - copyFromOffset);
|
| + return appendTo;
|
| +}
|
| +
|
| +ScientificNumberFormatter::Style *ScientificNumberFormatter::MarkupStyle::clone() const {
|
| + return new ScientificNumberFormatter::MarkupStyle(*this);
|
| +}
|
| +
|
| +UnicodeString &ScientificNumberFormatter::MarkupStyle::format(
|
| + const UnicodeString &original,
|
| + FieldPositionIterator &fpi,
|
| + const UnicodeString &preExponent,
|
| + const DecimalFormatStaticSets & /*unusedDecimalFormatSets*/,
|
| + UnicodeString &appendTo,
|
| + UErrorCode &status) const {
|
| + if (U_FAILURE(status)) {
|
| + return appendTo;
|
| + }
|
| + FieldPosition fp;
|
| + int32_t copyFromOffset = 0;
|
| + while (fpi.next(fp)) {
|
| + switch (fp.getField()) {
|
| + case UNUM_EXPONENT_SYMBOL_FIELD:
|
| + appendTo.append(
|
| + original,
|
| + copyFromOffset,
|
| + fp.getBeginIndex() - copyFromOffset);
|
| + copyFromOffset = fp.getEndIndex();
|
| + appendTo.append(preExponent);
|
| + appendTo.append(fBeginMarkup);
|
| + break;
|
| + case UNUM_EXPONENT_FIELD:
|
| + appendTo.append(
|
| + original,
|
| + copyFromOffset,
|
| + fp.getEndIndex() - copyFromOffset);
|
| + copyFromOffset = fp.getEndIndex();
|
| + appendTo.append(fEndMarkup);
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + }
|
| + appendTo.append(
|
| + original, copyFromOffset, original.length() - copyFromOffset);
|
| + return appendTo;
|
| +}
|
| +
|
| +ScientificNumberFormatter::ScientificNumberFormatter(
|
| + DecimalFormat *fmtToAdopt, Style *styleToAdopt, UErrorCode &status)
|
| + : fPreExponent(),
|
| + fDecimalFormat(fmtToAdopt),
|
| + fStyle(styleToAdopt),
|
| + fStaticSets(NULL) {
|
| + if (U_FAILURE(status)) {
|
| + return;
|
| + }
|
| + if (fDecimalFormat == NULL || fStyle == NULL) {
|
| + status = U_ILLEGAL_ARGUMENT_ERROR;
|
| + return;
|
| + }
|
| + const DecimalFormatSymbols *sym = fDecimalFormat->getDecimalFormatSymbols();
|
| + if (sym == NULL) {
|
| + status = U_ILLEGAL_ARGUMENT_ERROR;
|
| + return;
|
| + }
|
| + getPreExponent(*sym, fPreExponent);
|
| + fStaticSets = DecimalFormatStaticSets::getStaticSets(status);
|
| +}
|
| +
|
| +ScientificNumberFormatter::ScientificNumberFormatter(
|
| + const ScientificNumberFormatter &other)
|
| + : UObject(other),
|
| + fPreExponent(other.fPreExponent),
|
| + fDecimalFormat(NULL),
|
| + fStyle(NULL),
|
| + fStaticSets(other.fStaticSets) {
|
| + fDecimalFormat = static_cast<DecimalFormat *>(
|
| + other.fDecimalFormat->clone());
|
| + fStyle = other.fStyle->clone();
|
| +}
|
| +
|
| +ScientificNumberFormatter::~ScientificNumberFormatter() {
|
| + delete fDecimalFormat;
|
| + delete fStyle;
|
| +}
|
| +
|
| +UnicodeString &ScientificNumberFormatter::format(
|
| + const Formattable &number,
|
| + UnicodeString &appendTo,
|
| + UErrorCode &status) const {
|
| + if (U_FAILURE(status)) {
|
| + return appendTo;
|
| + }
|
| + UnicodeString original;
|
| + FieldPositionIterator fpi;
|
| + fDecimalFormat->format(number, original, &fpi, status);
|
| + return fStyle->format(
|
| + original,
|
| + fpi,
|
| + fPreExponent,
|
| + *fStaticSets,
|
| + appendTo,
|
| + status);
|
| +}
|
| +
|
| +void ScientificNumberFormatter::getPreExponent(
|
| + const DecimalFormatSymbols &dfs, UnicodeString &preExponent) {
|
| + preExponent.append(dfs.getConstSymbol(
|
| + DecimalFormatSymbols::kExponentMultiplicationSymbol));
|
| + preExponent.append(dfs.getConstSymbol(DecimalFormatSymbols::kOneDigitSymbol));
|
| + preExponent.append(dfs.getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol));
|
| +}
|
| +
|
| +U_NAMESPACE_END
|
| +
|
| +#endif /* !UCONFIG_NO_FORMATTING */
|
|
|