1*0e209d39SAndroid Build Coastguard Worker // © 2016 and later: Unicode, Inc. and others. 2*0e209d39SAndroid Build Coastguard Worker // License & terms of use: http://www.unicode.org/copyright.html 3*0e209d39SAndroid Build Coastguard Worker /* 4*0e209d39SAndroid Build Coastguard Worker ******************************************************************************* 5*0e209d39SAndroid Build Coastguard Worker * Copyright (C) 2007-2016, International Business Machines Corporation and 6*0e209d39SAndroid Build Coastguard Worker * others. All Rights Reserved. 7*0e209d39SAndroid Build Coastguard Worker ******************************************************************************* 8*0e209d39SAndroid Build Coastguard Worker * 9*0e209d39SAndroid Build Coastguard Worker * File PLURRULE_IMPL.H 10*0e209d39SAndroid Build Coastguard Worker * 11*0e209d39SAndroid Build Coastguard Worker ******************************************************************************* 12*0e209d39SAndroid Build Coastguard Worker */ 13*0e209d39SAndroid Build Coastguard Worker 14*0e209d39SAndroid Build Coastguard Worker 15*0e209d39SAndroid Build Coastguard Worker #ifndef PLURRULE_IMPL 16*0e209d39SAndroid Build Coastguard Worker #define PLURRULE_IMPL 17*0e209d39SAndroid Build Coastguard Worker 18*0e209d39SAndroid Build Coastguard Worker // Internal definitions for the PluralRules implementation. 19*0e209d39SAndroid Build Coastguard Worker 20*0e209d39SAndroid Build Coastguard Worker #include "unicode/utypes.h" 21*0e209d39SAndroid Build Coastguard Worker 22*0e209d39SAndroid Build Coastguard Worker #if !UCONFIG_NO_FORMATTING 23*0e209d39SAndroid Build Coastguard Worker 24*0e209d39SAndroid Build Coastguard Worker #include "unicode/format.h" 25*0e209d39SAndroid Build Coastguard Worker #include "unicode/locid.h" 26*0e209d39SAndroid Build Coastguard Worker #include "unicode/parseerr.h" 27*0e209d39SAndroid Build Coastguard Worker #include "unicode/strenum.h" 28*0e209d39SAndroid Build Coastguard Worker #include "unicode/ures.h" 29*0e209d39SAndroid Build Coastguard Worker #include "uvector.h" 30*0e209d39SAndroid Build Coastguard Worker #include "hash.h" 31*0e209d39SAndroid Build Coastguard Worker #include "uassert.h" 32*0e209d39SAndroid Build Coastguard Worker 33*0e209d39SAndroid Build Coastguard Worker /** 34*0e209d39SAndroid Build Coastguard Worker * A FixedDecimal version of UPLRULES_NO_UNIQUE_VALUE used in PluralRulesTest 35*0e209d39SAndroid Build Coastguard Worker * for parsing of samples. 36*0e209d39SAndroid Build Coastguard Worker */ 37*0e209d39SAndroid Build Coastguard Worker #define UPLRULES_NO_UNIQUE_VALUE_DECIMAL(ERROR_CODE) (DecimalQuantity::fromExponentString(u"-0.00123456777", ERROR_CODE)) 38*0e209d39SAndroid Build Coastguard Worker 39*0e209d39SAndroid Build Coastguard Worker class PluralRulesTest; 40*0e209d39SAndroid Build Coastguard Worker 41*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN 42*0e209d39SAndroid Build Coastguard Worker 43*0e209d39SAndroid Build Coastguard Worker class AndConstraint; 44*0e209d39SAndroid Build Coastguard Worker class RuleChain; 45*0e209d39SAndroid Build Coastguard Worker class DigitInterval; 46*0e209d39SAndroid Build Coastguard Worker class PluralRules; 47*0e209d39SAndroid Build Coastguard Worker class VisibleDigits; 48*0e209d39SAndroid Build Coastguard Worker 49*0e209d39SAndroid Build Coastguard Worker namespace pluralimpl { 50*0e209d39SAndroid Build Coastguard Worker 51*0e209d39SAndroid Build Coastguard Worker // TODO: Remove this and replace with u"" literals. Was for EBCDIC compatibility. 52*0e209d39SAndroid Build Coastguard Worker 53*0e209d39SAndroid Build Coastguard Worker static const char16_t DOT = ((char16_t) 0x002E); 54*0e209d39SAndroid Build Coastguard Worker static const char16_t SINGLE_QUOTE = ((char16_t) 0x0027); 55*0e209d39SAndroid Build Coastguard Worker static const char16_t SLASH = ((char16_t) 0x002F); 56*0e209d39SAndroid Build Coastguard Worker static const char16_t BACKSLASH = ((char16_t) 0x005C); 57*0e209d39SAndroid Build Coastguard Worker static const char16_t SPACE = ((char16_t) 0x0020); 58*0e209d39SAndroid Build Coastguard Worker static const char16_t EXCLAMATION = ((char16_t) 0x0021); 59*0e209d39SAndroid Build Coastguard Worker static const char16_t QUOTATION_MARK = ((char16_t) 0x0022); 60*0e209d39SAndroid Build Coastguard Worker static const char16_t NUMBER_SIGN = ((char16_t) 0x0023); 61*0e209d39SAndroid Build Coastguard Worker static const char16_t PERCENT_SIGN = ((char16_t) 0x0025); 62*0e209d39SAndroid Build Coastguard Worker static const char16_t ASTERISK = ((char16_t) 0x002A); 63*0e209d39SAndroid Build Coastguard Worker static const char16_t COMMA = ((char16_t) 0x002C); 64*0e209d39SAndroid Build Coastguard Worker static const char16_t HYPHEN = ((char16_t) 0x002D); 65*0e209d39SAndroid Build Coastguard Worker static const char16_t U_ZERO = ((char16_t) 0x0030); 66*0e209d39SAndroid Build Coastguard Worker static const char16_t U_ONE = ((char16_t) 0x0031); 67*0e209d39SAndroid Build Coastguard Worker static const char16_t U_TWO = ((char16_t) 0x0032); 68*0e209d39SAndroid Build Coastguard Worker static const char16_t U_THREE = ((char16_t) 0x0033); 69*0e209d39SAndroid Build Coastguard Worker static const char16_t U_FOUR = ((char16_t) 0x0034); 70*0e209d39SAndroid Build Coastguard Worker static const char16_t U_FIVE = ((char16_t) 0x0035); 71*0e209d39SAndroid Build Coastguard Worker static const char16_t U_SIX = ((char16_t) 0x0036); 72*0e209d39SAndroid Build Coastguard Worker static const char16_t U_SEVEN = ((char16_t) 0x0037); 73*0e209d39SAndroid Build Coastguard Worker static const char16_t U_EIGHT = ((char16_t) 0x0038); 74*0e209d39SAndroid Build Coastguard Worker static const char16_t U_NINE = ((char16_t) 0x0039); 75*0e209d39SAndroid Build Coastguard Worker static const char16_t COLON = ((char16_t) 0x003A); 76*0e209d39SAndroid Build Coastguard Worker static const char16_t SEMI_COLON = ((char16_t) 0x003B); 77*0e209d39SAndroid Build Coastguard Worker static const char16_t EQUALS = ((char16_t) 0x003D); 78*0e209d39SAndroid Build Coastguard Worker static const char16_t AT = ((char16_t) 0x0040); 79*0e209d39SAndroid Build Coastguard Worker static const char16_t CAP_A = ((char16_t) 0x0041); 80*0e209d39SAndroid Build Coastguard Worker static const char16_t CAP_B = ((char16_t) 0x0042); 81*0e209d39SAndroid Build Coastguard Worker static const char16_t CAP_R = ((char16_t) 0x0052); 82*0e209d39SAndroid Build Coastguard Worker static const char16_t CAP_Z = ((char16_t) 0x005A); 83*0e209d39SAndroid Build Coastguard Worker static const char16_t LOWLINE = ((char16_t) 0x005F); 84*0e209d39SAndroid Build Coastguard Worker static const char16_t LEFTBRACE = ((char16_t) 0x007B); 85*0e209d39SAndroid Build Coastguard Worker static const char16_t RIGHTBRACE = ((char16_t) 0x007D); 86*0e209d39SAndroid Build Coastguard Worker static const char16_t TILDE = ((char16_t) 0x007E); 87*0e209d39SAndroid Build Coastguard Worker static const char16_t ELLIPSIS = ((char16_t) 0x2026); 88*0e209d39SAndroid Build Coastguard Worker 89*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_A = ((char16_t) 0x0061); 90*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_B = ((char16_t) 0x0062); 91*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_C = ((char16_t) 0x0063); 92*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_D = ((char16_t) 0x0064); 93*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_E = ((char16_t) 0x0065); 94*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_F = ((char16_t) 0x0066); 95*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_G = ((char16_t) 0x0067); 96*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_H = ((char16_t) 0x0068); 97*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_I = ((char16_t) 0x0069); 98*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_J = ((char16_t) 0x006a); 99*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_K = ((char16_t) 0x006B); 100*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_L = ((char16_t) 0x006C); 101*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_M = ((char16_t) 0x006D); 102*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_N = ((char16_t) 0x006E); 103*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_O = ((char16_t) 0x006F); 104*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_P = ((char16_t) 0x0070); 105*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_Q = ((char16_t) 0x0071); 106*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_R = ((char16_t) 0x0072); 107*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_S = ((char16_t) 0x0073); 108*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_T = ((char16_t) 0x0074); 109*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_U = ((char16_t) 0x0075); 110*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_V = ((char16_t) 0x0076); 111*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_W = ((char16_t) 0x0077); 112*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_Y = ((char16_t) 0x0079); 113*0e209d39SAndroid Build Coastguard Worker static const char16_t LOW_Z = ((char16_t) 0x007A); 114*0e209d39SAndroid Build Coastguard Worker 115*0e209d39SAndroid Build Coastguard Worker } 116*0e209d39SAndroid Build Coastguard Worker 117*0e209d39SAndroid Build Coastguard Worker 118*0e209d39SAndroid Build Coastguard Worker static const int32_t PLURAL_RANGE_HIGH = 0x7fffffff; 119*0e209d39SAndroid Build Coastguard Worker 120*0e209d39SAndroid Build Coastguard Worker enum tokenType { 121*0e209d39SAndroid Build Coastguard Worker none, 122*0e209d39SAndroid Build Coastguard Worker tNumber, 123*0e209d39SAndroid Build Coastguard Worker tComma, 124*0e209d39SAndroid Build Coastguard Worker tSemiColon, 125*0e209d39SAndroid Build Coastguard Worker tSpace, 126*0e209d39SAndroid Build Coastguard Worker tColon, 127*0e209d39SAndroid Build Coastguard Worker tAt, // '@' 128*0e209d39SAndroid Build Coastguard Worker tDot, 129*0e209d39SAndroid Build Coastguard Worker tDot2, 130*0e209d39SAndroid Build Coastguard Worker tEllipsis, 131*0e209d39SAndroid Build Coastguard Worker tKeyword, 132*0e209d39SAndroid Build Coastguard Worker tAnd, 133*0e209d39SAndroid Build Coastguard Worker tOr, 134*0e209d39SAndroid Build Coastguard Worker tMod, // 'mod' or '%' 135*0e209d39SAndroid Build Coastguard Worker tNot, // 'not' only. 136*0e209d39SAndroid Build Coastguard Worker tIn, // 'in' only. 137*0e209d39SAndroid Build Coastguard Worker tEqual, // '=' only. 138*0e209d39SAndroid Build Coastguard Worker tNotEqual, // '!=' 139*0e209d39SAndroid Build Coastguard Worker tTilde, 140*0e209d39SAndroid Build Coastguard Worker tWithin, 141*0e209d39SAndroid Build Coastguard Worker tIs, 142*0e209d39SAndroid Build Coastguard Worker tVariableN, 143*0e209d39SAndroid Build Coastguard Worker tVariableI, 144*0e209d39SAndroid Build Coastguard Worker tVariableF, 145*0e209d39SAndroid Build Coastguard Worker tVariableV, 146*0e209d39SAndroid Build Coastguard Worker tVariableT, 147*0e209d39SAndroid Build Coastguard Worker tVariableE, 148*0e209d39SAndroid Build Coastguard Worker tVariableC, 149*0e209d39SAndroid Build Coastguard Worker tDecimal, 150*0e209d39SAndroid Build Coastguard Worker tInteger, 151*0e209d39SAndroid Build Coastguard Worker tEOF 152*0e209d39SAndroid Build Coastguard Worker }; 153*0e209d39SAndroid Build Coastguard Worker 154*0e209d39SAndroid Build Coastguard Worker 155*0e209d39SAndroid Build Coastguard Worker class PluralRuleParser: public UMemory { 156*0e209d39SAndroid Build Coastguard Worker public: 157*0e209d39SAndroid Build Coastguard Worker PluralRuleParser(); 158*0e209d39SAndroid Build Coastguard Worker virtual ~PluralRuleParser(); 159*0e209d39SAndroid Build Coastguard Worker 160*0e209d39SAndroid Build Coastguard Worker void parse(const UnicodeString &rules, PluralRules *dest, UErrorCode &status); 161*0e209d39SAndroid Build Coastguard Worker void getNextToken(UErrorCode &status); 162*0e209d39SAndroid Build Coastguard Worker void checkSyntax(UErrorCode &status); 163*0e209d39SAndroid Build Coastguard Worker static int32_t getNumberValue(const UnicodeString &token); 164*0e209d39SAndroid Build Coastguard Worker 165*0e209d39SAndroid Build Coastguard Worker private: 166*0e209d39SAndroid Build Coastguard Worker static tokenType getKeyType(const UnicodeString& token, tokenType type); 167*0e209d39SAndroid Build Coastguard Worker static tokenType charType(char16_t ch); 168*0e209d39SAndroid Build Coastguard Worker static UBool isValidKeyword(const UnicodeString& token); 169*0e209d39SAndroid Build Coastguard Worker 170*0e209d39SAndroid Build Coastguard Worker const UnicodeString *ruleSrc; // The rules string. 171*0e209d39SAndroid Build Coastguard Worker int32_t ruleIndex; // String index in the input rules, the current parse position. 172*0e209d39SAndroid Build Coastguard Worker UnicodeString token; // Token most recently scanned. 173*0e209d39SAndroid Build Coastguard Worker tokenType type; 174*0e209d39SAndroid Build Coastguard Worker tokenType prevType; 175*0e209d39SAndroid Build Coastguard Worker 176*0e209d39SAndroid Build Coastguard Worker // The items currently being parsed & built. 177*0e209d39SAndroid Build Coastguard Worker // Note: currentChain may not be the last RuleChain in the 178*0e209d39SAndroid Build Coastguard Worker // list because the "other" chain is forced to the end. 179*0e209d39SAndroid Build Coastguard Worker AndConstraint *curAndConstraint; 180*0e209d39SAndroid Build Coastguard Worker RuleChain *currentChain; 181*0e209d39SAndroid Build Coastguard Worker 182*0e209d39SAndroid Build Coastguard Worker int32_t rangeLowIdx; // Indices in the UVector of ranges of the 183*0e209d39SAndroid Build Coastguard Worker int32_t rangeHiIdx; // low and hi values currently being parsed. 184*0e209d39SAndroid Build Coastguard Worker 185*0e209d39SAndroid Build Coastguard Worker enum EParseState { 186*0e209d39SAndroid Build Coastguard Worker kKeyword, 187*0e209d39SAndroid Build Coastguard Worker kExpr, 188*0e209d39SAndroid Build Coastguard Worker kValue, 189*0e209d39SAndroid Build Coastguard Worker kRangeList, 190*0e209d39SAndroid Build Coastguard Worker kSamples 191*0e209d39SAndroid Build Coastguard Worker }; 192*0e209d39SAndroid Build Coastguard Worker }; 193*0e209d39SAndroid Build Coastguard Worker 194*0e209d39SAndroid Build Coastguard Worker enum PluralOperand { 195*0e209d39SAndroid Build Coastguard Worker /** 196*0e209d39SAndroid Build Coastguard Worker * The double value of the entire number. 197*0e209d39SAndroid Build Coastguard Worker */ 198*0e209d39SAndroid Build Coastguard Worker PLURAL_OPERAND_N, 199*0e209d39SAndroid Build Coastguard Worker 200*0e209d39SAndroid Build Coastguard Worker /** 201*0e209d39SAndroid Build Coastguard Worker * The integer value, with the fraction digits truncated off. 202*0e209d39SAndroid Build Coastguard Worker */ 203*0e209d39SAndroid Build Coastguard Worker PLURAL_OPERAND_I, 204*0e209d39SAndroid Build Coastguard Worker 205*0e209d39SAndroid Build Coastguard Worker /** 206*0e209d39SAndroid Build Coastguard Worker * All visible fraction digits as an integer, including trailing zeros. 207*0e209d39SAndroid Build Coastguard Worker */ 208*0e209d39SAndroid Build Coastguard Worker PLURAL_OPERAND_F, 209*0e209d39SAndroid Build Coastguard Worker 210*0e209d39SAndroid Build Coastguard Worker /** 211*0e209d39SAndroid Build Coastguard Worker * Visible fraction digits as an integer, not including trailing zeros. 212*0e209d39SAndroid Build Coastguard Worker */ 213*0e209d39SAndroid Build Coastguard Worker PLURAL_OPERAND_T, 214*0e209d39SAndroid Build Coastguard Worker 215*0e209d39SAndroid Build Coastguard Worker /** 216*0e209d39SAndroid Build Coastguard Worker * Number of visible fraction digits. 217*0e209d39SAndroid Build Coastguard Worker */ 218*0e209d39SAndroid Build Coastguard Worker PLURAL_OPERAND_V, 219*0e209d39SAndroid Build Coastguard Worker 220*0e209d39SAndroid Build Coastguard Worker /** 221*0e209d39SAndroid Build Coastguard Worker * Number of visible fraction digits, not including trailing zeros. 222*0e209d39SAndroid Build Coastguard Worker */ 223*0e209d39SAndroid Build Coastguard Worker PLURAL_OPERAND_W, 224*0e209d39SAndroid Build Coastguard Worker 225*0e209d39SAndroid Build Coastguard Worker /** 226*0e209d39SAndroid Build Coastguard Worker * Suppressed exponent for scientific notation (exponent needed in 227*0e209d39SAndroid Build Coastguard Worker * scientific notation to approximate i). 228*0e209d39SAndroid Build Coastguard Worker */ 229*0e209d39SAndroid Build Coastguard Worker PLURAL_OPERAND_E, 230*0e209d39SAndroid Build Coastguard Worker 231*0e209d39SAndroid Build Coastguard Worker /** 232*0e209d39SAndroid Build Coastguard Worker * This operand is currently treated as an alias for `PLURAL_OPERAND_E`. 233*0e209d39SAndroid Build Coastguard Worker * In the future, it will represent: 234*0e209d39SAndroid Build Coastguard Worker * 235*0e209d39SAndroid Build Coastguard Worker * Suppressed exponent for compact notation (exponent needed in 236*0e209d39SAndroid Build Coastguard Worker * compact notation to approximate i). 237*0e209d39SAndroid Build Coastguard Worker */ 238*0e209d39SAndroid Build Coastguard Worker PLURAL_OPERAND_C, 239*0e209d39SAndroid Build Coastguard Worker 240*0e209d39SAndroid Build Coastguard Worker /** 241*0e209d39SAndroid Build Coastguard Worker * THIS OPERAND IS DEPRECATED AND HAS BEEN REMOVED FROM THE SPEC. 242*0e209d39SAndroid Build Coastguard Worker * 243*0e209d39SAndroid Build Coastguard Worker * <p>Returns the integer value, but will fail if the number has fraction digits. 244*0e209d39SAndroid Build Coastguard Worker * That is, using "j" instead of "i" is like implicitly adding "v is 0". 245*0e209d39SAndroid Build Coastguard Worker * 246*0e209d39SAndroid Build Coastguard Worker * <p>For example, "j is 3" is equivalent to "i is 3 and v is 0": it matches 247*0e209d39SAndroid Build Coastguard Worker * "3" but not "3.1" or "3.0". 248*0e209d39SAndroid Build Coastguard Worker */ 249*0e209d39SAndroid Build Coastguard Worker PLURAL_OPERAND_J 250*0e209d39SAndroid Build Coastguard Worker }; 251*0e209d39SAndroid Build Coastguard Worker 252*0e209d39SAndroid Build Coastguard Worker /** 253*0e209d39SAndroid Build Coastguard Worker * Converts from the tokenType enum to PluralOperand. Asserts that the given 254*0e209d39SAndroid Build Coastguard Worker * tokenType can be mapped to a PluralOperand. 255*0e209d39SAndroid Build Coastguard Worker */ 256*0e209d39SAndroid Build Coastguard Worker PluralOperand tokenTypeToPluralOperand(tokenType tt); 257*0e209d39SAndroid Build Coastguard Worker 258*0e209d39SAndroid Build Coastguard Worker /** 259*0e209d39SAndroid Build Coastguard Worker * An interface to FixedDecimal, allowing for other implementations. 260*0e209d39SAndroid Build Coastguard Worker * @internal 261*0e209d39SAndroid Build Coastguard Worker */ 262*0e209d39SAndroid Build Coastguard Worker class U_I18N_API IFixedDecimal { 263*0e209d39SAndroid Build Coastguard Worker public: 264*0e209d39SAndroid Build Coastguard Worker virtual ~IFixedDecimal(); 265*0e209d39SAndroid Build Coastguard Worker 266*0e209d39SAndroid Build Coastguard Worker /** 267*0e209d39SAndroid Build Coastguard Worker * Returns the value corresponding to the specified operand (n, i, f, t, v, or w). 268*0e209d39SAndroid Build Coastguard Worker * If the operand is 'n', returns a double; otherwise, returns an integer. 269*0e209d39SAndroid Build Coastguard Worker */ 270*0e209d39SAndroid Build Coastguard Worker virtual double getPluralOperand(PluralOperand operand) const = 0; 271*0e209d39SAndroid Build Coastguard Worker 272*0e209d39SAndroid Build Coastguard Worker virtual bool isNaN() const = 0; 273*0e209d39SAndroid Build Coastguard Worker 274*0e209d39SAndroid Build Coastguard Worker virtual bool isInfinite() const = 0; 275*0e209d39SAndroid Build Coastguard Worker 276*0e209d39SAndroid Build Coastguard Worker /** Whether the number has no nonzero fraction digits. */ 277*0e209d39SAndroid Build Coastguard Worker virtual bool hasIntegerValue() const = 0; 278*0e209d39SAndroid Build Coastguard Worker }; 279*0e209d39SAndroid Build Coastguard Worker 280*0e209d39SAndroid Build Coastguard Worker /** 281*0e209d39SAndroid Build Coastguard Worker * class FixedDecimal serves to communicate the properties 282*0e209d39SAndroid Build Coastguard Worker * of a formatted number from a decimal formatter to PluralRules::select() 283*0e209d39SAndroid Build Coastguard Worker * 284*0e209d39SAndroid Build Coastguard Worker * see DecimalFormat::getFixedDecimal() 285*0e209d39SAndroid Build Coastguard Worker * @internal 286*0e209d39SAndroid Build Coastguard Worker */ 287*0e209d39SAndroid Build Coastguard Worker class U_I18N_API FixedDecimal: public IFixedDecimal, public UObject { 288*0e209d39SAndroid Build Coastguard Worker public: 289*0e209d39SAndroid Build Coastguard Worker /** 290*0e209d39SAndroid Build Coastguard Worker * @param n the number, e.g. 12.345 291*0e209d39SAndroid Build Coastguard Worker * @param v The number of visible fraction digits, e.g. 3 292*0e209d39SAndroid Build Coastguard Worker * @param f The fraction digits, e.g. 345 293*0e209d39SAndroid Build Coastguard Worker * @param e The exponent, e.g. 7 in 1.2e7, for scientific notation 294*0e209d39SAndroid Build Coastguard Worker * @param c Currently: an alias for param `e`. 295*0e209d39SAndroid Build Coastguard Worker */ 296*0e209d39SAndroid Build Coastguard Worker FixedDecimal(double n, int32_t v, int64_t f, int32_t e, int32_t c); 297*0e209d39SAndroid Build Coastguard Worker FixedDecimal(double n, int32_t v, int64_t f, int32_t e); 298*0e209d39SAndroid Build Coastguard Worker FixedDecimal(double n, int32_t v, int64_t f); 299*0e209d39SAndroid Build Coastguard Worker FixedDecimal(double n, int32_t); 300*0e209d39SAndroid Build Coastguard Worker explicit FixedDecimal(double n); 301*0e209d39SAndroid Build Coastguard Worker FixedDecimal(); 302*0e209d39SAndroid Build Coastguard Worker ~FixedDecimal() override; 303*0e209d39SAndroid Build Coastguard Worker FixedDecimal(const UnicodeString &s, UErrorCode &ec); 304*0e209d39SAndroid Build Coastguard Worker FixedDecimal(const FixedDecimal &other); 305*0e209d39SAndroid Build Coastguard Worker 306*0e209d39SAndroid Build Coastguard Worker static FixedDecimal createWithExponent(double n, int32_t v, int32_t e); 307*0e209d39SAndroid Build Coastguard Worker 308*0e209d39SAndroid Build Coastguard Worker double getPluralOperand(PluralOperand operand) const override; 309*0e209d39SAndroid Build Coastguard Worker bool isNaN() const override; 310*0e209d39SAndroid Build Coastguard Worker bool isInfinite() const override; 311*0e209d39SAndroid Build Coastguard Worker bool hasIntegerValue() const override; 312*0e209d39SAndroid Build Coastguard Worker 313*0e209d39SAndroid Build Coastguard Worker bool isNanOrInfinity() const; // used in decimfmtimpl.cpp 314*0e209d39SAndroid Build Coastguard Worker 315*0e209d39SAndroid Build Coastguard Worker int32_t getVisibleFractionDigitCount() const; 316*0e209d39SAndroid Build Coastguard Worker 317*0e209d39SAndroid Build Coastguard Worker void init(double n, int32_t v, int64_t f, int32_t e, int32_t c); 318*0e209d39SAndroid Build Coastguard Worker void init(double n, int32_t v, int64_t f, int32_t e); 319*0e209d39SAndroid Build Coastguard Worker void init(double n, int32_t v, int64_t f); 320*0e209d39SAndroid Build Coastguard Worker void init(double n); 321*0e209d39SAndroid Build Coastguard Worker UBool quickInit(double n); // Try a fast-path only initialization, 322*0e209d39SAndroid Build Coastguard Worker // return true if successful. 323*0e209d39SAndroid Build Coastguard Worker void adjustForMinFractionDigits(int32_t min); 324*0e209d39SAndroid Build Coastguard Worker static int64_t getFractionalDigits(double n, int32_t v); 325*0e209d39SAndroid Build Coastguard Worker static int32_t decimals(double n); 326*0e209d39SAndroid Build Coastguard Worker 327*0e209d39SAndroid Build Coastguard Worker FixedDecimal& operator=(const FixedDecimal& other) = default; 328*0e209d39SAndroid Build Coastguard Worker bool operator==(const FixedDecimal &other) const; 329*0e209d39SAndroid Build Coastguard Worker 330*0e209d39SAndroid Build Coastguard Worker UnicodeString toString() const; 331*0e209d39SAndroid Build Coastguard Worker 332*0e209d39SAndroid Build Coastguard Worker double doubleValue() const; 333*0e209d39SAndroid Build Coastguard Worker int64_t longValue() const; 334*0e209d39SAndroid Build Coastguard Worker 335*0e209d39SAndroid Build Coastguard Worker double source; 336*0e209d39SAndroid Build Coastguard Worker int32_t visibleDecimalDigitCount; 337*0e209d39SAndroid Build Coastguard Worker int64_t decimalDigits; 338*0e209d39SAndroid Build Coastguard Worker int64_t decimalDigitsWithoutTrailingZeros; 339*0e209d39SAndroid Build Coastguard Worker int64_t intValue; 340*0e209d39SAndroid Build Coastguard Worker int32_t exponent; 341*0e209d39SAndroid Build Coastguard Worker UBool _hasIntegerValue; 342*0e209d39SAndroid Build Coastguard Worker UBool isNegative; 343*0e209d39SAndroid Build Coastguard Worker UBool _isNaN; 344*0e209d39SAndroid Build Coastguard Worker UBool _isInfinite; 345*0e209d39SAndroid Build Coastguard Worker }; 346*0e209d39SAndroid Build Coastguard Worker 347*0e209d39SAndroid Build Coastguard Worker class AndConstraint : public UMemory { 348*0e209d39SAndroid Build Coastguard Worker public: 349*0e209d39SAndroid Build Coastguard Worker typedef enum RuleOp { 350*0e209d39SAndroid Build Coastguard Worker NONE, 351*0e209d39SAndroid Build Coastguard Worker MOD 352*0e209d39SAndroid Build Coastguard Worker } RuleOp; 353*0e209d39SAndroid Build Coastguard Worker RuleOp op = AndConstraint::NONE; 354*0e209d39SAndroid Build Coastguard Worker int32_t opNum = -1; // for mod expressions, the right operand of the mod. 355*0e209d39SAndroid Build Coastguard Worker int32_t value = -1; // valid for 'is' rules only. 356*0e209d39SAndroid Build Coastguard Worker UVector32 *rangeList = nullptr; // for 'in', 'within' rules. Null otherwise. 357*0e209d39SAndroid Build Coastguard Worker UBool negated = false; // true for negated rules. 358*0e209d39SAndroid Build Coastguard Worker UBool integerOnly = false; // true for 'within' rules. 359*0e209d39SAndroid Build Coastguard Worker tokenType digitsType = none; // n | i | v | f constraint. 360*0e209d39SAndroid Build Coastguard Worker AndConstraint *next = nullptr; 361*0e209d39SAndroid Build Coastguard Worker // Internal error status, used for errors that occur during the copy constructor. 362*0e209d39SAndroid Build Coastguard Worker UErrorCode fInternalStatus = U_ZERO_ERROR; 363*0e209d39SAndroid Build Coastguard Worker 364*0e209d39SAndroid Build Coastguard Worker AndConstraint() = default; 365*0e209d39SAndroid Build Coastguard Worker AndConstraint(const AndConstraint& other); 366*0e209d39SAndroid Build Coastguard Worker virtual ~AndConstraint(); 367*0e209d39SAndroid Build Coastguard Worker AndConstraint* add(UErrorCode& status); 368*0e209d39SAndroid Build Coastguard Worker // UBool isFulfilled(double number); 369*0e209d39SAndroid Build Coastguard Worker UBool isFulfilled(const IFixedDecimal &number); 370*0e209d39SAndroid Build Coastguard Worker }; 371*0e209d39SAndroid Build Coastguard Worker 372*0e209d39SAndroid Build Coastguard Worker class OrConstraint : public UMemory { 373*0e209d39SAndroid Build Coastguard Worker public: 374*0e209d39SAndroid Build Coastguard Worker AndConstraint *childNode = nullptr; 375*0e209d39SAndroid Build Coastguard Worker OrConstraint *next = nullptr; 376*0e209d39SAndroid Build Coastguard Worker // Internal error status, used for errors that occur during the copy constructor. 377*0e209d39SAndroid Build Coastguard Worker UErrorCode fInternalStatus = U_ZERO_ERROR; 378*0e209d39SAndroid Build Coastguard Worker 379*0e209d39SAndroid Build Coastguard Worker OrConstraint() = default; 380*0e209d39SAndroid Build Coastguard Worker OrConstraint(const OrConstraint& other); 381*0e209d39SAndroid Build Coastguard Worker virtual ~OrConstraint(); 382*0e209d39SAndroid Build Coastguard Worker AndConstraint* add(UErrorCode& status); 383*0e209d39SAndroid Build Coastguard Worker // UBool isFulfilled(double number); 384*0e209d39SAndroid Build Coastguard Worker UBool isFulfilled(const IFixedDecimal &number); 385*0e209d39SAndroid Build Coastguard Worker }; 386*0e209d39SAndroid Build Coastguard Worker 387*0e209d39SAndroid Build Coastguard Worker class RuleChain : public UMemory { 388*0e209d39SAndroid Build Coastguard Worker public: 389*0e209d39SAndroid Build Coastguard Worker UnicodeString fKeyword; 390*0e209d39SAndroid Build Coastguard Worker RuleChain *fNext = nullptr; 391*0e209d39SAndroid Build Coastguard Worker OrConstraint *ruleHeader = nullptr; 392*0e209d39SAndroid Build Coastguard Worker UnicodeString fDecimalSamples; // Samples strings from rule source 393*0e209d39SAndroid Build Coastguard Worker UnicodeString fIntegerSamples; // without @decimal or @integer, otherwise unprocessed. 394*0e209d39SAndroid Build Coastguard Worker UBool fDecimalSamplesUnbounded = false; 395*0e209d39SAndroid Build Coastguard Worker UBool fIntegerSamplesUnbounded = false; 396*0e209d39SAndroid Build Coastguard Worker // Internal error status, used for errors that occur during the copy constructor. 397*0e209d39SAndroid Build Coastguard Worker UErrorCode fInternalStatus = U_ZERO_ERROR; 398*0e209d39SAndroid Build Coastguard Worker 399*0e209d39SAndroid Build Coastguard Worker RuleChain() = default; 400*0e209d39SAndroid Build Coastguard Worker RuleChain(const RuleChain& other); 401*0e209d39SAndroid Build Coastguard Worker virtual ~RuleChain(); 402*0e209d39SAndroid Build Coastguard Worker 403*0e209d39SAndroid Build Coastguard Worker UnicodeString select(const IFixedDecimal &number) const; 404*0e209d39SAndroid Build Coastguard Worker void dumpRules(UnicodeString& result); 405*0e209d39SAndroid Build Coastguard Worker UErrorCode getKeywords(int32_t maxArraySize, UnicodeString *keywords, int32_t& arraySize) const; 406*0e209d39SAndroid Build Coastguard Worker UBool isKeyword(const UnicodeString& keyword) const; 407*0e209d39SAndroid Build Coastguard Worker }; 408*0e209d39SAndroid Build Coastguard Worker 409*0e209d39SAndroid Build Coastguard Worker class PluralKeywordEnumeration : public StringEnumeration { 410*0e209d39SAndroid Build Coastguard Worker public: 411*0e209d39SAndroid Build Coastguard Worker PluralKeywordEnumeration(RuleChain *header, UErrorCode& status); 412*0e209d39SAndroid Build Coastguard Worker virtual ~PluralKeywordEnumeration(); 413*0e209d39SAndroid Build Coastguard Worker static UClassID U_EXPORT2 getStaticClassID(); 414*0e209d39SAndroid Build Coastguard Worker virtual UClassID getDynamicClassID() const override; 415*0e209d39SAndroid Build Coastguard Worker virtual const UnicodeString* snext(UErrorCode& status) override; 416*0e209d39SAndroid Build Coastguard Worker virtual void reset(UErrorCode& status) override; 417*0e209d39SAndroid Build Coastguard Worker virtual int32_t count(UErrorCode& status) const override; 418*0e209d39SAndroid Build Coastguard Worker private: 419*0e209d39SAndroid Build Coastguard Worker int32_t pos; 420*0e209d39SAndroid Build Coastguard Worker UVector fKeywordNames; 421*0e209d39SAndroid Build Coastguard Worker }; 422*0e209d39SAndroid Build Coastguard Worker 423*0e209d39SAndroid Build Coastguard Worker 424*0e209d39SAndroid Build Coastguard Worker class U_I18N_API PluralAvailableLocalesEnumeration: public StringEnumeration { 425*0e209d39SAndroid Build Coastguard Worker public: 426*0e209d39SAndroid Build Coastguard Worker PluralAvailableLocalesEnumeration(UErrorCode &status); 427*0e209d39SAndroid Build Coastguard Worker virtual ~PluralAvailableLocalesEnumeration(); 428*0e209d39SAndroid Build Coastguard Worker virtual const char* next(int32_t *resultLength, UErrorCode& status) override; 429*0e209d39SAndroid Build Coastguard Worker virtual void reset(UErrorCode& status) override; 430*0e209d39SAndroid Build Coastguard Worker virtual int32_t count(UErrorCode& status) const override; 431*0e209d39SAndroid Build Coastguard Worker private: 432*0e209d39SAndroid Build Coastguard Worker UErrorCode fOpenStatus; 433*0e209d39SAndroid Build Coastguard Worker UResourceBundle *fLocales = nullptr; 434*0e209d39SAndroid Build Coastguard Worker UResourceBundle *fRes = nullptr; 435*0e209d39SAndroid Build Coastguard Worker }; 436*0e209d39SAndroid Build Coastguard Worker 437*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_END 438*0e209d39SAndroid Build Coastguard Worker 439*0e209d39SAndroid Build Coastguard Worker #endif /* #if !UCONFIG_NO_FORMATTING */ 440*0e209d39SAndroid Build Coastguard Worker 441*0e209d39SAndroid Build Coastguard Worker #endif // _PLURRULE_IMPL 442*0e209d39SAndroid Build Coastguard Worker //eof 443