diff --git a/.gitattributes b/.gitattributes index d82af5085b6..f4b0a7d36b4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -76,8 +76,10 @@ icu4c/source/extra/uconv/uconv.vcxproj -text icu4c/source/extra/uconv/uconv.vcxproj.filters -text icu4c/source/i18n/i18n.vcxproj -text icu4c/source/i18n/i18n.vcxproj.filters -text +icu4c/source/i18n/scientificnumberformatter.cpp -text icu4c/source/i18n/shareddatefmt.h -text icu4c/source/i18n/shareddatetimepatterngenerator.h -text +icu4c/source/i18n/unicode/scientificnumberformatter.h -text icu4c/source/io/io.vcxproj -text icu4c/source/io/io.vcxproj.filters -text icu4c/source/layout/layout.vcxproj -text @@ -147,6 +149,7 @@ icu4c/source/test/depstest/icu-dependencies-mode.el -text icu4c/source/test/intltest/intltest.vcxproj -text icu4c/source/test/intltest/intltest.vcxproj.filters -text icu4c/source/test/intltest/quantityformattertest.cpp -text +icu4c/source/test/intltest/scientificnumberformattertest.cpp -text icu4c/source/test/iotest/iotest.vcxproj -text icu4c/source/test/iotest/iotest.vcxproj.filters -text icu4c/source/test/letest/cletest.vcxproj -text diff --git a/icu4c/source/i18n/Makefile.in b/icu4c/source/i18n/Makefile.in index 3dc5b5ffdda..f2b89535b7e 100644 --- a/icu4c/source/i18n/Makefile.in +++ b/icu4c/source/i18n/Makefile.in @@ -94,7 +94,8 @@ uspoof.o uspoof_impl.o uspoof_build.o uspoof_conf.o uspoof_wsconf.o decfmtst.o s ztrans.o zrule.o vzone.o fphdlimp.o fpositer.o locdspnm.o \ decNumber.o decContext.o alphaindex.o tznames.o tznames_impl.o tzgnames.o \ tzfmt.o compactdecimalformat.o gender.o region.o scriptset.o identifier_info.o \ -uregion.o reldatefmt.o quantityformatter.o measunit.o filteredbrk.o scientificformathelper.o sharedbreakiterator.o +uregion.o reldatefmt.o quantityformatter.o measunit.o filteredbrk.o \ +scientificformathelper.o sharedbreakiterator.o scientificnumberformatter.o ## Header files to install HEADERS = $(srcdir)/unicode/*.h diff --git a/icu4c/source/i18n/scientificformathelper.cpp b/icu4c/source/i18n/scientificformathelper.cpp index 5a3a2bc0c61..988f7f035cf 100644 --- a/icu4c/source/i18n/scientificformathelper.cpp +++ b/icu4c/source/i18n/scientificformathelper.cpp @@ -9,29 +9,18 @@ #if !UCONFIG_NO_FORMATTING #include "unicode/scientificformathelper.h" -#include "unicode/dcfmtsym.h" -#include "unicode/fpositer.h" -#include "unicode/utf16.h" -#include "unicode/uniset.h" +#include "unicode/scientificnumberformatter.h" #include "decfmtst.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; - ScientificFormatHelper::ScientificFormatHelper( const DecimalFormatSymbols &dfs, UErrorCode &status) : fPreExponent(), fStaticSets(NULL) { if (U_FAILURE(status)) { return; } - fPreExponent.append(dfs.getConstSymbol( - DecimalFormatSymbols::kExponentMultiplicationSymbol)); - fPreExponent.append(dfs.getSymbol(DecimalFormatSymbols::kOneDigitSymbol)); - fPreExponent.append(dfs.getSymbol(DecimalFormatSymbols::kZeroDigitSymbol)); + ScientificNumberFormatter::getPreExponent(dfs, fPreExponent); fStaticSets = DecimalFormatStaticSets::getStaticSets(status); } @@ -64,57 +53,14 @@ UnicodeString &ScientificFormatHelper::insertMarkup( if (U_FAILURE(status)) { return result; } - FieldPosition fp; - int32_t copyFromOffset = 0; - UBool exponentSymbolFieldPresent = FALSE; - UBool exponentFieldPresent = FALSE; - while (fpi.next(fp)) { - switch (fp.getField()) { - case UNUM_EXPONENT_SYMBOL_FIELD: - exponentSymbolFieldPresent = TRUE; - result.append(s, copyFromOffset, fp.getBeginIndex() - copyFromOffset); - copyFromOffset = fp.getEndIndex(); - result.append(fPreExponent); - result.append(beginMarkup); - break; - case UNUM_EXPONENT_FIELD: - exponentFieldPresent = TRUE; - result.append(s, copyFromOffset, fp.getEndIndex() - copyFromOffset); - copyFromOffset = fp.getEndIndex(); - result.append(endMarkup); - break; - default: - break; - } - } - if (!exponentSymbolFieldPresent || !exponentFieldPresent) { - status = U_ILLEGAL_ARGUMENT_ERROR; - return result; - } - result.append(s, copyFromOffset, s.length() - copyFromOffset); - return result; -} - -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::MarkupStyle style(beginMarkup, endMarkup); + return style.format( + s, + fpi, + fPreExponent, + *fStaticSets, + result, + status); } UnicodeString &ScientificFormatHelper::toSuperscriptExponentDigits( @@ -125,55 +71,14 @@ UnicodeString &ScientificFormatHelper::toSuperscriptExponentDigits( if (U_FAILURE(status)) { return result; } - FieldPosition fp; - int32_t copyFromOffset = 0; - UBool exponentSymbolFieldPresent = FALSE; - UBool exponentFieldPresent = FALSE; - while (fpi.next(fp)) { - switch (fp.getField()) { - case UNUM_EXPONENT_SYMBOL_FIELD: - exponentSymbolFieldPresent = TRUE; - result.append(s, copyFromOffset, fp.getBeginIndex() - copyFromOffset); - copyFromOffset = fp.getEndIndex(); - result.append(fPreExponent); - break; - case UNUM_EXPONENT_SIGN_FIELD: - { - int32_t beginIndex = fp.getBeginIndex(); - int32_t endIndex = fp.getEndIndex(); - UChar32 aChar = s.char32At(beginIndex); - if (fStaticSets->fMinusSigns->contains(aChar)) { - result.append(s, copyFromOffset, beginIndex - copyFromOffset); - result.append(kSuperscriptMinusSign); - } else if (fStaticSets->fPlusSigns->contains(aChar)) { - result.append(s, copyFromOffset, beginIndex - copyFromOffset); - result.append(kSuperscriptPlusSign); - } else { - status = U_INVALID_CHAR_FOUND; - return result; - } - copyFromOffset = endIndex; - } - break; - case UNUM_EXPONENT_FIELD: - exponentFieldPresent = TRUE; - result.append(s, copyFromOffset, fp.getBeginIndex() - copyFromOffset); - if (!copyAsSuperscript( - s, fp.getBeginIndex(), fp.getEndIndex(), result, status)) { - return result; - } - copyFromOffset = fp.getEndIndex(); - break; - default: - break; - } - } - if (!exponentSymbolFieldPresent || !exponentFieldPresent) { - status = U_ILLEGAL_ARGUMENT_ERROR; - return result; - } - result.append(s, copyFromOffset, s.length() - copyFromOffset); - return result; + ScientificNumberFormatter::SuperscriptStyle style; + return style.format( + s, + fpi, + fPreExponent, + *fStaticSets, + result, + status); } U_NAMESPACE_END diff --git a/icu4c/source/i18n/scientificnumberformatter.cpp b/icu4c/source/i18n/scientificnumberformatter.cpp new file mode 100644 index 00000000000..f53189b1b6a --- /dev/null +++ b/icu4c/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::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::createScientificInstance(locale, status)), + new MarkupStyle(beginMarkup, endMarkup), + status); +} + +ScientificNumberFormatter *ScientificNumberFormatter::createInstance( + DecimalFormat *fmtToAdopt, + Style *styleToAdopt, + UErrorCode &status) { + LocalPointer fmt(fmtToAdopt); + LocalPointer