import cl @56673
diff --git a/i18n/decimfmt.cpp b/i18n/decimfmt.cpp
index a472088..dd2e809 100644
--- a/i18n/decimfmt.cpp
+++ b/i18n/decimfmt.cpp
@@ -60,6 +60,9 @@
#include <stdio.h>
+#define LOGI(...) printf("<I>"); printf(__VA_ARGS__); printf("</I>");
+
+
U_NAMESPACE_BEGIN
//#define FMT_DEBUG
@@ -1299,6 +1302,7 @@
return result;
}
+// BEGIN android-changed
/**
* Parses the given text as either a number or a currency amount.
* @param text the string to parse
@@ -1315,9 +1319,47 @@
Formattable& result,
ParsePosition& parsePosition,
UBool parseCurrency) const {
+ bool resultAssigned;
+ int scale;
+ DigitList digits;
+ parse(text, resultAssigned, result, parsePosition, parseCurrency, digits, scale);
+
+ if(!resultAssigned) {
+ result.setDouble(digits.getDouble() / scale);
+ }
+
+}
+
+/**
+ * Parses the given text as either a number or a currency amount.
+ * @param text the string to parse
+ * @param resultAssigned indicates whether or not the param result is assigned
+ * @param result output parameter for the parsing result
+ * ATTENTION: result is assigned ONLY for types long and int64
+ * @param parsePosition input-output position; on input, the
+ * position within text to match; must have 0 <= pos.getIndex() <
+ * text.length(); on output, the position after the last matched
+ * character. If the parse fails, the position in unchanged upon
+ * output.
+ * @param parseCurrency if true, a currency amount is parsed;
+ * otherwise a Number is parsed
+ * @param digits The DigitList that represents the result will be returned
+ * @param scale the scale with which the number in the DigitList
+ * has to be scaled
+ * ATTENTION: list and scale are only returned when result was not assigned
+ */
+void DecimalFormat::parse(const UnicodeString& text,
+ bool& resultAssigned,
+ Formattable& result,
+ ParsePosition& parsePosition,
+ UBool parseCurrency,
+ DigitList& digits,
+ int& scale) const {
int32_t backup;
int32_t i = backup = parsePosition.getIndex();
+ resultAssigned = true;
+
// Handle NaN as a special case:
// Skip padding characters, if around prefix
@@ -1347,7 +1389,6 @@
UBool status[fgStatusLength];
UChar curbuf[4];
UChar* currency = parseCurrency ? curbuf : NULL;
- DigitList digits;
if (!subparse(text, parsePosition, digits, status, currency)) {
parsePosition.setIndex(backup);
@@ -1359,7 +1400,6 @@
double inf = uprv_getInfinity();
result.setDouble(digits.fIsPositive ? inf : -inf);
}
-
else {
// Do as much of the multiplier conversion as possible without
// losing accuracy.
@@ -1393,11 +1433,13 @@
else { // else handle the remainder
result.setDouble(((double)n) / mult);
}
- }
+ }/*
+ else if (digits.fitsIntoDouble()) {
+ result.setDouble(digits.getDouble() / mult);LOGI("fits into neither\n");
+ }*/
else {
- // Handle non-integral or very large values
- // Dividing by one is okay and not that costly.
- result.setDouble(digits.getDouble() / mult);
+ scale = mult;
+ resultAssigned = false;
}
}
@@ -1408,7 +1450,7 @@
U_ASSERT(U_SUCCESS(ec)); // should always succeed
}
}
-
+// END android-changed
/*
This is an old implimentation that was preparing for 64-bit numbers in ICU.
diff --git a/i18n/digitlst.cpp b/i18n/digitlst.cpp
index 39e69fd..83f84ca 100644
--- a/i18n/digitlst.cpp
+++ b/i18n/digitlst.cpp
@@ -61,12 +61,19 @@
U_NAMESPACE_BEGIN
+// BEGIN android-added
+// capacity of a dynamically allocated fDecimalDigits buffer
+int fBufferSize = 0;
+// END android-added
// -------------------------------------
// default constructor
DigitList::DigitList()
{
+ // BEGIN android-added
+ fDecimalDigits = fDecimalDigitsBuffer;
+ // END android-added
fDigits = fDecimalDigits + 1; // skip the decimal
clear();
}
@@ -75,13 +82,32 @@
DigitList::~DigitList()
{
+ // BEGIN android-added
+ if (fDecimalDigits != fDecimalDigitsBuffer) free(fDecimalDigits);
+ // END android-added
}
+// BEGIN android-added
+// -------------------------------------
+// capacity constructor
+
+DigitList::DigitList(int capacity)
+{
+ fBufferSize = capacity;
+ fDecimalDigits = (char *) malloc(capacity);
+ fDigits = fDecimalDigits + 1; // skip the decimal
+ clear();
+}
+// END android-added
+
// -------------------------------------
// copy constructor
DigitList::DigitList(const DigitList &other)
{
+ // BEGIN android-added
+ fDecimalDigits = fDecimalDigitsBuffer;
+ // END android-added
fDigits = fDecimalDigits + 1; // skip the decimal
*this = other;
}
@@ -98,6 +124,14 @@
fCount = other.fCount;
fIsPositive = other.fIsPositive;
fRoundingMode = other.fRoundingMode;
+ // BEGIN android-added
+ if (other.fDecimalDigits != other.fDecimalDigitsBuffer)
+ {
+ fBufferSize = other.fBufferSize;
+ fDecimalDigits = (char *) malloc(fBufferSize);
+ fDigits = fDecimalDigits + 1; // skip the decimal
+ }
+ // END android-added
uprv_strncpy(fDigits, other.fDigits, fCount);
}
return *this;
diff --git a/i18n/digitlst.h b/i18n/digitlst.h
index e6266dd..eae501c 100644
--- a/i18n/digitlst.h
+++ b/i18n/digitlst.h
@@ -71,6 +71,14 @@
DigitList();
~DigitList();
+ // BEGIN android-added
+ /* capacity constructor
+ * @param capacity The size of the digit list buffer
+ * @return the newly created object.
+ */
+ DigitList(int capacity);
+ // END android-added
+
/* copy constructor
* @param DigitList The object to be copied.
* @return the newly created object.
@@ -227,8 +235,14 @@
private:
+ // BEGIN android-changed
/* One character before fDigits for the decimal*/
- char fDecimalDigits[MAX_DEC_DIGITS + 1];
+ char *fDecimalDigits;
+
+ char fDecimalDigitsBuffer[MAX_DEC_DIGITS + 1];
+
+ int fBufferSize;
+ // END android-changed
/**
* Round the representation to the given number of digits.
diff --git a/i18n/unicode/decimfmt.h b/i18n/unicode/decimfmt.h
index 9789043..92c96bf 100644
--- a/i18n/unicode/decimfmt.h
+++ b/i18n/unicode/decimfmt.h
@@ -907,6 +907,15 @@
*/
UnicodeString& format(int64_t number,
UnicodeString& appendTo) const;
+
+ // BEGIN android-added
+ UnicodeString& subformat(UnicodeString& appendTo,
+ FieldPosition& fieldPosition,
+ AttrBuffer attrBuffer,
+ DigitList& digits,
+ UBool isInteger) const;
+ // END android-changed
+
/**
* Parse the given string using this object's choices. The method
* does string comparisons to try to find an optimal match.
@@ -943,6 +952,36 @@
Formattable& result,
UErrorCode& status) const;
+ // BEGIN android-added
+ // A way to access parsing directly as workaround for missing
+ // BigNum parsing
+ /**
+ * Parses the given text as either a number or a currency amount.
+ * @param text the string to parse
+ * @param resultAssigned indicates whether or not the param result is assigned
+ * @param result output parameter for the result
+ * ATTENTION: result is assigned ONLY for types long and int64
+ * @param parsePosition input-output position; on input, the
+ * position within text to match; must have 0 <= pos.getIndex() <
+ * text.length(); on output, the position after the last matched
+ * character. If the parse fails, the position in unchanged upon
+ * output.
+ * @param parseCurrency if true, a currency amount is parsed;
+ * otherwise a Number is parsed
+ * @param digits The DigitList that represents the result will be returned
+ * @param scale the scale with which the number in the DigitList
+ * has to be scaled
+ * ATTENTION: list and scale are only returned when result was not assigned
+ */
+ virtual void parse(const UnicodeString& text,
+ bool& resultAssigned,
+ Formattable& result,
+ ParsePosition& parsePosition,
+ UBool parseCurrency,
+ DigitList& digits,
+ int& scale) const;
+ // END android-added
+
/**
* Parses text from the given string as a currency amount. Unlike
* the parse() method, this method will attempt to parse a generic
@@ -1726,11 +1765,13 @@
DigitList& digits,
UBool isInteger) const;
- UnicodeString& subformat(UnicodeString& appendTo,
- FieldPosition& fieldPosition,
- AttrBuffer attrBuffer,
- DigitList& digits,
- UBool isInteger) const;
+ // BEGIN android-removed
+ // UnicodeString& subformat(UnicodeString& appendTo,
+ // FieldPosition& fieldPosition,
+ // AttrBuffer attrBuffer,
+ // DigitList& digits,
+ // UBool isInteger) const;
+ // END android-removed
void parse(const UnicodeString& text,
Formattable& result,