1 /* 2 ******************************************************************************* 3 * Copyright (C) 2009-2014, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ******************************************************************************* 6 */ 7 8 package com.ibm.icu.impl; 9 10 import java.io.DataOutputStream; 11 import java.io.IOException; 12 import java.io.InputStream; 13 import java.nio.ByteBuffer; 14 import java.nio.ByteOrder; 15 import java.util.Iterator; 16 import java.util.NoSuchElementException; 17 18 19 /** 20 * This is the interface and common implementation of a Unicode Trie2. 21 * It is a kind of compressed table that maps from Unicode code points (0..0x10ffff) 22 * to 16- or 32-bit integer values. It works best when there are ranges of 23 * characters with the same value, which is generally the case with Unicode 24 * character properties. 25 * 26 * This is the second common version of a Unicode trie (hence the name Trie2). 27 * 28 */ 29 public abstract class Trie2 implements Iterable<Trie2.Range> { 30 31 32 /** 33 * Create a Trie2 from its serialized form. Inverse of utrie2_serialize(). 34 * 35 * Reads from the current position and leaves the buffer after the end of the trie. 36 * 37 * The serialized format is identical between ICU4C and ICU4J, so this function 38 * will work with serialized Trie2s from either. 39 * 40 * The actual type of the returned Trie2 will be either Trie2_16 or Trie2_32, depending 41 * on the width of the data. 42 * 43 * To obtain the width of the Trie2, check the actual class type of the returned Trie2. 44 * Or use the createFromSerialized() function of Trie2_16 or Trie2_32, which will 45 * return only Tries of their specific type/size. 46 * 47 * The serialized Trie2 on the stream may be in either little or big endian byte order. 48 * This allows using serialized Tries from ICU4C without needing to consider the 49 * byte order of the system that created them. 50 * 51 * @param bytes a byte buffer to the serialized form of a UTrie2. 52 * @return An unserialized Trie2, ready for use. 53 * @throws IllegalArgumentException if the stream does not contain a serialized Trie2. 54 * @throws IOException if a read error occurs in the buffer. 55 * 56 */ createFromSerialized(ByteBuffer bytes)57 public static Trie2 createFromSerialized(ByteBuffer bytes) throws IOException { 58 // From ICU4C utrie2_impl.h 59 // * Trie2 data structure in serialized form: 60 // * 61 // * UTrie2Header header; 62 // * uint16_t index[header.index2Length]; 63 // * uint16_t data[header.shiftedDataLength<<2]; -- or uint32_t data[...] 64 // * @internal 65 // */ 66 // typedef struct UTrie2Header { 67 // /** "Tri2" in big-endian US-ASCII (0x54726932) */ 68 // uint32_t signature; 69 70 // /** 71 // * options bit field: 72 // * 15.. 4 reserved (0) 73 // * 3.. 0 UTrie2ValueBits valueBits 74 // */ 75 // uint16_t options; 76 // 77 // /** UTRIE2_INDEX_1_OFFSET..UTRIE2_MAX_INDEX_LENGTH */ 78 // uint16_t indexLength; 79 // 80 // /** (UTRIE2_DATA_START_OFFSET..UTRIE2_MAX_DATA_LENGTH)>>UTRIE2_INDEX_SHIFT */ 81 // uint16_t shiftedDataLength; 82 // 83 // /** Null index and data blocks, not shifted. */ 84 // uint16_t index2NullOffset, dataNullOffset; 85 // 86 // /** 87 // * First code point of the single-value range ending with U+10ffff, 88 // * rounded up and then shifted right by UTRIE2_SHIFT_1. 89 // */ 90 // uint16_t shiftedHighStart; 91 // } UTrie2Header; 92 93 ByteOrder outerByteOrder = bytes.order(); 94 try { 95 UTrie2Header header = new UTrie2Header(); 96 97 /* check the signature */ 98 header.signature = bytes.getInt(); 99 switch (header.signature) { 100 case 0x54726932: 101 // The buffer is already set to the trie data byte order. 102 break; 103 case 0x32697254: 104 // Temporarily reverse the byte order. 105 boolean isBigEndian = outerByteOrder == ByteOrder.BIG_ENDIAN; 106 bytes.order(isBigEndian ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN); 107 header.signature = 0x54726932; 108 break; 109 default: 110 throw new IllegalArgumentException("Buffer does not contain a serialized UTrie2"); 111 } 112 113 header.options = bytes.getChar(); 114 header.indexLength = bytes.getChar(); 115 header.shiftedDataLength = bytes.getChar(); 116 header.index2NullOffset = bytes.getChar(); 117 header.dataNullOffset = bytes.getChar(); 118 header.shiftedHighStart = bytes.getChar(); 119 120 // Trie2 data width - 0: 16 bits 121 // 1: 32 bits 122 if ((header.options & UTRIE2_OPTIONS_VALUE_BITS_MASK) > 1) { 123 throw new IllegalArgumentException("UTrie2 serialized format error."); 124 } 125 ValueWidth width; 126 Trie2 This; 127 if ((header.options & UTRIE2_OPTIONS_VALUE_BITS_MASK) == 0) { 128 width = ValueWidth.BITS_16; 129 This = new Trie2_16(); 130 } else { 131 width = ValueWidth.BITS_32; 132 This = new Trie2_32(); 133 } 134 This.header = header; 135 136 /* get the length values and offsets */ 137 This.indexLength = header.indexLength; 138 This.dataLength = header.shiftedDataLength << UTRIE2_INDEX_SHIFT; 139 This.index2NullOffset = header.index2NullOffset; 140 This.dataNullOffset = header.dataNullOffset; 141 This.highStart = header.shiftedHighStart << UTRIE2_SHIFT_1; 142 This.highValueIndex = This.dataLength - UTRIE2_DATA_GRANULARITY; 143 if (width == ValueWidth.BITS_16) { 144 This.highValueIndex += This.indexLength; 145 } 146 147 // Allocate the Trie2 index array. If the data width is 16 bits, the array also 148 // includes the space for the data. 149 150 int indexArraySize = This.indexLength; 151 if (width == ValueWidth.BITS_16) { 152 indexArraySize += This.dataLength; 153 } 154 This.index = new char[indexArraySize]; 155 156 /* Read in the index */ 157 int i; 158 for (i=0; i<This.indexLength; i++) { 159 This.index[i] = bytes.getChar(); 160 } 161 162 /* Read in the data. 16 bit data goes in the same array as the index. 163 * 32 bit data goes in its own separate data array. 164 */ 165 if (width == ValueWidth.BITS_16) { 166 This.data16 = This.indexLength; 167 for (i=0; i<This.dataLength; i++) { 168 This.index[This.data16 + i] = bytes.getChar(); 169 } 170 } else { 171 This.data32 = new int[This.dataLength]; 172 for (i=0; i<This.dataLength; i++) { 173 This.data32[i] = bytes.getInt(); 174 } 175 } 176 177 switch(width) { 178 case BITS_16: 179 This.data32 = null; 180 This.initialValue = This.index[This.dataNullOffset]; 181 This.errorValue = This.index[This.data16+UTRIE2_BAD_UTF8_DATA_OFFSET]; 182 break; 183 case BITS_32: 184 This.data16=0; 185 This.initialValue = This.data32[This.dataNullOffset]; 186 This.errorValue = This.data32[UTRIE2_BAD_UTF8_DATA_OFFSET]; 187 break; 188 default: 189 throw new IllegalArgumentException("UTrie2 serialized format error."); 190 } 191 192 return This; 193 } finally { 194 bytes.order(outerByteOrder); 195 } 196 } 197 198 /** 199 * Get the UTrie version from an InputStream containing the serialized form 200 * of either a Trie (version 1) or a Trie2 (version 2). 201 * 202 * @param is an InputStream containing the serialized form 203 * of a UTrie, version 1 or 2. The stream must support mark() and reset(). 204 * The position of the input stream will be left unchanged. 205 * @param littleEndianOk If FALSE, only big-endian (Java native) serialized forms are recognized. 206 * If TRUE, little-endian serialized forms are recognized as well. 207 * @return the Trie version of the serialized form, or 0 if it is not 208 * recognized as a serialized UTrie 209 * @throws IOException on errors in reading from the input stream. 210 */ getVersion(InputStream is, boolean littleEndianOk)211 public static int getVersion(InputStream is, boolean littleEndianOk) throws IOException { 212 if (! is.markSupported()) { 213 throw new IllegalArgumentException("Input stream must support mark()."); 214 } 215 is.mark(4); 216 byte sig[] = new byte[4]; 217 int read = is.read(sig); 218 is.reset(); 219 220 if (read != sig.length) { 221 return 0; 222 } 223 224 if (sig[0]=='T' && sig[1]=='r' && sig[2]=='i' && sig[3]=='e') { 225 return 1; 226 } 227 if (sig[0]=='T' && sig[1]=='r' && sig[2]=='i' && sig[3]=='2') { 228 return 2; 229 } 230 if (littleEndianOk) { 231 if (sig[0]=='e' && sig[1]=='i' && sig[2]=='r' && sig[3]=='T') { 232 return 1; 233 } 234 if (sig[0]=='2' && sig[1]=='i' && sig[2]=='r' && sig[3]=='T') { 235 return 2; 236 } 237 } 238 return 0; 239 } 240 241 /** 242 * Get the value for a code point as stored in the Trie2. 243 * 244 * @param codePoint the code point 245 * @return the value 246 */ get(int codePoint)247 abstract public int get(int codePoint); 248 249 250 /** 251 * Get the trie value for a UTF-16 code unit. 252 * 253 * A Trie2 stores two distinct values for input in the lead surrogate 254 * range, one for lead surrogates, which is the value that will be 255 * returned by this function, and a second value that is returned 256 * by Trie2.get(). 257 * 258 * For code units outside of the lead surrogate range, this function 259 * returns the same result as Trie2.get(). 260 * 261 * This function, together with the alternate value for lead surrogates, 262 * makes possible very efficient processing of UTF-16 strings without 263 * first converting surrogate pairs to their corresponding 32 bit code point 264 * values. 265 * 266 * At build-time, enumerate the contents of the Trie2 to see if there 267 * is non-trivial (non-initialValue) data for any of the supplementary 268 * code points associated with a lead surrogate. 269 * If so, then set a special (application-specific) value for the 270 * lead surrogate code _unit_, with Trie2Writable.setForLeadSurrogateCodeUnit(). 271 * 272 * At runtime, use Trie2.getFromU16SingleLead(). If there is non-trivial 273 * data and the code unit is a lead surrogate, then check if a trail surrogate 274 * follows. If so, assemble the supplementary code point and look up its value 275 * with Trie2.get(); otherwise reset the lead 276 * surrogate's value or do a code point lookup for it. 277 * 278 * If there is only trivial data for lead and trail surrogates, then processing 279 * can often skip them. For example, in normalization or case mapping 280 * all characters that do not have any mappings are simply copied as is. 281 * 282 * @param c the code point or lead surrogate value. 283 * @return the value 284 */ getFromU16SingleLead(char c)285 abstract public int getFromU16SingleLead(char c); 286 287 288 /** 289 * Equals function. Two Tries are equal if their contents are equal. 290 * The type need not be the same, so a Trie2Writable will be equal to 291 * (read-only) Trie2_16 or Trie2_32 so long as they are storing the same values. 292 * 293 */ equals(Object other)294 public final boolean equals(Object other) { 295 if(!(other instanceof Trie2)) { 296 return false; 297 } 298 Trie2 OtherTrie = (Trie2)other; 299 Range rangeFromOther; 300 301 Iterator<Trie2.Range> otherIter = OtherTrie.iterator(); 302 for (Trie2.Range rangeFromThis: this) { 303 if (otherIter.hasNext() == false) { 304 return false; 305 } 306 rangeFromOther = otherIter.next(); 307 if (!rangeFromThis.equals(rangeFromOther)) { 308 return false; 309 } 310 } 311 if (otherIter.hasNext()) { 312 return false; 313 } 314 315 if (errorValue != OtherTrie.errorValue || 316 initialValue != OtherTrie.initialValue) { 317 return false; 318 } 319 320 return true; 321 } 322 323 hashCode()324 public int hashCode() { 325 if (fHash == 0) { 326 int hash = initHash(); 327 for (Range r: this) { 328 hash = hashInt(hash, r.hashCode()); 329 } 330 if (hash == 0) { 331 hash = 1; 332 } 333 fHash = hash; 334 } 335 return fHash; 336 } 337 338 /** 339 * When iterating over the contents of a Trie2, Elements of this type are produced. 340 * The iterator will return one item for each contiguous range of codepoints having the same value. 341 * 342 * When iterating, the same Trie2EnumRange object will be reused and returned for each range. 343 * If you need to retain complete iteration results, clone each returned Trie2EnumRange, 344 * or save the range in some other way, before advancing to the next iteration step. 345 */ 346 public static class Range { 347 public int startCodePoint; 348 public int endCodePoint; // Inclusive. 349 public int value; 350 public boolean leadSurrogate; 351 equals(Object other)352 public boolean equals(Object other) { 353 if (other == null || !(other.getClass().equals(getClass()))) { 354 return false; 355 } 356 Range tother = (Range)other; 357 return this.startCodePoint == tother.startCodePoint && 358 this.endCodePoint == tother.endCodePoint && 359 this.value == tother.value && 360 this.leadSurrogate == tother.leadSurrogate; 361 } 362 363 hashCode()364 public int hashCode() { 365 int h = initHash(); 366 h = hashUChar32(h, startCodePoint); 367 h = hashUChar32(h, endCodePoint); 368 h = hashInt(h, value); 369 h = hashByte(h, leadSurrogate? 1: 0); 370 return h; 371 } 372 } 373 374 375 /** 376 * Create an iterator over the value ranges in this Trie2. 377 * Values from the Trie2 are not remapped or filtered, but are returned as they 378 * are stored in the Trie2. 379 * 380 * @return an Iterator 381 */ iterator()382 public Iterator<Range> iterator() { 383 return iterator(defaultValueMapper); 384 } 385 386 private static ValueMapper defaultValueMapper = new ValueMapper() { 387 public int map(int in) { 388 return in; 389 } 390 }; 391 392 /** 393 * Create an iterator over the value ranges from this Trie2. 394 * Values from the Trie2 are passed through a caller-supplied remapping function, 395 * and it is the remapped values that determine the ranges that 396 * will be produced by the iterator. 397 * 398 * 399 * @param mapper provides a function to remap values obtained from the Trie2. 400 * @return an Iterator 401 */ iterator(ValueMapper mapper)402 public Iterator<Range> iterator(ValueMapper mapper) { 403 return new Trie2Iterator(mapper); 404 } 405 406 407 /** 408 * Create an iterator over the Trie2 values for the 1024=0x400 code points 409 * corresponding to a given lead surrogate. 410 * For example, for the lead surrogate U+D87E it will enumerate the values 411 * for [U+2F800..U+2FC00[. 412 * Used by data builder code that sets special lead surrogate code unit values 413 * for optimized UTF-16 string processing. 414 * 415 * Do not modify the Trie2 during the iteration. 416 * 417 * Except for the limited code point range, this functions just like Trie2.iterator(). 418 * 419 */ iteratorForLeadSurrogate(char lead, ValueMapper mapper)420 public Iterator<Range> iteratorForLeadSurrogate(char lead, ValueMapper mapper) { 421 return new Trie2Iterator(lead, mapper); 422 } 423 424 /** 425 * Create an iterator over the Trie2 values for the 1024=0x400 code points 426 * corresponding to a given lead surrogate. 427 * For example, for the lead surrogate U+D87E it will enumerate the values 428 * for [U+2F800..U+2FC00[. 429 * Used by data builder code that sets special lead surrogate code unit values 430 * for optimized UTF-16 string processing. 431 * 432 * Do not modify the Trie2 during the iteration. 433 * 434 * Except for the limited code point range, this functions just like Trie2.iterator(). 435 * 436 */ iteratorForLeadSurrogate(char lead)437 public Iterator<Range> iteratorForLeadSurrogate(char lead) { 438 return new Trie2Iterator(lead, defaultValueMapper); 439 } 440 441 /** 442 * When iterating over the contents of a Trie2, an instance of TrieValueMapper may 443 * be used to remap the values from the Trie2. The remapped values will be used 444 * both in determining the ranges of codepoints and as the value to be returned 445 * for each range. 446 * 447 * Example of use, with an anonymous subclass of TrieValueMapper: 448 * 449 * 450 * ValueMapper m = new ValueMapper() { 451 * int map(int in) {return in & 0x1f;}; 452 * } 453 * for (Iterator<Trie2EnumRange> iter = trie.iterator(m); i.hasNext(); ) { 454 * Trie2EnumRange r = i.next(); 455 * ... // Do something with the range r. 456 * } 457 * 458 */ 459 public interface ValueMapper { map(int originalVal)460 public int map(int originalVal); 461 } 462 463 464 /** 465 * Serialize a trie2 Header and Index onto an OutputStream. This is 466 * common code used for both the Trie2_16 and Trie2_32 serialize functions. 467 * @param dos the stream to which the serialized Trie2 data will be written. 468 * @return the number of bytes written. 469 */ serializeHeader(DataOutputStream dos)470 protected int serializeHeader(DataOutputStream dos) throws IOException { 471 // Write the header. It is already set and ready to use, having been 472 // created when the Trie2 was unserialized or when it was frozen. 473 int bytesWritten = 0; 474 475 dos.writeInt(header.signature); 476 dos.writeShort(header.options); 477 dos.writeShort(header.indexLength); 478 dos.writeShort(header.shiftedDataLength); 479 dos.writeShort(header.index2NullOffset); 480 dos.writeShort(header.dataNullOffset); 481 dos.writeShort(header.shiftedHighStart); 482 bytesWritten += 16; 483 484 // Write the index 485 int i; 486 for (i=0; i< header.indexLength; i++) { 487 dos.writeChar(index[i]); 488 } 489 bytesWritten += header.indexLength; 490 return bytesWritten; 491 } 492 493 494 /** 495 * Struct-like class for holding the results returned by a UTrie2 CharSequence iterator. 496 * The iteration walks over a CharSequence, and for each Unicode code point therein 497 * returns the character and its associated Trie2 value. 498 */ 499 public static class CharSequenceValues { 500 /** string index of the current code point. */ 501 public int index; 502 /** The code point at index. */ 503 public int codePoint; 504 /** The Trie2 value for the current code point */ 505 public int value; 506 } 507 508 509 /** 510 * Create an iterator that will produce the values from the Trie2 for 511 * the sequence of code points in an input text. 512 * 513 * @param text A text string to be iterated over. 514 * @param index The starting iteration position within the input text. 515 * @return the CharSequenceIterator 516 */ charSequenceIterator(CharSequence text, int index)517 public CharSequenceIterator charSequenceIterator(CharSequence text, int index) { 518 return new CharSequenceIterator(text, index); 519 } 520 521 // TODO: Survey usage of the equivalent of CharSequenceIterator in ICU4C 522 // and if there is none, remove it from here. 523 // Don't waste time testing and maintaining unused code. 524 525 /** 526 * An iterator that operates over an input CharSequence, and for each Unicode code point 527 * in the input returns the associated value from the Trie2. 528 * 529 * The iterator can move forwards or backwards, and can be reset to an arbitrary index. 530 * 531 * Note that Trie2_16 and Trie2_32 subclass Trie2.CharSequenceIterator. This is done 532 * only for performance reasons. It does require that any changes made here be propagated 533 * into the corresponding code in the subclasses. 534 */ 535 public class CharSequenceIterator implements Iterator<CharSequenceValues> { 536 /** 537 * Internal constructor. 538 */ CharSequenceIterator(CharSequence t, int index)539 CharSequenceIterator(CharSequence t, int index) { 540 text = t; 541 textLength = text.length(); 542 set(index); 543 } 544 545 private CharSequence text; 546 private int textLength; 547 private int index; 548 private Trie2.CharSequenceValues fResults = new Trie2.CharSequenceValues(); 549 550 set(int i)551 public void set(int i) { 552 if (i < 0 || i > textLength) { 553 throw new IndexOutOfBoundsException(); 554 } 555 index = i; 556 } 557 558 hasNext()559 public final boolean hasNext() { 560 return index<textLength; 561 } 562 563 hasPrevious()564 public final boolean hasPrevious() { 565 return index>0; 566 } 567 568 next()569 public Trie2.CharSequenceValues next() { 570 int c = Character.codePointAt(text, index); 571 int val = get(c); 572 573 fResults.index = index; 574 fResults.codePoint = c; 575 fResults.value = val; 576 index++; 577 if (c >= 0x10000) { 578 index++; 579 } 580 return fResults; 581 } 582 583 previous()584 public Trie2.CharSequenceValues previous() { 585 int c = Character.codePointBefore(text, index); 586 int val = get(c); 587 index--; 588 if (c >= 0x10000) { 589 index--; 590 } 591 fResults.index = index; 592 fResults.codePoint = c; 593 fResults.value = val; 594 return fResults; 595 } 596 597 /** 598 * Iterator.remove() is not supported by Trie2.CharSequenceIterator. 599 * @throws UnsupportedOperationException Always thrown because this operation is not supported 600 * @see java.util.Iterator#remove() 601 */ remove()602 public void remove() { 603 throw new UnsupportedOperationException("Trie2.CharSequenceIterator does not support remove()."); 604 } 605 } 606 607 608 //-------------------------------------------------------------------------------- 609 // 610 // Below this point are internal implementation items. No further public API. 611 // 612 //-------------------------------------------------------------------------------- 613 614 615 /** 616 * Selectors for the width of a UTrie2 data value. 617 */ 618 enum ValueWidth { 619 BITS_16, 620 BITS_32 621 } 622 623 /** 624 * Trie2 data structure in serialized form: 625 * 626 * UTrie2Header header; 627 * uint16_t index[header.index2Length]; 628 * uint16_t data[header.shiftedDataLength<<2]; -- or uint32_t data[...] 629 * 630 * For Java, this is read from the stream into an instance of UTrie2Header. 631 * (The C version just places a struct over the raw serialized data.) 632 * 633 * @internal 634 */ 635 static class UTrie2Header { 636 /** "Tri2" in big-endian US-ASCII (0x54726932) */ 637 int signature; 638 639 /** 640 * options bit field (uint16_t): 641 * 15.. 4 reserved (0) 642 * 3.. 0 UTrie2ValueBits valueBits 643 */ 644 int options; 645 646 /** UTRIE2_INDEX_1_OFFSET..UTRIE2_MAX_INDEX_LENGTH (uint16_t) */ 647 int indexLength; 648 649 /** (UTRIE2_DATA_START_OFFSET..UTRIE2_MAX_DATA_LENGTH)>>UTRIE2_INDEX_SHIFT (uint16_t) */ 650 int shiftedDataLength; 651 652 /** Null index and data blocks, not shifted. (uint16_t) */ 653 int index2NullOffset, dataNullOffset; 654 655 /** 656 * First code point of the single-value range ending with U+10ffff, 657 * rounded up and then shifted right by UTRIE2_SHIFT_1. (uint16_t) 658 */ 659 int shiftedHighStart; 660 } 661 662 // 663 // Data members of UTrie2. 664 // 665 UTrie2Header header; 666 char index[]; // Index array. Includes data for 16 bit Tries. 667 int data16; // Offset to data portion of the index array, if 16 bit data. 668 // zero if 32 bit data. 669 int data32[]; // NULL if 16b data is used via index 670 671 int indexLength; 672 int dataLength; 673 int index2NullOffset; // 0xffff if there is no dedicated index-2 null block 674 int initialValue; 675 676 /** Value returned for out-of-range code points and illegal UTF-8. */ 677 int errorValue; 678 679 /* Start of the last range which ends at U+10ffff, and its value. */ 680 int highStart; 681 int highValueIndex; 682 683 int dataNullOffset; 684 685 int fHash; // Zero if not yet computed. 686 // Shared by Trie2Writable, Trie2_16, Trie2_32. 687 // Thread safety: if two racing threads compute 688 // the same hash on a frozen Trie2, no damage is done. 689 690 691 /** 692 * Trie2 constants, defining shift widths, index array lengths, etc. 693 * 694 * These are needed for the runtime macros but users can treat these as 695 * implementation details and skip to the actual public API further below. 696 */ 697 698 static final int UTRIE2_OPTIONS_VALUE_BITS_MASK=0x000f; 699 700 701 /** Shift size for getting the index-1 table offset. */ 702 static final int UTRIE2_SHIFT_1=6+5; 703 704 /** Shift size for getting the index-2 table offset. */ 705 static final int UTRIE2_SHIFT_2=5; 706 707 /** 708 * Difference between the two shift sizes, 709 * for getting an index-1 offset from an index-2 offset. 6=11-5 710 */ 711 static final int UTRIE2_SHIFT_1_2=UTRIE2_SHIFT_1-UTRIE2_SHIFT_2; 712 713 /** 714 * Number of index-1 entries for the BMP. 32=0x20 715 * This part of the index-1 table is omitted from the serialized form. 716 */ 717 static final int UTRIE2_OMITTED_BMP_INDEX_1_LENGTH=0x10000>>UTRIE2_SHIFT_1; 718 719 /** Number of code points per index-1 table entry. 2048=0x800 */ 720 static final int UTRIE2_CP_PER_INDEX_1_ENTRY=1<<UTRIE2_SHIFT_1; 721 722 /** Number of entries in an index-2 block. 64=0x40 */ 723 static final int UTRIE2_INDEX_2_BLOCK_LENGTH=1<<UTRIE2_SHIFT_1_2; 724 725 /** Mask for getting the lower bits for the in-index-2-block offset. */ 726 static final int UTRIE2_INDEX_2_MASK=UTRIE2_INDEX_2_BLOCK_LENGTH-1; 727 728 /** Number of entries in a data block. 32=0x20 */ 729 static final int UTRIE2_DATA_BLOCK_LENGTH=1<<UTRIE2_SHIFT_2; 730 731 /** Mask for getting the lower bits for the in-data-block offset. */ 732 static final int UTRIE2_DATA_MASK=UTRIE2_DATA_BLOCK_LENGTH-1; 733 734 /** 735 * Shift size for shifting left the index array values. 736 * Increases possible data size with 16-bit index values at the cost 737 * of compactability. 738 * This requires data blocks to be aligned by UTRIE2_DATA_GRANULARITY. 739 */ 740 static final int UTRIE2_INDEX_SHIFT=2; 741 742 /** The alignment size of a data block. Also the granularity for compaction. */ 743 static final int UTRIE2_DATA_GRANULARITY=1<<UTRIE2_INDEX_SHIFT; 744 745 /* Fixed layout of the first part of the index array. ------------------- */ 746 747 /** 748 * The BMP part of the index-2 table is fixed and linear and starts at offset 0. 749 * Length=2048=0x800=0x10000>>UTRIE2_SHIFT_2. 750 */ 751 static final int UTRIE2_INDEX_2_OFFSET=0; 752 753 /** 754 * The part of the index-2 table for U+D800..U+DBFF stores values for 755 * lead surrogate code _units_ not code _points_. 756 * Values for lead surrogate code _points_ are indexed with this portion of the table. 757 * Length=32=0x20=0x400>>UTRIE2_SHIFT_2. (There are 1024=0x400 lead surrogates.) 758 */ 759 static final int UTRIE2_LSCP_INDEX_2_OFFSET=0x10000>>UTRIE2_SHIFT_2; 760 static final int UTRIE2_LSCP_INDEX_2_LENGTH=0x400>>UTRIE2_SHIFT_2; 761 762 /** Count the lengths of both BMP pieces. 2080=0x820 */ 763 static final int UTRIE2_INDEX_2_BMP_LENGTH=UTRIE2_LSCP_INDEX_2_OFFSET+UTRIE2_LSCP_INDEX_2_LENGTH; 764 765 /** 766 * The 2-byte UTF-8 version of the index-2 table follows at offset 2080=0x820. 767 * Length 32=0x20 for lead bytes C0..DF, regardless of UTRIE2_SHIFT_2. 768 */ 769 static final int UTRIE2_UTF8_2B_INDEX_2_OFFSET=UTRIE2_INDEX_2_BMP_LENGTH; 770 static final int UTRIE2_UTF8_2B_INDEX_2_LENGTH=0x800>>6; /* U+0800 is the first code point after 2-byte UTF-8 */ 771 772 /** 773 * The index-1 table, only used for supplementary code points, at offset 2112=0x840. 774 * Variable length, for code points up to highStart, where the last single-value range starts. 775 * Maximum length 512=0x200=0x100000>>UTRIE2_SHIFT_1. 776 * (For 0x100000 supplementary code points U+10000..U+10ffff.) 777 * 778 * The part of the index-2 table for supplementary code points starts 779 * after this index-1 table. 780 * 781 * Both the index-1 table and the following part of the index-2 table 782 * are omitted completely if there is only BMP data. 783 */ 784 static final int UTRIE2_INDEX_1_OFFSET=UTRIE2_UTF8_2B_INDEX_2_OFFSET+UTRIE2_UTF8_2B_INDEX_2_LENGTH; 785 static final int UTRIE2_MAX_INDEX_1_LENGTH=0x100000>>UTRIE2_SHIFT_1; 786 787 /* 788 * Fixed layout of the first part of the data array. ----------------------- 789 * Starts with 4 blocks (128=0x80 entries) for ASCII. 790 */ 791 792 /** 793 * The illegal-UTF-8 data block follows the ASCII block, at offset 128=0x80. 794 * Used with linear access for single bytes 0..0xbf for simple error handling. 795 * Length 64=0x40, not UTRIE2_DATA_BLOCK_LENGTH. 796 */ 797 static final int UTRIE2_BAD_UTF8_DATA_OFFSET=0x80; 798 799 /** The start of non-linear-ASCII data blocks, at offset 192=0xc0. */ 800 static final int UTRIE2_DATA_START_OFFSET=0xc0; 801 802 /* Building a Trie2 ---------------------------------------------------------- */ 803 804 /* 805 * These definitions are mostly needed by utrie2_builder.c, but also by 806 * utrie2_get32() and utrie2_enum(). 807 */ 808 809 /* 810 * At build time, leave a gap in the index-2 table, 811 * at least as long as the maximum lengths of the 2-byte UTF-8 index-2 table 812 * and the supplementary index-1 table. 813 * Round up to UTRIE2_INDEX_2_BLOCK_LENGTH for proper compacting. 814 */ 815 static final int UNEWTRIE2_INDEX_GAP_OFFSET = UTRIE2_INDEX_2_BMP_LENGTH; 816 static final int UNEWTRIE2_INDEX_GAP_LENGTH = 817 ((UTRIE2_UTF8_2B_INDEX_2_LENGTH + UTRIE2_MAX_INDEX_1_LENGTH) + UTRIE2_INDEX_2_MASK) & 818 ~UTRIE2_INDEX_2_MASK; 819 820 /** 821 * Maximum length of the build-time index-2 array. 822 * Maximum number of Unicode code points (0x110000) shifted right by UTRIE2_SHIFT_2, 823 * plus the part of the index-2 table for lead surrogate code points, 824 * plus the build-time index gap, 825 * plus the null index-2 block. 826 */ 827 static final int UNEWTRIE2_MAX_INDEX_2_LENGTH= 828 (0x110000>>UTRIE2_SHIFT_2)+ 829 UTRIE2_LSCP_INDEX_2_LENGTH+ 830 UNEWTRIE2_INDEX_GAP_LENGTH+ 831 UTRIE2_INDEX_2_BLOCK_LENGTH; 832 833 static final int UNEWTRIE2_INDEX_1_LENGTH = 0x110000>>UTRIE2_SHIFT_1; 834 835 /** 836 * Maximum length of the build-time data array. 837 * One entry per 0x110000 code points, plus the illegal-UTF-8 block and the null block, 838 * plus values for the 0x400 surrogate code units. 839 */ 840 static final int UNEWTRIE2_MAX_DATA_LENGTH = (0x110000+0x40+0x40+0x400); 841 842 843 844 /** 845 * Implementation class for an iterator over a Trie2. 846 * 847 * Iteration over a Trie2 first returns all of the ranges that are indexed by code points, 848 * then returns the special alternate values for the lead surrogates 849 * 850 * @internal 851 */ 852 class Trie2Iterator implements Iterator<Range> { 853 // The normal constructor that configures the iterator to cover the complete 854 // contents of the Trie2 Trie2Iterator(ValueMapper vm)855 Trie2Iterator(ValueMapper vm) { 856 mapper = vm; 857 nextStart = 0; 858 limitCP = 0x110000; 859 doLeadSurrogates = true; 860 } 861 862 // An alternate constructor that configures the iterator to cover only the 863 // code points corresponding to a particular Lead Surrogate value. Trie2Iterator(char leadSurrogate, ValueMapper vm)864 Trie2Iterator(char leadSurrogate, ValueMapper vm) { 865 if (leadSurrogate < 0xd800 || leadSurrogate > 0xdbff) { 866 throw new IllegalArgumentException("Bad lead surrogate value."); 867 } 868 mapper = vm; 869 nextStart = (leadSurrogate - 0xd7c0) << 10; 870 limitCP = nextStart + 0x400; 871 doLeadSurrogates = false; // Do not iterate over lead the special lead surrogate 872 // values after completing iteration over code points. 873 } 874 875 /** 876 * The main next() function for Trie2 iterators 877 * 878 */ next()879 public Range next() { 880 if (!hasNext()) { 881 throw new NoSuchElementException(); 882 } 883 if (nextStart >= limitCP) { 884 // Switch over from iterating normal code point values to 885 // doing the alternate lead-surrogate values. 886 doingCodePoints = false; 887 nextStart = 0xd800; 888 } 889 int endOfRange = 0; 890 int val = 0; 891 int mappedVal = 0; 892 893 if (doingCodePoints) { 894 // Iteration over code point values. 895 val = get(nextStart); 896 mappedVal = mapper.map(val); 897 endOfRange = rangeEnd(nextStart, limitCP, val); 898 // Loop once for each range in the Trie2 with the same raw (unmapped) value. 899 // Loop continues so long as the mapped values are the same. 900 for (;;) { 901 if (endOfRange >= limitCP-1) { 902 break; 903 } 904 val = get(endOfRange+1); 905 if (mapper.map(val) != mappedVal) { 906 break; 907 } 908 endOfRange = rangeEnd(endOfRange+1, limitCP, val); 909 } 910 } else { 911 // Iteration over the alternate lead surrogate values. 912 val = getFromU16SingleLead((char)nextStart); 913 mappedVal = mapper.map(val); 914 endOfRange = rangeEndLS((char)nextStart); 915 // Loop once for each range in the Trie2 with the same raw (unmapped) value. 916 // Loop continues so long as the mapped values are the same. 917 for (;;) { 918 if (endOfRange >= 0xdbff) { 919 break; 920 } 921 val = getFromU16SingleLead((char)(endOfRange+1)); 922 if (mapper.map(val) != mappedVal) { 923 break; 924 } 925 endOfRange = rangeEndLS((char)(endOfRange+1)); 926 } 927 } 928 returnValue.startCodePoint = nextStart; 929 returnValue.endCodePoint = endOfRange; 930 returnValue.value = mappedVal; 931 returnValue.leadSurrogate = !doingCodePoints; 932 nextStart = endOfRange+1; 933 return returnValue; 934 } 935 936 /** 937 * 938 */ hasNext()939 public boolean hasNext() { 940 return doingCodePoints && (doLeadSurrogates || nextStart < limitCP) || nextStart < 0xdc00; 941 } 942 remove()943 public void remove() { 944 throw new UnsupportedOperationException(); 945 } 946 947 948 /** 949 * Find the last lead surrogate in a contiguous range with the 950 * same Trie2 value as the input character. 951 * 952 * Use the alternate Lead Surrogate values from the Trie2, 953 * not the code-point values. 954 * 955 * Note: Trie2_16 and Trie2_32 override this implementation with optimized versions, 956 * meaning that the implementation here is only being used with 957 * Trie2Writable. The code here is logically correct with any type 958 * of Trie2, however. 959 * 960 * @param c The character to begin with. 961 * @return The last contiguous character with the same value. 962 */ rangeEndLS(char startingLS)963 private int rangeEndLS(char startingLS) { 964 if (startingLS >= 0xdbff) { 965 return 0xdbff; 966 } 967 968 int c; 969 int val = getFromU16SingleLead(startingLS); 970 for (c = startingLS+1; c <= 0x0dbff; c++) { 971 if (getFromU16SingleLead((char)c) != val) { 972 break; 973 } 974 } 975 return c-1; 976 } 977 978 // 979 // Iteration State Variables 980 // 981 private ValueMapper mapper; 982 private Range returnValue = new Range(); 983 // The starting code point for the next range to be returned. 984 private int nextStart; 985 // The upper limit for the last normal range to be returned. Normally 0x110000, but 986 // may be lower when iterating over the code points for a single lead surrogate. 987 private int limitCP; 988 989 // True while iterating over the the Trie2 values for code points. 990 // False while iterating over the alternate values for lead surrogates. 991 private boolean doingCodePoints = true; 992 993 // True if the iterator should iterate the special values for lead surrogates in 994 // addition to the normal values for code points. 995 private boolean doLeadSurrogates = true; 996 } 997 998 /** 999 * Find the last character in a contiguous range of characters with the 1000 * same Trie2 value as the input character. 1001 * 1002 * @param c The character to begin with. 1003 * @return The last contiguous character with the same value. 1004 */ rangeEnd(int start, int limitp, int val)1005 int rangeEnd(int start, int limitp, int val) { 1006 int c; 1007 int limit = Math.min(highStart, limitp); 1008 1009 for (c = start+1; c < limit; c++) { 1010 if (get(c) != val) { 1011 break; 1012 } 1013 } 1014 if (c >= highStart) { 1015 c = limitp; 1016 } 1017 return c - 1; 1018 } 1019 1020 1021 // 1022 // Hashing implementation functions. FNV hash. Respected public domain algorithm. 1023 // initHash()1024 private static int initHash() { 1025 return 0x811c9DC5; // unsigned 2166136261 1026 } 1027 hashByte(int h, int b)1028 private static int hashByte(int h, int b) { 1029 h = h * 16777619; 1030 h = h ^ b; 1031 return h; 1032 } 1033 hashUChar32(int h, int c)1034 private static int hashUChar32(int h, int c) { 1035 h = Trie2.hashByte(h, c & 255); 1036 h = Trie2.hashByte(h, (c>>8) & 255); 1037 h = Trie2.hashByte(h, c>>16); 1038 return h; 1039 } 1040 hashInt(int h, int i)1041 private static int hashInt(int h, int i) { 1042 h = Trie2.hashByte(h, i & 255); 1043 h = Trie2.hashByte(h, (i>>8) & 255); 1044 h = Trie2.hashByte(h, (i>>16) & 255); 1045 h = Trie2.hashByte(h, (i>>24) & 255); 1046 return h; 1047 } 1048 1049 } 1050