17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*******************************************************************************
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* Copyright (C) 1996-2010, International Business Machines Corporation and    *
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* others. All Rights Reserved.                                                *
57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*******************************************************************************
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*/
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.test.util;
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.dev.test.TestFmwk;
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.CharTrie;
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.IntTrie;
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.IntTrieBuilder;
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.Trie;
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.TrieBuilder;
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.TrieIterator;
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.UTF16;
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.RangeValueIterator;
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* Testing class for Trie. Tests here will be simple, since both CharTrie and
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* IntTrie are very similar and are heavily used in other parts of ICU4J.
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* Codes using Tries are expected to have detailed tests.
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* @author Syn Wee Quek
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert* @since release 2.1 Jan 01 2002
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*/
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic final class TrieTest extends TestFmwk
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert{
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // constructor ---------------------------------------------------
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    * Constructor
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    */
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public TrieTest()
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // public methods -----------------------------------------------
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public static void main(String arg[])
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TrieTest test = new TrieTest();
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        try {
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            test.run(arg);
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } catch (Exception e) {
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            test.errln("Error testing trietest");
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Values for setting possibly overlapping, out-of-order ranges of values
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final class SetRange
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SetRange(int start, int limit, int value, boolean overwrite)
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.start = start;
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.limit = limit;
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.value = value;
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.overwrite = overwrite;
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int start, limit;
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int value;
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean overwrite;
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Values for testing:
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * value is set from the previous boundary's limit to before
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * this boundary's limit
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final class CheckRange
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CheckRange(int limit, int value)
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.limit = limit;
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.value = value;
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int limit;
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int value;
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final class _testFoldedValue
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        implements TrieBuilder.DataManipulate
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public _testFoldedValue(IntTrieBuilder builder)
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            m_builder_ = builder;
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public int getFoldedValue(int start, int offset)
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int foldedValue = 0;
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int limit = start + 0x400;
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            while (start < limit) {
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int value = m_builder_.getValue(start);
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (m_builder_.isInZeroBlock(start)) {
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    start += TrieBuilder.DATA_BLOCK_LENGTH;
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                else {
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    foldedValue |= value;
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    ++ start;
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (foldedValue != 0) {
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                return (offset << 16) | foldedValue;
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return 0;
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        private IntTrieBuilder m_builder_;
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final class _testFoldingOffset
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                implements Trie.DataManipulate
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public int getFoldingOffset(int value)
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return value >>> 16;
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final class _testEnumValue extends TrieIterator
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public _testEnumValue(Trie data)
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            super(data);
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        protected int extract(int value)
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return value ^ 0x5555;
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void _testTrieIteration(IntTrie trie, CheckRange checkRanges[],
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    int countCheckRanges)
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // write a string
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int countValues = 0;
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuffer s = new StringBuffer();
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int values[] = new int[30];
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < countCheckRanges; ++ i) {
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int c = checkRanges[i].limit;
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (c != 0) {
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                -- c;
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                UTF16.append(s, c);
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                values[countValues ++] = checkRanges[i].value;
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int limit = s.length();
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // try forward
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int p = 0;
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int i = 0;
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while(p < limit) {
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int c = UTF16.charAt(s, p);
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            p += UTF16.getCharCount(c);
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int value = trie.getCodePointValue(c);
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (value != values[i]) {
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("wrong value from UTRIE_NEXT(U+"
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + Integer.toHexString(c) + "): 0x"
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + Integer.toHexString(value) + " instead of 0x"
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + Integer.toHexString(values[i]));
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // unlike the c version lead is 0 if c is non-supplementary
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            char lead = UTF16.getLeadSurrogate(c);
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            char trail = UTF16.getTrailSurrogate(c);
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lead == 0
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ? trail != s.charAt(p - 1)
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                : !UTF16.isLeadSurrogate(lead)
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  || !UTF16.isTrailSurrogate(trail) || lead != s.charAt(p - 2)
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  || trail != s.charAt(p - 1)) {
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("wrong (lead, trail) from UTRIE_NEXT(U+"
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + Integer.toHexString(c));
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (lead != 0) {
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                value = trie.getLeadValue(lead);
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                value = trie.getTrailValue(value, trail);
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (value != trie.getSurrogateValue(lead, trail)
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    && value != values[i]) {
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("wrong value from getting supplementary "
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + "values (U+"
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(c) + "): 0x"
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(value) + " instead of 0x"
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(values[i]));
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ++ i;
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void _testTrieRanges(SetRange setRanges[], int countSetRanges,
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                 CheckRange checkRanges[], int countCheckRanges,
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                 boolean latin1Linear)
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IntTrieBuilder newTrie = new IntTrieBuilder(null, 2000,
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                    checkRanges[0].value,
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                    checkRanges[0].value,
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                    latin1Linear);
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // set values from setRanges[]
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean ok = true;
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < countSetRanges; ++ i) {
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int start = setRanges[i].start;
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int limit = setRanges[i].limit;
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int value = setRanges[i].value;
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            boolean overwrite = setRanges[i].overwrite;
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ((limit - start) == 1 && overwrite) {
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ok &= newTrie.setValue(start, value);
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else {
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ok &= newTrie.setRange(start, limit, value, overwrite);
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!ok) {
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("setting values into a trie failed");
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return;
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // verify that all these values are in the new Trie
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int start = 0;
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < countCheckRanges; ++ i) {
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int limit = checkRanges[i].limit;
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int value = checkRanges[i].value;
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            while (start < limit) {
2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (value != newTrie.getValue(start)) {
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("newTrie [U+"
2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(start) + "]==0x"
2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(newTrie.getValue(start))
2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + " instead of 0x" + Integer.toHexString(value));
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ++ start;
2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IntTrie trie = newTrie.serialize(new _testFoldedValue(newTrie),
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                         new _testFoldingOffset());
2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // test linear Latin-1 range from utrie_getData()
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (latin1Linear) {
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            start = 0;
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (int i = 0; i < countCheckRanges && start <= 0xff; ++ i) {
2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int limit = checkRanges[i].limit;
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int value = checkRanges[i].value;
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                while (start < limit && start <= 0xff) {
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (value != trie.getLatin1LinearValue((char)start)) {
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        errln("IntTrie.getLatin1LinearValue[U+"
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              + Integer.toHexString(start) + "]==0x"
2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              + Integer.toHexString(
2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        trie.getLatin1LinearValue((char) start))
2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              + " instead of 0x" + Integer.toHexString(value));
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    ++ start;
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (latin1Linear != trie.isLatin1Linear()) {
2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("trie serialization did not preserve "
2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + "Latin-1-linearity");
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // verify that all these values are in the serialized Trie
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        start = 0;
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < countCheckRanges; ++ i) {
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int limit = checkRanges[i].limit;
2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int value = checkRanges[i].value;
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (start == 0xd800) {
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // skip surrogates
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                start = limit;
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            while (start < limit) {
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (start <= 0xffff) {
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int value2 = trie.getBMPValue((char)start);
2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (value != value2) {
2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        errln("serialized trie.getBMPValue(U+"
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              + Integer.toHexString(start) + " == 0x"
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              + Integer.toHexString(value2) + " instead of 0x"
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              + Integer.toHexString(value));
2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (!UTF16.isLeadSurrogate((char)start)) {
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        value2 = trie.getLeadValue((char)start);
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        if (value != value2) {
2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            errln("serialized trie.getLeadValue(U+"
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              + Integer.toHexString(start) + " == 0x"
2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              + Integer.toHexString(value2) + " instead of 0x"
2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              + Integer.toHexString(value));
2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        }
2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                int value2 = trie.getCodePointValue(start);
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (value != value2) {
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("serialized trie.getCodePointValue(U+"
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(start) + ")==0x"
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(value2) + " instead of 0x"
3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(value));
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ++ start;
3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // enumerate and verify all ranges
3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int enumRanges = 1;
3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TrieIterator iter  = new _testEnumValue(trie);
3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        RangeValueIterator.Element result = new RangeValueIterator.Element();
3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while (iter.next(result)) {
3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (result.start != checkRanges[enumRanges -1].limit
3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                || result.limit != checkRanges[enumRanges].limit
3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                || (result.value ^ 0x5555) != checkRanges[enumRanges].value) {
3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("utrie_enum() delivers wrong range [U+"
3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + Integer.toHexString(result.start) + "..U+"
3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + Integer.toHexString(result.limit) + "].0x"
3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + Integer.toHexString(result.value ^ 0x5555)
3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + " instead of [U+"
3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + Integer.toHexString(checkRanges[enumRanges -1].limit)
3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + "..U+"
3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + Integer.toHexString(checkRanges[enumRanges].limit)
3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + "].0x"
3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + Integer.toHexString(checkRanges[enumRanges].value));
3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            enumRanges ++;
3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // test linear Latin-1 range
3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (trie.isLatin1Linear()) {
3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (start = 0; start < 0x100; ++ start) {
3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (trie.getLatin1LinearValue((char)start)
3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    != trie.getLeadValue((char)start)) {
3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("trie.getLatin1LinearValue[U+"
3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(start) + "]=0x"
3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(
3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        trie.getLatin1LinearValue((char)start))
3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + " instead of 0x"
3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + Integer.toHexString(
3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                        trie.getLeadValue((char)start)));
3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        _testTrieIteration(trie, checkRanges, countCheckRanges);
3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void _testTrieRanges2(SetRange setRanges[],
3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                  int countSetRanges,
3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                  CheckRange checkRanges[],
3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                  int countCheckRanges)
3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        _testTrieRanges(setRanges, countSetRanges, checkRanges, countCheckRanges,
3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        false);
3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        _testTrieRanges(setRanges, countSetRanges, checkRanges, countCheckRanges,
3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        true);
3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void _testTrieRanges4(SetRange setRanges[], int countSetRanges,
3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                  CheckRange checkRanges[],
3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                  int countCheckRanges)
3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        _testTrieRanges2(setRanges, countSetRanges, checkRanges,
3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                         countCheckRanges);
3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // test data ------------------------------------------------------------
3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * set consecutive ranges, even with value 0
3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static SetRange setRanges1[]={
3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0,      0x20,       0,      false),
3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x20,   0xa7,       0x1234, false),
3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0xa7,   0x3400,     0,      false),
3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x3400, 0x9fa6,     0x6162, false),
3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x9fa6, 0xda9e,     0x3132, false),
3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // try to disrupt _testFoldingOffset16()
3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0xdada, 0xeeee,     0x87ff, false),
3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0xeeee, 0x11111,    1,      false),
3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x11111, 0x44444,   0x6162, false),
3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x44444, 0x60003,   0,      false),
3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0xf0003, 0xf0004,   0xf,    false),
3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0xf0004, 0xf0006,   0x10,   false),
3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0xf0006, 0xf0007,   0x11,   false),
3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0xf0007, 0xf0020,   0x12,   false),
3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0xf0020, 0x110000,  0,      false)
3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static CheckRange checkRanges1[]={
3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0,      0), // dummy start range to make _testEnumRange() simpler
3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x20,   0),
3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xa7,   0x1234),
4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x3400, 0),
4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x9fa6, 0x6162),
4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xda9e, 0x3132),
4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xdada, 0),
4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xeeee, 0x87ff),
4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x11111,1),
4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x44444,0x6162),
4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xf0003,0),
4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xf0004,0xf),
4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xf0006,0x10),
4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xf0007,0x11),
4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xf0020,0x12),
4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x110000, 0)
4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * set some interesting overlapping ranges
4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static SetRange setRanges2[]={
4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x21,   0x7f,       0x5555, true),
4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x2f800,0x2fedc,    0x7a,   true),
4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x72,   0xdd,       3,      true),
4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0xdd,   0xde,       4,      false),
4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x2f987,0x2fa98,    5,      true),
4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x2f777,0x2f833,    0,      true),
4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x2f900,0x2ffee,    1,      false),
4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x2ffee,0x2ffef,    2,      true)
4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static CheckRange checkRanges2[]={
4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // dummy start range to make _testEnumRange() simpler
4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0,      0),
4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x21,   0),
4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x72,   0x5555),
4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xdd,   3),
4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xde,   4),
4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x2f833,0),
4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x2f987,0x7a),
4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x2fa98,5),
4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x2fedc,0x7a),
4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x2ffee,1),
4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x2ffef,2),
4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x110000, 0)
4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * use a non-zero initial value
4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static SetRange setRanges3[]={
4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x31,   0xa4,   1,  false),
4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x3400, 0x6789, 2,  false),
4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x30000,0x34567,9,  true),
4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new SetRange(0x45678,0x56789,3,  true)
4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static CheckRange checkRanges3[]={
4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // dummy start range, also carries the initial value
4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0,      9),
4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x31,   9),
4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0xa4,   1),
4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x3400, 9),
4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x6789, 2),
4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x45678,9),
4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x56789,3),
4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        new CheckRange(0x110000,9)
4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestIntTrie()
4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        _testTrieRanges4(setRanges1, setRanges1.length, checkRanges1,
4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                         checkRanges1.length);
4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        _testTrieRanges4(setRanges2, setRanges2.length, checkRanges2,
4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                         checkRanges2.length);
4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        _testTrieRanges4(setRanges3, setRanges3.length, checkRanges3,
4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                         checkRanges3.length);
4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static class DummyGetFoldingOffset implements Trie.DataManipulate {
4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public int getFoldingOffset(int value) {
4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return -1; /* never get non-initialValue data for supplementary code points */
4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestDummyCharTrie() {
4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        CharTrie trie;
4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final int initialValue=0x313, leadUnitValue=0xaffe;
4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int value;
4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int c;
4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        trie=new CharTrie(initialValue, leadUnitValue, new DummyGetFoldingOffset());
4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* test that all code points have initialValue */
4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for(c=0; c<=0x10ffff; ++c) {
4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            value=trie.getCodePointValue(c);
4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(value!=initialValue) {
4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("CharTrie/dummy.getCodePointValue(c)(U+"+hex(c)+")=0x"+hex(value)+" instead of 0x"+hex(initialValue));
4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* test that the lead surrogate code units have leadUnitValue */
4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for(c=0xd800; c<=0xdbff; ++c) {
5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            value=trie.getLeadValue((char)c);
5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(value!=leadUnitValue) {
5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("CharTrie/dummy.getLeadValue(c)(U+"+hex(c)+")=0x"+hex(value)+" instead of 0x"+hex(leadUnitValue));
5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestDummyIntTrie() {
5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        IntTrie trie;
5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final int initialValue=0x01234567, leadUnitValue=0x89abcdef;
5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int value;
5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int c;
5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        trie=new IntTrie(initialValue, leadUnitValue, new DummyGetFoldingOffset());
5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* test that all code points have initialValue */
5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for(c=0; c<=0x10ffff; ++c) {
5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            value=trie.getCodePointValue(c);
5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(value!=initialValue) {
5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("IntTrie/dummy.getCodePointValue(c)(U+"+hex(c)+")=0x"+hex(value)+" instead of 0x"+hex(initialValue));
5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /* test that the lead surrogate code units have leadUnitValue */
5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for(c=0xd800; c<=0xdbff; ++c) {
5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            value=trie.getLeadValue((char)c);
5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(value!=leadUnitValue) {
5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("IntTrie/dummy.getLeadValue(c)(U+"+hex(c)+")=0x"+hex(value)+" instead of 0x"+hex(leadUnitValue));
5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
531