aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/icu/i18n/choicfmt.cpp
diff options
context:
space:
mode:
authorneksard <neksard@yandex-team.ru>2022-02-10 16:45:23 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:23 +0300
commit8f7cf138264e0caa318144bf8a2c950e0b0a8593 (patch)
tree83bf5c8c8047c42d8475e6095df90ccdc3d1b57f /contrib/libs/icu/i18n/choicfmt.cpp
parentd3a398281c6fd1d3672036cb2d63f842d2cb28c5 (diff)
downloadydb-8f7cf138264e0caa318144bf8a2c950e0b0a8593.tar.gz
Restoring authorship annotation for <neksard@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/icu/i18n/choicfmt.cpp')
-rw-r--r--contrib/libs/icu/i18n/choicfmt.cpp1148
1 files changed, 574 insertions, 574 deletions
diff --git a/contrib/libs/icu/i18n/choicfmt.cpp b/contrib/libs/icu/i18n/choicfmt.cpp
index 7e26bb7a1f..5cfe5a67f6 100644
--- a/contrib/libs/icu/i18n/choicfmt.cpp
+++ b/contrib/libs/icu/i18n/choicfmt.cpp
@@ -1,577 +1,577 @@
// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
-*******************************************************************************
-* Copyright (C) 1997-2013, 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 "messageimpl.h"
-#include "putilimp.h"
-#include "uassert.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) /*-*/
-
-static const UChar LEFT_CURLY_BRACE = 0x7B; /*{*/
-static const UChar RIGHT_CURLY_BRACE = 0x7D; /*}*/
-
-#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)
-: constructorErrorCode(status),
- msgPattern(status)
-{
- 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 )
-: constructorErrorCode(U_ZERO_ERROR),
- msgPattern(constructorErrorCode)
-{
- setChoices(limits, NULL, formats, cnt, constructorErrorCode);
-}
-
-// -------------------------------------
-
-ChoiceFormat::ChoiceFormat(const double* limits,
- const UBool* closures,
- const UnicodeString* formats,
- int32_t cnt )
-: constructorErrorCode(U_ZERO_ERROR),
- msgPattern(constructorErrorCode)
-{
- setChoices(limits, closures, formats, cnt, constructorErrorCode);
-}
-
-// -------------------------------------
-// copy constructor
-
-ChoiceFormat::ChoiceFormat(const ChoiceFormat& that)
-: NumberFormat(that),
- constructorErrorCode(that.constructorErrorCode),
- msgPattern(that.msgPattern)
-{
-}
-
-// -------------------------------------
-// Private constructor that creates a
-// ChoiceFormat instance based on the
-// pattern and populates UParseError
-
-ChoiceFormat::ChoiceFormat(const UnicodeString& newPattern,
- UParseError& parseError,
- UErrorCode& status)
-: constructorErrorCode(status),
- msgPattern(status)
-{
- 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;
- return msgPattern == thatAlias.msgPattern;
-}
-
-// -------------------------------------
-// copy constructor
-
-const ChoiceFormat&
-ChoiceFormat::operator=(const ChoiceFormat& that)
-{
- if (this != &that) {
- NumberFormat::operator=(that);
- constructorErrorCode = that.constructorErrorCode;
- msgPattern = that.msgPattern;
- }
- return *this;
-}
-
-// -------------------------------------
-
-ChoiceFormat::~ChoiceFormat()
-{
-}
-
-// -------------------------------------
-
-/**
- * Convert a double value to a string without the overhead of NumberFormat.
- */
-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)
-{
- msgPattern.parseChoiceStyle(pattern, NULL, status);
- constructorErrorCode = status;
-}
-
-// -------------------------------------
-// Applies the pattern to this ChoiceFormat instance.
-
-void
-ChoiceFormat::applyPattern(const UnicodeString& pattern,
- UParseError& parseError,
- UErrorCode& status)
-{
- msgPattern.parseChoiceStyle(pattern, &parseError, status);
- constructorErrorCode = status;
-}
-// -------------------------------------
-// Returns the input pattern string.
-
-UnicodeString&
-ChoiceFormat::toPattern(UnicodeString& result) const
-{
- return result = msgPattern.getPatternString();
-}
-
-// -------------------------------------
-// Sets the limit and format arrays.
-void
-ChoiceFormat::setChoices( const double* limits,
- const UnicodeString* formats,
- int32_t cnt )
-{
- UErrorCode errorCode = U_ZERO_ERROR;
- setChoices(limits, NULL, formats, cnt, errorCode);
-}
-
-// -------------------------------------
-// Sets the limit and format arrays.
-void
-ChoiceFormat::setChoices( const double* limits,
- const UBool* closures,
- const UnicodeString* formats,
- int32_t cnt )
-{
- UErrorCode errorCode = U_ZERO_ERROR;
- setChoices(limits, closures, formats, cnt, errorCode);
-}
-
-void
-ChoiceFormat::setChoices(const double* limits,
- const UBool* closures,
- const UnicodeString* formats,
- int32_t count,
- UErrorCode &errorCode) {
- if (U_FAILURE(errorCode)) {
- return;
- }
- if (limits == NULL || formats == NULL) {
- errorCode = U_ILLEGAL_ARGUMENT_ERROR;
- return;
- }
- // Reconstruct the original input pattern.
- // Modified version of the pre-ICU 4.8 toPattern() implementation.
- UnicodeString result;
- for (int32_t i = 0; i < count; ++i) {
- if (i != 0) {
- result += VERTICAL_BAR;
- }
- UnicodeString buf;
- if (uprv_isPositiveInfinity(limits[i])) {
- result += INFINITY;
- } else if (uprv_isNegativeInfinity(limits[i])) {
- result += MINUS;
- result += INFINITY;
- } else {
- result += dtos(limits[i], buf);
- }
- if (closures != NULL && closures[i]) {
- result += LESS_THAN;
- } else {
- result += LESS_EQUAL;
- }
- // Append formats[i], using quotes if there are special
- // characters. Single quotes themselves must be escaped in
- // either case.
- const UnicodeString& text = formats[i];
- int32_t textLength = text.length();
- int32_t nestingLevel = 0;
- for (int32_t j = 0; j < textLength; ++j) {
- UChar c = text[j];
- if (c == SINGLE_QUOTE && nestingLevel == 0) {
- // Double each top-level apostrophe.
- result.append(c);
- } else if (c == VERTICAL_BAR && nestingLevel == 0) {
- // Surround each pipe symbol with apostrophes for quoting.
- // If the next character is an apostrophe, then that will be doubled,
- // and although the parser will see the apostrophe pairs beginning
- // and ending one character earlier than our doubling, the result
- // is as desired.
- // | -> '|'
- // |' -> '|'''
- // |'' -> '|''''' etc.
- result.append(SINGLE_QUOTE).append(c).append(SINGLE_QUOTE);
- continue; // Skip the append(c) at the end of the loop body.
- } else if (c == LEFT_CURLY_BRACE) {
- ++nestingLevel;
- } else if (c == RIGHT_CURLY_BRACE && nestingLevel > 0) {
- --nestingLevel;
- }
- result.append(c);
- }
- }
- // Apply the reconstructed pattern.
- applyPattern(result, errorCode);
-}
-
-// -------------------------------------
-// Gets the limit array.
-
-const double*
-ChoiceFormat::getLimits(int32_t& cnt) const
-{
- cnt = 0;
- return NULL;
-}
-
-// -------------------------------------
-// Gets the closures array.
-
-const UBool*
-ChoiceFormat::getClosures(int32_t& cnt) const
-{
- cnt = 0;
- return NULL;
-}
-
-// -------------------------------------
-// Gets the format array.
-
-const UnicodeString*
-ChoiceFormat::getFormats(int32_t& cnt) const
-{
- cnt = 0;
- return NULL;
-}
-
-// -------------------------------------
-// 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,
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+*******************************************************************************
+* Copyright (C) 1997-2013, 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 "messageimpl.h"
+#include "putilimp.h"
+#include "uassert.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) /*-*/
+
+static const UChar LEFT_CURLY_BRACE = 0x7B; /*{*/
+static const UChar RIGHT_CURLY_BRACE = 0x7D; /*}*/
+
+#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)
+: constructorErrorCode(status),
+ msgPattern(status)
+{
+ 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 )
+: constructorErrorCode(U_ZERO_ERROR),
+ msgPattern(constructorErrorCode)
+{
+ setChoices(limits, NULL, formats, cnt, constructorErrorCode);
+}
+
+// -------------------------------------
+
+ChoiceFormat::ChoiceFormat(const double* limits,
+ const UBool* closures,
+ const UnicodeString* formats,
+ int32_t cnt )
+: constructorErrorCode(U_ZERO_ERROR),
+ msgPattern(constructorErrorCode)
+{
+ setChoices(limits, closures, formats, cnt, constructorErrorCode);
+}
+
+// -------------------------------------
+// copy constructor
+
+ChoiceFormat::ChoiceFormat(const ChoiceFormat& that)
+: NumberFormat(that),
+ constructorErrorCode(that.constructorErrorCode),
+ msgPattern(that.msgPattern)
+{
+}
+
+// -------------------------------------
+// Private constructor that creates a
+// ChoiceFormat instance based on the
+// pattern and populates UParseError
+
+ChoiceFormat::ChoiceFormat(const UnicodeString& newPattern,
+ UParseError& parseError,
+ UErrorCode& status)
+: constructorErrorCode(status),
+ msgPattern(status)
+{
+ 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;
+ return msgPattern == thatAlias.msgPattern;
+}
+
+// -------------------------------------
+// copy constructor
+
+const ChoiceFormat&
+ChoiceFormat::operator=(const ChoiceFormat& that)
+{
+ if (this != &that) {
+ NumberFormat::operator=(that);
+ constructorErrorCode = that.constructorErrorCode;
+ msgPattern = that.msgPattern;
+ }
+ return *this;
+}
+
+// -------------------------------------
+
+ChoiceFormat::~ChoiceFormat()
+{
+}
+
+// -------------------------------------
+
+/**
+ * Convert a double value to a string without the overhead of NumberFormat.
+ */
+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)
+{
+ msgPattern.parseChoiceStyle(pattern, NULL, status);
+ constructorErrorCode = status;
+}
+
+// -------------------------------------
+// Applies the pattern to this ChoiceFormat instance.
+
+void
+ChoiceFormat::applyPattern(const UnicodeString& pattern,
+ UParseError& parseError,
+ UErrorCode& status)
+{
+ msgPattern.parseChoiceStyle(pattern, &parseError, status);
+ constructorErrorCode = status;
+}
+// -------------------------------------
+// Returns the input pattern string.
+
+UnicodeString&
+ChoiceFormat::toPattern(UnicodeString& result) const
+{
+ return result = msgPattern.getPatternString();
+}
+
+// -------------------------------------
+// Sets the limit and format arrays.
+void
+ChoiceFormat::setChoices( const double* limits,
+ const UnicodeString* formats,
+ int32_t cnt )
+{
+ UErrorCode errorCode = U_ZERO_ERROR;
+ setChoices(limits, NULL, formats, cnt, errorCode);
+}
+
+// -------------------------------------
+// Sets the limit and format arrays.
+void
+ChoiceFormat::setChoices( const double* limits,
+ const UBool* closures,
+ const UnicodeString* formats,
+ int32_t cnt )
+{
+ UErrorCode errorCode = U_ZERO_ERROR;
+ setChoices(limits, closures, formats, cnt, errorCode);
+}
+
+void
+ChoiceFormat::setChoices(const double* limits,
+ const UBool* closures,
+ const UnicodeString* formats,
+ int32_t count,
+ UErrorCode &errorCode) {
+ if (U_FAILURE(errorCode)) {
+ return;
+ }
+ if (limits == NULL || formats == NULL) {
+ errorCode = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
+ // Reconstruct the original input pattern.
+ // Modified version of the pre-ICU 4.8 toPattern() implementation.
+ UnicodeString result;
+ for (int32_t i = 0; i < count; ++i) {
+ if (i != 0) {
+ result += VERTICAL_BAR;
+ }
+ UnicodeString buf;
+ if (uprv_isPositiveInfinity(limits[i])) {
+ result += INFINITY;
+ } else if (uprv_isNegativeInfinity(limits[i])) {
+ result += MINUS;
+ result += INFINITY;
+ } else {
+ result += dtos(limits[i], buf);
+ }
+ if (closures != NULL && closures[i]) {
+ result += LESS_THAN;
+ } else {
+ result += LESS_EQUAL;
+ }
+ // Append formats[i], using quotes if there are special
+ // characters. Single quotes themselves must be escaped in
+ // either case.
+ const UnicodeString& text = formats[i];
+ int32_t textLength = text.length();
+ int32_t nestingLevel = 0;
+ for (int32_t j = 0; j < textLength; ++j) {
+ UChar c = text[j];
+ if (c == SINGLE_QUOTE && nestingLevel == 0) {
+ // Double each top-level apostrophe.
+ result.append(c);
+ } else if (c == VERTICAL_BAR && nestingLevel == 0) {
+ // Surround each pipe symbol with apostrophes for quoting.
+ // If the next character is an apostrophe, then that will be doubled,
+ // and although the parser will see the apostrophe pairs beginning
+ // and ending one character earlier than our doubling, the result
+ // is as desired.
+ // | -> '|'
+ // |' -> '|'''
+ // |'' -> '|''''' etc.
+ result.append(SINGLE_QUOTE).append(c).append(SINGLE_QUOTE);
+ continue; // Skip the append(c) at the end of the loop body.
+ } else if (c == LEFT_CURLY_BRACE) {
+ ++nestingLevel;
+ } else if (c == RIGHT_CURLY_BRACE && nestingLevel > 0) {
+ --nestingLevel;
+ }
+ result.append(c);
+ }
+ }
+ // Apply the reconstructed pattern.
+ applyPattern(result, errorCode);
+}
+
+// -------------------------------------
+// Gets the limit array.
+
+const double*
+ChoiceFormat::getLimits(int32_t& cnt) const
+{
+ cnt = 0;
+ return NULL;
+}
+
+// -------------------------------------
+// Gets the closures array.
+
+const UBool*
+ChoiceFormat::getClosures(int32_t& cnt) const
+{
+ cnt = 0;
+ return NULL;
+}
+
+// -------------------------------------
+// Gets the format array.
+
+const UnicodeString*
+ChoiceFormat::getFormats(int32_t& cnt) const
+{
+ cnt = 0;
+ return NULL;
+}
+
+// -------------------------------------
+// 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 an int32_t number, it's actually formatted as
+// a double.
+
+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
+{
+ if (msgPattern.countParts() == 0) {
+ // No pattern was applied, or it failed.
+ return appendTo;
+ }
+ // Get the appropriate sub-message.
+ int32_t msgStart = findSubMessage(msgPattern, 0, number);
+ if (!MessageImpl::jdkAposMode(msgPattern)) {
+ int32_t patternStart = msgPattern.getPart(msgStart).getLimit();
+ int32_t msgLimit = msgPattern.getLimitPartIndex(msgStart);
+ appendTo.append(msgPattern.getPatternString(),
+ patternStart,
+ msgPattern.getPatternIndex(msgLimit) - patternStart);
+ return appendTo;
+ }
+ // JDK compatibility mode: Remove SKIP_SYNTAX.
+ return MessageImpl::appendSubMessageWithoutSkipSyntax(msgPattern, msgStart, appendTo);
+}
+
+int32_t
+ChoiceFormat::findSubMessage(const MessagePattern &pattern, int32_t partIndex, double number) {
+ int32_t count = pattern.countParts();
+ int32_t msgStart;
+ // Iterate over (ARG_INT|DOUBLE, ARG_SELECTOR, message) tuples
+ // until ARG_LIMIT or end of choice-only pattern.
+ // Ignore the first number and selector and start the loop on the first message.
+ partIndex += 2;
+ for (;;) {
+ // Skip but remember the current sub-message.
+ msgStart = partIndex;
+ partIndex = pattern.getLimitPartIndex(partIndex);
+ if (++partIndex >= count) {
+ // Reached the end of the choice-only pattern.
+ // Return with the last sub-message.
+ break;
+ }
+ const MessagePattern::Part &part = pattern.getPart(partIndex++);
+ UMessagePatternPartType type = part.getType();
+ if (type == UMSGPAT_PART_TYPE_ARG_LIMIT) {
+ // Reached the end of the ChoiceFormat style.
+ // Return with the last sub-message.
+ break;
+ }
+ // part is an ARG_INT or ARG_DOUBLE
+ U_ASSERT(MessagePattern::Part::hasNumericValue(type));
+ double boundary = pattern.getNumericValue(part);
+ // Fetch the ARG_SELECTOR character.
+ int32_t selectorIndex = pattern.getPatternIndex(partIndex++);
+ UChar boundaryChar = pattern.getPatternString().charAt(selectorIndex);
+ if (boundaryChar == LESS_THAN ? !(number > boundary) : !(number >= boundary)) {
+ // The number is in the interval between the previous boundary and the current one.
+ // Return with the sub-message between them.
+ // The !(a>b) and !(a>=b) comparisons are equivalent to
+ // (a<=b) and (a<b) except they "catch" NaN.
+ break;
+ }
+ }
+ return msgStart;
+}
+
+// -------------------------------------
+// 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& status) const
-{
- return format((double) number, appendTo, status);
-}
-
-// -------------------------------------
-// Formats an int32_t number, it's actually formatted as
-// a double.
-
-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
-{
- if (msgPattern.countParts() == 0) {
- // No pattern was applied, or it failed.
- return appendTo;
- }
- // Get the appropriate sub-message.
- int32_t msgStart = findSubMessage(msgPattern, 0, number);
- if (!MessageImpl::jdkAposMode(msgPattern)) {
- int32_t patternStart = msgPattern.getPart(msgStart).getLimit();
- int32_t msgLimit = msgPattern.getLimitPartIndex(msgStart);
- appendTo.append(msgPattern.getPatternString(),
- patternStart,
- msgPattern.getPatternIndex(msgLimit) - patternStart);
- return appendTo;
- }
- // JDK compatibility mode: Remove SKIP_SYNTAX.
- return MessageImpl::appendSubMessageWithoutSkipSyntax(msgPattern, msgStart, appendTo);
-}
-
-int32_t
-ChoiceFormat::findSubMessage(const MessagePattern &pattern, int32_t partIndex, double number) {
- int32_t count = pattern.countParts();
- int32_t msgStart;
- // Iterate over (ARG_INT|DOUBLE, ARG_SELECTOR, message) tuples
- // until ARG_LIMIT or end of choice-only pattern.
- // Ignore the first number and selector and start the loop on the first message.
- partIndex += 2;
- for (;;) {
- // Skip but remember the current sub-message.
- msgStart = partIndex;
- partIndex = pattern.getLimitPartIndex(partIndex);
- if (++partIndex >= count) {
- // Reached the end of the choice-only pattern.
- // Return with the last sub-message.
- break;
- }
- const MessagePattern::Part &part = pattern.getPart(partIndex++);
- UMessagePatternPartType type = part.getType();
- if (type == UMSGPAT_PART_TYPE_ARG_LIMIT) {
- // Reached the end of the ChoiceFormat style.
- // Return with the last sub-message.
- break;
- }
- // part is an ARG_INT or ARG_DOUBLE
- U_ASSERT(MessagePattern::Part::hasNumericValue(type));
- double boundary = pattern.getNumericValue(part);
- // Fetch the ARG_SELECTOR character.
- int32_t selectorIndex = pattern.getPatternIndex(partIndex++);
- UChar boundaryChar = pattern.getPatternString().charAt(selectorIndex);
- if (boundaryChar == LESS_THAN ? !(number > boundary) : !(number >= boundary)) {
- // The number is in the interval between the previous boundary and the current one.
- // Return with the sub-message between them.
- // The !(a>b) and !(a>=b) comparisons are equivalent to
- // (a<=b) and (a<b) except they "catch" NaN.
- break;
- }
- }
- return msgStart;
-}
-
-// -------------------------------------
-// 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;
- }
- if (msgPattern.countParts() == 0) {
- status = U_INVALID_STATE_ERROR;
- return appendTo;
- }
-
- for (int32_t i = 0; i < cnt; i++) {
- double objDouble = objs[i].getDouble(status);
- if (U_SUCCESS(status)) {
- format(objDouble, appendTo, pos);
- }
- }
-
- return appendTo;
-}
-
-// -------------------------------------
-
-void
-ChoiceFormat::parse(const UnicodeString& text,
- Formattable& result,
- ParsePosition& pos) const
-{
- result.setDouble(parseArgument(msgPattern, 0, text, pos));
-}
-
-double
-ChoiceFormat::parseArgument(
- const MessagePattern &pattern, int32_t partIndex,
- const UnicodeString &source, ParsePosition &pos) {
- // find the best number (defined as the one with the longest parse)
- int32_t start = pos.getIndex();
- int32_t furthest = start;
- double bestNumber = uprv_getNaN();
- double tempNumber = 0.0;
- int32_t count = pattern.countParts();
- while (partIndex < count && pattern.getPartType(partIndex) != UMSGPAT_PART_TYPE_ARG_LIMIT) {
- tempNumber = pattern.getNumericValue(pattern.getPart(partIndex));
- partIndex += 2; // skip the numeric part and ignore the ARG_SELECTOR
- int32_t msgLimit = pattern.getLimitPartIndex(partIndex);
- int32_t len = matchStringUntilLimitPart(pattern, partIndex, msgLimit, source, start);
- if (len >= 0) {
- int32_t newIndex = start + len;
- if (newIndex > furthest) {
- furthest = newIndex;
- bestNumber = tempNumber;
- if (furthest == source.length()) {
- break;
- }
- }
- }
- partIndex = msgLimit + 1;
- }
- if (furthest == start) {
- pos.setErrorIndex(start);
- } else {
- pos.setIndex(furthest);
- }
- return bestNumber;
-}
-
-int32_t
-ChoiceFormat::matchStringUntilLimitPart(
- const MessagePattern &pattern, int32_t partIndex, int32_t limitPartIndex,
- const UnicodeString &source, int32_t sourceOffset) {
- int32_t matchingSourceLength = 0;
- const UnicodeString &msgString = pattern.getPatternString();
- int32_t prevIndex = pattern.getPart(partIndex).getLimit();
- for (;;) {
- const MessagePattern::Part &part = pattern.getPart(++partIndex);
- if (partIndex == limitPartIndex || part.getType() == UMSGPAT_PART_TYPE_SKIP_SYNTAX) {
- int32_t index = part.getIndex();
- int32_t length = index - prevIndex;
- if (length != 0 && 0 != source.compare(sourceOffset, length, msgString, prevIndex, length)) {
- return -1; // mismatch
- }
- matchingSourceLength += length;
- if (partIndex == limitPartIndex) {
- return matchingSourceLength;
- }
- prevIndex = part.getLimit(); // SKIP_SYNTAX
- }
- }
-}
-
-// -------------------------------------
-
+ FieldPosition& pos,
+ UErrorCode& status) const
+{
+ if(cnt < 0) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return appendTo;
+ }
+ if (msgPattern.countParts() == 0) {
+ status = U_INVALID_STATE_ERROR;
+ return appendTo;
+ }
+
+ for (int32_t i = 0; i < cnt; i++) {
+ double objDouble = objs[i].getDouble(status);
+ if (U_SUCCESS(status)) {
+ format(objDouble, appendTo, pos);
+ }
+ }
+
+ return appendTo;
+}
+
+// -------------------------------------
+
+void
+ChoiceFormat::parse(const UnicodeString& text,
+ Formattable& result,
+ ParsePosition& pos) const
+{
+ result.setDouble(parseArgument(msgPattern, 0, text, pos));
+}
+
+double
+ChoiceFormat::parseArgument(
+ const MessagePattern &pattern, int32_t partIndex,
+ const UnicodeString &source, ParsePosition &pos) {
+ // find the best number (defined as the one with the longest parse)
+ int32_t start = pos.getIndex();
+ int32_t furthest = start;
+ double bestNumber = uprv_getNaN();
+ double tempNumber = 0.0;
+ int32_t count = pattern.countParts();
+ while (partIndex < count && pattern.getPartType(partIndex) != UMSGPAT_PART_TYPE_ARG_LIMIT) {
+ tempNumber = pattern.getNumericValue(pattern.getPart(partIndex));
+ partIndex += 2; // skip the numeric part and ignore the ARG_SELECTOR
+ int32_t msgLimit = pattern.getLimitPartIndex(partIndex);
+ int32_t len = matchStringUntilLimitPart(pattern, partIndex, msgLimit, source, start);
+ if (len >= 0) {
+ int32_t newIndex = start + len;
+ if (newIndex > furthest) {
+ furthest = newIndex;
+ bestNumber = tempNumber;
+ if (furthest == source.length()) {
+ break;
+ }
+ }
+ }
+ partIndex = msgLimit + 1;
+ }
+ if (furthest == start) {
+ pos.setErrorIndex(start);
+ } else {
+ pos.setIndex(furthest);
+ }
+ return bestNumber;
+}
+
+int32_t
+ChoiceFormat::matchStringUntilLimitPart(
+ const MessagePattern &pattern, int32_t partIndex, int32_t limitPartIndex,
+ const UnicodeString &source, int32_t sourceOffset) {
+ int32_t matchingSourceLength = 0;
+ const UnicodeString &msgString = pattern.getPatternString();
+ int32_t prevIndex = pattern.getPart(partIndex).getLimit();
+ for (;;) {
+ const MessagePattern::Part &part = pattern.getPart(++partIndex);
+ if (partIndex == limitPartIndex || part.getType() == UMSGPAT_PART_TYPE_SKIP_SYNTAX) {
+ int32_t index = part.getIndex();
+ int32_t length = index - prevIndex;
+ if (length != 0 && 0 != source.compare(sourceOffset, length, msgString, prevIndex, length)) {
+ return -1; // mismatch
+ }
+ matchingSourceLength += length;
+ if (partIndex == limitPartIndex) {
+ return matchingSourceLength;
+ }
+ prevIndex = part.getLimit(); // SKIP_SYNTAX
+ }
+ }
+}
+
+// -------------------------------------
+
ChoiceFormat*
-ChoiceFormat::clone() const
-{
- ChoiceFormat *aCopy = new ChoiceFormat(*this);
- return aCopy;
-}
-
-U_NAMESPACE_END
-
-#endif /* #if !UCONFIG_NO_FORMATTING */
-
-//eof
+ChoiceFormat::clone() const
+{
+ ChoiceFormat *aCopy = new ChoiceFormat(*this);
+ return aCopy;
+}
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+//eof