]> granicus.if.org Git - icu/commitdiff
ICU-20806 Removing obsolete number formatting methods.
authorShane F. Carr <shane.carr@wustl.edu>
Tue, 24 Mar 2020 07:03:31 +0000 (07:03 +0000)
committerShane F. Carr <shane@unicode.org>
Tue, 24 Mar 2020 20:21:32 +0000 (15:21 -0500)
See #1034

21 files changed:
icu4c/source/i18n/decimfmt.cpp
icu4c/source/i18n/fphdlimp.h
icu4c/source/i18n/measfmt.cpp
icu4c/source/i18n/number_capi.cpp
icu4c/source/i18n/number_output.cpp
icu4c/source/i18n/number_utypes.h
icu4c/source/i18n/numrange_fluent.cpp
icu4c/source/i18n/unicode/decimfmt.h
icu4c/source/i18n/unicode/numberformatter.h
icu4c/source/i18n/unicode/numberrangeformatter.h
icu4c/source/i18n/unicode/unumberformatter.h
icu4c/source/test/intltest/numbertest_api.cpp
icu4j/main/classes/core/src/com/ibm/icu/impl/number/LocalizedNumberFormatterAsFormat.java
icu4j/main/classes/core/src/com/ibm/icu/number/FormattedNumber.java
icu4j/main/classes/core/src/com/ibm/icu/number/FormattedNumberRange.java
icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberFormatter.java
icu4j/main/classes/core/src/com/ibm/icu/number/Precision.java
icu4j/main/classes/core/src/com/ibm/icu/number/ScientificNotation.java
icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java
icu4j/main/classes/core/src/com/ibm/icu/text/MeasureFormat.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java

index 07a41e58184580c002a69eaad5bd979450ce70c5..daa1129a6ab1d70e9ee83c4f74f31fb640a3066f 100644 (file)
@@ -519,7 +519,9 @@ UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, Fie
         return appendTo;
     }
     UErrorCode localStatus = U_ZERO_ERROR;
-    FormattedNumber output = fields->formatter.formatDouble(number, localStatus);
+    UFormattedNumberData output;
+    output.quantity.setToDouble(number);
+    fields->formatter.formatImpl(&output, localStatus);
     fieldPositionHelper(output, pos, appendTo.length(), localStatus);
     auto appendable = UnicodeStringAppendable(appendTo);
     output.appendTo(appendable, localStatus);
@@ -540,7 +542,9 @@ UnicodeString& DecimalFormat::format(double number, UnicodeString& appendTo, Fie
     if (pos.getField() == FieldPosition::DONT_CARE && fastFormatDouble(number, appendTo)) {
         return appendTo;
     }
-    FormattedNumber output = fields->formatter.formatDouble(number, status);
+    UFormattedNumberData output;
+    output.quantity.setToDouble(number);
+    fields->formatter.formatImpl(&output, status);
     fieldPositionHelper(output, pos, appendTo.length(), status);
     auto appendable = UnicodeStringAppendable(appendTo);
     output.appendTo(appendable, status);
@@ -562,7 +566,9 @@ DecimalFormat::format(double number, UnicodeString& appendTo, FieldPositionItera
     if (posIter == nullptr && fastFormatDouble(number, appendTo)) {
         return appendTo;
     }
-    FormattedNumber output = fields->formatter.formatDouble(number, status);
+    UFormattedNumberData output;
+    output.quantity.setToDouble(number);
+    fields->formatter.formatImpl(&output, status);
     fieldPositionIteratorHelper(output, posIter, appendTo.length(), status);
     auto appendable = UnicodeStringAppendable(appendTo);
     output.appendTo(appendable, status);
@@ -593,7 +599,9 @@ UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, Fi
         return appendTo;
     }
     UErrorCode localStatus = U_ZERO_ERROR;
-    FormattedNumber output = fields->formatter.formatInt(number, localStatus);
+    UFormattedNumberData output;
+    output.quantity.setToLong(number);
+    fields->formatter.formatImpl(&output, localStatus);
     fieldPositionHelper(output, pos, appendTo.length(), localStatus);
     auto appendable = UnicodeStringAppendable(appendTo);
     output.appendTo(appendable, localStatus);
@@ -614,7 +622,9 @@ UnicodeString& DecimalFormat::format(int64_t number, UnicodeString& appendTo, Fi
     if (pos.getField() == FieldPosition::DONT_CARE && fastFormatInt64(number, appendTo)) {
         return appendTo;
     }
-    FormattedNumber output = fields->formatter.formatInt(number, status);
+    UFormattedNumberData output;
+    output.quantity.setToLong(number);
+    fields->formatter.formatImpl(&output, status);
     fieldPositionHelper(output, pos, appendTo.length(), status);
     auto appendable = UnicodeStringAppendable(appendTo);
     output.appendTo(appendable, status);
@@ -636,7 +646,9 @@ DecimalFormat::format(int64_t number, UnicodeString& appendTo, FieldPositionIter
     if (posIter == nullptr && fastFormatInt64(number, appendTo)) {
         return appendTo;
     }
-    FormattedNumber output = fields->formatter.formatInt(number, status);
+    UFormattedNumberData output;
+    output.quantity.setToLong(number);
+    fields->formatter.formatImpl(&output, status);
     fieldPositionIteratorHelper(output, posIter, appendTo.length(), status);
     auto appendable = UnicodeStringAppendable(appendTo);
     output.appendTo(appendable, status);
@@ -655,7 +667,9 @@ DecimalFormat::format(StringPiece number, UnicodeString& appendTo, FieldPosition
         appendTo.setToBogus();
         return appendTo;
     }
-    FormattedNumber output = fields->formatter.formatDecimal(number, status);
+    UFormattedNumberData output;
+    output.quantity.setToDecNumber(number, status);
+    fields->formatter.formatImpl(&output, status);
     fieldPositionIteratorHelper(output, posIter, appendTo.length(), status);
     auto appendable = UnicodeStringAppendable(appendTo);
     output.appendTo(appendable, status);
@@ -673,7 +687,9 @@ UnicodeString& DecimalFormat::format(const DecimalQuantity& number, UnicodeStrin
         appendTo.setToBogus();
         return appendTo;
     }
-    FormattedNumber output = fields->formatter.formatDecimalQuantity(number, status);
+    UFormattedNumberData output;
+    output.quantity = number;
+    fields->formatter.formatImpl(&output, status);
     fieldPositionIteratorHelper(output, posIter, appendTo.length(), status);
     auto appendable = UnicodeStringAppendable(appendTo);
     output.appendTo(appendable, status);
@@ -692,7 +708,9 @@ DecimalFormat::format(const DecimalQuantity& number, UnicodeString& appendTo, Fi
         appendTo.setToBogus();
         return appendTo;
     }
-    FormattedNumber output = fields->formatter.formatDecimalQuantity(number, status);
+    UFormattedNumberData output;
+    output.quantity = number;
+    fields->formatter.formatImpl(&output, status);
     fieldPositionHelper(output, pos, appendTo.length(), status);
     auto appendable = UnicodeStringAppendable(appendTo);
     output.appendTo(appendable, status);
@@ -1703,8 +1721,11 @@ const numparse::impl::NumberParserImpl* DecimalFormat::getCurrencyParser(UErrorC
 }
 
 void
-DecimalFormat::fieldPositionHelper(const number::FormattedNumber& formatted, FieldPosition& fieldPosition,
-                                   int32_t offset, UErrorCode& status) {
+DecimalFormat::fieldPositionHelper(
+        const UFormattedNumberData& formatted,
+        FieldPosition& fieldPosition,
+        int32_t offset,
+        UErrorCode& status) {
     if (U_FAILURE(status)) { return; }
     // always return first occurrence:
     fieldPosition.setBeginIndex(0);
@@ -1717,12 +1738,15 @@ DecimalFormat::fieldPositionHelper(const number::FormattedNumber& formatted, Fie
 }
 
 void
-DecimalFormat::fieldPositionIteratorHelper(const number::FormattedNumber& formatted, FieldPositionIterator* fpi,
-                                           int32_t offset, UErrorCode& status) {
+DecimalFormat::fieldPositionIteratorHelper(
+        const UFormattedNumberData& formatted,
+        FieldPositionIterator* fpi,
+        int32_t offset,
+        UErrorCode& status) {
     if (U_SUCCESS(status) && (fpi != nullptr)) {
         FieldPositionIteratorHandler fpih(fpi, status);
         fpih.setShift(offset);
-        formatted.getAllFieldPositionsImpl(fpih, status);
+        formatted.getAllFieldPositions(fpih, status);
     }
 }
 
index 00937830fe7b801463c81bfa31ab6dc3d2d7d4c8..b9fa9b218149d4d9aacc05f91b3eda3dd17c98cc 100644 (file)
@@ -62,8 +62,9 @@ class FieldPositionOnlyHandler : public FieldPositionHandler {
 
 
 // utility subclass FieldPositionIteratorHandler
+// exported as U_I18N_API for tests
 
-class FieldPositionIteratorHandler : public FieldPositionHandler {
+class U_I18N_API FieldPositionIteratorHandler : public FieldPositionHandler {
   FieldPositionIterator* iter; // can be NULL
   UVector32* vec;
   UErrorCode status;
index f3ba6198cef2035a8f110d65a7d539b9be9a5e1b..e05d66d4135e595b1637674541123d006f5e3acb 100644 (file)
@@ -38,6 +38,7 @@
 #include "uassert.h"
 #include "unicode/numberformatter.h"
 #include "number_longnames.h"
+#include "number_utypes.h"
 
 #include "sharednumberformat.h"
 #include "sharedpluralrules.h"
@@ -47,6 +48,8 @@
 
 U_NAMESPACE_BEGIN
 
+using number::impl::UFormattedNumberData;
+
 static constexpr int32_t WIDTH_INDEX_COUNT = UMEASFMT_WIDTH_NARROW + 1;
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(MeasureFormat)
@@ -504,12 +507,13 @@ UnicodeString &MeasureFormat::formatMeasurePerUnit(
         status = U_UNSUPPORTED_ERROR;
         return appendTo;
     }
-    number::FormattedNumber result;
+    UFormattedNumberData result;
     if (auto* lnf = df->toNumberFormatter(status)) {
-        result = lnf->unit(measure.getUnit())
+        result.quantity.setToDouble(measure.getNumber().getDouble(status));
+        lnf->unit(measure.getUnit())
             .perUnit(perUnit)
             .unitWidth(getUnitWidth(fWidth))
-            .formatDouble(measure.getNumber().getDouble(status), status);
+            .formatImpl(&result, status);
     }
     DecimalFormat::fieldPositionHelper(result, pos, appendTo.length(), status);
     appendTo.append(result.toTempString(status));
@@ -699,11 +703,12 @@ UnicodeString &MeasureFormat::formatMeasure(
         SimpleFormatter formatter(pattern, 0, 1, status);
         return QuantityFormatter::format(formatter, formattedNumber, appendTo, pos, status);
     }
-    number::FormattedNumber result;
+    UFormattedNumberData result;
     if (auto* lnf = df->toNumberFormatter(status)) {
-        result = lnf->unit(amtUnit)
+        result.quantity.setToDouble(amtNumber.getDouble(status));
+        lnf->unit(amtUnit)
             .unitWidth(getUnitWidth(fWidth))
-            .formatDouble(amtNumber.getDouble(status), status);
+            .formatImpl(&result, status);
     }
     DecimalFormat::fieldPositionHelper(result, pos, appendTo.length(), status);
     appendTo.append(result.toTempString(status));
index f802e211049eb17a3c93c52b282c77f2bf4b54bd..21a600d6ab1ed399c7cdffb033d99b945aa376f4 100644 (file)
@@ -156,7 +156,7 @@ unumf_resultToString(const UFormattedNumber* uresult, UChar* buffer, int32_t buf
         return 0;
     }
 
-    return result->fImpl.toTempString(*ec).extract(buffer, bufferCapacity, *ec);
+    return result->fData.toTempString(*ec).extract(buffer, bufferCapacity, *ec);
 }
 
 U_CAPI UBool U_EXPORT2
@@ -173,7 +173,7 @@ unumf_resultNextFieldPosition(const UFormattedNumber* uresult, UFieldPosition* u
     fp.setField(ufpos->field);
     fp.setBeginIndex(ufpos->beginIndex);
     fp.setEndIndex(ufpos->endIndex);
-    bool retval = result->fImpl.nextFieldPosition(fp, *ec);
+    bool retval = result->fData.nextFieldPosition(fp, *ec);
     ufpos->beginIndex = fp.getBeginIndex();
     ufpos->endIndex = fp.getEndIndex();
     // NOTE: MSVC sometimes complains when implicitly converting between bool and UBool
@@ -192,7 +192,8 @@ unumf_resultGetAllFieldPositions(const UFormattedNumber* uresult, UFieldPosition
     }
 
     auto* fpi = reinterpret_cast<FieldPositionIterator*>(ufpositer);
-    result->fImpl.getAllFieldPositions(*fpi, *ec);
+    FieldPositionIteratorHandler fpih(fpi, *ec);
+    result->fData.getAllFieldPositions(fpih, *ec);
 }
 
 U_CAPI void U_EXPORT2
index e2f069139a4b47f8d3c704d34d4117338063cfdc..40192a9225b9de98635d991b5f55457999ef4108 100644 (file)
@@ -19,16 +19,6 @@ UPRV_FORMATTED_VALUE_SUBCLASS_AUTO_IMPL(FormattedNumber)
 
 #define UPRV_NOARG
 
-UBool FormattedNumber::nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const {
-    UPRV_FORMATTED_VALUE_METHOD_GUARD(FALSE)
-    return fData->nextFieldPosition(fieldPosition, status);
-}
-
-void FormattedNumber::getAllFieldPositions(FieldPositionIterator& iterator, UErrorCode& status) const {
-    FieldPositionIteratorHandler fpih(&iterator, status);
-    getAllFieldPositionsImpl(fpih, status);
-}
-
 void FormattedNumber::toDecimalNumber(ByteSink& sink, UErrorCode& status) const {
     UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG)
     impl::DecNum decnum;
index af25aa3398898c2f728f6b8260b5709b078586e4..7a1b7a4e80ac3150c9b5844ae6e8e0d273d6c724 100644 (file)
@@ -30,8 +30,10 @@ const DecimalQuantity* validateUFormattedNumberToDecimalQuantity(
  *
  * The DecimalQuantity is not currently being used by FormattedNumber, but at some point it could be used
  * to add a toDecNumber() or similar method.
+ *
+ * Exported as U_I18N_API for tests
  */
-class UFormattedNumberData : public FormattedValueStringBuilderImpl {
+class U_I18N_API UFormattedNumberData : public FormattedValueStringBuilderImpl {
 public:
     UFormattedNumberData() : FormattedValueStringBuilderImpl(kUndefinedField) {}
     virtual ~UFormattedNumberData();
index 654cafaf00bc821053f6d264ee687064e17f7f5e..33179026f8d2b53f3cbbb18eaf2fbf82bdc51167 100644 (file)
@@ -379,23 +379,6 @@ UPRV_FORMATTED_VALUE_SUBCLASS_AUTO_IMPL(FormattedNumberRange)
 
 #define UPRV_NOARG
 
-UBool FormattedNumberRange::nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const {
-    UPRV_FORMATTED_VALUE_METHOD_GUARD(FALSE)
-    // NOTE: MSVC sometimes complains when implicitly converting between bool and UBool
-    return fData->nextFieldPosition(fieldPosition, status);
-}
-
-void FormattedNumberRange::getAllFieldPositions(FieldPositionIterator& iterator, UErrorCode& status) const {
-    FieldPositionIteratorHandler fpih(&iterator, status);
-    getAllFieldPositionsImpl(fpih, status);
-}
-
-void FormattedNumberRange::getAllFieldPositionsImpl(
-        FieldPositionIteratorHandler& fpih, UErrorCode& status) const {
-    UPRV_FORMATTED_VALUE_METHOD_GUARD(UPRV_NOARG)
-    fData->getAllFieldPositions(fpih, status);
-}
-
 UnicodeString FormattedNumberRange::getFirstDecimal(UErrorCode& status) const {
     UPRV_FORMATTED_VALUE_METHOD_GUARD(ICU_Utility::makeBogusString())
     return fData->quantity1.toScientificString();
index c33ec80cacc5e08481652a3e93cc0750fb80ea57..9e60103531667357686ef6c6c28c68b25f7f07a2 100644 (file)
@@ -53,10 +53,10 @@ class CompactDecimalFormat;
 
 namespace number {
 class LocalizedNumberFormatter;
-class FormattedNumber;
 namespace impl {
 class DecimalQuantity;
 struct DecimalFormatFields;
+class UFormattedNumberData;
 }
 }
 
@@ -2168,11 +2168,17 @@ class U_I18N_API DecimalFormat : public NumberFormat {
 
     const numparse::impl::NumberParserImpl* getCurrencyParser(UErrorCode& status) const;
 
-    static void fieldPositionHelper(const number::FormattedNumber& formatted, FieldPosition& fieldPosition,
-                                    int32_t offset, UErrorCode& status);
-
-    static void fieldPositionIteratorHelper(const number::FormattedNumber& formatted,
-                                            FieldPositionIterator* fpi, int32_t offset, UErrorCode& status);
+    static void fieldPositionHelper(
+        const number::impl::UFormattedNumberData& formatted,
+        FieldPosition& fieldPosition,
+        int32_t offset,
+        UErrorCode& status);
+
+    static void fieldPositionIteratorHelper(
+        const number::impl::UFormattedNumberData& formatted,
+        FieldPositionIterator* fpi,
+        int32_t offset,
+        UErrorCode& status);
 
     void setupFastFormat();
 
index 985c02d4b02195779a36a3c8497d3a524768fa36..95f4337bcac6942322d2b0c9312b23ec51961274 100644 (file)
@@ -2490,60 +2490,6 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
     /** @copydoc FormattedValue::nextPosition() */
     UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE;
 
-#ifndef U_HIDE_DRAFT_API
-    /**
-     * Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the given
-     * <em>field</em> in the output string. This allows you to determine the locations of, for example,
-     * the integer part, fraction part, or symbols.
-     *
-     * This is a simpler but less powerful alternative to {@link #nextPosition}.
-     *
-     * If a field occurs just once, calling this method will find that occurrence and return it. If a
-     * field occurs multiple times, this method may be called repeatedly with the following pattern:
-     *
-     * <pre>
-     * FieldPosition fpos(UNUM_GROUPING_SEPARATOR_FIELD);
-     * while (formattedNumber.nextFieldPosition(fpos, status)) {
-     *   // do something with fpos.
-     * }
-     * </pre>
-     *
-     * This method is useful if you know which field to query. If you want all available field position
-     * information, use {@link #nextPosition} or {@link #getAllFieldPositions}.
-     *
-     * @param fieldPosition
-     *            Input+output variable. On input, the "field" property determines which field to look
-     *            up, and the "beginIndex" and "endIndex" properties determine where to begin the search.
-     *            On output, the "beginIndex" is set to the beginning of the first occurrence of the
-     *            field with either begin or end indices after the input indices; "endIndex" is set to
-     *            the end of that occurrence of the field (exclusive index). If a field position is not
-     *            found, the method returns FALSE and the FieldPosition may or may not be changed.
-     * @param status
-     *            Set if an error occurs while populating the FieldPosition.
-     * @return TRUE if a new occurrence of the field was found; FALSE otherwise.
-     * @draft ICU 62
-     * @see UNumberFormatFields
-     */
-    UBool nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const;
-
-    /**
-     * Export the formatted number to a FieldPositionIterator. This allows you to determine which characters in
-     * the output string correspond to which <em>fields</em>, such as the integer part, fraction part, and sign.
-     *
-     * This is an alternative to the more powerful #nextPosition() API.
-     *
-     * If information on only one field is needed, use #nextPosition() or #nextFieldPosition() instead.
-     *
-     * @param iterator
-     *            The FieldPositionIterator to populate with all of the fields present in the formatted number.
-     * @param status
-     *            Set if an error occurs while populating the FieldPositionIterator.
-     * @draft ICU 62
-     * @see UNumberFormatFields
-     */
-    void getAllFieldPositions(FieldPositionIterator &iterator, UErrorCode &status) const;
-#endif  /* U_HIDE_DRAFT_API */
-
 #ifndef U_HIDE_DRAFT_API
     /**
      * Export the formatted number as a "numeric string" conforming to the
index 0f0d2af5f5b2af960ff218d3204fef27eaf60ffb..c086a9e2861874e9f91c595350ad3a4848534f06 100644 (file)
@@ -728,52 +728,6 @@ class U_I18N_API FormattedNumberRange : public UMemory, public FormattedValue {
     UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE;
 
 #ifndef U_HIDE_DRAFT_API
-    /**
-     * Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the given
-     * <em>field</em> in the output string. This allows you to determine the locations of, for example,
-     * the integer part, fraction part, or symbols.
-     *
-     * If both sides of the range have the same field, the field will occur twice, once before the
-     * range separator and once after the range separator, if applicable.
-     *
-     * If a field occurs just once, calling this method will find that occurrence and return it. If a
-     * field occurs multiple times, this method may be called repeatedly with the following pattern:
-     *
-     * <pre>
-     * FieldPosition fpos(UNUM_INTEGER_FIELD);
-     * while (formattedNumberRange.nextFieldPosition(fpos, status)) {
-     *   // do something with fpos.
-     * }
-     * </pre>
-     *
-     * This method is useful if you know which field to query. If you want all available field position
-     * information, use #getAllFieldPositions().
-     *
-     * @param fieldPosition
-     *            Input+output variable. See {@link FormattedNumber#nextFieldPosition}.
-     * @param status
-     *            Set if an error occurs while populating the FieldPosition.
-     * @return TRUE if a new occurrence of the field was found; FALSE otherwise.
-     * @draft ICU 63
-     * @see UNumberFormatFields
-     */
-    UBool nextFieldPosition(FieldPosition& fieldPosition, UErrorCode& status) const;
-
-    /**
-     * Export the formatted number range to a FieldPositionIterator. This allows you to determine which characters in
-     * the output string correspond to which <em>fields</em>, such as the integer part, fraction part, and sign.
-     *
-     * If information on only one field is needed, use #nextFieldPosition() instead.
-     *
-     * @param iterator
-     *            The FieldPositionIterator to populate with all of the fields present in the formatted number.
-     * @param status
-     *            Set if an error occurs while populating the FieldPositionIterator.
-     * @draft ICU 63
-     * @see UNumberFormatFields
-     */
-    void getAllFieldPositions(FieldPositionIterator &iterator, UErrorCode &status) const;
-
     /**
      * Export the first formatted number as a decimal number. This endpoint
      * is useful for obtaining the exact number being printed after scaling
index 1d6b46030d0d8385339c6636d69bc79fb5aa4a4f..12b88a4de80e9a0b9e21530c979fd92cc5a79efa 100644 (file)
@@ -427,7 +427,7 @@ typedef struct UFormattedNumber UFormattedNumber;
  * NOTE: This is a C-compatible API; C++ users should build against numberformatter.h instead.
  *
  * @param skeleton The skeleton string, like u"percent precision-integer"
- * @param skeletonLen The number of UChars in the skeleton string, or -1 it it is NUL-terminated.
+ * @param skeletonLen The number of UChars in the skeleton string, or -1 if it is NUL-terminated.
  * @param locale The NUL-terminated locale ID.
  * @param ec Set if an error occurs.
  * @stable ICU 62
@@ -443,7 +443,7 @@ unumf_openForSkeletonAndLocale(const UChar* skeleton, int32_t skeletonLen, const
  * location of a skeleton syntax error if such a syntax error exists.
  *
  * @param skeleton The skeleton string, like u"percent precision-integer"
- * @param skeletonLen The number of UChars in the skeleton string, or -1 it it is NUL-terminated.
+ * @param skeletonLen The number of UChars in the skeleton string, or -1 if it is NUL-terminated.
  * @param locale The NUL-terminated locale ID.
  * @param perror A parse error struct populated if an error occurs when parsing. Can be NULL.
  *               If no error occurs, perror->offset will be set to -1.
index 60f4d44db3b25a961e5f338b73a3bc6131edbc66..9652ade9668fcb925599ab0320b4f127dd950b82 100644 (file)
@@ -16,6 +16,9 @@
 #include "number_utils.h"
 #include "numbertest.h"
 #include "unicode/utypes.h"
+#include "number_utypes.h"
+
+using number::impl::UFormattedNumberData;
 
 // Horrible workaround for the lack of a status code in the constructor...
 // (Also affects numbertest_range.cpp)
@@ -2730,9 +2733,10 @@ void NumberFormatterApiTest::fieldPositionLogic() {
             UPRV_LENGTHOF(expectedFieldPositions));
 
     // Test the iteration functionality of nextFieldPosition
-    FieldPosition actual = {UNUM_GROUPING_SEPARATOR_FIELD};
+    ConstrainedFieldPosition actual;
+    actual.constrainField(UFIELD_CATEGORY_NUMBER, UNUM_GROUPING_SEPARATOR_FIELD);
     int32_t i = 1;
-    while (fmtd.nextFieldPosition(actual, status)) {
+    while (fmtd.nextPosition(actual, status)) {
         UFieldPosition expected = expectedFieldPositions[i++];
         assertEquals(
                 UnicodeString(u"Next for grouping, field, case #") + Int64ToUnicodeString(i),
@@ -2741,18 +2745,19 @@ void NumberFormatterApiTest::fieldPositionLogic() {
         assertEquals(
                 UnicodeString(u"Next for grouping, begin index, case #") + Int64ToUnicodeString(i),
                 expected.beginIndex,
-                actual.getBeginIndex());
+                actual.getStart());
         assertEquals(
                 UnicodeString(u"Next for grouping, end index, case #") + Int64ToUnicodeString(i),
                 expected.endIndex,
-                actual.getEndIndex());
+                actual.getLimit());
     }
     assertEquals(u"Should have seen all grouping separators", 4, i);
 
     // Make sure strings without fraction do not contain fraction field
-    actual = {UNUM_FRACTION_FIELD};
+    actual.reset();
+    actual.constrainField(UFIELD_CATEGORY_NUMBER, UNUM_FRACTION_FIELD);
     fmtd = NumberFormatter::withLocale("en").formatInt(5, status);
-    assertFalse(u"No fraction part in an integer", fmtd.nextFieldPosition(actual, status));
+    assertFalse(u"No fraction part in an integer", fmtd.nextPosition(actual, status));
 }
 
 void NumberFormatterApiTest::fieldPositionCoverage() {
@@ -3064,10 +3069,18 @@ void NumberFormatterApiTest::toFormat() {
             dynamic_cast<LocalizedNumberFormatterAsFormat*>(format.getAlias())->getNumberFormatter()
                     .toSkeleton(status));
 
+    UFormattedNumberData result;
+    result.quantity.setToDouble(514.23);
+    lnf.formatImpl(&result, status);
     FieldPositionIterator fpi1;
-    lnf.formatDouble(514.23, status).getAllFieldPositions(fpi1, status);
+    {
+        FieldPositionIteratorHandler fpih(&fpi1, status);
+        result.getAllFieldPositions(fpih, status);
+    }
+
     FieldPositionIterator fpi2;
     format->format(514.23, sb.remove(), &fpi2, status);
+
     assertTrue("Should produce same field position iterator", fpi1 == fpi2);
 }
 
@@ -3119,19 +3132,20 @@ void NumberFormatterApiTest::errors() {
             "Terminal toSkeleton on error object should be bogus",
             output.isBogus());
 
-    // FieldPosition
+    // FieldPosition (constrained category)
     status = U_ZERO_ERROR;
-    FieldPosition fp;
-    fn.nextFieldPosition(fp, status);
+    ConstrainedFieldPosition fp;
+    fp.constrainCategory(UFIELD_CATEGORY_NUMBER);
+    fn.nextPosition(fp, status);
     assertEquals(
             "Should fail on FieldPosition terminal method with correct error code",
             U_NUMBER_ARG_OUTOFBOUNDS_ERROR,
             status);
 
-    // FieldPositionIterator
+    // FieldPositionIterator (no constraints)
     status = U_ZERO_ERROR;
-    FieldPositionIterator fpi;
-    fn.getAllFieldPositions(fpi, status);
+    fp.reset();
+    fn.nextPosition(fp, status);
     assertEquals(
             "Should fail on FieldPositoinIterator terminal method with correct error code",
             U_NUMBER_ARG_OUTOFBOUNDS_ERROR,
@@ -3592,64 +3606,6 @@ void NumberFormatterApiTest::assertNumberFieldPositions(
         UFIELD_CATEGORY_NUMBER,
         expectedFieldPositions,
         length);
-
-    // Check FormattedNumber-specific functions
-    UnicodeString baseMessage = UnicodeString(message) + u": " + formattedNumber.toString(status) + u": ";
-    FieldPositionIterator fpi;
-    formattedNumber.getAllFieldPositions(fpi, status);
-    int32_t i = 0;
-    FieldPosition actual;
-    while (fpi.next(actual)) {
-        UFieldPosition expected = expectedFieldPositions[i++];
-        assertEquals(
-                baseMessage + UnicodeString(u"Field, case #") + Int64ToUnicodeString(i),
-                expected.field,
-                actual.getField());
-        assertEquals(
-                baseMessage + UnicodeString(u"Iterator, begin, case #") + Int64ToUnicodeString(i),
-                expected.beginIndex,
-                actual.getBeginIndex());
-        assertEquals(
-                baseMessage + UnicodeString(u"Iterator, end, case #") + Int64ToUnicodeString(i),
-                expected.endIndex,
-                actual.getEndIndex());
-
-        // Check for the first location of the field
-        FieldPosition actual2(expected.field);
-        // Fast-forward the field to skip previous occurrences of the field:
-        actual2.setBeginIndex(expected.beginIndex);
-        actual2.setEndIndex(expected.beginIndex);
-        UBool found = formattedNumber.nextFieldPosition(actual2, status);
-        assertEquals(
-                baseMessage + UnicodeString(u"Next, found first, case #") + Int64ToUnicodeString(i),
-                (UBool) TRUE,
-                found);
-        assertEquals(
-                baseMessage + UnicodeString(u"Next, begin, case #") + Int64ToUnicodeString(i),
-                expected.beginIndex,
-                actual2.getBeginIndex());
-        assertEquals(
-                baseMessage + UnicodeString(u"Next, end, case #") + Int64ToUnicodeString(i),
-                expected.endIndex,
-                actual2.getEndIndex());
-
-        // The next position should be empty unless the field occurs again
-        UBool occursAgain = false;
-        for (int32_t j=i; j<length; j++) {
-            if (expectedFieldPositions[j].field == expected.field) {
-                occursAgain = true;
-                break;
-            }
-        }
-        if (!occursAgain) {
-            found = formattedNumber.nextFieldPosition(actual2, status);
-            assertEquals(
-                    baseMessage + UnicodeString(u"Next, found second, case #") + Int64ToUnicodeString(i),
-                    (UBool) FALSE,
-                    found);
-        }
-    }
-    assertEquals(baseMessage + u"Should have seen every field position", length, i);
 }
 
 
index cd1ee7911497c0c59f45eb45c7749e288e471796..437be95c063ba7cc6e05d6edfe5ff756698e2f2c 100644 (file)
@@ -12,7 +12,9 @@ import java.text.FieldPosition;
 import java.text.Format;
 import java.text.ParsePosition;
 
-import com.ibm.icu.number.FormattedNumber;
+import com.ibm.icu.impl.FormattedStringBuilder;
+import com.ibm.icu.impl.FormattedValueStringBuilderImpl;
+import com.ibm.icu.impl.Utility;
 import com.ibm.icu.number.LocalizedNumberFormatter;
 import com.ibm.icu.number.NumberFormatter;
 import com.ibm.icu.util.ULocale;
@@ -46,16 +48,18 @@ public class LocalizedNumberFormatterAsFormat extends Format {
         if (!(obj instanceof Number)) {
             throw new IllegalArgumentException();
         }
-        FormattedNumber result = formatter.format((Number) obj);
+        DecimalQuantity dq = new DecimalQuantity_DualStorageBCD((Number) obj);
+        FormattedStringBuilder string = new FormattedStringBuilder();
+        formatter.formatImpl(dq, string);
         // always return first occurrence:
         pos.setBeginIndex(0);
         pos.setEndIndex(0);
-        boolean found = result.nextFieldPosition(pos);
+        boolean found = FormattedValueStringBuilderImpl.nextFieldPosition(string, pos);
         if (found && toAppendTo.length() != 0) {
             pos.setBeginIndex(pos.getBeginIndex() + toAppendTo.length());
             pos.setEndIndex(pos.getEndIndex() + toAppendTo.length());
         }
-        result.appendTo(toAppendTo);
+        Utility.appendTo(string, toAppendTo);
         return toAppendTo;
     }
 
index 945d9075d1fe26843e35136130cf3800f5da9a8a..397b1d0515a8260412cfbd2287863d1fa0ca273e 100644 (file)
@@ -4,8 +4,6 @@ package com.ibm.icu.number;
 
 import java.math.BigDecimal;
 import java.text.AttributedCharacterIterator;
-import java.text.FieldPosition;
-import java.util.Arrays;
 
 import com.ibm.icu.impl.FormattedStringBuilder;
 import com.ibm.icu.impl.FormattedValueStringBuilderImpl;
@@ -107,44 +105,6 @@ public class FormattedNumber implements FormattedValue {
         return FormattedValueStringBuilderImpl.toCharacterIterator(string, null);
     }
 
-    /**
-     * Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the
-     * given <em>field</em> in the output string. This allows you to determine the locations of,
-     * for example, the integer part, fraction part, or symbols.
-     * <p>
-     * This is a simpler but less powerful alternative to {@link #nextPosition}.
-     * <p>
-     * If a field occurs just once, calling this method will find that occurrence and return it. If a
-     * field occurs multiple times, this method may be called repeatedly with the following pattern:
-     *
-     * <pre>
-     * FieldPosition fpos = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
-     * while (formattedNumber.nextFieldPosition(fpos, status)) {
-     *     // do something with fpos.
-     * }
-     * </pre>
-     * <p>
-     * This method is useful if you know which field to query. If you want all available field position
-     * information, use {@link #nextPosition} or {@link #toCharacterIterator()}.
-     *
-     * @param fieldPosition
-     *            Input+output variable. On input, the "field" property determines which field to look
-     *            up, and the "beginIndex" and "endIndex" properties determine where to begin the search.
-     *            On output, the "beginIndex" is set to the beginning of the first occurrence of the
-     *            field with either begin or end indices after the input indices, "endIndex" is set to
-     *            the end of that occurrence of the field (exclusive index). If a field position is not
-     *            found, the method returns FALSE and the FieldPosition may or may not be changed.
-     * @return true if a new occurrence of the field was found; false otherwise.
-     * @draft ICU 62
-     * @provisional This API might change or be removed in a future release.
-     * @see com.ibm.icu.text.NumberFormat.Field
-     * @see NumberFormatter
-     */
-    public boolean nextFieldPosition(FieldPosition fieldPosition) {
-        fq.populateUFieldPosition(fieldPosition);
-        return FormattedValueStringBuilderImpl.nextFieldPosition(string, fieldPosition);
-    }
-
     /**
      * Export the formatted number as a BigDecimal. This endpoint is useful for obtaining the exact
      * number being printed after scaling and rounding have been applied by the number formatting
@@ -166,41 +126,4 @@ public class FormattedNumber implements FormattedValue {
     public IFixedDecimal getFixedDecimal() {
         return fq;
     }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @draft ICU 60
-     * @provisional This API might change or be removed in a future release.
-     */
-    @Override
-    public int hashCode() {
-        // FormattedStringBuilder and BigDecimal are mutable, so we can't call
-        // #equals() or #hashCode() on them directly.
-        return Arrays.hashCode(string.toCharArray())
-                ^ Arrays.hashCode(string.toFieldArray())
-                ^ fq.toBigDecimal().hashCode();
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @draft ICU 60
-     * @provisional This API might change or be removed in a future release.
-     */
-    @Override
-    public boolean equals(Object other) {
-        if (this == other)
-            return true;
-        if (other == null)
-            return false;
-        if (!(other instanceof FormattedNumber))
-            return false;
-        // FormattedStringBuilder and BigDecimal are mutable, so we can't call
-        // #equals() or #hashCode() on them directly.
-        FormattedNumber _other = (FormattedNumber) other;
-        return Arrays.equals(string.toCharArray(), _other.string.toCharArray())
-                && Arrays.equals(string.toFieldArray(), _other.string.toFieldArray())
-                && fq.toBigDecimal().equals(_other.fq.toBigDecimal());
-    }
 }
\ No newline at end of file
index 8189e59cc0a25aa15ddfa584955a6940926fe2be..fa5503bbfc93b14881ab2484eea7a9c3741bde5e 100644 (file)
@@ -5,7 +5,6 @@ package com.ibm.icu.number;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.text.AttributedCharacterIterator;
-import java.text.FieldPosition;
 import java.util.Arrays;
 
 import com.ibm.icu.impl.FormattedStringBuilder;
@@ -110,39 +109,6 @@ public class FormattedNumberRange implements FormattedValue {
         return FormattedValueStringBuilderImpl.nextPosition(string, cfpos, null);
     }
 
-    /**
-     * Determines the start (inclusive) and end (exclusive) indices of the next occurrence of the given
-     * <em>field</em> in the output string. This allows you to determine the locations of, for example,
-     * the integer part, fraction part, or symbols.
-     * <p>
-     * If both sides of the range have the same field, the field will occur twice, once before the range separator and
-     * once after the range separator, if applicable.
-     * <p>
-     * If a field occurs just once, calling this method will find that occurrence and return it. If a field occurs
-     * multiple times, this method may be called repeatedly with the following pattern:
-     *
-     * <pre>
-     * FieldPosition fpos = new FieldPosition(NumberFormat.Field.INTEGER);
-     * while (formattedNumberRange.nextFieldPosition(fpos, status)) {
-     *     // do something with fpos.
-     * }
-     * </pre>
-     * <p>
-     * This method is useful if you know which field to query. If you want all available field position information, use
-     * {@link #toCharacterIterator()}.
-     *
-     * @param fieldPosition
-     *            Input+output variable. See {@link FormattedNumber#nextFieldPosition(FieldPosition)}.
-     * @return true if a new occurrence of the field was found; false otherwise.
-     * @draft ICU 63
-     * @provisional This API might change or be removed in a future release.
-     * @see com.ibm.icu.text.NumberFormat.Field
-     * @see NumberRangeFormatter
-     */
-    public boolean nextFieldPosition(FieldPosition fieldPosition) {
-        return FormattedValueStringBuilderImpl.nextFieldPosition(string, fieldPosition);
-    }
-
     /**
      * {@inheritDoc}
      *
index 1e3f26a579003d0fa34ec4a0db3bfa06aeb3afb2..85e2cebd1a8c947f34c15c2329734b766de09119 100644 (file)
@@ -97,20 +97,11 @@ public class LocalizedNumberFormatter extends NumberFormatterSettings<LocalizedN
      * @see NumberFormatter
      */
     public FormattedNumber format(Measure input) {
+        DecimalQuantity fq = new DecimalQuantity_DualStorageBCD(input.getNumber());
         MeasureUnit unit = input.getUnit();
-        Number number = input.getNumber();
-        // Use this formatter if possible
-        if (Objects.equals(resolve().unit, unit)) {
-            return format(number);
-        }
-        // This mechanism saves the previously used unit, so if the user calls this method with the
-        // same unit multiple times in a row, they get a more efficient code path.
-        LocalizedNumberFormatter withUnit = savedWithUnit;
-        if (withUnit == null || !Objects.equals(withUnit.resolve().unit, unit)) {
-            withUnit = new LocalizedNumberFormatter(this, KEY_UNIT, unit);
-            savedWithUnit = withUnit;
-        }
-        return withUnit.format(number);
+        FormattedStringBuilder string = new FormattedStringBuilder();
+        formatImpl(fq, unit, string);
+        return new FormattedNumber(string, fq);
     }
 
     /**
@@ -161,6 +152,29 @@ public class LocalizedNumberFormatter extends NumberFormatterSettings<LocalizedN
         }
     }
 
+    /**
+     * Version of above for unit override.
+     *
+     * @internal
+     * @deprecated ICU 67 This API is ICU internal only.
+     */
+    @Deprecated
+    public void formatImpl(DecimalQuantity fq, MeasureUnit unit, FormattedStringBuilder string) {
+        // Use this formatter if possible
+        if (Objects.equals(resolve().unit, unit)) {
+            formatImpl(fq, string);
+            return;
+        }
+        // This mechanism saves the previously used unit, so if the user calls this method with the
+        // same unit multiple times in a row, they get a more efficient code path.
+        LocalizedNumberFormatter withUnit = savedWithUnit;
+        if (withUnit == null || !Objects.equals(withUnit.resolve().unit, unit)) {
+            withUnit = new LocalizedNumberFormatter(this, KEY_UNIT, unit);
+            savedWithUnit = withUnit;
+        }
+        withUnit.formatImpl(fq, string);
+    }
+
     /**
      * @internal
      * @deprecated This API is ICU internal only. Use {@link FormattedNumber#nextPosition}
index 8e2319aeb5c945c1328a92c5a89eaecaa015384d..bfc0afe9650097ce0f0907efc236afffe3b51d2b 100644 (file)
@@ -346,25 +346,13 @@ public abstract class Precision implements Cloneable {
         if (this.mathContext.equals(mathContext)) {
             return this;
         }
-        Precision other = (Precision) this.clone();
+        Precision other = createCopy();
         other.mathContext = mathContext;
         return other;
     }
 
-    /**
-     * {@inheritDoc}
-     * @draft ICU 62
-     * @provisional This API might change or be removed in a future release.
-     */
-    @Override
-    public Object clone() {
-        try {
-            return super.clone();
-        } catch (CloneNotSupportedException e) {
-            // Should not happen since parent is Object
-            throw new AssertionError(e);
-        }
-    }
+    /** Package-private clone method */
+    abstract Precision createCopy();
 
     /**
      * @internal
@@ -566,6 +554,13 @@ public abstract class Precision implements Cloneable {
             value.roundToInfinity();
             value.setMinFraction(0);
         }
+
+        @Override
+        InfiniteRounderImpl createCopy() {
+            InfiniteRounderImpl copy = new InfiniteRounderImpl();
+            copy.mathContext = mathContext;
+            return copy;
+        }
     }
 
     static class FractionRounderImpl extends FractionPrecision {
@@ -582,6 +577,13 @@ public abstract class Precision implements Cloneable {
             value.roundToMagnitude(getRoundingMagnitudeFraction(maxFrac), mathContext);
             value.setMinFraction(Math.max(0, -getDisplayMagnitudeFraction(minFrac)));
         }
+
+        @Override
+        FractionRounderImpl createCopy() {
+            FractionRounderImpl copy = new FractionRounderImpl(minFrac, maxFrac);
+            copy.mathContext = mathContext;
+            return copy;
+        }
     }
 
     static class SignificantRounderImpl extends Precision {
@@ -611,6 +613,13 @@ public abstract class Precision implements Cloneable {
             assert quantity.isZeroish();
             quantity.setMinFraction(minSig - minInt);
         }
+
+        @Override
+        SignificantRounderImpl createCopy() {
+            SignificantRounderImpl copy = new SignificantRounderImpl(minSig, maxSig);
+            copy.mathContext = mathContext;
+            return copy;
+        }
     }
 
     static class FracSigRounderImpl extends Precision {
@@ -642,6 +651,13 @@ public abstract class Precision implements Cloneable {
             value.roundToMagnitude(roundingMag, mathContext);
             value.setMinFraction(Math.max(0, -displayMag));
         }
+
+        @Override
+        FracSigRounderImpl createCopy() {
+            FracSigRounderImpl copy = new FracSigRounderImpl(minFrac, maxFrac, minSig, maxSig);
+            copy.mathContext = mathContext;
+            return copy;
+        }
     }
 
     /**
@@ -659,6 +675,13 @@ public abstract class Precision implements Cloneable {
             value.roundToIncrement(increment, mathContext);
             value.setMinFraction(increment.scale());
         }
+
+        @Override
+        IncrementRounderImpl createCopy() {
+            IncrementRounderImpl copy = new IncrementRounderImpl(increment);
+            copy.mathContext = mathContext;
+            return copy;
+        }
     }
 
     /**
@@ -681,6 +704,13 @@ public abstract class Precision implements Cloneable {
             value.roundToMagnitude(-maxFrac, mathContext);
             value.setMinFraction(minFrac);
         }
+
+        @Override
+        IncrementOneRounderImpl createCopy() {
+            IncrementOneRounderImpl copy = new IncrementOneRounderImpl(increment, minFrac, maxFrac);
+            copy.mathContext = mathContext;
+            return copy;
+        }
     }
 
     /**
@@ -701,6 +731,13 @@ public abstract class Precision implements Cloneable {
             value.roundToNickel(-maxFrac, mathContext);
             value.setMinFraction(minFrac);
         }
+
+        @Override
+        IncrementFiveRounderImpl createCopy() {
+            IncrementFiveRounderImpl copy = new IncrementFiveRounderImpl(increment, minFrac, maxFrac);
+            copy.mathContext = mathContext;
+            return copy;
+        }
     }
 
     static class CurrencyRounderImpl extends CurrencyPrecision {
@@ -715,6 +752,13 @@ public abstract class Precision implements Cloneable {
             // Call .withCurrency() before .apply()!
             throw new AssertionError();
         }
+
+        @Override
+        CurrencyRounderImpl createCopy() {
+            CurrencyRounderImpl copy = new CurrencyRounderImpl(usage);
+            copy.mathContext = mathContext;
+            return copy;
+        }
     }
 
     private static int getRoundingMagnitudeFraction(int maxFrac) {
index 91d97d053bbc963848c7531bcbf271d2eba68627..49147f4f2d9054f1eaec8106406178693c3d4761 100644 (file)
@@ -27,7 +27,7 @@ import com.ibm.icu.text.NumberFormat;
  * @stable ICU 60
  * @see NumberFormatter
  */
-public class ScientificNotation extends Notation implements Cloneable {
+public class ScientificNotation extends Notation {
 
     int engineeringInterval;
     boolean requireMinInt;
@@ -62,7 +62,7 @@ public class ScientificNotation extends Notation implements Cloneable {
      */
     public ScientificNotation withMinExponentDigits(int minExponentDigits) {
         if (minExponentDigits >= 1 && minExponentDigits <= RoundingUtils.MAX_INT_FRAC_SIG) {
-            ScientificNotation other = (ScientificNotation) this.clone();
+            ScientificNotation other = createCopy();
             other.minExponentDigits = minExponentDigits;
             return other;
         } else {
@@ -87,23 +87,19 @@ public class ScientificNotation extends Notation implements Cloneable {
      * @see NumberFormatter
      */
     public ScientificNotation withExponentSignDisplay(SignDisplay exponentSignDisplay) {
-        ScientificNotation other = (ScientificNotation) this.clone();
+        ScientificNotation other = createCopy();
         other.exponentSignDisplay = exponentSignDisplay;
         return other;
     }
 
-    /**
-     * @draft ICU 60
-     * @provisional This API might change or be removed in a future release.
-     */
-    @Override
-    public Object clone() {
-        try {
-            return super.clone();
-        } catch (CloneNotSupportedException e) {
-            // Should not happen since parent is Object
-            throw new AssertionError(e);
-        }
+    /** Package-private clone method */
+    ScientificNotation createCopy() {
+        return new ScientificNotation(
+            engineeringInterval,
+            requireMinInt,
+            minExponentDigits,
+            exponentSignDisplay
+        );
     }
 
     /* package-private */ MicroPropsGenerator withLocaleData(
index a83bd1ba25921eeae18154e8cf909288b034af58..10a4e7596d93dc2064ca194e969abb0e8c63c988 100644 (file)
@@ -12,9 +12,14 @@ import java.text.AttributedCharacterIterator;
 import java.text.FieldPosition;
 import java.text.ParsePosition;
 
+import com.ibm.icu.impl.FormattedStringBuilder;
+import com.ibm.icu.impl.FormattedValueStringBuilderImpl;
+import com.ibm.icu.impl.Utility;
 import com.ibm.icu.impl.number.AffixUtils;
 import com.ibm.icu.impl.number.DecimalFormatProperties;
 import com.ibm.icu.impl.number.DecimalFormatProperties.ParseMode;
+import com.ibm.icu.impl.number.DecimalQuantity;
+import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
 import com.ibm.icu.impl.number.Padder;
 import com.ibm.icu.impl.number.Padder.PadPosition;
 import com.ibm.icu.impl.number.PatternStringParser;
@@ -708,9 +713,11 @@ public class DecimalFormat extends NumberFormat {
    */
   @Override
   public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) {
-    FormattedNumber output = formatter.format(number);
-    fieldPositionHelper(output, fieldPosition, result.length());
-    output.appendTo(result);
+    DecimalQuantity dq = new DecimalQuantity_DualStorageBCD(number);
+    FormattedStringBuilder string = new FormattedStringBuilder();
+    formatter.formatImpl(dq, string);
+    fieldPositionHelper(dq, string, fieldPosition, result.length());
+    Utility.appendTo(string, result);
     return result;
   }
 
@@ -721,9 +728,11 @@ public class DecimalFormat extends NumberFormat {
    */
   @Override
   public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition) {
-    FormattedNumber output = formatter.format(number);
-    fieldPositionHelper(output, fieldPosition, result.length());
-    output.appendTo(result);
+    DecimalQuantity dq = new DecimalQuantity_DualStorageBCD(number);
+    FormattedStringBuilder string = new FormattedStringBuilder();
+    formatter.formatImpl(dq, string);
+    fieldPositionHelper(dq, string, fieldPosition, result.length());
+    Utility.appendTo(string, result);
     return result;
   }
 
@@ -734,9 +743,11 @@ public class DecimalFormat extends NumberFormat {
    */
   @Override
   public StringBuffer format(BigInteger number, StringBuffer result, FieldPosition fieldPosition) {
-    FormattedNumber output = formatter.format(number);
-    fieldPositionHelper(output, fieldPosition, result.length());
-    output.appendTo(result);
+    DecimalQuantity dq = new DecimalQuantity_DualStorageBCD(number);
+    FormattedStringBuilder string = new FormattedStringBuilder();
+    formatter.formatImpl(dq, string);
+    fieldPositionHelper(dq, string, fieldPosition, result.length());
+    Utility.appendTo(string, result);
     return result;
   }
 
@@ -748,9 +759,11 @@ public class DecimalFormat extends NumberFormat {
   @Override
   public StringBuffer format(
       java.math.BigDecimal number, StringBuffer result, FieldPosition fieldPosition) {
-    FormattedNumber output = formatter.format(number);
-    fieldPositionHelper(output, fieldPosition, result.length());
-    output.appendTo(result);
+    DecimalQuantity dq = new DecimalQuantity_DualStorageBCD(number);
+    FormattedStringBuilder string = new FormattedStringBuilder();
+    formatter.formatImpl(dq, string);
+    fieldPositionHelper(dq, string, fieldPosition, result.length());
+    Utility.appendTo(string, result);
     return result;
   }
 
@@ -761,9 +774,11 @@ public class DecimalFormat extends NumberFormat {
    */
   @Override
   public StringBuffer format(BigDecimal number, StringBuffer result, FieldPosition fieldPosition) {
-    FormattedNumber output = formatter.format(number);
-    fieldPositionHelper(output, fieldPosition, result.length());
-    output.appendTo(result);
+    DecimalQuantity dq = new DecimalQuantity_DualStorageBCD(number);
+    FormattedStringBuilder string = new FormattedStringBuilder();
+    formatter.formatImpl(dq, string);
+    fieldPositionHelper(dq, string, fieldPosition, result.length());
+    Utility.appendTo(string, result);
     return result;
   }
 
@@ -792,12 +807,14 @@ public class DecimalFormat extends NumberFormat {
     // because its caching mechanism will not provide any benefit here.
     DecimalFormatSymbols localSymbols = (DecimalFormatSymbols) symbols.clone();
     localSymbols.setCurrency(currAmt.getCurrency());
-    FormattedNumber output = formatter
-            .symbols(localSymbols)
+
+    DecimalQuantity dq = new DecimalQuantity_DualStorageBCD(currAmt.getNumber());
+    FormattedStringBuilder string = new FormattedStringBuilder();
+    formatter.symbols(localSymbols)
             .unit(currAmt.getCurrency())
-            .format(currAmt.getNumber());
-    fieldPositionHelper(output, fieldPosition, result.length());
-    output.appendTo(result);
+            .formatImpl(dq, string);
+    fieldPositionHelper(dq, string, fieldPosition, result.length());
+    Utility.appendTo(string, result);
     return result;
   }
 
@@ -2585,11 +2602,13 @@ public synchronized void setParseStrictMode(ParseMode parseMode) {
     PatternStringParser.parseToExistingProperties(pattern, properties, ignoreRounding);
   }
 
-  static void fieldPositionHelper(FormattedNumber formatted, FieldPosition fieldPosition, int offset) {
+  static void fieldPositionHelper(
+          DecimalQuantity dq, FormattedStringBuilder string, FieldPosition fieldPosition, int offset) {
       // always return first occurrence:
       fieldPosition.setBeginIndex(0);
       fieldPosition.setEndIndex(0);
-      boolean found = formatted.nextFieldPosition(fieldPosition);
+      dq.populateUFieldPosition(fieldPosition);
+      boolean found = FormattedValueStringBuilderImpl.nextFieldPosition(string, fieldPosition);;
       if (found && offset != 0) {
           fieldPosition.setBeginIndex(fieldPosition.getBeginIndex() + offset);
           fieldPosition.setEndIndex(fieldPosition.getEndIndex() + offset);
index fb7799c9bdaddb93051c1b01f24b87d2b19df9d4..b9876f777856d5a452001ccd23883e6c9e87ba0d 100644 (file)
@@ -31,13 +31,16 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import com.ibm.icu.impl.DontCareFieldPosition;
 import com.ibm.icu.impl.FormattedStringBuilder;
+import com.ibm.icu.impl.FormattedValueStringBuilderImpl;
 import com.ibm.icu.impl.ICUData;
 import com.ibm.icu.impl.ICUResourceBundle;
 import com.ibm.icu.impl.SimpleCache;
 import com.ibm.icu.impl.SimpleFormatterImpl;
+import com.ibm.icu.impl.Utility;
+import com.ibm.icu.impl.number.DecimalQuantity;
+import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
 import com.ibm.icu.impl.number.LongNameHandler;
 import com.ibm.icu.impl.number.RoundingUtils;
-import com.ibm.icu.number.FormattedNumber;
 import com.ibm.icu.number.IntegerWidth;
 import com.ibm.icu.number.LocalizedNumberFormatter;
 import com.ibm.icu.number.NumberFormatter;
@@ -320,9 +323,10 @@ public class MeasureFormat extends UFormat {
         } else if (obj instanceof Measure[]) {
             formatMeasuresInternal(toAppendTo, fpos, (Measure[]) obj);
         } else if (obj instanceof Measure) {
-            FormattedNumber result = formatMeasure((Measure) obj);
-            result.nextFieldPosition(fpos); // No offset: toAppendTo.length() is considered below
-            result.appendTo(toAppendTo);
+            FormattedStringBuilder result = formatMeasure((Measure) obj);
+            // No offset: toAppendTo.length() is considered below
+            FormattedValueStringBuilderImpl.nextFieldPosition(result, fpos);
+            Utility.appendTo(result, toAppendTo);
         } else {
             throw new IllegalArgumentException(obj.toString());
         }
@@ -386,11 +390,13 @@ public class MeasureFormat extends UFormat {
             MeasureUnit perUnit,
             StringBuilder appendTo,
             FieldPosition pos) {
-        FormattedNumber result = getUnitFormatterFromCache(NUMBER_FORMATTER_STANDARD,
-                measure.getUnit(),
-                perUnit).format(measure.getNumber());
-        DecimalFormat.fieldPositionHelper(result, pos, appendTo.length());
-        result.appendTo(appendTo);
+        DecimalQuantity dq = new DecimalQuantity_DualStorageBCD(measure.getNumber());
+        FormattedStringBuilder string = new FormattedStringBuilder();
+        getUnitFormatterFromCache(
+            NUMBER_FORMATTER_STANDARD, measure.getUnit(), perUnit
+        ).formatImpl(dq, string);
+        DecimalFormat.fieldPositionHelper(dq, string, pos, appendTo.length());
+        Utility.appendTo(string, appendTo);
         return appendTo;
     }
 
@@ -433,9 +439,9 @@ public class MeasureFormat extends UFormat {
             return;
         }
         if (measures.length == 1) {
-            FormattedNumber result = formatMeasure(measures[0]);
-            result.nextFieldPosition(fieldPosition);
-            result.appendTo(appendTo);
+            FormattedStringBuilder result = formatMeasure(measures[0]);
+            FormattedValueStringBuilderImpl.nextFieldPosition(result, fieldPosition);
+            Utility.appendTo(result, appendTo);
             return;
         }
 
@@ -768,20 +774,26 @@ public class MeasureFormat extends UFormat {
 
     /// END NUMBER FORMATTER CACHING MACHINERY ///
 
-    private FormattedNumber formatMeasure(Measure measure) {
+    private FormattedStringBuilder formatMeasure(Measure measure) {
         MeasureUnit unit = measure.getUnit();
+        DecimalQuantity dq = new DecimalQuantity_DualStorageBCD(measure.getNumber());
+        FormattedStringBuilder string = new FormattedStringBuilder();
         if (unit instanceof Currency) {
-            return getUnitFormatterFromCache(NUMBER_FORMATTER_CURRENCY, unit, null)
-                    .format(measure.getNumber());
+            getUnitFormatterFromCache(NUMBER_FORMATTER_CURRENCY, unit, null)
+                    .formatImpl(dq, string);
         } else {
-            return getUnitFormatterFromCache(NUMBER_FORMATTER_STANDARD, unit, null)
-                    .format(measure.getNumber());
+            getUnitFormatterFromCache(NUMBER_FORMATTER_STANDARD, unit, null)
+                    .formatImpl(dq, string);
         }
+        return string;
     }
 
-    private FormattedNumber formatMeasureInteger(Measure measure) {
-        return getUnitFormatterFromCache(NUMBER_FORMATTER_INTEGER, measure.getUnit(), null)
-                .format(measure.getNumber());
+    private FormattedStringBuilder formatMeasureInteger(Measure measure) {
+        DecimalQuantity dq = new DecimalQuantity_DualStorageBCD(measure.getNumber());
+        FormattedStringBuilder string = new FormattedStringBuilder();
+        getUnitFormatterFromCache(NUMBER_FORMATTER_INTEGER, measure.getUnit(), null)
+                .formatImpl(dq, string);
+        return string;
     }
 
     private void formatMeasuresSlowTrack(
@@ -797,14 +809,14 @@ public class MeasureFormat extends UFormat {
 
         int fieldPositionFoundIndex = -1;
         for (int i = 0; i < measures.length; ++i) {
-            FormattedNumber result;
+            FormattedStringBuilder result;
             if (i == measures.length - 1) {
                 result = formatMeasure(measures[i]);
             } else {
                 result = formatMeasureInteger(measures[i]);
             }
             if (fieldPositionFoundIndex == -1) {
-                result.nextFieldPosition(fpos);
+                FormattedValueStringBuilderImpl.nextFieldPosition(result, fpos);
                 if (fpos.getEndIndex() != 0) {
                     fieldPositionFoundIndex = i;
                 }
index 54c1d98e630cc7a80708df91fb697fa8746f2cfc..ae3eab4008cff1449bbc18f35e179f80080a5cfa 100644 (file)
@@ -46,6 +46,7 @@ import com.ibm.icu.number.Precision;
 import com.ibm.icu.number.Scale;
 import com.ibm.icu.number.ScientificNotation;
 import com.ibm.icu.number.UnlocalizedNumberFormatter;
+import com.ibm.icu.text.ConstrainedFieldPosition;
 import com.ibm.icu.text.DecimalFormatSymbols;
 import com.ibm.icu.text.NumberFormat;
 import com.ibm.icu.text.NumberingSystem;
@@ -2585,9 +2586,10 @@ public class NumberFormatterApiTest {
         assertNumberFieldPositions(message, fmtd, expectedFieldPositions);
 
         // Test the iteration functionality of nextFieldPosition
-        FieldPosition actual = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
+        ConstrainedFieldPosition actual = new ConstrainedFieldPosition();
+        actual.constrainField(NumberFormat.Field.GROUPING_SEPARATOR);
         int i = 1;
-        while (fmtd.nextFieldPosition(actual)) {
+        while (fmtd.nextPosition(actual)) {
             Object[] cas = expectedFieldPositions[i++];
             NumberFormat.Field expectedField = (NumberFormat.Field) cas[0];
             int expectedBeginIndex = (Integer) cas[1];
@@ -2596,22 +2598,23 @@ public class NumberFormatterApiTest {
             assertEquals(
                     "Next for grouping, field, case #" + i,
                     expectedField,
-                    actual.getFieldAttribute());
+                    actual.getField());
             assertEquals(
                     "Next for grouping, begin index, case #" + i,
                     expectedBeginIndex,
-                    actual.getBeginIndex());
+                    actual.getStart());
             assertEquals(
                     "Next for grouping, end index, case #" + i,
                     expectedEndIndex,
-                    actual.getEndIndex());
+                    actual.getLimit());
         }
         assertEquals("Should have seen all grouping separators", 4, i);
 
         // Make sure strings without fraction do not contain fraction field
-        actual = new FieldPosition(NumberFormat.Field.FRACTION);
+        actual.reset();
+        actual.constrainField(NumberFormat.Field.FRACTION);
         fmtd = NumberFormatter.withLocale(ULocale.ENGLISH).format(5);
-        assertFalse("No fraction part in an integer", fmtd.nextFieldPosition(actual));
+        assertFalse("No fraction part in an integer", fmtd.nextPosition(actual));
     }
 
     @Test