1 7 package com.ibm.icu.text; 8 9 83 public final class CollationKey implements Comparable 84 { 85 87 92 public static final class BoundMode 93 { 94 98 99 103 public static final int LOWER = 0; 104 105 109 public static final int UPPER = 1; 110 111 116 public static final int UPPER_LONG = 2; 117 118 122 public static final int COUNT = 3; 123 124 127 private BoundMode(){} 129 } 131 132 134 145 public CollationKey(String source, byte key[]) 146 { 147 m_source_ = source; 148 m_key_ = key; 149 m_hashCode_ = 0; 150 m_length_ = -1; 151 } 152 153 164 public CollationKey(String source, RawCollationKey key) 165 { 166 m_source_ = source; 167 m_key_ = key.releaseBytes(); 168 m_hashCode_ = 0; 169 m_length_ = -1; 170 } 171 172 174 179 public String getSourceString() 180 { 181 return m_source_; 182 } 183 184 215 public byte[] toByteArray() 216 { 217 int length = 0; 218 while (true) { 219 if (m_key_[length] == 0) { 220 break; 221 } 222 length ++; 223 } 224 length ++; 225 byte result[] = new byte[length]; 226 System.arraycopy(m_key_, 0, result, 0, length); 227 return result; 228 } 229 230 232 250 public int compareTo(CollationKey target) 251 { 252 for (int i = 0;; ++i) { 253 int l = m_key_[i]&0xff; 254 int r = target.m_key_[i]&0xff; 255 if (l < r) { 256 return -1; 257 } else if (l > r) { 258 return 1; 259 } else if (l == 0) { 260 return 0; 261 } 262 } 263 } 264 265 283 public int compareTo(Object obj) 284 { 285 return compareTo((CollationKey)obj); 286 } 287 288 304 public boolean equals(Object target) 305 { 306 if (!(target instanceof CollationKey)) { 307 return false; 308 } 309 310 return equals((CollationKey)target); 311 } 312 313 328 public boolean equals(CollationKey target) 329 { 330 if (this == target) { 331 return true; 332 } 333 if (target == null) { 334 return false; 335 } 336 CollationKey other = (CollationKey)target; 337 int i = 0; 338 while (true) { 339 if (m_key_[i] != other.m_key_[i]) { 340 return false; 341 } 342 if (m_key_[i] == 0) { 343 break; 344 } 345 i ++; 346 } 347 return true; 348 } 349 350 360 public int hashCode() 361 { 362 if (m_hashCode_ == 0) { 363 if (m_key_ == null) { 364 m_hashCode_ = 1; 365 } 366 else { 367 int size = m_key_.length >> 1; 368 StringBuffer key = new StringBuffer (size); 369 int i = 0; 370 while (m_key_[i] != 0 && m_key_[i + 1] != 0) { 371 key.append((char)((m_key_[i] << 8) | m_key_[i + 1])); 372 i += 2; 373 } 374 if (m_key_[i] != 0) { 375 key.append((char)(m_key_[i] << 8)); 376 } 377 m_hashCode_ = key.toString().hashCode(); 378 } 379 } 380 return m_hashCode_; 381 } 382 383 440 public CollationKey getBound(int boundType, int noOfLevels) 441 { 442 int offset = 0; 445 int keystrength = Collator.PRIMARY; 446 447 if (noOfLevels > Collator.PRIMARY) { 448 while (offset < m_key_.length && m_key_[offset] != 0) { 449 if (m_key_[offset ++] 450 == RuleBasedCollator.SORT_LEVEL_TERMINATOR_) { 451 keystrength ++; 452 noOfLevels --; 453 if (noOfLevels == Collator.PRIMARY 454 || offset == m_key_.length || m_key_[offset] == 0) { 455 offset --; 456 break; 457 } 458 } 459 } 460 } 461 462 if (noOfLevels > 0) { 463 throw new IllegalArgumentException ( 464 "Source collation key has only " 465 + keystrength 466 + " strength level. Call getBound() again " 467 + " with noOfLevels < " + keystrength); 468 } 469 470 byte resultkey[] = new byte[offset + boundType + 1]; 474 System.arraycopy(m_key_, 0, resultkey, 0, offset); 475 switch (boundType) { 476 case BoundMode.LOWER: break; 479 case BoundMode.UPPER: resultkey[offset ++] = 2; 482 break; 483 case BoundMode.UPPER_LONG: resultkey[offset ++] = (byte)0xFF; 486 resultkey[offset ++] = (byte)0xFF; 487 break; 488 default: 489 throw new IllegalArgumentException ( 490 "Illegal boundType argument"); 491 } 492 resultkey[offset ++] = 0; 493 return new CollationKey(null, resultkey); 494 } 495 496 497 498 536 public CollationKey merge(CollationKey source) 537 { 538 if (source == null || source.getLength() == 0) { 540 throw new IllegalArgumentException ( 541 "CollationKey argument can not be null or of 0 length"); 542 } 543 544 getLength(); int sourcelength = source.getLength(); 546 byte result[] = new byte[m_length_ + sourcelength + 2]; 548 549 int rindex = 0; 551 int index = 0; 552 int sourceindex = 0; 553 while (true) { 554 while (m_key_[index] < 0 || m_key_[index] >= MERGE_SEPERATOR_) { 558 result[rindex ++] = m_key_[index ++]; 559 } 560 561 result[rindex ++] = MERGE_SEPERATOR_; 563 564 while (source.m_key_[sourceindex] < 0 566 || source.m_key_[sourceindex] >= MERGE_SEPERATOR_) { 567 result[rindex ++] = source.m_key_[sourceindex ++]; 568 } 569 570 if (m_key_[index] == RuleBasedCollator.SORT_LEVEL_TERMINATOR_ 573 && source.m_key_[sourceindex] 574 == RuleBasedCollator.SORT_LEVEL_TERMINATOR_) { 575 ++ index; 576 ++ sourceindex; 577 result[rindex ++] = RuleBasedCollator.SORT_LEVEL_TERMINATOR_; 578 } 579 else { 580 break; 581 } 582 } 583 584 if (m_key_[index] != 0) { 588 System.arraycopy(m_key_, index, result, rindex, 589 m_length_ - index); 590 } 591 else if (source.m_key_[sourceindex] != 0) { 592 System.arraycopy(source.m_key_, sourceindex, result, rindex, 593 source.m_length_ - sourceindex); 594 } 595 result[result.length - 1] = 0; 596 597 return new CollationKey(null, result); 599 } 600 601 603 606 private byte m_key_[]; 607 608 611 private String m_source_; 612 613 616 private int m_hashCode_; 617 620 private int m_length_; 621 624 private static final int MERGE_SEPERATOR_ = 2; 625 626 628 632 private int getLength() 633 { 634 if (m_length_ >= 0) { 635 return m_length_; 636 } 637 int length = m_key_.length; 638 for (int index = 0; index < length; index ++) { 639 if (m_key_[index] == 0) { 640 length = index; 641 break; 642 } 643 } 644 m_length_ = length; 645 return m_length_; 646 } 647 } 648 | Popular Tags |