Index: icu46/source/i18n/choicfmt.cpp |
=================================================================== |
--- icu46/source/i18n/choicfmt.cpp (revision 0) |
+++ icu46/source/i18n/choicfmt.cpp (revision 0) |
@@ -0,0 +1,764 @@ |
+/* |
+******************************************************************************* |
+* Copyright (C) 1997-2009, International Business Machines Corporation and * |
+* others. All Rights Reserved. * |
+******************************************************************************* |
+* |
+* File CHOICFMT.CPP |
+* |
+* Modification History: |
+* |
+* Date Name Description |
+* 02/19/97 aliu Converted from java. |
+* 03/20/97 helena Finished first cut of implementation and got rid |
+* of nextDouble/previousDouble and replaced with |
+* boolean array. |
+* 4/10/97 aliu Clean up. Modified to work on AIX. |
+* 06/04/97 helena Fixed applyPattern(), toPattern() and not to include |
+* wchar.h. |
+* 07/09/97 helena Made ParsePosition into a class. |
+* 08/06/97 nos removed overloaded constructor, fixed 'format(array)' |
+* 07/22/98 stephen JDK 1.2 Sync - removed UBool array (doubleFlags) |
+* 02/22/99 stephen Removed character literals for EBCDIC safety |
+******************************************************************************** |
+*/ |
+ |
+#include "unicode/utypes.h" |
+ |
+#if !UCONFIG_NO_FORMATTING |
+ |
+#include "unicode/choicfmt.h" |
+#include "unicode/numfmt.h" |
+#include "unicode/locid.h" |
+#include "cpputils.h" |
+#include "cstring.h" |
+#include "putilimp.h" |
+#include <stdio.h> |
+#include <float.h> |
+ |
+// ***************************************************************************** |
+// class ChoiceFormat |
+// ***************************************************************************** |
+ |
+U_NAMESPACE_BEGIN |
+ |
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ChoiceFormat) |
+ |
+// Special characters used by ChoiceFormat. There are two characters |
+// used interchangeably to indicate <=. Either is parsed, but only |
+// LESS_EQUAL is generated by toPattern(). |
+#define SINGLE_QUOTE ((UChar)0x0027) /*'*/ |
+#define LESS_THAN ((UChar)0x003C) /*<*/ |
+#define LESS_EQUAL ((UChar)0x0023) /*#*/ |
+#define LESS_EQUAL2 ((UChar)0x2264) |
+#define VERTICAL_BAR ((UChar)0x007C) /*|*/ |
+#define MINUS ((UChar)0x002D) /*-*/ |
+ |
+#ifdef INFINITY |
+#undef INFINITY |
+#endif |
+#define INFINITY ((UChar)0x221E) |
+ |
+static const UChar gPositiveInfinity[] = {INFINITY, 0}; |
+static const UChar gNegativeInfinity[] = {MINUS, INFINITY, 0}; |
+#define POSITIVE_INF_STRLEN 1 |
+#define NEGATIVE_INF_STRLEN 2 |
+ |
+// ------------------------------------- |
+// Creates a ChoiceFormat instance based on the pattern. |
+ |
+ChoiceFormat::ChoiceFormat(const UnicodeString& newPattern, |
+ UErrorCode& status) |
+: fChoiceLimits(0), |
+ fClosures(0), |
+ fChoiceFormats(0), |
+ fCount(0) |
+{ |
+ applyPattern(newPattern, status); |
+} |
+ |
+// ------------------------------------- |
+// Creates a ChoiceFormat instance with the limit array and |
+// format strings for each limit. |
+ |
+ChoiceFormat::ChoiceFormat(const double* limits, |
+ const UnicodeString* formats, |
+ int32_t cnt ) |
+: fChoiceLimits(0), |
+ fClosures(0), |
+ fChoiceFormats(0), |
+ fCount(0) |
+{ |
+ setChoices(limits, formats, cnt ); |
+} |
+ |
+// ------------------------------------- |
+ |
+ChoiceFormat::ChoiceFormat(const double* limits, |
+ const UBool* closures, |
+ const UnicodeString* formats, |
+ int32_t cnt ) |
+: fChoiceLimits(0), |
+ fClosures(0), |
+ fChoiceFormats(0), |
+ fCount(0) |
+{ |
+ setChoices(limits, closures, formats, cnt ); |
+} |
+ |
+// ------------------------------------- |
+// copy constructor |
+ |
+ChoiceFormat::ChoiceFormat(const ChoiceFormat& that) |
+: NumberFormat(that), |
+ fChoiceLimits(0), |
+ fClosures(0), |
+ fChoiceFormats(0) |
+{ |
+ *this = that; |
+} |
+ |
+// ------------------------------------- |
+// Private constructor that creates a |
+// ChoiceFormat instance based on the |
+// pattern and populates UParseError |
+ |
+ChoiceFormat::ChoiceFormat(const UnicodeString& newPattern, |
+ UParseError& parseError, |
+ UErrorCode& status) |
+: fChoiceLimits(0), |
+ fClosures(0), |
+ fChoiceFormats(0), |
+ fCount(0) |
+{ |
+ applyPattern(newPattern,parseError, status); |
+} |
+// ------------------------------------- |
+ |
+UBool |
+ChoiceFormat::operator==(const Format& that) const |
+{ |
+ if (this == &that) return TRUE; |
+ if (!NumberFormat::operator==(that)) return FALSE; |
+ ChoiceFormat& thatAlias = (ChoiceFormat&)that; |
+ if (fCount != thatAlias.fCount) return FALSE; |
+ // Checks the limits, the corresponding format string and LE or LT flags. |
+ // LE means less than and equal to, LT means less than. |
+ for (int32_t i = 0; i < fCount; i++) { |
+ if ((fChoiceLimits[i] != thatAlias.fChoiceLimits[i]) || |
+ (fClosures[i] != thatAlias.fClosures[i]) || |
+ (fChoiceFormats[i] != thatAlias.fChoiceFormats[i])) |
+ return FALSE; |
+ } |
+ return TRUE; |
+} |
+ |
+// ------------------------------------- |
+// copy constructor |
+ |
+const ChoiceFormat& |
+ChoiceFormat::operator=(const ChoiceFormat& that) |
+{ |
+ if (this != &that) { |
+ NumberFormat::operator=(that); |
+ fCount = that.fCount; |
+ uprv_free(fChoiceLimits); |
+ fChoiceLimits = NULL; |
+ uprv_free(fClosures); |
+ fClosures = NULL; |
+ delete [] fChoiceFormats; |
+ fChoiceFormats = NULL; |
+ |
+ fChoiceLimits = (double*) uprv_malloc( sizeof(double) * fCount); |
+ fClosures = (UBool*) uprv_malloc( sizeof(UBool) * fCount); |
+ fChoiceFormats = new UnicodeString[fCount]; |
+ |
+ // check for memory allocation error |
+ if (!fChoiceLimits || !fClosures || !fChoiceFormats) { |
+ if (fChoiceLimits) { |
+ uprv_free(fChoiceLimits); |
+ fChoiceLimits = NULL; |
+ } |
+ if (fClosures) { |
+ uprv_free(fClosures); |
+ fClosures = NULL; |
+ } |
+ if (fChoiceFormats) { |
+ delete[] fChoiceFormats; |
+ fChoiceFormats = NULL; |
+ } |
+ } else { |
+ uprv_arrayCopy(that.fChoiceLimits, fChoiceLimits, fCount); |
+ uprv_arrayCopy(that.fClosures, fClosures, fCount); |
+ uprv_arrayCopy(that.fChoiceFormats, fChoiceFormats, fCount); |
+ } |
+ } |
+ return *this; |
+} |
+ |
+// ------------------------------------- |
+ |
+ChoiceFormat::~ChoiceFormat() |
+{ |
+ uprv_free(fChoiceLimits); |
+ fChoiceLimits = NULL; |
+ uprv_free(fClosures); |
+ fClosures = NULL; |
+ delete [] fChoiceFormats; |
+ fChoiceFormats = NULL; |
+ fCount = 0; |
+} |
+ |
+/** |
+ * Convert a string to a double value |
+ */ |
+double |
+ChoiceFormat::stod(const UnicodeString& string) |
+{ |
+ char source[256]; |
+ char* end; |
+ |
+ string.extract(0, string.length(), source, (int32_t)sizeof(source), US_INV); /* invariant codepage */ |
+ return uprv_strtod(source,&end); |
+} |
+ |
+// ------------------------------------- |
+ |
+/** |
+ * Convert a double value to a string without the overhead of ICU. |
+ */ |
+UnicodeString& |
+ChoiceFormat::dtos(double value, |
+ UnicodeString& string) |
+{ |
+ /* Buffer to contain the digits and any extra formatting stuff. */ |
+ char temp[DBL_DIG + 16]; |
+ char *itrPtr = temp; |
+ char *expPtr; |
+ |
+ sprintf(temp, "%.*g", DBL_DIG, value); |
+ |
+ /* Find and convert the decimal point. |
+ Using setlocale on some machines will cause sprintf to use a comma for certain locales. |
+ */ |
+ while (*itrPtr && (*itrPtr == '-' || isdigit(*itrPtr))) { |
+ itrPtr++; |
+ } |
+ if (*itrPtr != 0 && *itrPtr != 'e') { |
+ /* We reached something that looks like a decimal point. |
+ In case someone used setlocale(), which changes the decimal point. */ |
+ *itrPtr = '.'; |
+ itrPtr++; |
+ } |
+ /* Search for the exponent */ |
+ while (*itrPtr && *itrPtr != 'e') { |
+ itrPtr++; |
+ } |
+ if (*itrPtr == 'e') { |
+ itrPtr++; |
+ /* Verify the exponent sign */ |
+ if (*itrPtr == '+' || *itrPtr == '-') { |
+ itrPtr++; |
+ } |
+ /* Remove leading zeros. You will see this on Windows machines. */ |
+ expPtr = itrPtr; |
+ while (*itrPtr == '0') { |
+ itrPtr++; |
+ } |
+ if (*itrPtr && expPtr != itrPtr) { |
+ /* Shift the exponent without zeros. */ |
+ while (*itrPtr) { |
+ *(expPtr++) = *(itrPtr++); |
+ } |
+ // NULL terminate |
+ *expPtr = 0; |
+ } |
+ } |
+ |
+ string = UnicodeString(temp, -1, US_INV); /* invariant codepage */ |
+ return string; |
+} |
+ |
+// ------------------------------------- |
+// calls the overloaded applyPattern method. |
+ |
+void |
+ChoiceFormat::applyPattern(const UnicodeString& pattern, |
+ UErrorCode& status) |
+{ |
+ UParseError parseError; |
+ applyPattern(pattern, parseError, status); |
+} |
+ |
+// ------------------------------------- |
+// Applies the pattern to this ChoiceFormat instance. |
+ |
+void |
+ChoiceFormat::applyPattern(const UnicodeString& pattern, |
+ UParseError& parseError, |
+ UErrorCode& status) |
+{ |
+ if (U_FAILURE(status)) |
+ { |
+ return; |
+ } |
+ |
+ // Clear error struct |
+ parseError.offset = -1; |
+ parseError.preContext[0] = parseError.postContext[0] = (UChar)0; |
+ |
+ // Perform 2 passes. The first computes the number of limits in |
+ // this pattern (fCount), which is 1 more than the number of |
+ // literal VERTICAL_BAR characters. |
+ int32_t count = 1; |
+ int32_t i; |
+ for (i=0; i<pattern.length(); ++i) { |
+ UChar c = pattern[i]; |
+ if (c == SINGLE_QUOTE) { |
+ // Skip over the entire quote, including embedded |
+ // contiguous pairs of SINGLE_QUOTE. |
+ for (;;) { |
+ do { |
+ ++i; |
+ } while (i<pattern.length() && |
+ pattern[i] != SINGLE_QUOTE); |
+ if ((i+1)<pattern.length() && |
+ pattern[i+1] == SINGLE_QUOTE) { |
+ // SINGLE_QUOTE pair; skip over it |
+ ++i; |
+ } else { |
+ break; |
+ } |
+ } |
+ } else if (c == VERTICAL_BAR) { |
+ ++count; |
+ } |
+ } |
+ |
+ // Allocate the required storage. |
+ double *newLimits = (double*) uprv_malloc( sizeof(double) * count); |
+ /* test for NULL */ |
+ if (newLimits == 0) { |
+ status = U_MEMORY_ALLOCATION_ERROR; |
+ return; |
+ } |
+ UBool *newClosures = (UBool*) uprv_malloc( sizeof(UBool) * count); |
+ /* test for NULL */ |
+ if (newClosures == 0) { |
+ status = U_MEMORY_ALLOCATION_ERROR; |
+ uprv_free(newLimits); |
+ return; |
+ } |
+ UnicodeString *newFormats = new UnicodeString[count]; |
+ /* test for NULL */ |
+ if (newFormats == 0) { |
+ status = U_MEMORY_ALLOCATION_ERROR; |
+ uprv_free(newLimits); |
+ uprv_free(newClosures); |
+ return; |
+ } |
+ |
+ // Perform the second pass |
+ int32_t k = 0; // index into newXxx[] arrays |
+ UnicodeString buf; // scratch buffer |
+ UBool inQuote = FALSE; |
+ UBool inNumber = TRUE; // TRUE before < or #, FALSE after |
+ |
+ for (i=0; i<pattern.length(); ++i) { |
+ UChar c = pattern[i]; |
+ if (c == SINGLE_QUOTE) { |
+ // Check for SINGLE_QUOTE pair indicating a literal quote |
+ if ((i+1) < pattern.length() && |
+ pattern[i+1] == SINGLE_QUOTE) { |
+ buf += SINGLE_QUOTE; |
+ ++i; |
+ } else { |
+ inQuote = !inQuote; |
+ } |
+ } else if (inQuote) { |
+ buf += c; |
+ } else if (c == LESS_THAN || c == LESS_EQUAL || c == LESS_EQUAL2) { |
+ if (!inNumber || buf.length() == 0) { |
+ goto error; |
+ } |
+ inNumber = FALSE; |
+ |
+ double limit; |
+ buf.trim(); |
+ if (!buf.compare(gPositiveInfinity, POSITIVE_INF_STRLEN)) { |
+ limit = uprv_getInfinity(); |
+ } else if (!buf.compare(gNegativeInfinity, NEGATIVE_INF_STRLEN)) { |
+ limit = -uprv_getInfinity(); |
+ } else { |
+ limit = stod(buf); |
+ } |
+ |
+ if (k == count) { |
+ // This shouldn't happen. If it does, it means that |
+ // the count determined in the first pass did not |
+ // match the number of elements found in the second |
+ // pass. |
+ goto error; |
+ } |
+ newLimits[k] = limit; |
+ newClosures[k] = (c == LESS_THAN); |
+ |
+ if (k > 0 && limit <= newLimits[k-1]) { |
+ // Each limit must be strictly > than the previous |
+ // limit. One exception: Two subsequent limits may be |
+ // == if the first closure is FALSE and the second |
+ // closure is TRUE. This places the limit value in |
+ // the second interval. |
+ if (!(limit == newLimits[k-1] && |
+ !newClosures[k-1] && |
+ newClosures[k])) { |
+ goto error; |
+ } |
+ } |
+ |
+ buf.truncate(0); |
+ } else if (c == VERTICAL_BAR) { |
+ if (inNumber) { |
+ goto error; |
+ } |
+ inNumber = TRUE; |
+ |
+ newFormats[k] = buf; |
+ ++k; |
+ buf.truncate(0); |
+ } else { |
+ buf += c; |
+ } |
+ } |
+ |
+ if (k != (count-1) || inNumber || inQuote) { |
+ goto error; |
+ } |
+ newFormats[k] = buf; |
+ |
+ // Don't modify this object until the parse succeeds |
+ uprv_free(fChoiceLimits); |
+ uprv_free(fClosures); |
+ delete[] fChoiceFormats; |
+ fCount = count; |
+ fChoiceLimits = newLimits; |
+ fClosures = newClosures; |
+ fChoiceFormats = newFormats; |
+ return; |
+ |
+error: |
+ status = U_ILLEGAL_ARGUMENT_ERROR; |
+ syntaxError(pattern,i,parseError); |
+ uprv_free(newLimits); |
+ uprv_free(newClosures); |
+ delete[] newFormats; |
+ return; |
+ |
+} |
+// ------------------------------------- |
+// Reconstruct the original input pattern. |
+ |
+UnicodeString& |
+ChoiceFormat::toPattern(UnicodeString& result) const |
+{ |
+ result.remove(); |
+ for (int32_t i = 0; i < fCount; ++i) { |
+ if (i != 0) { |
+ result += VERTICAL_BAR; |
+ } |
+ UnicodeString buf; |
+ if (uprv_isPositiveInfinity(fChoiceLimits[i])) { |
+ result += INFINITY; |
+ } else if (uprv_isNegativeInfinity(fChoiceLimits[i])) { |
+ result += MINUS; |
+ result += INFINITY; |
+ } else { |
+ result += dtos(fChoiceLimits[i], buf); |
+ } |
+ if (fClosures[i]) { |
+ result += LESS_THAN; |
+ } else { |
+ result += LESS_EQUAL; |
+ } |
+ // Append fChoiceFormats[i], using quotes if there are special |
+ // characters. Single quotes themselves must be escaped in |
+ // either case. |
+ const UnicodeString& text = fChoiceFormats[i]; |
+ UBool needQuote = text.indexOf(LESS_THAN) >= 0 |
+ || text.indexOf(LESS_EQUAL) >= 0 |
+ || text.indexOf(LESS_EQUAL2) >= 0 |
+ || text.indexOf(VERTICAL_BAR) >= 0; |
+ if (needQuote) { |
+ result += SINGLE_QUOTE; |
+ } |
+ if (text.indexOf(SINGLE_QUOTE) < 0) { |
+ result += text; |
+ } |
+ else { |
+ for (int32_t j = 0; j < text.length(); ++j) { |
+ UChar c = text[j]; |
+ result += c; |
+ if (c == SINGLE_QUOTE) { |
+ result += c; |
+ } |
+ } |
+ } |
+ if (needQuote) { |
+ result += SINGLE_QUOTE; |
+ } |
+ } |
+ |
+ return result; |
+} |
+ |
+// ------------------------------------- |
+// Sets the limit and format arrays. |
+void |
+ChoiceFormat::setChoices( const double* limits, |
+ const UnicodeString* formats, |
+ int32_t cnt ) |
+{ |
+ setChoices(limits, 0, formats, cnt); |
+} |
+ |
+// ------------------------------------- |
+// Sets the limit and format arrays. |
+void |
+ChoiceFormat::setChoices( const double* limits, |
+ const UBool* closures, |
+ const UnicodeString* formats, |
+ int32_t cnt ) |
+{ |
+ if(limits == 0 || formats == 0) |
+ return; |
+ |
+ if (fChoiceLimits) { |
+ uprv_free(fChoiceLimits); |
+ } |
+ if (fClosures) { |
+ uprv_free(fClosures); |
+ } |
+ if (fChoiceFormats) { |
+ delete [] fChoiceFormats; |
+ } |
+ |
+ // Note that the old arrays are deleted and this owns |
+ // the created array. |
+ fCount = cnt; |
+ fChoiceLimits = (double*) uprv_malloc( sizeof(double) * fCount); |
+ fClosures = (UBool*) uprv_malloc( sizeof(UBool) * fCount); |
+ fChoiceFormats = new UnicodeString[fCount]; |
+ |
+ //check for memory allocation error |
+ if (!fChoiceLimits || !fClosures || !fChoiceFormats) { |
+ if (fChoiceLimits) { |
+ uprv_free(fChoiceLimits); |
+ fChoiceLimits = NULL; |
+ } |
+ if (fClosures) { |
+ uprv_free(fClosures); |
+ fClosures = NULL; |
+ } |
+ if (fChoiceFormats) { |
+ delete[] fChoiceFormats; |
+ fChoiceFormats = NULL; |
+ } |
+ return; |
+ } |
+ |
+ uprv_arrayCopy(limits, fChoiceLimits, fCount); |
+ uprv_arrayCopy(formats, fChoiceFormats, fCount); |
+ |
+ if (closures != 0) { |
+ uprv_arrayCopy(closures, fClosures, fCount); |
+ } else { |
+ int32_t i; |
+ for (i=0; i<fCount; ++i) { |
+ fClosures[i] = FALSE; |
+ } |
+ } |
+} |
+ |
+// ------------------------------------- |
+// Gets the limit array. |
+ |
+const double* |
+ChoiceFormat::getLimits(int32_t& cnt) const |
+{ |
+ cnt = fCount; |
+ return fChoiceLimits; |
+} |
+ |
+// ------------------------------------- |
+// Gets the closures array. |
+ |
+const UBool* |
+ChoiceFormat::getClosures(int32_t& cnt) const |
+{ |
+ cnt = fCount; |
+ return fClosures; |
+} |
+ |
+// ------------------------------------- |
+// Gets the format array. |
+ |
+const UnicodeString* |
+ChoiceFormat::getFormats(int32_t& cnt) const |
+{ |
+ cnt = fCount; |
+ return fChoiceFormats; |
+} |
+ |
+// ------------------------------------- |
+// Formats an int64 number, it's actually formatted as |
+// a double. The returned format string may differ |
+// from the input number because of this. |
+ |
+UnicodeString& |
+ChoiceFormat::format(int64_t number, |
+ UnicodeString& appendTo, |
+ FieldPosition& status) const |
+{ |
+ return format((double) number, appendTo, status); |
+} |
+ |
+// ------------------------------------- |
+// Formats a long number, it's actually formatted as |
+// a double. The returned format string may differ |
+// from the input number because of this. |
+ |
+UnicodeString& |
+ChoiceFormat::format(int32_t number, |
+ UnicodeString& appendTo, |
+ FieldPosition& status) const |
+{ |
+ return format((double) number, appendTo, status); |
+} |
+ |
+// ------------------------------------- |
+// Formats a double number. |
+ |
+UnicodeString& |
+ChoiceFormat::format(double number, |
+ UnicodeString& appendTo, |
+ FieldPosition& /*pos*/) const |
+{ |
+ // find the number |
+ int32_t i; |
+ for (i = 0; i < fCount; ++i) { |
+ if (fClosures[i]) { |
+ if (!(number > fChoiceLimits[i])) { |
+ // same as number <= fChoiceLimits, except catches NaN |
+ break; |
+ } |
+ } else if (!(number >= fChoiceLimits[i])) { |
+ // same as number < fChoiceLimits, except catches NaN |
+ break; |
+ } |
+ } |
+ --i; |
+ if (i < 0) { |
+ i = 0; |
+ } |
+ // return either a formatted number, or a string |
+ appendTo += fChoiceFormats[i]; |
+ return appendTo; |
+} |
+ |
+// ------------------------------------- |
+// Formats an array of objects. Checks if the data type of the objects |
+// to get the right value for formatting. |
+ |
+UnicodeString& |
+ChoiceFormat::format(const Formattable* objs, |
+ int32_t cnt, |
+ UnicodeString& appendTo, |
+ FieldPosition& pos, |
+ UErrorCode& status) const |
+{ |
+ if(cnt < 0) { |
+ status = U_ILLEGAL_ARGUMENT_ERROR; |
+ return appendTo; |
+ } |
+ |
+ UnicodeString buffer; |
+ for (int32_t i = 0; i < cnt; i++) { |
+ double objDouble = objs[i].getDouble(status); |
+ if (U_SUCCESS(status)) { |
+ buffer.remove(); |
+ appendTo += format(objDouble, buffer, pos); |
+ } |
+ } |
+ |
+ return appendTo; |
+} |
+ |
+// ------------------------------------- |
+// Formats an array of objects. Checks if the data type of the objects |
+// to get the right value for formatting. |
+ |
+UnicodeString& |
+ChoiceFormat::format(const Formattable& obj, |
+ UnicodeString& appendTo, |
+ FieldPosition& pos, |
+ UErrorCode& status) const |
+{ |
+ return NumberFormat::format(obj, appendTo, pos, status); |
+} |
+// ------------------------------------- |
+ |
+void |
+ChoiceFormat::parse(const UnicodeString& text, |
+ Formattable& result, |
+ ParsePosition& status) const |
+{ |
+ // find the best number (defined as the one with the longest parse) |
+ int32_t start = status.getIndex(); |
+ int32_t furthest = start; |
+ double bestNumber = uprv_getNaN(); |
+ double tempNumber = 0.0; |
+ for (int i = 0; i < fCount; ++i) { |
+ int32_t len = fChoiceFormats[i].length(); |
+ if (text.compare(start, len, fChoiceFormats[i]) == 0) { |
+ status.setIndex(start + len); |
+ tempNumber = fChoiceLimits[i]; |
+ if (status.getIndex() > furthest) { |
+ furthest = status.getIndex(); |
+ bestNumber = tempNumber; |
+ if (furthest == text.length()) |
+ break; |
+ } |
+ } |
+ } |
+ status.setIndex(furthest); |
+ if (status.getIndex() == start) { |
+ status.setErrorIndex(furthest); |
+ } |
+ result.setDouble(bestNumber); |
+} |
+ |
+// ------------------------------------- |
+// Parses the text and return the Formattable object. |
+ |
+void |
+ChoiceFormat::parse(const UnicodeString& text, |
+ Formattable& result, |
+ UErrorCode& status) const |
+{ |
+ NumberFormat::parse(text, result, status); |
+} |
+ |
+// ------------------------------------- |
+ |
+Format* |
+ChoiceFormat::clone() const |
+{ |
+ ChoiceFormat *aCopy = new ChoiceFormat(*this); |
+ return aCopy; |
+} |
+ |
+U_NAMESPACE_END |
+ |
+#endif /* #if !UCONFIG_NO_FORMATTING */ |
+ |
+//eof |
Property changes on: icu46/source/i18n/choicfmt.cpp |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |