1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*******************************************************************************
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project* Copyright (C) 1996-2005, International Business Machines Corporation and    *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project* others. All Rights Reserved.                                                *
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*******************************************************************************
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*******************************************************************************
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.ibm.icu4jni.text;
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project* Collation key wrapper, containing the byte array sort key.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project* @author syn wee quek
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project* @stable ICU 2.4
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class CollationKey implements Comparable
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  // public methods -----------------------------------------------
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /**
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Bitwise comparison for the collation keys
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @param target CollationKey to be compared
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @return comparison result from Collator, RESULT_LESS, RESULT_EQUAL,
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  *         RESULT_GREATER
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @stable ICU 2.4
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  */
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  public int compareTo(CollationKey target)
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  {
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    byte tgtbytes[] = target.m_bytes_;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (m_bytes_ == null || m_bytes_.length == 0) {
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (tgtbytes == null || tgtbytes.length == 0) {
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Collator.RESULT_EQUAL;
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      }
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return Collator.RESULT_LESS;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    else {
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (tgtbytes == null || tgtbytes.length == 0) {
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Collator.RESULT_GREATER;
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      }
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int count = m_bytes_.length;
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (tgtbytes.length < count) {
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      count = tgtbytes.length;
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int s,
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        t;
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (int i = 0; i < count; i ++)
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      // unable to use Arrays.equals
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      s = m_bytes_[i] & UNSIGNED_BYTE_MASK_;
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      t = tgtbytes[i] & UNSIGNED_BYTE_MASK_;
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (s < t) {
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Collator.RESULT_LESS;
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      }
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (s > t) {
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Collator.RESULT_GREATER;
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      }
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (m_bytes_.length < target.m_bytes_.length) {
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return Collator.RESULT_LESS;
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (m_bytes_.length > target.m_bytes_.length) {
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return Collator.RESULT_GREATER;
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return Collator.RESULT_EQUAL;
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  }
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /**
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Bitwise comparison for the collation keys.
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Argument is casted to CollationKey
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @param target CollationKey to be compared
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @return comparison result from Collator, RESULT_LESS, RESULT_EQUAL,
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * RESULT_GREATER
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @stable ICU 2.4
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  */
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  public int compareTo(Object target)
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  {
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return compareTo((CollationKey)target);
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  }
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /**
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Checks if target object is equal to this object.
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Target is first casted to CollationKey and bitwise compared.
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @param target comparison object
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @return true if both objects are equal, false otherwise
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @stable ICU 2.4
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  */
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  public boolean equals(Object target)
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  {
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (this == target) {
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return true;
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // checks getClass here since CollationKey is final not subclassable
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (target == null || target.getClass() != getClass()) {
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return false;
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return compareTo((CollationKey)target) == Collator.RESULT_EQUAL;
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  }
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /**
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Creates a hash code for this CollationKey.
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Compute the hash by iterating sparsely over about 32 (up to 63) bytes
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * spaced evenly through the string.  For each byte, multiply the previous
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * hash value by a prime number and add the new byte in, like a linear
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * congruential random number generator, producing a pseudorandom
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * deterministic value well distributed over the output range.
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @return hash value of collation key. Hash value is never 0.
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @stable ICU 2.4
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  */
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  public int hashCode()
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  {
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (m_hash_ == 0)
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
125113154c2cf1c09894c4426d30e37f03dd6fe4785Elliott Hughes      if (m_bytes_ != null && m_bytes_.length != 0)
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      {
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int len = m_bytes_.length;
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int inc = ((len - 32) / 32) + 1;
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < len;)
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          m_hash_ = (m_hash_ * 37) + m_bytes_[i];
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          i += inc;
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      }
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (m_hash_ == 0)
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        m_hash_ = 1;
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return m_hash_;
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  }
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /**
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Create the value of the Collation key in term of bytes
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @return value of Collation key in bytes
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * @stable ICU 2.4
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  */
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  public byte[] toByteArray()
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  {
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (m_bytes_ == null || m_bytes_.length == 0)
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return null;
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (byte[])m_bytes_.clone();
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  }
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  // package constructors ----------------------------------------------
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /**
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Default constructor, for use by the Collator and its subclasses.
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  */
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  CollationKey()
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  {
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    m_hash_ = 0;
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  }
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /**
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Constructor, for use only by the Collator and its subclasses.
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  */
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  CollationKey(byte[] bytes)
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    m_bytes_ = bytes;
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    m_hash_ = 0;
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  }
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  // private data members -----------------------------------------------
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  private byte m_bytes_[];
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /**
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Mask value to retrieve a single unsigned byte
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  */
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  private static final int UNSIGNED_BYTE_MASK_ = 0x00FF;
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /**
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  * Cached hash value
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  */
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  private int m_hash_;
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
187