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