|
32 | 32 | import java.util.TreeMap; |
33 | 33 | import java.util.function.Predicate; |
34 | 34 | import java.util.regex.Pattern; |
| 35 | +import org.unicode.cldr.util.Rational.RationalParser; |
35 | 36 | import org.unicode.cldr.util.props.UnicodeLabel; |
36 | 37 |
|
37 | 38 | public abstract class UnicodeProperty extends UnicodeLabel { |
@@ -198,6 +199,7 @@ public UnicodeProperty setDelimiter(String value) { |
198 | 199 | EXTENDED_MASK = 1, |
199 | 200 | CORE_MASK = ~EXTENDED_MASK, |
200 | 201 | BINARY_MASK = (1 << BINARY) | (1 << EXTENDED_BINARY), |
| 202 | + NUMERIC_MASK = (1 << NUMERIC) | (1 << EXTENDED_NUMERIC), |
201 | 203 | STRING_MASK = (1 << STRING) | (1 << EXTENDED_STRING), |
202 | 204 | STRING_OR_MISC_MASK = |
203 | 205 | (1 << STRING) | (1 << EXTENDED_STRING) | (1 << MISC) | (1 << EXTENDED_MISC), |
@@ -443,19 +445,25 @@ public final UnicodeSet getSet(String propertyValue, UnicodeSet result) { |
443 | 445 | if (isMultivalued && propertyValue != null && propertyValue.contains(delimiter)) { |
444 | 446 | throw new IllegalArgumentException( |
445 | 447 | "Multivalued property values can't contain the delimiter."); |
| 448 | + } |
| 449 | + if (propertyValue == null) { |
| 450 | + return getSet(NULL_MATCHER, result); |
| 451 | + } |
| 452 | + Comparator<String> comparator; |
| 453 | + if (isType(NUMERIC_MASK)) { |
| 454 | + // UAX44-LM1. |
| 455 | + comparator = RATIONAL_COMPARATOR; |
| 456 | + } else if (getName().equals("Name") || getName().equals("Name_Alias")) { |
| 457 | + // UAX44-LM2. |
| 458 | + comparator = CHARACTER_NAME_COMPARATOR; |
| 459 | + } else if (isType(BINARY_OR_ENUMERATED_OR_CATALOG_MASK)) { |
| 460 | + // UAX44-LM3 |
| 461 | + comparator = PROPERTY_COMPARATOR; |
446 | 462 | } else { |
447 | | - return getSet( |
448 | | - propertyValue == null |
449 | | - ? NULL_MATCHER |
450 | | - : new SimpleMatcher( |
451 | | - propertyValue, |
452 | | - getName().equals("Name") || getName().equals("Name_Alias") |
453 | | - ? CHARACTER_NAME_COMPARATOR |
454 | | - : isType(STRING_OR_MISC_MASK) |
455 | | - ? null |
456 | | - : PROPERTY_COMPARATOR), |
457 | | - result); |
| 463 | + // String-valued or Miscellaneous property. |
| 464 | + comparator = null; |
458 | 465 | } |
| 466 | + return getSet(new SimpleMatcher(propertyValue, comparator), result); |
459 | 467 | } |
460 | 468 |
|
461 | 469 | private UnicodeMap<String> unicodeMap = null; |
@@ -725,6 +733,26 @@ public static String toSkeleton(String source) { |
725 | 733 | return skeletonBuffer.toString(); |
726 | 734 | } |
727 | 735 |
|
| 736 | + public static final Comparator<String> RATIONAL_COMPARATOR = |
| 737 | + new Comparator<String>() { |
| 738 | + @Override |
| 739 | + public int compare(String x, String y) { |
| 740 | + return compareRationals(x, y); |
| 741 | + } |
| 742 | + }; |
| 743 | + |
| 744 | + public static int compareRationals(String a, String b) { |
| 745 | + if (a == b) return 0; |
| 746 | + if (a == null) return -1; |
| 747 | + if (b == null) return 1; |
| 748 | + final boolean aIsNaN = equalNames(a, "NaN"); |
| 749 | + final boolean bIsNaN = equalNames(b, "NaN"); |
| 750 | + if (aIsNaN && bIsNaN) return 0; |
| 751 | + if (aIsNaN) return -1; |
| 752 | + if (bIsNaN) return 1; |
| 753 | + return RationalParser.BASIC.parse(a).compareTo(RationalParser.BASIC.parse(b)); |
| 754 | + } |
| 755 | + |
728 | 756 | public static final Comparator<String> CHARACTER_NAME_COMPARATOR = |
729 | 757 | new Comparator<String>() { |
730 | 758 | @Override |
|
0 commit comments