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