OLD | NEW |
1 // © 2016 and later: Unicode, Inc. and others. | 1 // © 2016 and later: Unicode, Inc. and others. |
2 // License & terms of use: http://www.unicode.org/copyright.html#License | 2 // License & terms of use: http://www.unicode.org/copyright.html#License |
3 /* | 3 /* |
4 ******************************************************************************* | 4 ******************************************************************************* |
5 * Copyright (C) 2007-2016, International Business Machines Corporation and | 5 * Copyright (C) 2007-2016, International Business Machines Corporation and |
6 * others. All Rights Reserved. | 6 * others. All Rights Reserved. |
7 ******************************************************************************* | 7 ******************************************************************************* |
8 */ | 8 */ |
9 | 9 |
10 package com.ibm.icu.text; | 10 package com.ibm.icu.text; |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 ORDINAL | 349 ORDINAL |
350 }; | 350 }; |
351 | 351 |
352 /* | 352 /* |
353 * The default constraint that is always satisfied. | 353 * The default constraint that is always satisfied. |
354 */ | 354 */ |
355 private static final Constraint NO_CONSTRAINT = new Constraint() { | 355 private static final Constraint NO_CONSTRAINT = new Constraint() { |
356 private static final long serialVersionUID = 9163464945387899416L; | 356 private static final long serialVersionUID = 9163464945387899416L; |
357 | 357 |
358 @Override | 358 @Override |
359 public boolean isFulfilled(FixedDecimal n) { | 359 public boolean isFulfilled(IFixedDecimal n) { |
360 return true; | 360 return true; |
361 } | 361 } |
362 | 362 |
363 @Override | 363 @Override |
364 public boolean isLimited(SampleType sampleType) { | 364 public boolean isLimited(SampleType sampleType) { |
365 return false; | 365 return false; |
366 } | 366 } |
367 | 367 |
368 @Override | 368 @Override |
369 public String toString() { | 369 public String toString() { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 } | 405 } |
406 } | 406 } |
407 | 407 |
408 /** | 408 /** |
409 * The default rules that accept any number and return | 409 * The default rules that accept any number and return |
410 * {@link #KEYWORD_OTHER}. | 410 * {@link #KEYWORD_OTHER}. |
411 * @stable ICU 3.8 | 411 * @stable ICU 3.8 |
412 */ | 412 */ |
413 public static final PluralRules DEFAULT = new PluralRules(new RuleList().add
Rule(DEFAULT_RULE)); | 413 public static final PluralRules DEFAULT = new PluralRules(new RuleList().add
Rule(DEFAULT_RULE)); |
414 | 414 |
415 private enum Operand { | 415 /** |
| 416 * @internal |
| 417 * @deprecated This API is ICU internal only. |
| 418 */ |
| 419 @Deprecated |
| 420 public static enum Operand { |
| 421 /** The double value of the entire number. */ |
416 n, | 422 n, |
| 423 /** The integer value, with the fraction digits truncated off. */ |
417 i, | 424 i, |
| 425 /** All visible fraction digits as an integer, including trailing zeros.
*/ |
418 f, | 426 f, |
| 427 /** Visible fraction digits, not including trailing zeros. */ |
419 t, | 428 t, |
| 429 /** Number of visible fraction digits. */ |
420 v, | 430 v, |
421 w, | 431 w, |
422 /* deprecated */ | 432 /* deprecated */ |
423 j; | 433 j; |
424 } | 434 } |
425 | 435 |
426 /** | 436 /** |
427 * @internal | 437 * @internal |
428 * @deprecated This API is ICU internal only. | 438 * @deprecated This API is ICU internal only. |
429 */ | 439 */ |
430 @Deprecated | 440 @Deprecated |
431 public static class FixedDecimal extends Number implements Comparable<FixedD
ecimal> { | 441 public static interface IFixedDecimal { |
| 442 public double getPluralOperand(Operand operand); |
| 443 public boolean isNaN(); |
| 444 public boolean isInfinite(); |
| 445 } |
| 446 |
| 447 /** |
| 448 * @internal |
| 449 * @deprecated This API is ICU internal only. |
| 450 */ |
| 451 @Deprecated |
| 452 public static class FixedDecimal extends Number implements Comparable<FixedD
ecimal>, IFixedDecimal { |
432 private static final long serialVersionUID = -4756200506571685661L; | 453 private static final long serialVersionUID = -4756200506571685661L; |
433 /** | 454 /** |
434 * @internal | 455 * @internal |
435 * @deprecated This API is ICU internal only. | 456 * @deprecated This API is ICU internal only. |
436 */ | 457 */ |
437 @Deprecated | 458 @Deprecated |
438 public final double source; | 459 public final double source; |
439 /** | 460 /** |
440 * @internal | 461 * @internal |
441 * @deprecated This API is ICU internal only. | 462 * @deprecated This API is ICU internal only. |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 return 0; | 740 return 0; |
720 } else { | 741 } else { |
721 return value.length() - decimalPos; | 742 return value.length() - decimalPos; |
722 } | 743 } |
723 } | 744 } |
724 | 745 |
725 /** | 746 /** |
726 * @internal | 747 * @internal |
727 * @deprecated This API is ICU internal only. | 748 * @deprecated This API is ICU internal only. |
728 */ | 749 */ |
| 750 @Override |
729 @Deprecated | 751 @Deprecated |
730 public double get(Operand operand) { | 752 public double getPluralOperand(Operand operand) { |
731 switch(operand) { | 753 switch(operand) { |
732 default: return source; | 754 default: return source; |
733 case i: return integerValue; | 755 case i: return integerValue; |
734 case f: return decimalDigits; | 756 case f: return decimalDigits; |
735 case t: return decimalDigitsWithoutTrailingZeros; | 757 case t: return decimalDigitsWithoutTrailingZeros; |
736 case v: return visibleDecimalDigitCount; | 758 case v: return visibleDecimalDigitCount; |
737 case w: return visibleDecimalDigitCountWithoutTrailingZeros; | 759 case w: return visibleDecimalDigitCountWithoutTrailingZeros; |
738 } | 760 } |
739 } | 761 } |
740 | 762 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 private void writeObject( | 896 private void writeObject( |
875 ObjectOutputStream out) | 897 ObjectOutputStream out) |
876 throws IOException { | 898 throws IOException { |
877 throw new NotSerializableException(); | 899 throw new NotSerializableException(); |
878 } | 900 } |
879 | 901 |
880 private void readObject(ObjectInputStream in | 902 private void readObject(ObjectInputStream in |
881 ) throws IOException, ClassNotFoundException { | 903 ) throws IOException, ClassNotFoundException { |
882 throw new NotSerializableException(); | 904 throw new NotSerializableException(); |
883 } | 905 } |
| 906 |
| 907 /* (non-Javadoc) |
| 908 * @see com.ibm.icu.text.PluralRules.IFixedDecimal#isNaN() |
| 909 */ |
| 910 @Override |
| 911 public boolean isNaN() { |
| 912 return Double.isNaN(source); |
| 913 } |
| 914 |
| 915 /* (non-Javadoc) |
| 916 * @see com.ibm.icu.text.PluralRules.IFixedDecimal#isInfinite() |
| 917 */ |
| 918 @Override |
| 919 public boolean isInfinite() { |
| 920 return Double.isInfinite(source); |
| 921 } |
884 } | 922 } |
885 | 923 |
886 /** | 924 /** |
887 * Selection parameter for either integer-only or decimal-only. | 925 * Selection parameter for either integer-only or decimal-only. |
888 * @internal | 926 * @internal |
889 * @deprecated This API is ICU internal only. | 927 * @deprecated This API is ICU internal only. |
890 */ | 928 */ |
891 @Deprecated | 929 @Deprecated |
892 public enum SampleType { | 930 public enum SampleType { |
893 /** | 931 /** |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1099 } | 1137 } |
1100 | 1138 |
1101 /* | 1139 /* |
1102 * A constraint on a number. | 1140 * A constraint on a number. |
1103 */ | 1141 */ |
1104 private interface Constraint extends Serializable { | 1142 private interface Constraint extends Serializable { |
1105 /* | 1143 /* |
1106 * Returns true if the number fulfills the constraint. | 1144 * Returns true if the number fulfills the constraint. |
1107 * @param n the number to test, >= 0. | 1145 * @param n the number to test, >= 0. |
1108 */ | 1146 */ |
1109 boolean isFulfilled(FixedDecimal n); | 1147 boolean isFulfilled(IFixedDecimal n); |
1110 | 1148 |
1111 /* | 1149 /* |
1112 * Returns false if an unlimited number of values fulfills the | 1150 * Returns false if an unlimited number of values fulfills the |
1113 * constraint. | 1151 * constraint. |
1114 */ | 1152 */ |
1115 boolean isLimited(SampleType sampleType); | 1153 boolean isLimited(SampleType sampleType); |
1116 } | 1154 } |
1117 | 1155 |
1118 static class SimpleTokenizer { | 1156 static class SimpleTokenizer { |
1119 static final UnicodeSet BREAK_AND_IGNORE = new UnicodeSet(0x09, 0x0a, 0x
0c, 0x0d, 0x20, 0x20).freeze(); | 1157 static final UnicodeSet BREAK_AND_IGNORE = new UnicodeSet(0x09, 0x0a, 0x
0c, 0x0d, 0x20, 0x20).freeze(); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 this.mod = mod; | 1494 this.mod = mod; |
1457 this.inRange = inRange; | 1495 this.inRange = inRange; |
1458 this.integersOnly = integersOnly; | 1496 this.integersOnly = integersOnly; |
1459 this.lowerBound = lowBound; | 1497 this.lowerBound = lowBound; |
1460 this.upperBound = highBound; | 1498 this.upperBound = highBound; |
1461 this.range_list = vals; | 1499 this.range_list = vals; |
1462 this.operand = operand; | 1500 this.operand = operand; |
1463 } | 1501 } |
1464 | 1502 |
1465 @Override | 1503 @Override |
1466 public boolean isFulfilled(FixedDecimal number) { | 1504 public boolean isFulfilled(IFixedDecimal number) { |
1467 double n = number.get(operand); | 1505 double n = number.getPluralOperand(operand); |
1468 if ((integersOnly && (n - (long)n) != 0.0 | 1506 if ((integersOnly && (n - (long)n) != 0.0 |
1469 || operand == Operand.j && number.visibleDecimalDigitCount !
= 0)) { | 1507 || operand == Operand.j && number.getPluralOperand(Operand.v
) != 0)) { |
1470 return !inRange; | 1508 return !inRange; |
1471 } | 1509 } |
1472 if (mod != 0) { | 1510 if (mod != 0) { |
1473 n = n % mod; // java % handles double numerator the way we wa
nt | 1511 n = n % mod; // java % handles double numerator the way we wa
nt |
1474 } | 1512 } |
1475 boolean test = n >= lowerBound && n <= upperBound; | 1513 boolean test = n >= lowerBound && n <= upperBound; |
1476 if (test && range_list != null) { | 1514 if (test && range_list != null) { |
1477 test = false; | 1515 test = false; |
1478 for (int i = 0; !test && i < range_list.length; i += 2) { | 1516 for (int i = 0; !test && i < range_list.length; i += 2) { |
1479 test = n >= range_list[i] && n <= range_list[i+1]; | 1517 test = n >= range_list[i] && n <= range_list[i+1]; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1559 | 1597 |
1560 /* A constraint representing the logical and of two constraints. */ | 1598 /* A constraint representing the logical and of two constraints. */ |
1561 private static class AndConstraint extends BinaryConstraint { | 1599 private static class AndConstraint extends BinaryConstraint { |
1562 private static final long serialVersionUID = 7766999779862263523L; | 1600 private static final long serialVersionUID = 7766999779862263523L; |
1563 | 1601 |
1564 AndConstraint(Constraint a, Constraint b) { | 1602 AndConstraint(Constraint a, Constraint b) { |
1565 super(a, b); | 1603 super(a, b); |
1566 } | 1604 } |
1567 | 1605 |
1568 @Override | 1606 @Override |
1569 public boolean isFulfilled(FixedDecimal n) { | 1607 public boolean isFulfilled(IFixedDecimal n) { |
1570 return a.isFulfilled(n) | 1608 return a.isFulfilled(n) |
1571 && b.isFulfilled(n); | 1609 && b.isFulfilled(n); |
1572 } | 1610 } |
1573 | 1611 |
1574 @Override | 1612 @Override |
1575 public boolean isLimited(SampleType sampleType) { | 1613 public boolean isLimited(SampleType sampleType) { |
1576 // we ignore the case where both a and b are unlimited but no values | 1614 // we ignore the case where both a and b are unlimited but no values |
1577 // satisfy both-- we still consider this 'unlimited' | 1615 // satisfy both-- we still consider this 'unlimited' |
1578 return a.isLimited(sampleType) | 1616 return a.isLimited(sampleType) |
1579 || b.isLimited(sampleType); | 1617 || b.isLimited(sampleType); |
1580 } | 1618 } |
1581 | 1619 |
1582 @Override | 1620 @Override |
1583 public String toString() { | 1621 public String toString() { |
1584 return a.toString() + " and " + b.toString(); | 1622 return a.toString() + " and " + b.toString(); |
1585 } | 1623 } |
1586 } | 1624 } |
1587 | 1625 |
1588 /* A constraint representing the logical or of two constraints. */ | 1626 /* A constraint representing the logical or of two constraints. */ |
1589 private static class OrConstraint extends BinaryConstraint { | 1627 private static class OrConstraint extends BinaryConstraint { |
1590 private static final long serialVersionUID = 1405488568664762222L; | 1628 private static final long serialVersionUID = 1405488568664762222L; |
1591 | 1629 |
1592 OrConstraint(Constraint a, Constraint b) { | 1630 OrConstraint(Constraint a, Constraint b) { |
1593 super(a, b); | 1631 super(a, b); |
1594 } | 1632 } |
1595 | 1633 |
1596 @Override | 1634 @Override |
1597 public boolean isFulfilled(FixedDecimal n) { | 1635 public boolean isFulfilled(IFixedDecimal n) { |
1598 return a.isFulfilled(n) | 1636 return a.isFulfilled(n) |
1599 || b.isFulfilled(n); | 1637 || b.isFulfilled(n); |
1600 } | 1638 } |
1601 | 1639 |
1602 @Override | 1640 @Override |
1603 public boolean isLimited(SampleType sampleType) { | 1641 public boolean isLimited(SampleType sampleType) { |
1604 return a.isLimited(sampleType) | 1642 return a.isLimited(sampleType) |
1605 && b.isLimited(sampleType); | 1643 && b.isLimited(sampleType); |
1606 } | 1644 } |
1607 | 1645 |
(...skipping 30 matching lines...) Expand all Loading... |
1638 | 1676 |
1639 @SuppressWarnings("unused") | 1677 @SuppressWarnings("unused") |
1640 public Rule or(Constraint c) { | 1678 public Rule or(Constraint c) { |
1641 return new Rule(keyword, new OrConstraint(constraint, c), integerSam
ples, decimalSamples); | 1679 return new Rule(keyword, new OrConstraint(constraint, c), integerSam
ples, decimalSamples); |
1642 } | 1680 } |
1643 | 1681 |
1644 public String getKeyword() { | 1682 public String getKeyword() { |
1645 return keyword; | 1683 return keyword; |
1646 } | 1684 } |
1647 | 1685 |
1648 public boolean appliesTo(FixedDecimal n) { | 1686 public boolean appliesTo(IFixedDecimal n) { |
1649 return constraint.isFulfilled(n); | 1687 return constraint.isFulfilled(n); |
1650 } | 1688 } |
1651 | 1689 |
1652 public boolean isLimited(SampleType sampleType) { | 1690 public boolean isLimited(SampleType sampleType) { |
1653 return constraint.isLimited(sampleType); | 1691 return constraint.isLimited(sampleType); |
1654 } | 1692 } |
1655 | 1693 |
1656 @Override | 1694 @Override |
1657 public String toString() { | 1695 public String toString() { |
1658 return keyword + ": " + constraint.toString() | 1696 return keyword + ": " + constraint.toString() |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1701 it.remove(); | 1739 it.remove(); |
1702 } | 1740 } |
1703 } | 1741 } |
1704 if (otherRule == null) { | 1742 if (otherRule == null) { |
1705 otherRule = parseRule("other:"); // make sure we have always hav
e an 'other' a rule | 1743 otherRule = parseRule("other:"); // make sure we have always hav
e an 'other' a rule |
1706 } | 1744 } |
1707 rules.add(otherRule); | 1745 rules.add(otherRule); |
1708 return this; | 1746 return this; |
1709 } | 1747 } |
1710 | 1748 |
1711 private Rule selectRule(FixedDecimal n) { | 1749 private Rule selectRule(IFixedDecimal n) { |
1712 for (Rule rule : rules) { | 1750 for (Rule rule : rules) { |
1713 if (rule.appliesTo(n)) { | 1751 if (rule.appliesTo(n)) { |
1714 return rule; | 1752 return rule; |
1715 } | 1753 } |
1716 } | 1754 } |
1717 return null; | 1755 return null; |
1718 } | 1756 } |
1719 | 1757 |
1720 public String select(FixedDecimal n) { | 1758 public String select(IFixedDecimal n) { |
1721 if (Double.isInfinite(n.source) || Double.isNaN(n.source)) { | 1759 if (n.isInfinite() || n.isNaN()) { |
1722 return KEYWORD_OTHER; | 1760 return KEYWORD_OTHER; |
1723 } | 1761 } |
1724 Rule r = selectRule(n); | 1762 Rule r = selectRule(n); |
1725 return r.getKeyword(); | 1763 return r.getKeyword(); |
1726 } | 1764 } |
1727 | 1765 |
1728 public Set<String> getKeywords() { | 1766 public Set<String> getKeywords() { |
1729 Set<String> result = new LinkedHashSet<String>(); | 1767 Set<String> result = new LinkedHashSet<String>(); |
1730 for (Rule rule : rules) { | 1768 for (Rule rule : rules) { |
1731 result.add(rule.getKeyword()); | 1769 result.add(rule.getKeyword()); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1773 | 1811 |
1774 public String getRules(String keyword) { | 1812 public String getRules(String keyword) { |
1775 for (Rule rule : rules) { | 1813 for (Rule rule : rules) { |
1776 if (rule.getKeyword().equals(keyword)) { | 1814 if (rule.getKeyword().equals(keyword)) { |
1777 return rule.getConstraint(); | 1815 return rule.getConstraint(); |
1778 } | 1816 } |
1779 } | 1817 } |
1780 return null; | 1818 return null; |
1781 } | 1819 } |
1782 | 1820 |
1783 public boolean select(FixedDecimal sample, String keyword) { | 1821 public boolean select(IFixedDecimal sample, String keyword) { |
1784 for (Rule rule : rules) { | 1822 for (Rule rule : rules) { |
1785 if (rule.getKeyword().equals(keyword) && rule.appliesTo(sample))
{ | 1823 if (rule.getKeyword().equals(keyword) && rule.appliesTo(sample))
{ |
1786 return true; | 1824 return true; |
1787 } | 1825 } |
1788 } | 1826 } |
1789 return false; | 1827 return false; |
1790 } | 1828 } |
1791 | 1829 |
1792 public FixedDecimalSamples getDecimalSamples(String keyword, SampleType
sampleType) { | 1830 public FixedDecimalSamples getDecimalSamples(String keyword, SampleType
sampleType) { |
1793 for (Rule rule : rules) { | 1831 for (Rule rule : rules) { |
1794 if (rule.getKeyword().equals(keyword)) { | 1832 if (rule.getKeyword().equals(keyword)) { |
1795 return sampleType == SampleType.INTEGER ? rule.integerSample
s : rule.decimalSamples; | 1833 return sampleType == SampleType.INTEGER ? rule.integerSample
s : rule.decimalSamples; |
1796 } | 1834 } |
1797 } | 1835 } |
1798 return null; | 1836 return null; |
1799 } | 1837 } |
1800 } | 1838 } |
1801 | 1839 |
1802 @SuppressWarnings("unused") | 1840 @SuppressWarnings("unused") |
1803 private boolean addConditional(Set<FixedDecimal> toAddTo, Set<FixedDecimal>
others, double trial) { | 1841 private boolean addConditional(Set<IFixedDecimal> toAddTo, Set<IFixedDecimal
> others, double trial) { |
1804 boolean added; | 1842 boolean added; |
1805 FixedDecimal toAdd = new FixedDecimal(trial); | 1843 IFixedDecimal toAdd = new FixedDecimal(trial); |
1806 if (!toAddTo.contains(toAdd) && !others.contains(toAdd)) { | 1844 if (!toAddTo.contains(toAdd) && !others.contains(toAdd)) { |
1807 others.add(toAdd); | 1845 others.add(toAdd); |
1808 added = true; | 1846 added = true; |
1809 } else { | 1847 } else { |
1810 added = false; | 1848 added = false; |
1811 } | 1849 } |
1812 return added; | 1850 return added; |
1813 } | 1851 } |
1814 | 1852 |
1815 | 1853 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1962 /** | 2000 /** |
1963 * Given a number information, returns the keyword of the first rule that ap
plies to | 2001 * Given a number information, returns the keyword of the first rule that ap
plies to |
1964 * the number. | 2002 * the number. |
1965 * | 2003 * |
1966 * @param number The number information for which the rule has to be determi
ned. | 2004 * @param number The number information for which the rule has to be determi
ned. |
1967 * @return The keyword of the selected rule. | 2005 * @return The keyword of the selected rule. |
1968 * @internal | 2006 * @internal |
1969 * @deprecated This API is ICU internal only. | 2007 * @deprecated This API is ICU internal only. |
1970 */ | 2008 */ |
1971 @Deprecated | 2009 @Deprecated |
1972 public String select(FixedDecimal number) { | 2010 public String select(IFixedDecimal number) { |
1973 return rules.select(number); | 2011 return rules.select(number); |
1974 } | 2012 } |
1975 | 2013 |
1976 /** | 2014 /** |
1977 * Given a number information, and keyword, return whether the keyword would
match the number. | 2015 * Given a number information, and keyword, return whether the keyword would
match the number. |
1978 * | 2016 * |
1979 * @param sample The number information for which the rule has to be determi
ned. | 2017 * @param sample The number information for which the rule has to be determi
ned. |
1980 * @param keyword The keyword to filter on | 2018 * @param keyword The keyword to filter on |
1981 * @internal | 2019 * @internal |
1982 * @deprecated This API is ICU internal only. | 2020 * @deprecated This API is ICU internal only. |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2393 | 2431 |
2394 /** | 2432 /** |
2395 * @internal | 2433 * @internal |
2396 * @deprecated internal | 2434 * @deprecated internal |
2397 */ | 2435 */ |
2398 @Deprecated | 2436 @Deprecated |
2399 public boolean computeLimited(String keyword, SampleType sampleType) { | 2437 public boolean computeLimited(String keyword, SampleType sampleType) { |
2400 return rules.computeLimited(keyword, sampleType); | 2438 return rules.computeLimited(keyword, sampleType); |
2401 } | 2439 } |
2402 } | 2440 } |
OLD | NEW |