10596faeddefbf198de137d5e893708495ab1584cFredrik Roubert// © 2016 and later: Unicode, Inc. and others. 264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html 385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/* 485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho******************************************************************************* 58de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert* Copyright (C) 2007-2016, International Business Machines Corporation and 685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho* others. All Rights Reserved. 785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho******************************************************************************* 885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho* 985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho* File PLURRULE_IMPL.H 1085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho* 1185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho******************************************************************************* 1285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*/ 1385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 1485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 150b3ec0516c035ea443fdc334025048597c740be1Markus Scherer#ifndef PLURRULE_IMPL 160b3ec0516c035ea443fdc334025048597c740be1Markus Scherer#define PLURRULE_IMPL 1785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Internal definitions for the PluralRules implementation. 19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 200b3ec0516c035ea443fdc334025048597c740be1Markus Scherer#include "unicode/utypes.h" 210b3ec0516c035ea443fdc334025048597c740be1Markus Scherer 2285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !UCONFIG_NO_FORMATTING 2385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 2485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/format.h" 2585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/locid.h" 2685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/parseerr.h" 270596faeddefbf198de137d5e893708495ab1584cFredrik Roubert#include "unicode/strenum.h" 2859d709d503bab6e2b61931737e662dd293b40578ccornelius#include "unicode/ures.h" 2985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "uvector.h" 3085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "hash.h" 31ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert#include "uassert.h" 3285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 3359d709d503bab6e2b61931737e662dd293b40578ccorneliusclass PluralRulesTest; 3459d709d503bab6e2b61931737e662dd293b40578ccornelius 3585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_NAMESPACE_BEGIN 3685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 3759d709d503bab6e2b61931737e662dd293b40578ccorneliusclass AndConstraint; 3859d709d503bab6e2b61931737e662dd293b40578ccorneliusclass RuleChain; 39c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertclass DigitInterval; 408de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubertclass PluralRules; 41c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertclass VisibleDigits; 4259d709d503bab6e2b61931737e662dd293b40578ccornelius 4359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar DOT = ((UChar)0x002E); 4459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar SINGLE_QUOTE = ((UChar)0x0027); 4559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar SLASH = ((UChar)0x002F); 4659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar BACKSLASH = ((UChar)0x005C); 4759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar SPACE = ((UChar)0x0020); 4859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar EXCLAMATION = ((UChar)0x0021); 4959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar QUOTATION_MARK = ((UChar)0x0022); 5059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar NUMBER_SIGN = ((UChar)0x0023); 5159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar PERCENT_SIGN = ((UChar)0x0025); 5259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar ASTERISK = ((UChar)0x002A); 5359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar COMMA = ((UChar)0x002C); 5459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar HYPHEN = ((UChar)0x002D); 5559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_ZERO = ((UChar)0x0030); 5659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_ONE = ((UChar)0x0031); 5759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_TWO = ((UChar)0x0032); 5859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_THREE = ((UChar)0x0033); 5959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_FOUR = ((UChar)0x0034); 6059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_FIVE = ((UChar)0x0035); 6159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_SIX = ((UChar)0x0036); 6259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_SEVEN = ((UChar)0x0037); 6359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_EIGHT = ((UChar)0x0038); 6459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar U_NINE = ((UChar)0x0039); 6559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar COLON = ((UChar)0x003A); 6659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar SEMI_COLON = ((UChar)0x003B); 6759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar EQUALS = ((UChar)0x003D); 6859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar AT = ((UChar)0x0040); 6959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar CAP_A = ((UChar)0x0041); 7059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar CAP_B = ((UChar)0x0042); 7159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar CAP_R = ((UChar)0x0052); 7259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar CAP_Z = ((UChar)0x005A); 7359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOWLINE = ((UChar)0x005F); 7459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LEFTBRACE = ((UChar)0x007B); 7559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar RIGHTBRACE = ((UChar)0x007D); 7659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar TILDE = ((UChar)0x007E); 7759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar ELLIPSIS = ((UChar)0x2026); 7859d709d503bab6e2b61931737e662dd293b40578ccornelius 7959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_A = ((UChar)0x0061); 8059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_B = ((UChar)0x0062); 8159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_C = ((UChar)0x0063); 8259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_D = ((UChar)0x0064); 8359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_E = ((UChar)0x0065); 8459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_F = ((UChar)0x0066); 8559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_G = ((UChar)0x0067); 8659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_H = ((UChar)0x0068); 8759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_I = ((UChar)0x0069); 8859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_J = ((UChar)0x006a); 8959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_K = ((UChar)0x006B); 9059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_L = ((UChar)0x006C); 9159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_M = ((UChar)0x006D); 9259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_N = ((UChar)0x006E); 9359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_O = ((UChar)0x006F); 9459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_P = ((UChar)0x0070); 9559d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_Q = ((UChar)0x0071); 9659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_R = ((UChar)0x0072); 9759d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_S = ((UChar)0x0073); 9859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_T = ((UChar)0x0074); 9959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_U = ((UChar)0x0075); 10059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_V = ((UChar)0x0076); 10159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_W = ((UChar)0x0077); 10259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_Y = ((UChar)0x0079); 10359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const UChar LOW_Z = ((UChar)0x007A); 10459d709d503bab6e2b61931737e662dd293b40578ccornelius 10559d709d503bab6e2b61931737e662dd293b40578ccornelius 10659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic const int32_t PLURAL_RANGE_HIGH = 0x7fffffff; 10759d709d503bab6e2b61931737e662dd293b40578ccornelius 10859d709d503bab6e2b61931737e662dd293b40578ccorneliusenum tokenType { 10985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho none, 11085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tNumber, 11185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tComma, 11285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tSemiColon, 11385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tSpace, 11485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tColon, 11559d709d503bab6e2b61931737e662dd293b40578ccornelius tAt, // '@' 11685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tDot, 11759d709d503bab6e2b61931737e662dd293b40578ccornelius tDot2, 11859d709d503bab6e2b61931737e662dd293b40578ccornelius tEllipsis, 11985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tKeyword, 12085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tAnd, 12185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tOr, 12259d709d503bab6e2b61931737e662dd293b40578ccornelius tMod, // 'mod' or '%' 12359d709d503bab6e2b61931737e662dd293b40578ccornelius tNot, // 'not' only. 12459d709d503bab6e2b61931737e662dd293b40578ccornelius tIn, // 'in' only. 12559d709d503bab6e2b61931737e662dd293b40578ccornelius tEqual, // '=' only. 12659d709d503bab6e2b61931737e662dd293b40578ccornelius tNotEqual, // '!=' 12759d709d503bab6e2b61931737e662dd293b40578ccornelius tTilde, 12885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tWithin, 12985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho tIs, 13059d709d503bab6e2b61931737e662dd293b40578ccornelius tVariableN, 13159d709d503bab6e2b61931737e662dd293b40578ccornelius tVariableI, 13259d709d503bab6e2b61931737e662dd293b40578ccornelius tVariableF, 13359d709d503bab6e2b61931737e662dd293b40578ccornelius tVariableV, 13459d709d503bab6e2b61931737e662dd293b40578ccornelius tVariableT, 13559d709d503bab6e2b61931737e662dd293b40578ccornelius tDecimal, 13659d709d503bab6e2b61931737e662dd293b40578ccornelius tInteger, 13759d709d503bab6e2b61931737e662dd293b40578ccornelius tEOF 13859d709d503bab6e2b61931737e662dd293b40578ccornelius}; 13959d709d503bab6e2b61931737e662dd293b40578ccornelius 14085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 14159d709d503bab6e2b61931737e662dd293b40578ccorneliusclass PluralRuleParser: public UMemory { 14285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic: 14359d709d503bab6e2b61931737e662dd293b40578ccornelius PluralRuleParser(); 14459d709d503bab6e2b61931737e662dd293b40578ccornelius virtual ~PluralRuleParser(); 14559d709d503bab6e2b61931737e662dd293b40578ccornelius 14659d709d503bab6e2b61931737e662dd293b40578ccornelius void parse(const UnicodeString &rules, PluralRules *dest, UErrorCode &status); 14759d709d503bab6e2b61931737e662dd293b40578ccornelius void getNextToken(UErrorCode &status); 14859d709d503bab6e2b61931737e662dd293b40578ccornelius void checkSyntax(UErrorCode &status); 14959d709d503bab6e2b61931737e662dd293b40578ccornelius static int32_t getNumberValue(const UnicodeString &token); 15059d709d503bab6e2b61931737e662dd293b40578ccornelius 15185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoprivate: 15259d709d503bab6e2b61931737e662dd293b40578ccornelius static tokenType getKeyType(const UnicodeString& token, tokenType type); 15359d709d503bab6e2b61931737e662dd293b40578ccornelius static tokenType charType(UChar ch); 15459d709d503bab6e2b61931737e662dd293b40578ccornelius static UBool isValidKeyword(const UnicodeString& token); 15559d709d503bab6e2b61931737e662dd293b40578ccornelius 15659d709d503bab6e2b61931737e662dd293b40578ccornelius const UnicodeString *ruleSrc; // The rules string. 15759d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t ruleIndex; // String index in the input rules, the current parse position. 15859d709d503bab6e2b61931737e662dd293b40578ccornelius UnicodeString token; // Token most recently scanned. 15959d709d503bab6e2b61931737e662dd293b40578ccornelius tokenType type; 16059d709d503bab6e2b61931737e662dd293b40578ccornelius tokenType prevType; 16159d709d503bab6e2b61931737e662dd293b40578ccornelius 16259d709d503bab6e2b61931737e662dd293b40578ccornelius // The items currently being parsed & built. 16359d709d503bab6e2b61931737e662dd293b40578ccornelius // Note: currentChain may not be the last RuleChain in the 16459d709d503bab6e2b61931737e662dd293b40578ccornelius // list because the "other" chain is forced to the end. 16559d709d503bab6e2b61931737e662dd293b40578ccornelius AndConstraint *curAndConstraint; 16659d709d503bab6e2b61931737e662dd293b40578ccornelius RuleChain *currentChain; 16759d709d503bab6e2b61931737e662dd293b40578ccornelius 16859d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t rangeLowIdx; // Indices in the UVector of ranges of the 16959d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t rangeHiIdx; // low and hi values currently being parsed. 17059d709d503bab6e2b61931737e662dd293b40578ccornelius 17159d709d503bab6e2b61931737e662dd293b40578ccornelius enum EParseState { 17259d709d503bab6e2b61931737e662dd293b40578ccornelius kKeyword, 17359d709d503bab6e2b61931737e662dd293b40578ccornelius kExpr, 17459d709d503bab6e2b61931737e662dd293b40578ccornelius kValue, 17559d709d503bab6e2b61931737e662dd293b40578ccornelius kRangeList, 17659d709d503bab6e2b61931737e662dd293b40578ccornelius kSamples 17759d709d503bab6e2b61931737e662dd293b40578ccornelius }; 17859d709d503bab6e2b61931737e662dd293b40578ccornelius 17959d709d503bab6e2b61931737e662dd293b40578ccornelius}; 18059d709d503bab6e2b61931737e662dd293b40578ccornelius 181ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubertenum PluralOperand { 182ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert /** 183ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * The double value of the entire number. 184ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 185ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert PLURAL_OPERAND_N, 186ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 187ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert /** 188ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * The integer value, with the fraction digits truncated off. 189ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 190ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert PLURAL_OPERAND_I, 191ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 192ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert /** 193ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * All visible fraction digits as an integer, including trailing zeros. 194ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 195ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert PLURAL_OPERAND_F, 196ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 197ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert /** 198ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * Visible fraction digits as an integer, not including trailing zeros. 199ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 200ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert PLURAL_OPERAND_T, 201ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 202ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert /** 203ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * Number of visible fraction digits. 204ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 205ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert PLURAL_OPERAND_V, 206ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 207ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert /** 208ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * Number of visible fraction digits, not including trailing zeros. 209ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 210ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert PLURAL_OPERAND_W, 211ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 212ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert /** 213ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * THIS OPERAND IS DEPRECATED AND HAS BEEN REMOVED FROM THE SPEC. 214ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * 215ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * <p>Returns the integer value, but will fail if the number has fraction digits. 216ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * That is, using "j" instead of "i" is like implicitly adding "v is 0". 217ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * 218ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * <p>For example, "j is 3" is equivalent to "i is 3 and v is 0": it matches 219ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * "3" but not "3.1" or "3.0". 220ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 221ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert PLURAL_OPERAND_J 222ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert}; 223ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 224ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert/** 225ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * Converts from the tokenType enum to PluralOperand. Asserts that the given 226ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * tokenType can be mapped to a PluralOperand. 227ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 228ffdc27edd5503111189fc11165c5a11289a71f79Fredrik RoubertPluralOperand tokenTypeToPluralOperand(tokenType tt); 229ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 230ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert/** 231ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * An interface to FixedDecimal, allowing for other implementations. 232ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * @internal 233ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 234ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubertclass U_I18N_API IFixedDecimal { 235ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert public: 236ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert virtual ~IFixedDecimal(); 237ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 238ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert /** 239ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * Returns the value corresponding to the specified operand (n, i, f, t, v, or w). 240ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * If the operand is 'n', returns a double; otherwise, returns an integer. 241ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 242ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert virtual double getPluralOperand(PluralOperand operand) const = 0; 243ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 244ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert virtual bool isNaN() const = 0; 245ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 246ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert virtual bool isInfinite() const = 0; 247ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert}; 248ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 24959d709d503bab6e2b61931737e662dd293b40578ccornelius/** 25059d709d503bab6e2b61931737e662dd293b40578ccornelius * class FixedDecimal serves to communicate the properties 25159d709d503bab6e2b61931737e662dd293b40578ccornelius * of a formatted number from a decimal formatter to PluralRules::select() 25259d709d503bab6e2b61931737e662dd293b40578ccornelius * 25359d709d503bab6e2b61931737e662dd293b40578ccornelius * see DecimalFormat::getFixedDecimal() 25459d709d503bab6e2b61931737e662dd293b40578ccornelius * @internal 25559d709d503bab6e2b61931737e662dd293b40578ccornelius */ 256ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubertclass U_I18N_API FixedDecimal: public IFixedDecimal, public UObject { 25759d709d503bab6e2b61931737e662dd293b40578ccornelius public: 25859d709d503bab6e2b61931737e662dd293b40578ccornelius /** 25959d709d503bab6e2b61931737e662dd293b40578ccornelius * @param n the number, e.g. 12.345 26059d709d503bab6e2b61931737e662dd293b40578ccornelius * @param v The number of visible fraction digits, e.g. 3 26159d709d503bab6e2b61931737e662dd293b40578ccornelius * @param f The fraction digits, e.g. 345 26259d709d503bab6e2b61931737e662dd293b40578ccornelius */ 26359d709d503bab6e2b61931737e662dd293b40578ccornelius FixedDecimal(double n, int32_t v, int64_t f); 26459d709d503bab6e2b61931737e662dd293b40578ccornelius FixedDecimal(double n, int32_t); 26559d709d503bab6e2b61931737e662dd293b40578ccornelius explicit FixedDecimal(double n); 266c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert explicit FixedDecimal(const VisibleDigits &n); 26759d709d503bab6e2b61931737e662dd293b40578ccornelius FixedDecimal(); 268ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert ~FixedDecimal() U_OVERRIDE; 26959d709d503bab6e2b61931737e662dd293b40578ccornelius FixedDecimal(const UnicodeString &s, UErrorCode &ec); 27059d709d503bab6e2b61931737e662dd293b40578ccornelius FixedDecimal(const FixedDecimal &other); 27159d709d503bab6e2b61931737e662dd293b40578ccornelius 272ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert double getPluralOperand(PluralOperand operand) const U_OVERRIDE; 273ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert bool isNaN() const U_OVERRIDE; 274ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert bool isInfinite() const U_OVERRIDE; 275ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 276ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert bool isNanOrInfinity() const; // used in decimfmtimpl.cpp 277ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 27859d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t getVisibleFractionDigitCount() const; 27959d709d503bab6e2b61931737e662dd293b40578ccornelius 28059d709d503bab6e2b61931737e662dd293b40578ccornelius void init(double n, int32_t v, int64_t f); 28159d709d503bab6e2b61931737e662dd293b40578ccornelius void init(double n); 28259d709d503bab6e2b61931737e662dd293b40578ccornelius UBool quickInit(double n); // Try a fast-path only initialization, 28359d709d503bab6e2b61931737e662dd293b40578ccornelius // return TRUE if successful. 28459d709d503bab6e2b61931737e662dd293b40578ccornelius void adjustForMinFractionDigits(int32_t min); 28559d709d503bab6e2b61931737e662dd293b40578ccornelius static int64_t getFractionalDigits(double n, int32_t v); 28659d709d503bab6e2b61931737e662dd293b40578ccornelius static int32_t decimals(double n); 28759d709d503bab6e2b61931737e662dd293b40578ccornelius 28859d709d503bab6e2b61931737e662dd293b40578ccornelius double source; 28959d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t visibleDecimalDigitCount; 29059d709d503bab6e2b61931737e662dd293b40578ccornelius int64_t decimalDigits; 29159d709d503bab6e2b61931737e662dd293b40578ccornelius int64_t decimalDigitsWithoutTrailingZeros; 29259d709d503bab6e2b61931737e662dd293b40578ccornelius int64_t intValue; 29359d709d503bab6e2b61931737e662dd293b40578ccornelius UBool hasIntegerValue; 29459d709d503bab6e2b61931737e662dd293b40578ccornelius UBool isNegative; 295ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert UBool _isNaN; 296ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert UBool _isInfinite; 29785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}; 29885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 29985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoclass AndConstraint : public UMemory { 30085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic: 30185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho typedef enum RuleOp { 30285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho NONE, 30385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho MOD 30485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } RuleOp; 30585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho RuleOp op; 30659d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t opNum; // for mod expressions, the right operand of the mod. 30759d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t value; // valid for 'is' rules only. 30859d709d503bab6e2b61931737e662dd293b40578ccornelius UVector32 *rangeList; // for 'in', 'within' rules. Null otherwise. 30959d709d503bab6e2b61931737e662dd293b40578ccornelius UBool negated; // TRUE for negated rules. 31059d709d503bab6e2b61931737e662dd293b40578ccornelius UBool integerOnly; // TRUE for 'within' rules. 31159d709d503bab6e2b61931737e662dd293b40578ccornelius tokenType digitsType; // n | i | v | f constraint. 31285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho AndConstraint *next; 313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 31485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho AndConstraint(); 31585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho AndConstraint(const AndConstraint& other); 31685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho virtual ~AndConstraint(); 31785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho AndConstraint* add(); 31859d709d503bab6e2b61931737e662dd293b40578ccornelius // UBool isFulfilled(double number); 319ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert UBool isFulfilled(const IFixedDecimal &number); 32085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}; 32185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 32285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoclass OrConstraint : public UMemory { 32385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic: 32485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho AndConstraint *childNode; 32585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho OrConstraint *next; 32685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho OrConstraint(); 327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 32885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho OrConstraint(const OrConstraint& other); 32985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho virtual ~OrConstraint(); 33085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho AndConstraint* add(); 33159d709d503bab6e2b61931737e662dd293b40578ccornelius // UBool isFulfilled(double number); 332ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert UBool isFulfilled(const IFixedDecimal &number); 33385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}; 33485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 33585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoclass RuleChain : public UMemory { 33685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic: 33759d709d503bab6e2b61931737e662dd293b40578ccornelius UnicodeString fKeyword; 33859d709d503bab6e2b61931737e662dd293b40578ccornelius RuleChain *fNext; 33959d709d503bab6e2b61931737e662dd293b40578ccornelius OrConstraint *ruleHeader; 34059d709d503bab6e2b61931737e662dd293b40578ccornelius UnicodeString fDecimalSamples; // Samples strings from rule source 34159d709d503bab6e2b61931737e662dd293b40578ccornelius UnicodeString fIntegerSamples; // without @decimal or @integer, otherwise unprocessed. 34259d709d503bab6e2b61931737e662dd293b40578ccornelius UBool fDecimalSamplesUnbounded; 34359d709d503bab6e2b61931737e662dd293b40578ccornelius UBool fIntegerSamplesUnbounded; 34459d709d503bab6e2b61931737e662dd293b40578ccornelius 34559d709d503bab6e2b61931737e662dd293b40578ccornelius 34685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho RuleChain(); 34785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho RuleChain(const RuleChain& other); 34885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho virtual ~RuleChain(); 34959d709d503bab6e2b61931737e662dd293b40578ccornelius 350ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert UnicodeString select(const IFixedDecimal &number) const; 35159d709d503bab6e2b61931737e662dd293b40578ccornelius void dumpRules(UnicodeString& result); 35259d709d503bab6e2b61931737e662dd293b40578ccornelius UErrorCode getKeywords(int32_t maxArraySize, UnicodeString *keywords, int32_t& arraySize) const; 35359d709d503bab6e2b61931737e662dd293b40578ccornelius UBool isKeyword(const UnicodeString& keyword) const; 35485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}; 35585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 35685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoclass PluralKeywordEnumeration : public StringEnumeration { 35785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic: 35885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho PluralKeywordEnumeration(RuleChain *header, UErrorCode& status); 35985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho virtual ~PluralKeywordEnumeration(); 36085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho static UClassID U_EXPORT2 getStaticClassID(void); 36185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho virtual UClassID getDynamicClassID(void) const; 36285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho virtual const UnicodeString* snext(UErrorCode& status); 36385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho virtual void reset(UErrorCode& status); 36485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho virtual int32_t count(UErrorCode& status) const; 36585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoprivate: 36659d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t pos; 36759d709d503bab6e2b61931737e662dd293b40578ccornelius UVector fKeywordNames; 36859d709d503bab6e2b61931737e662dd293b40578ccornelius}; 36959d709d503bab6e2b61931737e662dd293b40578ccornelius 37059d709d503bab6e2b61931737e662dd293b40578ccornelius 37159d709d503bab6e2b61931737e662dd293b40578ccorneliusclass U_I18N_API PluralAvailableLocalesEnumeration: public StringEnumeration { 37259d709d503bab6e2b61931737e662dd293b40578ccornelius public: 37359d709d503bab6e2b61931737e662dd293b40578ccornelius PluralAvailableLocalesEnumeration(UErrorCode &status); 37459d709d503bab6e2b61931737e662dd293b40578ccornelius virtual ~PluralAvailableLocalesEnumeration(); 37559d709d503bab6e2b61931737e662dd293b40578ccornelius virtual const char* next(int32_t *resultLength, UErrorCode& status); 37659d709d503bab6e2b61931737e662dd293b40578ccornelius virtual void reset(UErrorCode& status); 37759d709d503bab6e2b61931737e662dd293b40578ccornelius virtual int32_t count(UErrorCode& status) const; 37859d709d503bab6e2b61931737e662dd293b40578ccornelius private: 37959d709d503bab6e2b61931737e662dd293b40578ccornelius UErrorCode fOpenStatus; 38059d709d503bab6e2b61931737e662dd293b40578ccornelius UResourceBundle *fLocales; 38159d709d503bab6e2b61931737e662dd293b40578ccornelius UResourceBundle *fRes; 38285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}; 38385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 38485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_NAMESPACE_END 38585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 38685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif /* #if !UCONFIG_NO_FORMATTING */ 38785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 38885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif // _PLURRULE_IMPL 38985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//eof 390