/* */ package com.ibm.icu.text;
/* */
/* */ import com.ibm.icu.impl.PatternProps;
/* */ import com.ibm.icu.impl.Utility;
/* */ import java.text.ParsePosition;
/* */ import java.util.ArrayList;
/* */ import java.util.List;
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ final class NFRuleSet
/* */ {
/* */ private String name;
/* */ private NFRule[] rules;
/* 42 */ private NFRule negativeNumberRule = null;
/* */
/* */
/* */
/* */
/* */
/* */
/* 49 */ private NFRule[] fractionRules = new NFRule[3];
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 59 */ private boolean isFractionRuleSet = false;
/* */
/* */
/* */
/* */
/* 64 */ private int recursionCount = 0;
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private static final int RECURSION_LIMIT = 50;
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public NFRuleSet(String[] descriptions, int index)
/* */ throws IllegalArgumentException
/* */ {
/* 84 */ String description = descriptions[index];
/* */
/* 86 */ if (description.length() == 0) {
/* 87 */ throw new IllegalArgumentException("Empty rule set description");
/* */ }
/* */
/* */
/* */
/* */
/* */
/* 94 */ if (description.charAt(0) == '%') {
/* 95 */ int pos = description.indexOf(':');
/* 96 */ if (pos == -1) {
/* 97 */ throw new IllegalArgumentException("Rule set name doesn't end in colon");
/* */ }
/* 99 */ this.name = description.substring(0, pos);
/* 100 */ while ((pos < description.length()) && (PatternProps.isWhiteSpace(description.charAt(++pos)))) {}
/* */
/* */
/* 103 */ description = description.substring(pos);
/* 104 */ descriptions[index] = description;
/* */
/* */ }
/* */ else
/* */ {
/* */
/* 110 */ this.name = "%default";
/* */ }
/* */
/* 113 */ if (description.length() == 0) {
/* 114 */ throw new IllegalArgumentException("Empty rule set description");
/* */ }
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public void parseRules(String description, RuleBasedNumberFormat owner)
/* */ {
/* 137 */ List<String> ruleDescriptions = new ArrayList();
/* */
/* 139 */ int oldP = 0;
/* 140 */ int p = description.indexOf(';');
/* 141 */ while (oldP != -1) {
/* 142 */ if (p != -1) {
/* 143 */ ruleDescriptions.add(description.substring(oldP, p));
/* 144 */ oldP = p + 1;
/* */ } else {
/* 146 */ if (oldP < description.length()) {
/* 147 */ ruleDescriptions.add(description.substring(oldP));
/* */ }
/* 149 */ oldP = p;
/* */ }
/* 151 */ p = description.indexOf(';', p + 1);
/* */ }
/* */
/* */
/* */
/* */
/* 157 */ List<NFRule> tempRules = new ArrayList();
/* */
/* */
/* */
/* 161 */ NFRule predecessor = null;
/* 162 */ for (int i = 0; i < ruleDescriptions.size(); i++)
/* */ {
/* */
/* */
/* 166 */ Object temp = NFRule.makeRules((String)ruleDescriptions.get(i), this, predecessor, owner);
/* */
/* */
/* 169 */ if ((temp instanceof NFRule)) {
/* 170 */ tempRules.add((NFRule)temp);
/* 171 */ predecessor = (NFRule)temp;
/* */ }
/* 173 */ else if ((temp instanceof NFRule[])) {
/* 174 */ NFRule[] rulesToAdd = (NFRule[])temp;
/* */
/* 176 */ for (int j = 0; j < rulesToAdd.length; j++) {
/* 177 */ tempRules.add(rulesToAdd[j]);
/* 178 */ predecessor = rulesToAdd[j];
/* */ }
/* */ }
/* */ }
/* */
/* 183 */ ruleDescriptions = null;
/* */
/* */
/* */
/* */
/* */
/* 189 */ long defaultBaseValue = 0L;
/* */
/* */
/* */
/* */
/* 194 */ int i = 0;
/* 195 */ while (i < tempRules.size()) {
/* 196 */ NFRule rule = (NFRule)tempRules.get(i);
/* */
/* 198 */ switch ((int)rule.getBaseValue())
/* */ {
/* */
/* */
/* */
/* */
/* */ case 0:
/* 205 */ rule.setBaseValue(defaultBaseValue);
/* 206 */ if (!this.isFractionRuleSet) {
/* 207 */ defaultBaseValue += 1L;
/* */ }
/* 209 */ i++;
/* 210 */ break;
/* */
/* */
/* */
/* */ case -1:
/* 215 */ this.negativeNumberRule = rule;
/* 216 */ tempRules.remove(i);
/* 217 */ break;
/* */
/* */
/* */
/* */ case -2:
/* 222 */ this.fractionRules[0] = rule;
/* 223 */ tempRules.remove(i);
/* 224 */ break;
/* */
/* */
/* */
/* */ case -3:
/* 229 */ this.fractionRules[1] = rule;
/* 230 */ tempRules.remove(i);
/* 231 */ break;
/* */
/* */
/* */
/* */ case -4:
/* 236 */ this.fractionRules[2] = rule;
/* 237 */ tempRules.remove(i);
/* 238 */ break;
/* */
/* */
/* */
/* */
/* */ default:
/* 244 */ if (rule.getBaseValue() < defaultBaseValue) {
/* 245 */ throw new IllegalArgumentException("Rules are not in order, base: " + rule.getBaseValue() + " < " + defaultBaseValue);
/* */ }
/* */
/* 248 */ defaultBaseValue = rule.getBaseValue();
/* 249 */ if (!this.isFractionRuleSet) {
/* 250 */ defaultBaseValue += 1L;
/* */ }
/* 252 */ i++;
/* */ }
/* */
/* */ }
/* */
/* */
/* */
/* 259 */ this.rules = new NFRule[tempRules.size()];
/* 260 */ tempRules.toArray(this.rules);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public void makeIntoFractionRuleSet()
/* */ {
/* 272 */ this.isFractionRuleSet = true;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public boolean equals(Object that)
/* */ {
/* 286 */ if (!(that instanceof NFRuleSet)) {
/* 287 */ return false;
/* */ }
/* */
/* 290 */ NFRuleSet that2 = (NFRuleSet)that;
/* */
/* 292 */ if ((!this.name.equals(that2.name)) || (!Utility.objectEquals(this.negativeNumberRule, that2.negativeNumberRule)) || (!Utility.objectEquals(this.fractionRules[0], that2.fractionRules[0])) || (!Utility.objectEquals(this.fractionRules[1], that2.fractionRules[1])) || (!Utility.objectEquals(this.fractionRules[2], that2.fractionRules[2])) || (this.rules.length != that2.rules.length) || (this.isFractionRuleSet != that2.isFractionRuleSet))
/* */ {
/* */
/* */
/* */
/* */
/* */
/* */
/* 300 */ return false;
/* */ }
/* */
/* */
/* 304 */ for (int i = 0; i < this.rules.length; i++) {
/* 305 */ if (!this.rules[i].equals(that2.rules[i])) {
/* 306 */ return false;
/* */ }
/* */ }
/* */
/* */
/* 311 */ return true;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public String toString()
/* */ {
/* 323 */ StringBuilder result = new StringBuilder();
/* */
/* */
/* 326 */ result.append(this.name + ":\n");
/* */
/* */
/* 329 */ for (int i = 0; i < this.rules.length; i++) {
/* 330 */ result.append(" " + this.rules[i].toString() + "\n");
/* */ }
/* */
/* */
/* 334 */ if (this.negativeNumberRule != null) {
/* 335 */ result.append(" " + this.negativeNumberRule.toString() + "\n");
/* */ }
/* 337 */ if (this.fractionRules[0] != null) {
/* 338 */ result.append(" " + this.fractionRules[0].toString() + "\n");
/* */ }
/* 340 */ if (this.fractionRules[1] != null) {
/* 341 */ result.append(" " + this.fractionRules[1].toString() + "\n");
/* */ }
/* 343 */ if (this.fractionRules[2] != null) {
/* 344 */ result.append(" " + this.fractionRules[2].toString() + "\n");
/* */ }
/* */
/* 347 */ return result.toString();
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public boolean isFractionSet()
/* */ {
/* 359 */ return this.isFractionRuleSet;
/* */ }
/* */
/* */
/* */
/* */
/* */ public String getName()
/* */ {
/* 367 */ return this.name;
/* */ }
/* */
/* */
/* */
/* */
/* */ public boolean isPublic()
/* */ {
/* 375 */ return !this.name.startsWith("%%");
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public boolean isParseable()
/* */ {
/* 388 */ return (!this.name.endsWith("-prefixpart")) && (!this.name.endsWith("-postfixpart")) && (!this.name.endsWith("-postfx"));
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public void format(long number, StringBuffer toInsertInto, int pos)
/* */ {
/* 406 */ NFRule applicableRule = findNormalRule(number);
/* */
/* 408 */ if (++this.recursionCount >= 50) {
/* 409 */ this.recursionCount = 0;
/* 410 */ throw new IllegalStateException("Recursion limit exceeded when applying ruleSet " + this.name);
/* */ }
/* 412 */ applicableRule.doFormat(number, toInsertInto, pos);
/* 413 */ this.recursionCount -= 1;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public void format(double number, StringBuffer toInsertInto, int pos)
/* */ {
/* 425 */ NFRule applicableRule = findRule(number);
/* */
/* 427 */ if (++this.recursionCount >= 50) {
/* 428 */ this.recursionCount = 0;
/* 429 */ throw new IllegalStateException("Recursion limit exceeded when applying ruleSet " + this.name);
/* */ }
/* 431 */ applicableRule.doFormat(number, toInsertInto, pos);
/* 432 */ this.recursionCount -= 1;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private NFRule findRule(double number)
/* */ {
/* 442 */ if (this.isFractionRuleSet) {
/* 443 */ return findFractionRuleSetRule(number);
/* */ }
/* */
/* */
/* */
/* */
/* 449 */ if (number < 0.0D) {
/* 450 */ if (this.negativeNumberRule != null) {
/* 451 */ return this.negativeNumberRule;
/* */ }
/* 453 */ number = -number;
/* */ }
/* */
/* */
/* */
/* 458 */ if (number != Math.floor(number))
/* */ {
/* */
/* 461 */ if ((number < 1.0D) && (this.fractionRules[1] != null)) {
/* 462 */ return this.fractionRules[1];
/* */ }
/* */
/* */
/* 466 */ if (this.fractionRules[0] != null) {
/* 467 */ return this.fractionRules[0];
/* */ }
/* */ }
/* */
/* */
/* 472 */ if (this.fractionRules[2] != null) {
/* 473 */ return this.fractionRules[2];
/* */ }
/* */
/* */
/* */
/* 478 */ return findNormalRule(Math.round(number));
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private NFRule findNormalRule(long number)
/* */ {
/* 502 */ if (this.isFractionRuleSet) {
/* 503 */ return findFractionRuleSetRule(number);
/* */ }
/* */
/* */
/* */
/* 508 */ if (number < 0L) {
/* 509 */ if (this.negativeNumberRule != null) {
/* 510 */ return this.negativeNumberRule;
/* */ }
/* 512 */ number = -number;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 528 */ int lo = 0;
/* 529 */ int hi = this.rules.length;
/* 530 */ if (hi > 0) {
/* 531 */ while (lo < hi) {
/* 532 */ int mid = (lo + hi) / 2;
/* 533 */ if (this.rules[mid].getBaseValue() == number) {
/* 534 */ return this.rules[mid];
/* */ }
/* 536 */ if (this.rules[mid].getBaseValue() > number) {
/* 537 */ hi = mid;
/* */ }
/* */ else {
/* 540 */ lo = mid + 1;
/* */ }
/* */ }
/* 543 */ if (hi == 0) {
/* 544 */ throw new IllegalStateException("The rule set " + this.name + " cannot format the value " + number);
/* */ }
/* 546 */ NFRule result = this.rules[(hi - 1)];
/* */
/* */
/* */
/* */
/* */
/* */
/* 553 */ if (result.shouldRollBack(number)) {
/* 554 */ if (hi == 1) {
/* 555 */ throw new IllegalStateException("The rule set " + this.name + " cannot roll back from the rule '" + result + "'");
/* */ }
/* */
/* 558 */ result = this.rules[(hi - 2)];
/* */ }
/* 560 */ return result;
/* */ }
/* */
/* 563 */ return this.fractionRules[2];
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private NFRule findFractionRuleSetRule(double number)
/* */ {
/* 591 */ long leastCommonMultiple = this.rules[0].getBaseValue();
/* 592 */ for (int i = 1; i < this.rules.length; i++) {
/* 593 */ leastCommonMultiple = lcm(leastCommonMultiple, this.rules[i].getBaseValue());
/* */ }
/* 595 */ long numerator = Math.round(number * leastCommonMultiple);
/* */
/* */
/* */
/* 599 */ long difference = Long.MAX_VALUE;
/* 600 */ int winner = 0;
/* 601 */ for (int i = 0; i < this.rules.length; i++)
/* */ {
/* */
/* */
/* */
/* */
/* */
/* 608 */ long tempDifference = numerator * this.rules[i].getBaseValue() % leastCommonMultiple;
/* */
/* */
/* */
/* */
/* 613 */ if (leastCommonMultiple - tempDifference < tempDifference) {
/* 614 */ tempDifference = leastCommonMultiple - tempDifference;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* 621 */ if (tempDifference < difference) {
/* 622 */ difference = tempDifference;
/* 623 */ winner = i;
/* 624 */ if (difference == 0L) {
/* */ break;
/* */ }
/* */ }
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 636 */ if ((winner + 1 < this.rules.length) && (this.rules[(winner + 1)].getBaseValue() == this.rules[winner].getBaseValue()))
/* */ {
/* 638 */ if ((Math.round(number * this.rules[winner].getBaseValue()) < 1L) || (Math.round(number * this.rules[winner].getBaseValue()) >= 2L))
/* */ {
/* 640 */ winner++;
/* */ }
/* */ }
/* */
/* */
/* 645 */ return this.rules[winner];
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */ private static long lcm(long x, long y)
/* */ {
/* 654 */ long x1 = x;
/* 655 */ long y1 = y;
/* */
/* 657 */ int p2 = 0;
/* 658 */ while (((x1 & 1L) == 0L) && ((y1 & 1L) == 0L)) {
/* 659 */ p2++;
/* 660 */ x1 >>= 1;
/* 661 */ y1 >>= 1;
/* */ }
/* */ long t;
/* */ long t;
/* 665 */ if ((x1 & 1L) == 1L) {
/* 666 */ t = -y1;
/* */ } else {
/* 668 */ t = x1;
/* */ }
/* */
/* 671 */ while (t != 0L) {
/* 672 */ while ((t & 1L) == 0L) {
/* 673 */ t >>= 1;
/* */ }
/* 675 */ if (t > 0L) {
/* 676 */ x1 = t;
/* */ } else {
/* 678 */ y1 = -t;
/* */ }
/* 680 */ t = x1 - y1;
/* */ }
/* 682 */ long gcd = x1 << p2;
/* */
/* */
/* 685 */ return x / gcd * y;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public Number parse(String text, ParsePosition parsePosition, double upperBound)
/* */ {
/* 718 */ ParsePosition highWaterMark = new ParsePosition(0);
/* 719 */ Number result = new Long(0L);
/* 720 */ Number tempResult = null;
/* */
/* */
/* 723 */ if (text.length() == 0) {
/* 724 */ return result;
/* */ }
/* */
/* */
/* 728 */ if (this.negativeNumberRule != null) {
/* 729 */ tempResult = this.negativeNumberRule.doParse(text, parsePosition, false, upperBound);
/* 730 */ if (parsePosition.getIndex() > highWaterMark.getIndex()) {
/* 731 */ result = tempResult;
/* 732 */ highWaterMark.setIndex(parsePosition.getIndex());
/* */ }
/* */
/* */
/* */
/* */
/* 738 */ parsePosition.setIndex(0);
/* */ }
/* */
/* */
/* 742 */ for (int i = 0; i < 3; i++) {
/* 743 */ if (this.fractionRules[i] != null) {
/* 744 */ tempResult = this.fractionRules[i].doParse(text, parsePosition, false, upperBound);
/* 745 */ if (parsePosition.getIndex() > highWaterMark.getIndex()) {
/* 746 */ result = tempResult;
/* 747 */ highWaterMark.setIndex(parsePosition.getIndex());
/* */ }
/* */
/* */
/* */
/* */
/* 753 */ parsePosition.setIndex(0);
/* */ }
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 766 */ for (int i = this.rules.length - 1; (i >= 0) && (highWaterMark.getIndex() < text.length()); i--) {
/* 767 */ if ((this.isFractionRuleSet) || (this.rules[i].getBaseValue() < upperBound))
/* */ {
/* */
/* */
/* 771 */ tempResult = this.rules[i].doParse(text, parsePosition, this.isFractionRuleSet, upperBound);
/* 772 */ if (parsePosition.getIndex() > highWaterMark.getIndex()) {
/* 773 */ result = tempResult;
/* 774 */ highWaterMark.setIndex(parsePosition.getIndex());
/* */ }
/* */
/* */
/* */
/* */
/* 780 */ parsePosition.setIndex(0);
/* */ }
/* */ }
/* */
/* */
/* */
/* 786 */ parsePosition.setIndex(highWaterMark.getIndex());
/* */
/* */
/* */
/* */
/* */
/* 792 */ return result;
/* */ }
/* */ }
/* Location: C:\Users\Ethan\Desktop\FontZip\FontTool\sfnttool.jar!\com\ibm\icu\text\NFRuleSet.class
* Java compiler version: 5 (49.0)
* JD-Core Version: 0.7.1
*/