intl/icu/source/i18n/plurrule_impl.h

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /*
michael@0 2 *******************************************************************************
michael@0 3 * Copyright (C) 2007-2013, International Business Machines Corporation and
michael@0 4 * others. All Rights Reserved.
michael@0 5 *******************************************************************************
michael@0 6 *
michael@0 7 * File PLURRULE_IMPL.H
michael@0 8 *
michael@0 9 *******************************************************************************
michael@0 10 */
michael@0 11
michael@0 12
michael@0 13 #ifndef PLURRULE_IMPLE
michael@0 14 #define PLURRULE_IMPLE
michael@0 15
michael@0 16 // Internal definitions for the PluralRules implementation.
michael@0 17
michael@0 18 #if !UCONFIG_NO_FORMATTING
michael@0 19
michael@0 20 #include "unicode/format.h"
michael@0 21 #include "unicode/locid.h"
michael@0 22 #include "unicode/parseerr.h"
michael@0 23 #include "unicode/ures.h"
michael@0 24 #include "unicode/utypes.h"
michael@0 25 #include "uvector.h"
michael@0 26 #include "hash.h"
michael@0 27
michael@0 28 class PluralRulesTest;
michael@0 29
michael@0 30 U_NAMESPACE_BEGIN
michael@0 31
michael@0 32 class AndConstraint;
michael@0 33 class RuleChain;
michael@0 34
michael@0 35 static const UChar DOT = ((UChar)0x002E);
michael@0 36 static const UChar SINGLE_QUOTE = ((UChar)0x0027);
michael@0 37 static const UChar SLASH = ((UChar)0x002F);
michael@0 38 static const UChar BACKSLASH = ((UChar)0x005C);
michael@0 39 static const UChar SPACE = ((UChar)0x0020);
michael@0 40 static const UChar EXCLAMATION = ((UChar)0x0021);
michael@0 41 static const UChar QUOTATION_MARK = ((UChar)0x0022);
michael@0 42 static const UChar NUMBER_SIGN = ((UChar)0x0023);
michael@0 43 static const UChar PERCENT_SIGN = ((UChar)0x0025);
michael@0 44 static const UChar ASTERISK = ((UChar)0x002A);
michael@0 45 static const UChar COMMA = ((UChar)0x002C);
michael@0 46 static const UChar HYPHEN = ((UChar)0x002D);
michael@0 47 static const UChar U_ZERO = ((UChar)0x0030);
michael@0 48 static const UChar U_ONE = ((UChar)0x0031);
michael@0 49 static const UChar U_TWO = ((UChar)0x0032);
michael@0 50 static const UChar U_THREE = ((UChar)0x0033);
michael@0 51 static const UChar U_FOUR = ((UChar)0x0034);
michael@0 52 static const UChar U_FIVE = ((UChar)0x0035);
michael@0 53 static const UChar U_SIX = ((UChar)0x0036);
michael@0 54 static const UChar U_SEVEN = ((UChar)0x0037);
michael@0 55 static const UChar U_EIGHT = ((UChar)0x0038);
michael@0 56 static const UChar U_NINE = ((UChar)0x0039);
michael@0 57 static const UChar COLON = ((UChar)0x003A);
michael@0 58 static const UChar SEMI_COLON = ((UChar)0x003B);
michael@0 59 static const UChar EQUALS = ((UChar)0x003D);
michael@0 60 static const UChar AT = ((UChar)0x0040);
michael@0 61 static const UChar CAP_A = ((UChar)0x0041);
michael@0 62 static const UChar CAP_B = ((UChar)0x0042);
michael@0 63 static const UChar CAP_R = ((UChar)0x0052);
michael@0 64 static const UChar CAP_Z = ((UChar)0x005A);
michael@0 65 static const UChar LOWLINE = ((UChar)0x005F);
michael@0 66 static const UChar LEFTBRACE = ((UChar)0x007B);
michael@0 67 static const UChar RIGHTBRACE = ((UChar)0x007D);
michael@0 68 static const UChar TILDE = ((UChar)0x007E);
michael@0 69 static const UChar ELLIPSIS = ((UChar)0x2026);
michael@0 70
michael@0 71 static const UChar LOW_A = ((UChar)0x0061);
michael@0 72 static const UChar LOW_B = ((UChar)0x0062);
michael@0 73 static const UChar LOW_C = ((UChar)0x0063);
michael@0 74 static const UChar LOW_D = ((UChar)0x0064);
michael@0 75 static const UChar LOW_E = ((UChar)0x0065);
michael@0 76 static const UChar LOW_F = ((UChar)0x0066);
michael@0 77 static const UChar LOW_G = ((UChar)0x0067);
michael@0 78 static const UChar LOW_H = ((UChar)0x0068);
michael@0 79 static const UChar LOW_I = ((UChar)0x0069);
michael@0 80 static const UChar LOW_J = ((UChar)0x006a);
michael@0 81 static const UChar LOW_K = ((UChar)0x006B);
michael@0 82 static const UChar LOW_L = ((UChar)0x006C);
michael@0 83 static const UChar LOW_M = ((UChar)0x006D);
michael@0 84 static const UChar LOW_N = ((UChar)0x006E);
michael@0 85 static const UChar LOW_O = ((UChar)0x006F);
michael@0 86 static const UChar LOW_P = ((UChar)0x0070);
michael@0 87 static const UChar LOW_Q = ((UChar)0x0071);
michael@0 88 static const UChar LOW_R = ((UChar)0x0072);
michael@0 89 static const UChar LOW_S = ((UChar)0x0073);
michael@0 90 static const UChar LOW_T = ((UChar)0x0074);
michael@0 91 static const UChar LOW_U = ((UChar)0x0075);
michael@0 92 static const UChar LOW_V = ((UChar)0x0076);
michael@0 93 static const UChar LOW_W = ((UChar)0x0077);
michael@0 94 static const UChar LOW_Y = ((UChar)0x0079);
michael@0 95 static const UChar LOW_Z = ((UChar)0x007A);
michael@0 96
michael@0 97
michael@0 98 static const int32_t PLURAL_RANGE_HIGH = 0x7fffffff;
michael@0 99
michael@0 100 enum tokenType {
michael@0 101 none,
michael@0 102 tNumber,
michael@0 103 tComma,
michael@0 104 tSemiColon,
michael@0 105 tSpace,
michael@0 106 tColon,
michael@0 107 tAt, // '@'
michael@0 108 tDot,
michael@0 109 tDot2,
michael@0 110 tEllipsis,
michael@0 111 tKeyword,
michael@0 112 tAnd,
michael@0 113 tOr,
michael@0 114 tMod, // 'mod' or '%'
michael@0 115 tNot, // 'not' only.
michael@0 116 tIn, // 'in' only.
michael@0 117 tEqual, // '=' only.
michael@0 118 tNotEqual, // '!='
michael@0 119 tTilde,
michael@0 120 tWithin,
michael@0 121 tIs,
michael@0 122 tVariableN,
michael@0 123 tVariableI,
michael@0 124 tVariableF,
michael@0 125 tVariableV,
michael@0 126 tVariableT,
michael@0 127 tDecimal,
michael@0 128 tInteger,
michael@0 129 tEOF
michael@0 130 };
michael@0 131
michael@0 132
michael@0 133 class PluralRuleParser: public UMemory {
michael@0 134 public:
michael@0 135 PluralRuleParser();
michael@0 136 virtual ~PluralRuleParser();
michael@0 137
michael@0 138 void parse(const UnicodeString &rules, PluralRules *dest, UErrorCode &status);
michael@0 139 void getNextToken(UErrorCode &status);
michael@0 140 void checkSyntax(UErrorCode &status);
michael@0 141 static int32_t getNumberValue(const UnicodeString &token);
michael@0 142
michael@0 143 private:
michael@0 144 static tokenType getKeyType(const UnicodeString& token, tokenType type);
michael@0 145 static tokenType charType(UChar ch);
michael@0 146 static UBool isValidKeyword(const UnicodeString& token);
michael@0 147
michael@0 148 const UnicodeString *ruleSrc; // The rules string.
michael@0 149 int32_t ruleIndex; // String index in the input rules, the current parse position.
michael@0 150 UnicodeString token; // Token most recently scanned.
michael@0 151 tokenType type;
michael@0 152 tokenType prevType;
michael@0 153
michael@0 154 // The items currently being parsed & built.
michael@0 155 // Note: currentChain may not be the last RuleChain in the
michael@0 156 // list because the "other" chain is forced to the end.
michael@0 157 AndConstraint *curAndConstraint;
michael@0 158 RuleChain *currentChain;
michael@0 159
michael@0 160 int32_t rangeLowIdx; // Indices in the UVector of ranges of the
michael@0 161 int32_t rangeHiIdx; // low and hi values currently being parsed.
michael@0 162
michael@0 163 enum EParseState {
michael@0 164 kKeyword,
michael@0 165 kExpr,
michael@0 166 kValue,
michael@0 167 kRangeList,
michael@0 168 kSamples
michael@0 169 };
michael@0 170
michael@0 171 };
michael@0 172
michael@0 173 /**
michael@0 174 * class FixedDecimal serves to communicate the properties
michael@0 175 * of a formatted number from a decimal formatter to PluralRules::select()
michael@0 176 *
michael@0 177 * see DecimalFormat::getFixedDecimal()
michael@0 178 * @internal
michael@0 179 */
michael@0 180 class U_I18N_API FixedDecimal: public UMemory {
michael@0 181 public:
michael@0 182 /**
michael@0 183 * @param n the number, e.g. 12.345
michael@0 184 * @param v The number of visible fraction digits, e.g. 3
michael@0 185 * @param f The fraction digits, e.g. 345
michael@0 186 */
michael@0 187 FixedDecimal(double n, int32_t v, int64_t f);
michael@0 188 FixedDecimal(double n, int32_t);
michael@0 189 explicit FixedDecimal(double n);
michael@0 190 FixedDecimal();
michael@0 191 FixedDecimal(const UnicodeString &s, UErrorCode &ec);
michael@0 192 FixedDecimal(const FixedDecimal &other);
michael@0 193
michael@0 194 double get(tokenType operand) const;
michael@0 195 int32_t getVisibleFractionDigitCount() const;
michael@0 196
michael@0 197 void init(double n, int32_t v, int64_t f);
michael@0 198 void init(double n);
michael@0 199 UBool quickInit(double n); // Try a fast-path only initialization,
michael@0 200 // return TRUE if successful.
michael@0 201 void adjustForMinFractionDigits(int32_t min);
michael@0 202 static int64_t getFractionalDigits(double n, int32_t v);
michael@0 203 static int32_t decimals(double n);
michael@0 204
michael@0 205 double source;
michael@0 206 int32_t visibleDecimalDigitCount;
michael@0 207 int64_t decimalDigits;
michael@0 208 int64_t decimalDigitsWithoutTrailingZeros;
michael@0 209 int64_t intValue;
michael@0 210 UBool hasIntegerValue;
michael@0 211 UBool isNegative;
michael@0 212 UBool isNanOrInfinity;
michael@0 213 };
michael@0 214
michael@0 215 class AndConstraint : public UMemory {
michael@0 216 public:
michael@0 217 typedef enum RuleOp {
michael@0 218 NONE,
michael@0 219 MOD
michael@0 220 } RuleOp;
michael@0 221 RuleOp op;
michael@0 222 int32_t opNum; // for mod expressions, the right operand of the mod.
michael@0 223 int32_t value; // valid for 'is' rules only.
michael@0 224 UVector32 *rangeList; // for 'in', 'within' rules. Null otherwise.
michael@0 225 UBool negated; // TRUE for negated rules.
michael@0 226 UBool integerOnly; // TRUE for 'within' rules.
michael@0 227 tokenType digitsType; // n | i | v | f constraint.
michael@0 228 AndConstraint *next;
michael@0 229
michael@0 230 AndConstraint();
michael@0 231 AndConstraint(const AndConstraint& other);
michael@0 232 virtual ~AndConstraint();
michael@0 233 AndConstraint* add();
michael@0 234 // UBool isFulfilled(double number);
michael@0 235 UBool isFulfilled(const FixedDecimal &number);
michael@0 236 };
michael@0 237
michael@0 238 class OrConstraint : public UMemory {
michael@0 239 public:
michael@0 240 AndConstraint *childNode;
michael@0 241 OrConstraint *next;
michael@0 242 OrConstraint();
michael@0 243
michael@0 244 OrConstraint(const OrConstraint& other);
michael@0 245 virtual ~OrConstraint();
michael@0 246 AndConstraint* add();
michael@0 247 // UBool isFulfilled(double number);
michael@0 248 UBool isFulfilled(const FixedDecimal &number);
michael@0 249 };
michael@0 250
michael@0 251 class RuleChain : public UMemory {
michael@0 252 public:
michael@0 253 UnicodeString fKeyword;
michael@0 254 RuleChain *fNext;
michael@0 255 OrConstraint *ruleHeader;
michael@0 256 UnicodeString fDecimalSamples; // Samples strings from rule source
michael@0 257 UnicodeString fIntegerSamples; // without @decimal or @integer, otherwise unprocessed.
michael@0 258 UBool fDecimalSamplesUnbounded;
michael@0 259 UBool fIntegerSamplesUnbounded;
michael@0 260
michael@0 261
michael@0 262 RuleChain();
michael@0 263 RuleChain(const RuleChain& other);
michael@0 264 virtual ~RuleChain();
michael@0 265
michael@0 266 UnicodeString select(const FixedDecimal &number) const;
michael@0 267 void dumpRules(UnicodeString& result);
michael@0 268 UErrorCode getKeywords(int32_t maxArraySize, UnicodeString *keywords, int32_t& arraySize) const;
michael@0 269 UBool isKeyword(const UnicodeString& keyword) const;
michael@0 270 };
michael@0 271
michael@0 272 class PluralKeywordEnumeration : public StringEnumeration {
michael@0 273 public:
michael@0 274 PluralKeywordEnumeration(RuleChain *header, UErrorCode& status);
michael@0 275 virtual ~PluralKeywordEnumeration();
michael@0 276 static UClassID U_EXPORT2 getStaticClassID(void);
michael@0 277 virtual UClassID getDynamicClassID(void) const;
michael@0 278 virtual const UnicodeString* snext(UErrorCode& status);
michael@0 279 virtual void reset(UErrorCode& status);
michael@0 280 virtual int32_t count(UErrorCode& status) const;
michael@0 281 private:
michael@0 282 int32_t pos;
michael@0 283 UVector fKeywordNames;
michael@0 284 };
michael@0 285
michael@0 286
michael@0 287 class U_I18N_API PluralAvailableLocalesEnumeration: public StringEnumeration {
michael@0 288 public:
michael@0 289 PluralAvailableLocalesEnumeration(UErrorCode &status);
michael@0 290 virtual ~PluralAvailableLocalesEnumeration();
michael@0 291 virtual const char* next(int32_t *resultLength, UErrorCode& status);
michael@0 292 virtual void reset(UErrorCode& status);
michael@0 293 virtual int32_t count(UErrorCode& status) const;
michael@0 294 private:
michael@0 295 UErrorCode fOpenStatus;
michael@0 296 UResourceBundle *fLocales;
michael@0 297 UResourceBundle *fRes;
michael@0 298 };
michael@0 299
michael@0 300 U_NAMESPACE_END
michael@0 301
michael@0 302 #endif /* #if !UCONFIG_NO_FORMATTING */
michael@0 303
michael@0 304 #endif // _PLURRULE_IMPL
michael@0 305 //eof

mercurial