12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others.
22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
5aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert * Copyright (C) 2009-2015, International Business Machines Corporation and
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved.
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.test.util;
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.ByteArrayInputStream;
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.ByteArrayOutputStream;
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.IOException;
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.InputStream;
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.nio.ByteBuffer;
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Iterator;
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
192d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubertimport org.junit.Test;
20fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubertimport org.junit.runner.RunWith;
21fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubertimport org.junit.runners.JUnit4;
222d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.dev.test.TestFmwk;
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.ICUBinary;
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.Trie2;
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.Trie2Writable;
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.Trie2_16;
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.Trie2_32;
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
30fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert@RunWith(JUnit4.class)
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class Trie2Test extends TestFmwk {
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Constructor
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     public Trie2Test()
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     {
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
38fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     // public methods -----------------------------------------------
40fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //  TestAPI.  Check that all API methods can be called, and do at least some minimal
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //            operation correctly.  This is not a full test of correct behavior.
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //
452d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     public void TestTrie2API() {
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Trie2.createFromSerialized()
48fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         //   This function is well exercised by TestRanges().
49fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Trie2.getVersion(InputStream is, boolean anyEndianOk)
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //
52fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         try {
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2Writable trie = new Trie2Writable(0,0);
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             ByteArrayOutputStream os = new ByteArrayOutputStream();
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             trie.toTrie2_16().serialize(os);
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals(null, 2, Trie2.getVersion(is, true));
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         } catch (IOException e) {
60fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert             errln(where() + e.toString());
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
62fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Equals & hashCode
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         {
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2Writable trieWA = new Trie2Writable(0,0);
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2Writable trieWB = new Trie2Writable(0,0);
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2 trieA = trieWA;
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2 trieB = trieWB;
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertTrue("", trieA.equals(trieB));
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", trieA, trieB);
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", trieA.hashCode(), trieB.hashCode());
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             trieWA.set(500, 2);
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertNotEquals("", trieA, trieB);
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             // Note that the hash codes do not strictly need to be different,
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             //   but it's highly likely that something is wrong if they are the same.
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertNotEquals("", trieA.hashCode(), trieB.hashCode());
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             trieWB.set(500, 2);
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             trieA = trieWA.toTrie2_16();
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", trieA, trieB);
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", trieA.hashCode(), trieB.hashCode());
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
83fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
84fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         //
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Iterator creation
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         {
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2Writable trie = new Trie2Writable(17,0);
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Iterator<Trie2.Range>   it;
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             it = trie.iterator();
91fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2.Range r = it.next();
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0, r.startCodePoint);
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0x10ffff, r.endCodePoint);
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 17, r.value);
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", false, r.leadSurrogate);
97fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             r = it.next();
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0xd800, r.startCodePoint);
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0xdbff, r.endCodePoint);
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 17, r.value);
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", true, r.leadSurrogate);
103fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
104fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             int i = 0;
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             for (Trie2.Range rr: trie) {
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 switch (i) {
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 case 0:
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals("", 0, rr.startCodePoint);
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals("", 0x10ffff, rr.endCodePoint);
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals("", 17, rr.value);
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals("", false, rr.leadSurrogate);
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     break;
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 case 1:
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals("", 0xd800, rr.startCodePoint);
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals("", 0xdbff, rr.endCodePoint);
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals("", 17, rr.value);
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals("", true, rr.leadSurrogate);
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     break;
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 default:
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     errln(where() + " Unexpected iteration result");
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 }
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 i++;
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             }
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
126fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Iteration with a value mapping function
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         {
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2Writable trie = new Trie2Writable(0xbadfeed, 0);
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             trie.set(0x10123, 42);
132fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2.ValueMapper vm = new Trie2.ValueMapper() {
134fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                 @Override
135fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                public int map(int v) {
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     if (v == 0xbadfeed) {
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                         v = 42;
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     }
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     return v;
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 }
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             };
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Iterator<Trie2.Range> it = trie.iterator(vm);
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2.Range r = it.next();
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0, r.startCodePoint);
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0x10ffff, r.endCodePoint);
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 42, r.value);
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", false, r.leadSurrogate);
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
149fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
150fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Iteration over a leading surrogate range.
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         {
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2Writable trie = new Trie2Writable(0xdefa17, 0);
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             trie.set(0x2f810, 10);
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Iterator<Trie2.Range> it = trie.iteratorForLeadSurrogate((char)0xd87e);
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2.Range r = it.next();
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0x2f800,  r.startCodePoint);
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0x2f80f,  r.endCodePoint);
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0xdefa17, r.value);
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", false,    r.leadSurrogate);
162fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             r = it.next();
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0x2f810, r.startCodePoint);
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0x2f810, r.endCodePoint);
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 10,      r.value);
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", false,   r.leadSurrogate);
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             r = it.next();
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0x2f811,  r.startCodePoint);
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0x2fbff,  r.endCodePoint);
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0xdefa17, r.value);
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", false,    r.leadSurrogate);
174fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertFalse("", it.hasNext());
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
177fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Iteration over a leading surrogate range with a ValueMapper.
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         {
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2Writable trie = new Trie2Writable(0xdefa17, 0);
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             trie.set(0x2f810, 10);
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2.ValueMapper m = new Trie2.ValueMapper() {
184fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                 @Override
185fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                public int map(int in) {
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     if (in==10) {
187fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                         in = 0xdefa17;
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     }
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     return in;
190fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                 }
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             };
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Iterator<Trie2.Range> it = trie.iteratorForLeadSurrogate((char)0xd87e, m);
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2.Range r = it.next();
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0x2f800,  r.startCodePoint);
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0x2fbff,  r.endCodePoint);
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 0xdefa17, r.value);
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", false,    r.leadSurrogate);
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertFalse("", it.hasNext());
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
201fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Trie2.serialize()
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //     Test the implementation in Trie2, which is used with Read Only Tries.
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         {
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2Writable trie = new Trie2Writable(101, 0);
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             trie.setRange(0xf000, 0x3c000, 200, true);
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             trie.set(0xffee, 300);
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2_16 frozen16 = trie.toTrie2_16();
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2_32 frozen32 = trie.toTrie2_32();
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", trie, frozen16);
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", trie, frozen32);
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", frozen16, frozen32);
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             ByteArrayOutputStream os = new ByteArrayOutputStream();
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             try {
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 frozen16.serialize(os);
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 Trie2 unserialized16 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray()));
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 assertEquals("", trie, unserialized16);
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 assertEquals("", Trie2_16.class, unserialized16.getClass());
220fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 os.reset();
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 frozen32.serialize(os);
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 Trie2 unserialized32 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray()));
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 assertEquals("", trie, unserialized32);
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 assertEquals("", Trie2_32.class, unserialized32.getClass());
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             } catch (IOException e) {
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 errln(where() + " Unexpected exception:  " + e);
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             }
229fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
230fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
233fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
234fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2352d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     public void TestTrie2WritableAPI() {
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //
238fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         //   Trie2Writable methods.  Check that all functions are present and
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //      nominally working.  Not an in-depth test.
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //
241fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Trie2Writable constructor
2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2 t1 = new Trie2Writable(6, 666);
244fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Constructor from another Trie2
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2 t2 = new Trie2Writable(t1);
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertTrue("", t1.equals(t2));
248fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Set / Get
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2Writable t1w = new Trie2Writable(10, 666);
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(0x4567, 99);
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 10, t1w.get(0x4566));
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 99, t1w.get(0x4567));
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 666, t1w.get(-1));
2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 666, t1w.get(0x110000));
256fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
257fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // SetRange
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w = new Trie2Writable(10, 666);
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.setRange(13 /*start*/, 6666 /*end*/, 7788 /*value*/, false  /*overwrite */);
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.setRange(6000, 7000, 9900, true);
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("",   10, t1w.get(12));
2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 7788, t1w.get(13));
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 7788, t1w.get(5999));
2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 9900, t1w.get(6000));
2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 9900, t1w.get(7000));
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("",   10, t1w.get(7001));
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("",  666, t1w.get(0x110000));
269fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // setRange from a Trie2.Range
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //    (Ranges are more commonly created by iterating over a Trie2,
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //     but create one by hand here)
2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2.Range r = new Trie2.Range();
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         r.startCodePoint = 50;
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         r.endCodePoint   = 52;
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         r.value          = 0x12345678;
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         r.leadSurrogate  = false;
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w = new Trie2Writable(0, 0xbad);
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.setRange(r, true);
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals(null, 0, t1w.get(49));
2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 0x12345678, t1w.get(50));
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 0x12345678, t1w.get(52));
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 0, t1w.get(53));
284fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
285fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // setForLeadSurrogateCodeUnit / getFromU16SingleLead
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w = new Trie2Writable(10, 0xbad);
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 10, t1w.getFromU16SingleLead((char)0x0d801));
2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.setForLeadSurrogateCodeUnit((char)0xd801, 5000);
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(0xd801, 6000);
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 5000, t1w.getFromU16SingleLead((char)0x0d801));
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 6000, t1w.get(0x0d801));
293fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // get().  Is covered by nearly every other test.
295fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
296fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Trie2_16 getAsFrozen_16()
2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w = new Trie2Writable(10, 666);
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(42, 5555);
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(0x1ff00, 224);
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2_16 t1_16 = t1w.toTrie2_16();
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertTrue("", t1w.equals(t1_16));
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // alter the writable Trie2 and then re-freeze.
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(152, 129);
3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1_16 = t1w.toTrie2_16();
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertTrue("", t1w.equals(t1_16));
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 129, t1w.get(152));
308fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Trie2_32 getAsFrozen_32()
3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //
3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w = new Trie2Writable(10, 666);
3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(42, 5555);
3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(0x1ff00, 224);
3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2_32 t1_32 = t1w.toTrie2_32();
3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertTrue("", t1w.equals(t1_32));
3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // alter the writable Trie2 and then re-freeze.
3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(152, 129);
3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertNotEquals("", t1_32, t1w);
3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1_32 = t1w.toTrie2_32();
3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertTrue("", t1w.equals(t1_32));
3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 129, t1w.get(152));
322fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
323fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // serialize(OutputStream os, ValueWidth width)
325fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         //
3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         ByteArrayOutputStream os = new ByteArrayOutputStream();
3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w = new Trie2Writable(0, 0xbad);
3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(0x41, 0x100);
3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(0xc2, 0x200);
3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(0x404, 0x300);
3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(0xd903, 0x500);
3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(0xdd29, 0x600);
3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.set(0x1055d3, 0x700);
3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         t1w.setForLeadSurrogateCodeUnit((char)0xda1a, 0x800);
3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         try {
3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             // Serialize to 16 bits.
3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             int serializedLen = t1w.toTrie2_16().serialize(os);
3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             // Fragile test.  Serialized length could change with changes to compaction.
3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             //                But it should not change unexpectedly.
3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 3508, serializedLen);
3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2 t1ws16 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray()));
3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", t1ws16.getClass(), Trie2_16.class);
3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", t1w, t1ws16);
344fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             // Serialize to 32 bits
3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             os.reset();
3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             serializedLen = t1w.toTrie2_32().serialize(os);
3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             // Fragile test.  Serialized length could change with changes to compaction.
3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             //                But it should not change unexpectedly.
3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", 4332, serializedLen);
3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             Trie2 t1ws32 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray()));
3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", t1ws32.getClass(), Trie2_32.class);
3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("", t1w, t1ws32);
3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         } catch (IOException e) {
3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             errln(where() + e.toString());
3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
357fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
358fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
360fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
3612d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     public void TestCharSequenceIterator() {
3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         String text = "abc123\ud800\udc01 ";    // Includes a Unicode supplemental character
3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         String vals = "LLLNNNX?S";
365fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2Writable  tw = new Trie2Writable(0, 666);
3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         tw.setRange('a', 'z', 'L', false);
3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         tw.setRange('1', '9', 'N', false);
3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         tw.set(' ', 'S');
3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         tw.set(0x10001, 'X');
3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2.CharSequenceIterator it = tw.charSequenceIterator(text, 0);
373fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Check forwards iteration.
3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2.CharSequenceValues ir;
3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         int i;
3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         for (i=0; it.hasNext(); i++) {
3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             ir = it.next();
3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             int expectedCP = Character.codePointAt(text, i);
3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("" + " i="+i, expectedCP,     ir.codePoint);
3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("" + " i="+i, i,              ir.index);
3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("" + " i="+i, vals.charAt(i), ir.value);
3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             if (expectedCP >= 0x10000) {
3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 i++;
3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             }
3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", text.length(), i);
388fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Check reverse iteration, starting at an intermediate point.
3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         it.set(5);
3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         for (i=5; it.hasPrevious(); ) {
3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             ir = it.previous();
3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             int expectedCP = Character.codePointBefore(text, i);
394fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert             i -= (expectedCP < 0x10000? 1 : 2);
3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("" + " i="+i, expectedCP,     ir.codePoint);
3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("" + " i="+i, i,              ir.index);
3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             assertEquals("" + " i="+i, vals.charAt(i), ir.value);
3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", 0, i);
400fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
402fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
403fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //
4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //  Port of Tests from ICU4C ...
4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //
4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //     setRanges array elements are
4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //        {start Code point, limit CP, value, overwrite}
4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //
4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //     There must be an entry with limit 0 and with the intialValue.
4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //     It may be preceded by an entry with negative limit and the errorValue.
4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //
4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //     checkRanges array elemets are
4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //        { limit code point, value}
415fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert     //
4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //     The expected value range is from the previous boundary's limit to before
4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //        this boundary's limit
4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
419fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert     //
4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     String[] trieNames = {"setRanges1", "setRanges2", "setRanges3", "setRangesEmpty", "setRangesSingleValue"};
4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     /* set consecutive ranges, even with value 0 */
422fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
423fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
424fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][] setRanges1 ={
4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        0,        0,      0 },
4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        0x40,     0,      0 },
4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x40,     0xe7,     0x1234, 0 },
4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xe7,     0x3400,   0,      0 },
4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x3400,   0x9fa6,   0x6162, 0 },
4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x9fa6,   0xda9e,   0x3132, 0 },
4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xdada,   0xeeee,   0x87ff, 0 },
4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xeeee,   0x11111,  1,      0 },
4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x11111,  0x44444,  0x6162, 0 },
4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x44444,  0x60003,  0,      0 },
4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xf0003,  0xf0004,  0xf,    0 },
4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xf0004,  0xf0006,  0x10,   0 },
4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xf0006,  0xf0007,  0x11,   0 },
4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xf0007,  0xf0040,  0x12,   0 },
4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xf0040,  0x110000, 0,      0 }
4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][]  checkRanges1 = {
4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        0 },
4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x40,     0 },
4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xe7,     0x1234 },
4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x3400,   0 },
4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x9fa6,   0x6162 },
4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xda9e,   0x3132 },
4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xdada,   0 },
4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xeeee,   0x87ff },
4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x11111,  1 },
4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x44444,  0x6162 },
4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xf0003,  0 },
4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xf0004,  0xf },
4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xf0006,  0x10 },
4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xf0007,  0x11 },
4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xf0040,  0x12 },
4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x110000, 0 }
4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     /* set some interesting overlapping ranges */
4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static  int [][] setRanges2={
4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        0,        0,      0 },
4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x21,     0x7f,     0x5555, 1 },
4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2f800,  0x2fedc,  0x7a,   1 },
4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x72,     0xdd,     3,      1 },
4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xdd,     0xde,     4,      0 },
4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x201,    0x240,    6,      1 },  /* 3 consecutive blocks with the same pattern but */
4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x241,    0x280,    6,      1 },  /* discontiguous value ranges, testing utrie2_enum() */
4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x281,    0x2c0,    6,      1 },
4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2f987,  0x2fa98,  5,      1 },
4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2f777,  0x2f883,  0,      1 },
4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2f900,  0x2ffaa,  1,      0 },
4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2ffaa,  0x2ffab,  2,      1 },
4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2ffbb,  0x2ffc0,  7,      1 }
4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[] [] checkRanges2={
4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        0 },
4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x21,     0 },
4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x72,     0x5555 },
4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xdd,     3 },
4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xde,     4 },
4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x201,    0 },
4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x240,    6 },
4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x241,    0 },
4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x280,    6 },
4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x281,    0 },
4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2c0,    6 },
4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2f883,  0 },
4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2f987,  0x7a },
4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2fa98,  5 },
4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2fedc,  0x7a },
4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2ffaa,  1 },
4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2ffab,  2 },
4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2ffbb,  0 },
4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2ffc0,  7 },
4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x110000, 0 }
5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*
5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[] [] checkRanges2_d800={
5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x10000,  0 },
5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x10400,  0 }
5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][] checkRanges2_d87e={
5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2f800,  6 },
5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2f883,  0 },
5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2f987,  0x7a },
5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2fa98,  5 },
5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2fc00,  0x7a }
5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][] checkRanges2_d87f={
5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2fc00,  0 },
5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2fedc,  0x7a },
5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2ffaa,  1 },
5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2ffab,  2 },
5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2ffbb,  0 },
5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x2ffc0,  7 },
5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x30000,  0 }
5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][]  checkRanges2_dbff={
5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x10fc00, 0 },
5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x110000, 0 }
5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert*/
5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     /* use a non-zero initial value */
5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][] setRanges3={
5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        0,        9, 0 },     // non-zero initial value.
5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x31,     0xa4,     1, 0 },
5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x3400,   0x6789,   2, 0 },
5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x8000,   0x89ab,   9, 1 },
5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x9000,   0xa000,   4, 1 },
5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xabcd,   0xbcde,   3, 1 },
5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x55555,  0x110000, 6, 1 },  /* highStart<U+ffff with non-initialValue */
5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xcccc,   0x55555,  6, 1 }
5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][] checkRanges3={
5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        9 },  /* non-zero initialValue */
5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x31,     9 },
5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xa4,     1 },
5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x3400,   9 },
5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x6789,   2 },
5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x9000,   9 },
5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xa000,   4 },
5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xabcd,   9 },
5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xbcde,   3 },
5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0xcccc,   9 },
5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x110000, 6 }
5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     /* empty or single-value tries, testing highStart==0 */
5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][] setRangesEmpty={
5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        0,        3, 0 }         // Only the element with the initial value.
5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][] checkRangesEmpty={
5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        3 },
5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x110000, 3 }
5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][] setRangesSingleValue={
5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        0,        3,  0 },   // Initial value = 3
5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        0x110000, 5, 1 },
5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private static int[][] checkRangesSingleValue={
5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0,        3 },
5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         { 0x110000, 5 }
5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     };
5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //
5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     // Create a test Trie2 from a setRanges test array.
5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //    Range data ported from C.
5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //
5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private Trie2Writable genTrieFromSetRanges(int [][] ranges) {
5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         int i = 0;
5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         int initialValue = 0;
5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         int errorValue   = 0x0bad;
587fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         if (ranges[i][1] < 0) {
5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             errorValue = ranges[i][2];
5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             i++;
5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         initialValue = ranges[i++][2];
5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2Writable trie = new Trie2Writable(initialValue, errorValue);
594fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         for (; i<ranges.length; i++) {
5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             int     rangeStart = ranges[i][0];
5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             int     rangeEnd   = ranges[i][1]-1;
5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             int     value      = ranges[i][2];
5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             boolean overwrite = (ranges[i][3] != 0);
6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             trie.setRange(rangeStart, rangeEnd, value, overwrite);
6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
602fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Insert some non-default values for lead surrogates.
6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         //   TODO:  this should be represented in the data.
6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         trie.setForLeadSurrogateCodeUnit((char)0xd800, 90);
6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         trie.setForLeadSurrogateCodeUnit((char)0xd999, 94);
6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         trie.setForLeadSurrogateCodeUnit((char)0xdbff, 99);
608fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         return trie;
6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
612fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //
6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //  Check the expected values from a single Trie2.
6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     //
6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private void trieGettersTest(String           testName,
6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                  Trie2            trie,         // The Trie2 to test.
618fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                                  int[][]          checkRanges)  // Expected data.
6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                 //   Tuples of (value, high limit code point)
6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                 //   High limit is first code point following the range
6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                 //   with the indicated value.
6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                 //      (Structures copied from ICU4C tests.)
6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     {
6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         int countCheckRanges = checkRanges.length;
6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         int initialValue, errorValue;
6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         int value, value2;
6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         int start, limit;
6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         int i, countSpecials;
6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         countSpecials=0;  /*getSpecialValues(checkRanges, countCheckRanges, &initialValue, &errorValue);*/
6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         errorValue = 0x0bad;
6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         initialValue = 0;
6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         if (checkRanges[countSpecials][0] == 0) {
6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             initialValue = checkRanges[countSpecials][1];
6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             countSpecials++;
6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
6387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         start=0;
6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         for(i=countSpecials; i<countCheckRanges; ++i) {
6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             limit=checkRanges[i][0];
6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             value=checkRanges[i][1];
6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             while(start<limit) {
6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 value2=trie.get(start);
6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 if (value != value2) {
647fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                     // The redundant if, outside of the assert, is for speed.
6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     // It makes a significant difference for this test.
6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals("wrong value for " + testName + " of " + Integer.toHexString(start), value, value2);
6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 }
6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 ++start;
6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             }
6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         if(!testName.startsWith("dummy") && !testName.startsWith("trie1")) {
6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             /* Test values for lead surrogate code units.
6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              * For non-lead-surrogate code units,  getFromU16SingleLead() and get()
6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              *   should be the same.
6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              */
6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             for(start=0xd7ff; start<0xdc01; ++start) {
6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 switch(start) {
6637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 case 0xd7ff:
6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 case 0xdc00:
6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     value=trie.get(start);
6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     break;
6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 case 0xd800:
6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     value=90;
6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     break;
6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 case 0xd999:
6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     value=94;
6727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     break;
6737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 case 0xdbff:
6747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     value=99;
6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     break;
6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 default:
6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     value=initialValue;
6787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     break;
6797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 }
6807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 value2 = trie.getFromU16SingleLead((char)start);
6817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 if(value2!=value) {
6827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     errln(where() + " testName: " + testName + " getFromU16SingleLead() failed." +
683fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert                             "char, exected, actual = " + Integer.toHexString(start) + ", " +
6847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                             Integer.toHexString(value) + ", " + Integer.toHexString(value2));
6857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 }
6867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             }
6877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
6887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         /* test errorValue */
6907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         value=trie.get(-1);
6917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         value2=trie.get(0x110000);
6927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         if(value!=errorValue || value2!=errorValue) {
6937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             errln("trie2.get() error value test.  Expected, actual1, actual2 = " +
6947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     errorValue + ", " + value + ", " + value2);
6957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
696fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
6977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Check that Trie enumeration produces the same contents as simple get()
6987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         for (Trie2.Range range: trie) {
6997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             for (int cp=range.startCodePoint; cp<=range.endCodePoint; cp++) {
7007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 if (range.leadSurrogate) {
7017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertTrue(testName, cp>=(char)0xd800 && cp<(char)0xdc00);
7027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals(testName, range.value, trie.getFromU16SingleLead((char)cp));
7037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 } else {
7047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     assertEquals(testName, range.value, trie.get(cp));
7057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                 }
7067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             }
7077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         }
7087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
709fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
7107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     // Was testTrieRanges in ICU4C.  Renamed to not conflict with ICU4J test framework.
7117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private void checkTrieRanges(String testName, String serializedName, boolean withClone,
7127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             int[][] setRanges, int [][] checkRanges) throws IOException {
713fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
7147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Run tests against Tries that were built by ICU4C and serialized.
7157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         String fileName16 = "Trie2Test." + serializedName + ".16.tri2";
7167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         String fileName32 = "Trie2Test." + serializedName + ".32.tri2";
717fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
7187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         InputStream is = Trie2Test.class.getResourceAsStream(fileName16);
719aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert         Trie2 trie16;
720aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert         try {
721aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert             trie16 = Trie2.createFromSerialized(ICUBinary.getByteBufferFromInputStreamAndCloseStream(is));
722aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert         } finally {
723aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert             is.close();
724aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert         }
7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         trieGettersTest(testName, trie16, checkRanges);
726aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert
7277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         is = Trie2Test.class.getResourceAsStream(fileName32);
728aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert         Trie2 trie32;
729aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert         try {
730aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert             trie32 = Trie2.createFromSerialized(ICUBinary.getByteBufferFromInputStreamAndCloseStream(is));
731aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert         } finally {
732aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert             is.close();
733aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert         }
7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         trieGettersTest(testName, trie32, checkRanges);
735aacdd6f022693689b3bf76f70670711f3254a441Fredrik Roubert
7367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // Run the same tests against locally contructed Tries.
7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2Writable trieW = genTrieFromSetRanges(setRanges);
7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         trieGettersTest(testName, trieW,  checkRanges);
7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", trieW, trie16);   // Locally built tries must be
7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         assertEquals("", trieW, trie32);   //   the same as those imported from ICU4C
741fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
742fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2_32 trie32a = trieW.toTrie2_32();
7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         trieGettersTest(testName, trie32a, checkRanges);
7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         Trie2_16 trie16a = trieW.toTrie2_16();
7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         trieGettersTest(testName, trie16a, checkRanges);
748fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
750fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
751fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert     // Was "TrieTest" in trie2test.c
7522d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
7537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     public void TestRanges() throws IOException {
754fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         checkTrieRanges("set1",           "setRanges1",     false, setRanges1,     checkRanges1);
7557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         checkTrieRanges("set2-overlap",   "setRanges2",     false, setRanges2,     checkRanges2);
7567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         checkTrieRanges("set3-initial-9", "setRanges3",     false, setRanges3,     checkRanges3);
7577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         checkTrieRanges("set-empty",      "setRangesEmpty", false, setRangesEmpty, checkRangesEmpty);
758fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert         checkTrieRanges("set-single-value", "setRangesSingleValue", false, setRangesSingleValue,
7597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             checkRangesSingleValue);
7607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         checkTrieRanges("set2-overlap.withClone", "setRanges2", true, setRanges2,     checkRanges2);
7617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
7627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
763fe77e7203e518f62b5bd8e8c603bca361e9cf47bFredrik Roubert
7647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     private String where() {
7657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         StackTraceElement[] st = new Throwable().getStackTrace();
7667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         String w = "File: " + st[1].getFileName() + ", Line " + st[1].getLineNumber();
7677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         return w;
7687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
7697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
770