16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 1997-2013, International Business Machines Corporation and * 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* others. All Rights Reserved. * 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* File CHOICFMT.CPP 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Modification History: 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Date Name Description 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 02/19/97 aliu Converted from java. 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 03/20/97 helena Finished first cut of implementation and got rid 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* of nextDouble/previousDouble and replaced with 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* boolean array. 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 4/10/97 aliu Clean up. Modified to work on AIX. 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 06/04/97 helena Fixed applyPattern(), toPattern() and not to include 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* wchar.h. 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 07/09/97 helena Made ParsePosition into a class. 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 08/06/97 nos removed overloaded constructor, fixed 'format(array)' 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 07/22/98 stephen JDK 1.2 Sync - removed UBool array (doubleFlags) 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 02/22/99 stephen Removed character literals for EBCDIC safety 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************** 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/choicfmt.h" 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/numfmt.h" 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/locid.h" 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cpputils.h" 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h" 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "messageimpl.h" 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "putilimp.h" 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stdio.h> 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <float.h> 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ***************************************************************************** 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// class ChoiceFormat 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ***************************************************************************** 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ChoiceFormat) 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Special characters used by ChoiceFormat. There are two characters 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// used interchangeably to indicate <=. Either is parsed, but only 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// LESS_EQUAL is generated by toPattern(). 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define SINGLE_QUOTE ((UChar)0x0027) /*'*/ 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LESS_THAN ((UChar)0x003C) /*<*/ 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LESS_EQUAL ((UChar)0x0023) /*#*/ 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LESS_EQUAL2 ((UChar)0x2264) 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define VERTICAL_BAR ((UChar)0x007C) /*|*/ 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define MINUS ((UChar)0x002D) /*-*/ 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar LEFT_CURLY_BRACE = 0x7B; /*{*/ 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar RIGHT_CURLY_BRACE = 0x7D; /*}*/ 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifdef INFINITY 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#undef INFINITY 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define INFINITY ((UChar)0x221E) 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//static const UChar gPositiveInfinity[] = {INFINITY, 0}; 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//static const UChar gNegativeInfinity[] = {MINUS, INFINITY, 0}; 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define POSITIVE_INF_STRLEN 1 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define NEGATIVE_INF_STRLEN 2 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a ChoiceFormat instance based on the pattern. 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::ChoiceFormat(const UnicodeString& newPattern, 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: constructorErrorCode(status), 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern(status) 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org applyPattern(newPattern, status); 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a ChoiceFormat instance with the limit array and 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// format strings for each limit. 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::ChoiceFormat(const double* limits, 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString* formats, 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt ) 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: constructorErrorCode(U_ZERO_ERROR), 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern(constructorErrorCode) 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setChoices(limits, NULL, formats, cnt, constructorErrorCode); 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::ChoiceFormat(const double* limits, 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UBool* closures, 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString* formats, 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt ) 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: constructorErrorCode(U_ZERO_ERROR), 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern(constructorErrorCode) 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setChoices(limits, closures, formats, cnt, constructorErrorCode); 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// copy constructor 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::ChoiceFormat(const ChoiceFormat& that) 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: NumberFormat(that), 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org constructorErrorCode(that.constructorErrorCode), 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern(that.msgPattern) 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Private constructor that creates a 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ChoiceFormat instance based on the 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// pattern and populates UParseError 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::ChoiceFormat(const UnicodeString& newPattern, 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError& parseError, 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: constructorErrorCode(status), 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern(status) 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org applyPattern(newPattern,parseError, status); 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::operator==(const Format& that) const 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (this == &that) return TRUE; 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!NumberFormat::operator==(that)) return FALSE; 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ChoiceFormat& thatAlias = (ChoiceFormat&)that; 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return msgPattern == thatAlias.msgPattern; 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// copy constructor 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst ChoiceFormat& 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::operator=(const ChoiceFormat& that) 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (this != &that) { 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NumberFormat::operator=(that); 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org constructorErrorCode = that.constructorErrorCode; 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern = that.msgPattern; 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return *this; 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::~ChoiceFormat() 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Convert a double value to a string without the overhead of NumberFormat. 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::dtos(double value, 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& string) 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Buffer to contain the digits and any extra formatting stuff. */ 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char temp[DBL_DIG + 16]; 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *itrPtr = temp; 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *expPtr; 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sprintf(temp, "%.*g", DBL_DIG, value); 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Find and convert the decimal point. 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Using setlocale on some machines will cause sprintf to use a comma for certain locales. 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (*itrPtr && (*itrPtr == '-' || isdigit(*itrPtr))) { 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org itrPtr++; 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*itrPtr != 0 && *itrPtr != 'e') { 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* We reached something that looks like a decimal point. 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org In case someone used setlocale(), which changes the decimal point. */ 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *itrPtr = '.'; 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org itrPtr++; 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Search for the exponent */ 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (*itrPtr && *itrPtr != 'e') { 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org itrPtr++; 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*itrPtr == 'e') { 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org itrPtr++; 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Verify the exponent sign */ 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*itrPtr == '+' || *itrPtr == '-') { 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org itrPtr++; 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Remove leading zeros. You will see this on Windows machines. */ 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org expPtr = itrPtr; 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (*itrPtr == '0') { 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org itrPtr++; 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*itrPtr && expPtr != itrPtr) { 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Shift the exponent without zeros. */ 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (*itrPtr) { 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *(expPtr++) = *(itrPtr++); 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // NULL terminate 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *expPtr = 0; 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org string = UnicodeString(temp, -1, US_INV); /* invariant codepage */ 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return string; 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// calls the overloaded applyPattern method. 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::applyPattern(const UnicodeString& pattern, 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern.parseChoiceStyle(pattern, NULL, status); 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org constructorErrorCode = status; 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Applies the pattern to this ChoiceFormat instance. 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::applyPattern(const UnicodeString& pattern, 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError& parseError, 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern.parseChoiceStyle(pattern, &parseError, status); 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org constructorErrorCode = status; 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Returns the input pattern string. 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::toPattern(UnicodeString& result) const 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result = msgPattern.getPatternString(); 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets the limit and format arrays. 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::setChoices( const double* limits, 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString* formats, 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt ) 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode errorCode = U_ZERO_ERROR; 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setChoices(limits, NULL, formats, cnt, errorCode); 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets the limit and format arrays. 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::setChoices( const double* limits, 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UBool* closures, 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString* formats, 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt ) 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode errorCode = U_ZERO_ERROR; 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setChoices(limits, closures, formats, cnt, errorCode); 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::setChoices(const double* limits, 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UBool* closures, 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString* formats, 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t count, 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode &errorCode) { 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(errorCode)) { 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (limits == NULL || formats == NULL) { 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org errorCode = U_ILLEGAL_ARGUMENT_ERROR; 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Reconstruct the original input pattern. 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Modified version of the pre-ICU 4.8 toPattern() implementation. 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString result; 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; i < count; ++i) { 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (i != 0) { 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result += VERTICAL_BAR; 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString buf; 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (uprv_isPositiveInfinity(limits[i])) { 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result += INFINITY; 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (uprv_isNegativeInfinity(limits[i])) { 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result += MINUS; 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result += INFINITY; 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result += dtos(limits[i], buf); 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (closures != NULL && closures[i]) { 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result += LESS_THAN; 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result += LESS_EQUAL; 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Append formats[i], using quotes if there are special 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // characters. Single quotes themselves must be escaped in 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // either case. 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& text = formats[i]; 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t textLength = text.length(); 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t nestingLevel = 0; 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t j = 0; j < textLength; ++j) { 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar c = text[j]; 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (c == SINGLE_QUOTE && nestingLevel == 0) { 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Double each top-level apostrophe. 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.append(c); 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (c == VERTICAL_BAR && nestingLevel == 0) { 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Surround each pipe symbol with apostrophes for quoting. 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // If the next character is an apostrophe, then that will be doubled, 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // and although the parser will see the apostrophe pairs beginning 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // and ending one character earlier than our doubling, the result 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // is as desired. 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // | -> '|' 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // |' -> '|''' 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // |'' -> '|''''' etc. 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.append(SINGLE_QUOTE).append(c).append(SINGLE_QUOTE); 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; // Skip the append(c) at the end of the loop body. 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (c == LEFT_CURLY_BRACE) { 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++nestingLevel; 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (c == RIGHT_CURLY_BRACE && nestingLevel > 0) { 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org --nestingLevel; 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.append(c); 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Apply the reconstructed pattern. 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org applyPattern(result, errorCode); 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Gets the limit array. 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst double* 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::getLimits(int32_t& cnt) const 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnt = 0; 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Gets the closures array. 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UBool* 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::getClosures(int32_t& cnt) const 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnt = 0; 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Gets the format array. 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UnicodeString* 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::getFormats(int32_t& cnt) const 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnt = 0; 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Formats an int64 number, it's actually formatted as 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// a double. The returned format string may differ 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// from the input number because of this. 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::format(int64_t number, 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition& status) const 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return format((double) number, appendTo, status); 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Formats an int32_t number, it's actually formatted as 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// a double. 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::format(int32_t number, 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition& status) const 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return format((double) number, appendTo, status); 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Formats a double number. 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::format(double number, 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition& /*pos*/) const 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (msgPattern.countParts() == 0) { 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // No pattern was applied, or it failed. 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Get the appropriate sub-message. 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t msgStart = findSubMessage(msgPattern, 0, number); 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!MessageImpl::jdkAposMode(msgPattern)) { 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t patternStart = msgPattern.getPart(msgStart).getLimit(); 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t msgLimit = msgPattern.getLimitPartIndex(msgStart); 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.append(msgPattern.getPatternString(), 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org patternStart, 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern.getPatternIndex(msgLimit) - patternStart); 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // JDK compatibility mode: Remove SKIP_SYNTAX. 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return MessageImpl::appendSubMessageWithoutSkipSyntax(msgPattern, msgStart, appendTo); 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::findSubMessage(const MessagePattern &pattern, int32_t partIndex, double number) { 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t count = pattern.countParts(); 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t msgStart; 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Iterate over (ARG_INT|DOUBLE, ARG_SELECTOR, message) tuples 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // until ARG_LIMIT or end of choice-only pattern. 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Ignore the first number and selector and start the loop on the first message. 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org partIndex += 2; 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (;;) { 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Skip but remember the current sub-message. 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgStart = partIndex; 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org partIndex = pattern.getLimitPartIndex(partIndex); 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (++partIndex >= count) { 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Reached the end of the choice-only pattern. 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Return with the last sub-message. 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part &part = pattern.getPart(partIndex++); 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UMessagePatternPartType type = part.getType(); 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (type == UMSGPAT_PART_TYPE_ARG_LIMIT) { 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Reached the end of the ChoiceFormat style. 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Return with the last sub-message. 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // part is an ARG_INT or ARG_DOUBLE 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(MessagePattern::Part::hasNumericValue(type)); 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org double boundary = pattern.getNumericValue(part); 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Fetch the ARG_SELECTOR character. 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t selectorIndex = pattern.getPatternIndex(partIndex++); 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar boundaryChar = pattern.getPatternString().charAt(selectorIndex); 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (boundaryChar == LESS_THAN ? !(number > boundary) : !(number >= boundary)) { 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The number is in the interval between the previous boundary and the current one. 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Return with the sub-message between them. 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The !(a>b) and !(a>=b) comparisons are equivalent to 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // (a<=b) and (a<b) except they "catch" NaN. 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return msgStart; 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Formats an array of objects. Checks if the data type of the objects 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// to get the right value for formatting. 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::format(const Formattable* objs, 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt, 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition& pos, 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) const 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cnt < 0) { 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ILLEGAL_ARGUMENT_ERROR; 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (msgPattern.countParts() == 0) { 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_STATE_ERROR; 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; i < cnt; i++) { 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org double objDouble = objs[i].getDouble(status); 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org format(objDouble, appendTo, pos); 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::parse(const UnicodeString& text, 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable& result, 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ParsePosition& pos) const 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.setDouble(parseArgument(msgPattern, 0, text, pos)); 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdouble 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::parseArgument( 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern &pattern, int32_t partIndex, 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString &source, ParsePosition &pos) { 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // find the best number (defined as the one with the longest parse) 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t start = pos.getIndex(); 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t furthest = start; 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org double bestNumber = uprv_getNaN(); 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org double tempNumber = 0.0; 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t count = pattern.countParts(); 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while (partIndex < count && pattern.getPartType(partIndex) != UMSGPAT_PART_TYPE_ARG_LIMIT) { 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempNumber = pattern.getNumericValue(pattern.getPart(partIndex)); 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org partIndex += 2; // skip the numeric part and ignore the ARG_SELECTOR 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t msgLimit = pattern.getLimitPartIndex(partIndex); 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = matchStringUntilLimitPart(pattern, partIndex, msgLimit, source, start); 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (len >= 0) { 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t newIndex = start + len; 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newIndex > furthest) { 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org furthest = newIndex; 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bestNumber = tempNumber; 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (furthest == source.length()) { 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org partIndex = msgLimit + 1; 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (furthest == start) { 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos.setErrorIndex(start); 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos.setIndex(furthest); 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return bestNumber; 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::matchStringUntilLimitPart( 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern &pattern, int32_t partIndex, int32_t limitPartIndex, 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString &source, int32_t sourceOffset) { 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t matchingSourceLength = 0; 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString &msgString = pattern.getPatternString(); 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t prevIndex = pattern.getPart(partIndex).getLimit(); 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (;;) { 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part &part = pattern.getPart(++partIndex); 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (partIndex == limitPartIndex || part.getType() == UMSGPAT_PART_TYPE_SKIP_SYNTAX) { 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t index = part.getIndex(); 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length = index - prevIndex; 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (length != 0 && 0 != source.compare(sourceOffset, length, msgString, prevIndex, length)) { 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; // mismatch 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org matchingSourceLength += length; 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (partIndex == limitPartIndex) { 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return matchingSourceLength; 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex = part.getLimit(); // SKIP_SYNTAX 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormat* 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgChoiceFormat::clone() const 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ChoiceFormat *aCopy = new ChoiceFormat(*this); 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return aCopy; 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_FORMATTING */ 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//eof 576