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