164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// Copyright (C) 2016 and later: Unicode, Inc. and others. 264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 559d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 1997-2013, International Business Machines Corporation and * 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* others. All Rights Reserved. * 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* File CHOICFMT.CPP 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Modification History: 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Date Name Description 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 02/19/97 aliu Converted from java. 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 03/20/97 helena Finished first cut of implementation and got rid 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* of nextDouble/previousDouble and replaced with 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* boolean array. 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 4/10/97 aliu Clean up. Modified to work on AIX. 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 06/04/97 helena Fixed applyPattern(), toPattern() and not to include 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* wchar.h. 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 07/09/97 helena Made ParsePosition into a class. 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 08/06/97 nos removed overloaded constructor, fixed 'format(array)' 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 07/22/98 stephen JDK 1.2 Sync - removed UBool array (doubleFlags) 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 02/22/99 stephen Removed character literals for EBCDIC safety 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************** 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/choicfmt.h" 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/numfmt.h" 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/locid.h" 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cpputils.h" 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h" 37b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "messageimpl.h" 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "putilimp.h" 39b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uassert.h" 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h> 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <float.h> 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ***************************************************************************** 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// class ChoiceFormat 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ***************************************************************************** 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(ChoiceFormat) 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Special characters used by ChoiceFormat. There are two characters 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// used interchangeably to indicate <=. Either is parsed, but only 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// LESS_EQUAL is generated by toPattern(). 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SINGLE_QUOTE ((UChar)0x0027) /*'*/ 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define LESS_THAN ((UChar)0x003C) /*<*/ 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define LESS_EQUAL ((UChar)0x0023) /*#*/ 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define LESS_EQUAL2 ((UChar)0x2264) 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define VERTICAL_BAR ((UChar)0x007C) /*|*/ 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MINUS ((UChar)0x002D) /*-*/ 6085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 61b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar LEFT_CURLY_BRACE = 0x7B; /*{*/ 62b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar RIGHT_CURLY_BRACE = 0x7D; /*}*/ 63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 6485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#ifdef INFINITY 6585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#undef INFINITY 6685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define INFINITY ((UChar)0x221E) 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 6954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gPositiveInfinity[] = {INFINITY, 0}; 7054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar gNegativeInfinity[] = {MINUS, INFINITY, 0}; 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define POSITIVE_INF_STRLEN 1 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define NEGATIVE_INF_STRLEN 2 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Creates a ChoiceFormat instance based on the pattern. 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::ChoiceFormat(const UnicodeString& newPattern, 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) 79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: constructorErrorCode(status), 80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern(status) 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru applyPattern(newPattern, status); 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Creates a ChoiceFormat instance with the limit array and 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// format strings for each limit. 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::ChoiceFormat(const double* limits, 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString* formats, 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cnt ) 92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: constructorErrorCode(U_ZERO_ERROR), 93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern(constructorErrorCode) 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setChoices(limits, NULL, formats, cnt, constructorErrorCode); 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::ChoiceFormat(const double* limits, 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UBool* closures, 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString* formats, 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cnt ) 104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: constructorErrorCode(U_ZERO_ERROR), 105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern(constructorErrorCode) 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setChoices(limits, closures, formats, cnt, constructorErrorCode); 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// copy constructor 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::ChoiceFormat(const ChoiceFormat& that) 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru: NumberFormat(that), 115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho constructorErrorCode(that.constructorErrorCode), 116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern(that.msgPattern) 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Private constructor that creates a 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ChoiceFormat instance based on the 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// pattern and populates UParseError 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::ChoiceFormat(const UnicodeString& newPattern, 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& parseError, 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) 128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: constructorErrorCode(status), 129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern(status) 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru applyPattern(newPattern,parseError, status); 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::operator==(const Format& that) const 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (this == &that) return TRUE; 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!NumberFormat::operator==(that)) return FALSE; 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ChoiceFormat& thatAlias = (ChoiceFormat&)that; 141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return msgPattern == thatAlias.msgPattern; 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// copy constructor 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst ChoiceFormat& 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::operator=(const ChoiceFormat& that) 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (this != &that) { 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NumberFormat::operator=(that); 152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho constructorErrorCode = that.constructorErrorCode; 153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern = that.msgPattern; 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *this; 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::~ChoiceFormat() 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Convert a double value to a string without the overhead of NumberFormat. 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::dtos(double value, 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& string) 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Buffer to contain the digits and any extra formatting stuff. */ 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char temp[DBL_DIG + 16]; 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char *itrPtr = temp; 17685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho char *expPtr; 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 17885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho sprintf(temp, "%.*g", DBL_DIG, value); 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Find and convert the decimal point. 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Using setlocale on some machines will cause sprintf to use a comma for certain locales. 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (*itrPtr && (*itrPtr == '-' || isdigit(*itrPtr))) { 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru itrPtr++; 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 18685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (*itrPtr != 0 && *itrPtr != 'e') { 18785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* We reached something that looks like a decimal point. 18885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho In case someone used setlocale(), which changes the decimal point. */ 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *itrPtr = '.'; 19085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho itrPtr++; 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 19285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* Search for the exponent */ 19385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while (*itrPtr && *itrPtr != 'e') { 19485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho itrPtr++; 19585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 19685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (*itrPtr == 'e') { 19785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho itrPtr++; 19885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* Verify the exponent sign */ 19985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (*itrPtr == '+' || *itrPtr == '-') { 20085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho itrPtr++; 20185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 20285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* Remove leading zeros. You will see this on Windows machines. */ 20385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho expPtr = itrPtr; 20485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while (*itrPtr == '0') { 20585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho itrPtr++; 20685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 20785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (*itrPtr && expPtr != itrPtr) { 20885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* Shift the exponent without zeros. */ 20985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while (*itrPtr) { 21085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *(expPtr++) = *(itrPtr++); 21185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 21285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // NULL terminate 21385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *expPtr = 0; 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 21685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru string = UnicodeString(temp, -1, US_INV); /* invariant codepage */ 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return string; 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// calls the overloaded applyPattern method. 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::applyPattern(const UnicodeString& pattern, 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern.parseChoiceStyle(pattern, NULL, status); 229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho constructorErrorCode = status; 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Applies the pattern to this ChoiceFormat instance. 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::applyPattern(const UnicodeString& pattern, 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& parseError, 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern.parseChoiceStyle(pattern, &parseError, status); 241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho constructorErrorCode = status; 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Returns the input pattern string. 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::toPattern(UnicodeString& result) const 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return result = msgPattern.getPatternString(); 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Sets the limit and format arrays. 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::setChoices( const double* limits, 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString* formats, 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cnt ) 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode errorCode = U_ZERO_ERROR; 260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setChoices(limits, NULL, formats, cnt, errorCode); 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Sets the limit and format arrays. 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::setChoices( const double* limits, 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UBool* closures, 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString* formats, 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cnt ) 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode errorCode = U_ZERO_ERROR; 272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setChoices(limits, closures, formats, cnt, errorCode); 273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoChoiceFormat::setChoices(const double* limits, 277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UBool* closures, 278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString* formats, 279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t count, 280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode &errorCode) { 281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(errorCode)) { 282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 28385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (limits == NULL || formats == NULL) { 285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho errorCode = U_ILLEGAL_ARGUMENT_ERROR; 286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 28785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Reconstruct the original input pattern. 289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Modified version of the pre-ICU 4.8 toPattern() implementation. 290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString result; 291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < count; ++i) { 292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (i != 0) { 293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result += VERTICAL_BAR; 29485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString buf; 296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (uprv_isPositiveInfinity(limits[i])) { 297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result += INFINITY; 298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (uprv_isNegativeInfinity(limits[i])) { 299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result += MINUS; 300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result += INFINITY; 301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result += dtos(limits[i], buf); 30385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (closures != NULL && closures[i]) { 305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result += LESS_THAN; 306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result += LESS_EQUAL; 30885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Append formats[i], using quotes if there are special 310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // characters. Single quotes themselves must be escaped in 311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // either case. 312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString& text = formats[i]; 313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t textLength = text.length(); 314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t nestingLevel = 0; 315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t j = 0; j < textLength; ++j) { 316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar c = text[j]; 317b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (c == SINGLE_QUOTE && nestingLevel == 0) { 318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Double each top-level apostrophe. 319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result.append(c); 320b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (c == VERTICAL_BAR && nestingLevel == 0) { 321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Surround each pipe symbol with apostrophes for quoting. 322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // If the next character is an apostrophe, then that will be doubled, 323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // and although the parser will see the apostrophe pairs beginning 324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // and ending one character earlier than our doubling, the result 325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // is as desired. 326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // | -> '|' 327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // |' -> '|''' 328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // |'' -> '|''''' etc. 329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result.append(SINGLE_QUOTE).append(c).append(SINGLE_QUOTE); 330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho continue; // Skip the append(c) at the end of the loop body. 331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (c == LEFT_CURLY_BRACE) { 332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++nestingLevel; 333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (c == RIGHT_CURLY_BRACE && nestingLevel > 0) { 334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho --nestingLevel; 335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result.append(c); 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Apply the reconstructed pattern. 340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho applyPattern(result, errorCode); 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Gets the limit array. 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst double* 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::getLimits(int32_t& cnt) const 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 349b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cnt = 0; 350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Gets the closures array. 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UBool* 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::getClosures(int32_t& cnt) const 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 359b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cnt = 0; 360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Gets the format array. 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UnicodeString* 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::getFormats(int32_t& cnt) const 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cnt = 0; 370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Formats an int64 number, it's actually formatted as 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// a double. The returned format string may differ 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// from the input number because of this. 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::format(int64_t number, 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& appendTo, 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& status) const 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return format((double) number, appendTo, status); 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Formats an int32_t number, it's actually formatted as 388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// a double. 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::format(int32_t number, 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& appendTo, 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& status) const 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return format((double) number, appendTo, status); 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Formats a double number. 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::format(double number, 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& appendTo, 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /*pos*/) const 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (msgPattern.countParts() == 0) { 407b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // No pattern was applied, or it failed. 408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return appendTo; 409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Get the appropriate sub-message. 411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t msgStart = findSubMessage(msgPattern, 0, number); 412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!MessageImpl::jdkAposMode(msgPattern)) { 413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t patternStart = msgPattern.getPart(msgStart).getLimit(); 414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t msgLimit = msgPattern.getLimitPartIndex(msgStart); 415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.append(msgPattern.getPatternString(), 416b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho patternStart, 417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern.getPatternIndex(msgLimit) - patternStart); 418b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return appendTo; 419b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // JDK compatibility mode: Remove SKIP_SYNTAX. 421b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return MessageImpl::appendSubMessageWithoutSkipSyntax(msgPattern, msgStart, appendTo); 422b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 423b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 424b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t 425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoChoiceFormat::findSubMessage(const MessagePattern &pattern, int32_t partIndex, double number) { 426b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t count = pattern.countParts(); 427b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t msgStart; 428b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Iterate over (ARG_INT|DOUBLE, ARG_SELECTOR, message) tuples 429b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // until ARG_LIMIT or end of choice-only pattern. 430b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Ignore the first number and selector and start the loop on the first message. 431b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho partIndex += 2; 432b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (;;) { 433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Skip but remember the current sub-message. 434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgStart = partIndex; 435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho partIndex = pattern.getLimitPartIndex(partIndex); 436b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (++partIndex >= count) { 437b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Reached the end of the choice-only pattern. 438b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Return with the last sub-message. 439b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 440b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part &part = pattern.getPart(partIndex++); 442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UMessagePatternPartType type = part.getType(); 443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (type == UMSGPAT_PART_TYPE_ARG_LIMIT) { 444b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Reached the end of the ChoiceFormat style. 445b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Return with the last sub-message. 446b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 447b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 448b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // part is an ARG_INT or ARG_DOUBLE 449b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(MessagePattern::Part::hasNumericValue(type)); 450b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho double boundary = pattern.getNumericValue(part); 451b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Fetch the ARG_SELECTOR character. 452b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t selectorIndex = pattern.getPatternIndex(partIndex++); 453b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar boundaryChar = pattern.getPatternString().charAt(selectorIndex); 454b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (boundaryChar == LESS_THAN ? !(number > boundary) : !(number >= boundary)) { 455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // The number is in the interval between the previous boundary and the current one. 456b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Return with the sub-message between them. 457b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // The !(a>b) and !(a>=b) comparisons are equivalent to 458b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // (a<=b) and (a<b) except they "catch" NaN. 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 462b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return msgStart; 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Formats an array of objects. Checks if the data type of the objects 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// to get the right value for formatting. 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::format(const Formattable* objs, 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cnt, 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& appendTo, 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& pos, 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) const 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(cnt < 0) { 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return appendTo; 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 480b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (msgPattern.countParts() == 0) { 481b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_INVALID_STATE_ERROR; 482b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return appendTo; 483b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t i = 0; i < cnt; i++) { 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double objDouble = objs[i].getDouble(status); 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho format(objDouble, appendTo, pos); 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return appendTo; 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::parse(const UnicodeString& text, 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Formattable& result, 500b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ParsePosition& pos) const 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 502b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result.setDouble(parseArgument(msgPattern, 0, text, pos)); 503b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 504b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehodouble 506b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoChoiceFormat::parseArgument( 507b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern &pattern, int32_t partIndex, 508b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString &source, ParsePosition &pos) { 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // find the best number (defined as the one with the longest parse) 510b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t start = pos.getIndex(); 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t furthest = start; 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double bestNumber = uprv_getNaN(); 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double tempNumber = 0.0; 514b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t count = pattern.countParts(); 515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (partIndex < count && pattern.getPartType(partIndex) != UMSGPAT_PART_TYPE_ARG_LIMIT) { 516b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tempNumber = pattern.getNumericValue(pattern.getPart(partIndex)); 517b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho partIndex += 2; // skip the numeric part and ignore the ARG_SELECTOR 518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t msgLimit = pattern.getLimitPartIndex(partIndex); 519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t len = matchStringUntilLimitPart(pattern, partIndex, msgLimit, source, start); 520b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (len >= 0) { 521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t newIndex = start + len; 522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newIndex > furthest) { 523b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho furthest = newIndex; 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bestNumber = tempNumber; 525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (furthest == source.length()) { 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 527b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 530b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho partIndex = msgLimit + 1; 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 532b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (furthest == start) { 533b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos.setErrorIndex(start); 534b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 535b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos.setIndex(furthest); 536b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 537b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return bestNumber; 538b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 539b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 540b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t 541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoChoiceFormat::matchStringUntilLimitPart( 542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern &pattern, int32_t partIndex, int32_t limitPartIndex, 543b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString &source, int32_t sourceOffset) { 544b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t matchingSourceLength = 0; 545b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString &msgString = pattern.getPatternString(); 546b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t prevIndex = pattern.getPart(partIndex).getLimit(); 547b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (;;) { 548b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part &part = pattern.getPart(++partIndex); 549b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (partIndex == limitPartIndex || part.getType() == UMSGPAT_PART_TYPE_SKIP_SYNTAX) { 550b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index = part.getIndex(); 551b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t length = index - prevIndex; 552b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (length != 0 && 0 != source.compare(sourceOffset, length, msgString, prevIndex, length)) { 553b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return -1; // mismatch 554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 555b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho matchingSourceLength += length; 556b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (partIndex == limitPartIndex) { 557b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return matchingSourceLength; 558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 559b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex = part.getLimit(); // SKIP_SYNTAX 560b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruFormat* 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruChoiceFormat::clone() const 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ChoiceFormat *aCopy = new ChoiceFormat(*this); 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return aCopy; 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */ 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//eof 578