NamedCollator.java 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package gnu.xquery.util;
  2. import java.io.*;
  3. public class NamedCollator
  4. /* #ifdef JAVA2 */
  5. extends java.text.Collator
  6. /* #endif */
  7. implements Externalizable
  8. {
  9. /* #ifdef JAVA2 */
  10. java.text.Collator collator;
  11. /* #endif */
  12. String name;
  13. public static final String UNICODE_CODEPOINT_COLLATION
  14. = "http://www.w3.org/2005/xpath-functions/collation/codepoint";
  15. public static NamedCollator make (String name)
  16. {
  17. NamedCollator coll = new NamedCollator();
  18. coll.name = name;
  19. coll.resolve();
  20. return coll;
  21. }
  22. public String getName ()
  23. {
  24. return name;
  25. }
  26. public static NamedCollator find (String name)
  27. {
  28. return make(name);
  29. }
  30. public static final NamedCollator codepointCollation = new NamedCollator();
  31. static { codepointCollation.name = UNICODE_CODEPOINT_COLLATION; }
  32. public void resolve ()
  33. {
  34. if (name != null && ! name.equals(UNICODE_CODEPOINT_COLLATION))
  35. {
  36. // FIXME!
  37. throw new RuntimeException("unknown collation: "+name);
  38. }
  39. }
  40. /** Compares two strings lexicographically by codepoint.
  41. * Same as {@code String.compareTo} but handles surrogate characters.
  42. * @return -1, 0, or 1 depending on their relative order.
  43. */
  44. public static int codepointCompare (String str1, String str2)
  45. {
  46. int i1 = 0, i2 = 0;
  47. int len1 = str1.length();
  48. int len2 = str2.length();
  49. for (;;)
  50. {
  51. if (i1 == len1)
  52. return i2 == len2 ? 0 : -1;
  53. if (i2 == len2)
  54. return 1;
  55. int c1 = str1.charAt(i1++);
  56. if (c1 >= 0xD800 && c1 < 0xDC00 && i1 < len1)
  57. c1 = (c1 - 0xD800) * 0x400
  58. + (str1.charAt(i1++) - 0xDC00) + 0x10000;
  59. int c2 = str2.charAt(i2++);
  60. if (c2 >= 0xD800 && c2 < 0xDC00 && i2 < len2)
  61. c2 = (c2 - 0xD800) * 0x400
  62. + (str2.charAt(i2++) - 0xDC00) + 0x10000;
  63. if (c1 != c2)
  64. return c1 < c2 ? -1 : 1;
  65. }
  66. }
  67. public int compare (String str1, String str2)
  68. {
  69. /* #ifdef JAVA2 */
  70. if (collator != null)
  71. return collator.compare(str1, str2);
  72. /* #endif */
  73. return codepointCompare(str1, str2);
  74. }
  75. /* #ifdef JAVA2 */
  76. public java.text.CollationKey getCollationKey (String source)
  77. {
  78. return collator.getCollationKey(source);
  79. }
  80. /* #endif */
  81. public int hashCode ()
  82. {
  83. /* #ifdef JAVA2 */
  84. if (collator != null)
  85. return collator.hashCode();
  86. /* #endif */
  87. return 0;
  88. }
  89. public void writeExternal(ObjectOutput out) throws IOException
  90. {
  91. out.writeUTF(name);
  92. }
  93. public void readExternal(ObjectInput in)
  94. throws IOException, ClassNotFoundException
  95. {
  96. name = in.readUTF();
  97. resolve();
  98. }
  99. }