1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project******************************************************************************* 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* Copyright (C) 1996-2005, International Business Machines Corporation and * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* others. All Rights Reserved. * 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project******************************************************************************* 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project******************************************************************************* 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*/ 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 114dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughespackage libcore.icu; 124dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughes 134dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughesimport java.text.CollationKey; 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 16ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * A concrete implementation of the abstract java.text.CollationKey. 17ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes */ 184dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughespublic final class CollationKeyICU extends CollationKey { 19ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes /** 20ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * The key. 21ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes */ 22ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes private final byte[] bytes; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 24ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes /** 25ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * Cached hash value. 26ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes */ 27ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes private int hashCode; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 294dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughes CollationKeyICU(String source, byte[] bytes) { 30ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes super(source); 31ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes this.bytes = bytes; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 344dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughes @Override public int compareTo(CollationKey other) { 35ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes // Get the bytes from the other collation key. 36ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes final byte[] rhsBytes; 374dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughes if (other instanceof CollationKeyICU) { 384dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughes rhsBytes = ((CollationKeyICU) other).bytes; 39ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } else { 40ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes rhsBytes = other.toByteArray(); 41ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 43ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (bytes == null || bytes.length == 0) { 44ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (rhsBytes == null || rhsBytes.length == 0) { 45ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return 0; 46ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 47ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return -1; 48ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } else { 49ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (rhsBytes == null || rhsBytes.length == 0) { 50ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return 1; 51ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 52ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes int count = Math.min(bytes.length, rhsBytes.length); 55ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes for (int i = 0; i < count; ++i) { 56ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes int s = bytes[i] & 0xff; 57ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes int t = rhsBytes[i] & 0xff; 58ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (s < t) { 59ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return -1; 60ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 61ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (s > t) { 62ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return 1; 63ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 64ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 65ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (bytes.length < rhsBytes.length) { 66ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return -1; 67ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 68ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (bytes.length > rhsBytes.length) { 69ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return 1; 70ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 71ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return 0; 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 744dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughes @Override public boolean equals(Object object) { 75ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (object == this) { 76ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return true; 77ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 78ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (!(object instanceof CollationKey)) { 79ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return false; 80ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 81ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return compareTo((CollationKey) object) == 0; 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 84ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes /** 85ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * Creates a hash code for this CollationKey. 86ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * Compute the hash by iterating sparsely over about 32 (up to 63) bytes 87ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * spaced evenly through the string. For each byte, multiply the previous 88ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * hash value by a prime number and add the new byte in, like a linear 89ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * congruential random number generator, producing a pseudo-random 90ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * deterministic value well distributed over the output range. 91ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * @return hash value of collation key. Hash value is never 0. 92ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes * @stable ICU 2.4 93ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes */ 944dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughes @Override public int hashCode() { 95ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (hashCode == 0) { 96ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (bytes != null && bytes.length != 0) { 97ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes int len = bytes.length; 98ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes int inc = ((len - 32) / 32) + 1; 99ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes for (int i = 0; i < len;) { 100ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes hashCode = (hashCode * 37) + bytes[i]; 101ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes i += inc; 102ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 103ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 104ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (hashCode == 0) { 105ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes hashCode = 1; 106ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 107ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 108ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return hashCode; 109ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1114dfae7b3e2b56160646c17d93b32b3ff495c0053Elliott Hughes @Override public byte[] toByteArray() { 112ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (bytes == null || bytes.length == 0) { 113ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return null; 114ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 115ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return bytes.clone(); 116ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 118