Home | History | Annotate | Download | only in util
      1 /* GENERATED SOURCE. DO NOT MODIFY. */
      2 //  2016 and later: Unicode, Inc. and others.
      3 // License & terms of use: http://www.unicode.org/copyright.html#License
      4 /*
      5  *******************************************************************************
      6  * Copyright (C) 2009-2015, International Business Machines Corporation and
      7  * others. All Rights Reserved.
      8  *******************************************************************************
      9  */
     10 
     11 package android.icu.dev.test.util;
     12 
     13 import java.io.ByteArrayInputStream;
     14 import java.io.ByteArrayOutputStream;
     15 import java.io.IOException;
     16 import java.io.InputStream;
     17 import java.nio.ByteBuffer;
     18 import java.util.Iterator;
     19 
     20 import org.junit.Test;
     21 import org.junit.runner.RunWith;
     22 import org.junit.runners.JUnit4;
     23 
     24 import android.icu.dev.test.TestFmwk;
     25 import android.icu.impl.ICUBinary;
     26 import android.icu.impl.Trie2;
     27 import android.icu.impl.Trie2Writable;
     28 import android.icu.impl.Trie2_16;
     29 import android.icu.impl.Trie2_32;
     30 import android.icu.testsharding.MainTestShard;
     31 
     32 @MainTestShard
     33 @RunWith(JUnit4.class)
     34 public class Trie2Test extends TestFmwk {
     35     /**
     36      * Constructor
     37      */
     38      public Trie2Test()
     39      {
     40      }
     41 
     42      // public methods -----------------------------------------------
     43 
     44      //
     45      //  TestAPI.  Check that all API methods can be called, and do at least some minimal
     46      //            operation correctly.  This is not a full test of correct behavior.
     47      //
     48     @Test
     49      public void TestTrie2API() {
     50          // Trie2.createFromSerialized()
     51          //   This function is well exercised by TestRanges().
     52 
     53          // Trie2.getVersion(InputStream is, boolean anyEndianOk)
     54          //
     55 
     56          try {
     57              Trie2Writable trie = new Trie2Writable(0,0);
     58              ByteArrayOutputStream os = new ByteArrayOutputStream();
     59              trie.toTrie2_16().serialize(os);
     60              ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
     61              assertEquals(null, 2, Trie2.getVersion(is, true));
     62          } catch (IOException e) {
     63              errln(where() + e.toString());
     64          }
     65 
     66          // Equals & hashCode
     67          //
     68          {
     69              Trie2Writable trieWA = new Trie2Writable(0,0);
     70              Trie2Writable trieWB = new Trie2Writable(0,0);
     71              Trie2 trieA = trieWA;
     72              Trie2 trieB = trieWB;
     73              assertTrue("", trieA.equals(trieB));
     74              assertEquals("", trieA, trieB);
     75              assertEquals("", trieA.hashCode(), trieB.hashCode());
     76              trieWA.set(500, 2);
     77              assertNotEquals("", trieA, trieB);
     78              // Note that the hash codes do not strictly need to be different,
     79              //   but it's highly likely that something is wrong if they are the same.
     80              assertNotEquals("", trieA.hashCode(), trieB.hashCode());
     81              trieWB.set(500, 2);
     82              trieA = trieWA.toTrie2_16();
     83              assertEquals("", trieA, trieB);
     84              assertEquals("", trieA.hashCode(), trieB.hashCode());
     85          }
     86 
     87          //
     88          // Iterator creation
     89          //
     90          {
     91              Trie2Writable trie = new Trie2Writable(17,0);
     92              Iterator<Trie2.Range>   it;
     93              it = trie.iterator();
     94 
     95              Trie2.Range r = it.next();
     96              assertEquals("", 0, r.startCodePoint);
     97              assertEquals("", 0x10ffff, r.endCodePoint);
     98              assertEquals("", 17, r.value);
     99              assertEquals("", false, r.leadSurrogate);
    100 
    101              r = it.next();
    102              assertEquals("", 0xd800, r.startCodePoint);
    103              assertEquals("", 0xdbff, r.endCodePoint);
    104              assertEquals("", 17, r.value);
    105              assertEquals("", true, r.leadSurrogate);
    106 
    107 
    108              int i = 0;
    109              for (Trie2.Range rr: trie) {
    110                  switch (i) {
    111                  case 0:
    112                      assertEquals("", 0, rr.startCodePoint);
    113                      assertEquals("", 0x10ffff, rr.endCodePoint);
    114                      assertEquals("", 17, rr.value);
    115                      assertEquals("", false, rr.leadSurrogate);
    116                      break;
    117                  case 1:
    118                      assertEquals("", 0xd800, rr.startCodePoint);
    119                      assertEquals("", 0xdbff, rr.endCodePoint);
    120                      assertEquals("", 17, rr.value);
    121                      assertEquals("", true, rr.leadSurrogate);
    122                      break;
    123                  default:
    124                      errln(where() + " Unexpected iteration result");
    125                  }
    126                  i++;
    127              }
    128          }
    129 
    130          // Iteration with a value mapping function
    131          //
    132          {
    133              Trie2Writable trie = new Trie2Writable(0xbadfeed, 0);
    134              trie.set(0x10123, 42);
    135 
    136              Trie2.ValueMapper vm = new Trie2.ValueMapper() {
    137                  @Override
    138                 public int map(int v) {
    139                      if (v == 0xbadfeed) {
    140                          v = 42;
    141                      }
    142                      return v;
    143                  }
    144              };
    145              Iterator<Trie2.Range> it = trie.iterator(vm);
    146              Trie2.Range r = it.next();
    147              assertEquals("", 0, r.startCodePoint);
    148              assertEquals("", 0x10ffff, r.endCodePoint);
    149              assertEquals("", 42, r.value);
    150              assertEquals("", false, r.leadSurrogate);
    151          }
    152 
    153 
    154          // Iteration over a leading surrogate range.
    155          //
    156          {
    157              Trie2Writable trie = new Trie2Writable(0xdefa17, 0);
    158              trie.set(0x2f810, 10);
    159              Iterator<Trie2.Range> it = trie.iteratorForLeadSurrogate((char)0xd87e);
    160              Trie2.Range r = it.next();
    161              assertEquals("", 0x2f800,  r.startCodePoint);
    162              assertEquals("", 0x2f80f,  r.endCodePoint);
    163              assertEquals("", 0xdefa17, r.value);
    164              assertEquals("", false,    r.leadSurrogate);
    165 
    166              r = it.next();
    167              assertEquals("", 0x2f810, r.startCodePoint);
    168              assertEquals("", 0x2f810, r.endCodePoint);
    169              assertEquals("", 10,      r.value);
    170              assertEquals("", false,   r.leadSurrogate);
    171 
    172              r = it.next();
    173              assertEquals("", 0x2f811,  r.startCodePoint);
    174              assertEquals("", 0x2fbff,  r.endCodePoint);
    175              assertEquals("", 0xdefa17, r.value);
    176              assertEquals("", false,    r.leadSurrogate);
    177 
    178              assertFalse("", it.hasNext());
    179          }
    180 
    181          // Iteration over a leading surrogate range with a ValueMapper.
    182          //
    183          {
    184              Trie2Writable trie = new Trie2Writable(0xdefa17, 0);
    185              trie.set(0x2f810, 10);
    186              Trie2.ValueMapper m = new Trie2.ValueMapper() {
    187                  @Override
    188                 public int map(int in) {
    189                      if (in==10) {
    190                          in = 0xdefa17;
    191                      }
    192                      return in;
    193                  }
    194              };
    195              Iterator<Trie2.Range> it = trie.iteratorForLeadSurrogate((char)0xd87e, m);
    196              Trie2.Range r = it.next();
    197              assertEquals("", 0x2f800,  r.startCodePoint);
    198              assertEquals("", 0x2fbff,  r.endCodePoint);
    199              assertEquals("", 0xdefa17, r.value);
    200              assertEquals("", false,    r.leadSurrogate);
    201 
    202              assertFalse("", it.hasNext());
    203          }
    204 
    205          // Trie2.serialize()
    206          //     Test the implementation in Trie2, which is used with Read Only Tries.
    207          //
    208          {
    209              Trie2Writable trie = new Trie2Writable(101, 0);
    210              trie.setRange(0xf000, 0x3c000, 200, true);
    211              trie.set(0xffee, 300);
    212              Trie2_16 frozen16 = trie.toTrie2_16();
    213              Trie2_32 frozen32 = trie.toTrie2_32();
    214              assertEquals("", trie, frozen16);
    215              assertEquals("", trie, frozen32);
    216              assertEquals("", frozen16, frozen32);
    217              ByteArrayOutputStream os = new ByteArrayOutputStream();
    218              try {
    219                  frozen16.serialize(os);
    220                  Trie2 unserialized16 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray()));
    221                  assertEquals("", trie, unserialized16);
    222                  assertEquals("", Trie2_16.class, unserialized16.getClass());
    223 
    224                  os.reset();
    225                  frozen32.serialize(os);
    226                  Trie2 unserialized32 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray()));
    227                  assertEquals("", trie, unserialized32);
    228                  assertEquals("", Trie2_32.class, unserialized32.getClass());
    229              } catch (IOException e) {
    230                  errln(where() + " Unexpected exception:  " + e);
    231              }
    232 
    233 
    234          }
    235      }
    236 
    237 
    238     @Test
    239      public void TestTrie2WritableAPI() {
    240          //
    241          //   Trie2Writable methods.  Check that all functions are present and
    242          //      nominally working.  Not an in-depth test.
    243          //
    244 
    245          // Trie2Writable constructor
    246          Trie2 t1 = new Trie2Writable(6, 666);
    247 
    248          // Constructor from another Trie2
    249          Trie2 t2 = new Trie2Writable(t1);
    250          assertTrue("", t1.equals(t2));
    251 
    252          // Set / Get
    253          Trie2Writable t1w = new Trie2Writable(10, 666);
    254          t1w.set(0x4567, 99);
    255          assertEquals("", 10, t1w.get(0x4566));
    256          assertEquals("", 99, t1w.get(0x4567));
    257          assertEquals("", 666, t1w.get(-1));
    258          assertEquals("", 666, t1w.get(0x110000));
    259 
    260 
    261          // SetRange
    262          t1w = new Trie2Writable(10, 666);
    263          t1w.setRange(13 /*start*/, 6666 /*end*/, 7788 /*value*/, false  /*overwrite */);
    264          t1w.setRange(6000, 7000, 9900, true);
    265          assertEquals("",   10, t1w.get(12));
    266          assertEquals("", 7788, t1w.get(13));
    267          assertEquals("", 7788, t1w.get(5999));
    268          assertEquals("", 9900, t1w.get(6000));
    269          assertEquals("", 9900, t1w.get(7000));
    270          assertEquals("",   10, t1w.get(7001));
    271          assertEquals("",  666, t1w.get(0x110000));
    272 
    273          // setRange from a Trie2.Range
    274          //    (Ranges are more commonly created by iterating over a Trie2,
    275          //     but create one by hand here)
    276          Trie2.Range r = new Trie2.Range();
    277          r.startCodePoint = 50;
    278          r.endCodePoint   = 52;
    279          r.value          = 0x12345678;
    280          r.leadSurrogate  = false;
    281          t1w = new Trie2Writable(0, 0xbad);
    282          t1w.setRange(r, true);
    283          assertEquals(null, 0, t1w.get(49));
    284          assertEquals("", 0x12345678, t1w.get(50));
    285          assertEquals("", 0x12345678, t1w.get(52));
    286          assertEquals("", 0, t1w.get(53));
    287 
    288 
    289          // setForLeadSurrogateCodeUnit / getFromU16SingleLead
    290          t1w = new Trie2Writable(10, 0xbad);
    291          assertEquals("", 10, t1w.getFromU16SingleLead((char)0x0d801));
    292          t1w.setForLeadSurrogateCodeUnit((char)0xd801, 5000);
    293          t1w.set(0xd801, 6000);
    294          assertEquals("", 5000, t1w.getFromU16SingleLead((char)0x0d801));
    295          assertEquals("", 6000, t1w.get(0x0d801));
    296 
    297          // get().  Is covered by nearly every other test.
    298 
    299 
    300          // Trie2_16 getAsFrozen_16()
    301          t1w = new Trie2Writable(10, 666);
    302          t1w.set(42, 5555);
    303          t1w.set(0x1ff00, 224);
    304          Trie2_16 t1_16 = t1w.toTrie2_16();
    305          assertTrue("", t1w.equals(t1_16));
    306          // alter the writable Trie2 and then re-freeze.
    307          t1w.set(152, 129);
    308          t1_16 = t1w.toTrie2_16();
    309          assertTrue("", t1w.equals(t1_16));
    310          assertEquals("", 129, t1w.get(152));
    311 
    312          // Trie2_32 getAsFrozen_32()
    313          //
    314          t1w = new Trie2Writable(10, 666);
    315          t1w.set(42, 5555);
    316          t1w.set(0x1ff00, 224);
    317          Trie2_32 t1_32 = t1w.toTrie2_32();
    318          assertTrue("", t1w.equals(t1_32));
    319          // alter the writable Trie2 and then re-freeze.
    320          t1w.set(152, 129);
    321          assertNotEquals("", t1_32, t1w);
    322          t1_32 = t1w.toTrie2_32();
    323          assertTrue("", t1w.equals(t1_32));
    324          assertEquals("", 129, t1w.get(152));
    325 
    326 
    327          // serialize(OutputStream os, ValueWidth width)
    328          //
    329          ByteArrayOutputStream os = new ByteArrayOutputStream();
    330          t1w = new Trie2Writable(0, 0xbad);
    331          t1w.set(0x41, 0x100);
    332          t1w.set(0xc2, 0x200);
    333          t1w.set(0x404, 0x300);
    334          t1w.set(0xd903, 0x500);
    335          t1w.set(0xdd29, 0x600);
    336          t1w.set(0x1055d3, 0x700);
    337          t1w.setForLeadSurrogateCodeUnit((char)0xda1a, 0x800);
    338          try {
    339              // Serialize to 16 bits.
    340              int serializedLen = t1w.toTrie2_16().serialize(os);
    341              // Fragile test.  Serialized length could change with changes to compaction.
    342              //                But it should not change unexpectedly.
    343              assertEquals("", 3508, serializedLen);
    344              Trie2 t1ws16 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray()));
    345              assertEquals("", t1ws16.getClass(), Trie2_16.class);
    346              assertEquals("", t1w, t1ws16);
    347 
    348              // Serialize to 32 bits
    349              os.reset();
    350              serializedLen = t1w.toTrie2_32().serialize(os);
    351              // Fragile test.  Serialized length could change with changes to compaction.
    352              //                But it should not change unexpectedly.
    353              assertEquals("", 4332, serializedLen);
    354              Trie2 t1ws32 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray()));
    355              assertEquals("", t1ws32.getClass(), Trie2_32.class);
    356              assertEquals("", t1w, t1ws32);
    357          } catch (IOException e) {
    358              errln(where() + e.toString());
    359          }
    360 
    361 
    362      }
    363 
    364     @Test
    365      public void TestCharSequenceIterator() {
    366          String text = "abc123\ud800\udc01 ";    // Includes a Unicode supplemental character
    367          String vals = "LLLNNNX?S";
    368 
    369          Trie2Writable  tw = new Trie2Writable(0, 666);
    370          tw.setRange('a', 'z', 'L', false);
    371          tw.setRange('1', '9', 'N', false);
    372          tw.set(' ', 'S');
    373          tw.set(0x10001, 'X');
    374 
    375          Trie2.CharSequenceIterator it = tw.charSequenceIterator(text, 0);
    376 
    377          // Check forwards iteration.
    378          Trie2.CharSequenceValues ir;
    379          int i;
    380          for (i=0; it.hasNext(); i++) {
    381              ir = it.next();
    382              int expectedCP = Character.codePointAt(text, i);
    383              assertEquals("" + " i="+i, expectedCP,     ir.codePoint);
    384              assertEquals("" + " i="+i, i,              ir.index);
    385              assertEquals("" + " i="+i, vals.charAt(i), ir.value);
    386              if (expectedCP >= 0x10000) {
    387                  i++;
    388              }
    389          }
    390          assertEquals("", text.length(), i);
    391 
    392          // Check reverse iteration, starting at an intermediate point.
    393          it.set(5);
    394          for (i=5; it.hasPrevious(); ) {
    395              ir = it.previous();
    396              int expectedCP = Character.codePointBefore(text, i);
    397              i -= (expectedCP < 0x10000? 1 : 2);
    398              assertEquals("" + " i="+i, expectedCP,     ir.codePoint);
    399              assertEquals("" + " i="+i, i,              ir.index);
    400              assertEquals("" + " i="+i, vals.charAt(i), ir.value);
    401          }
    402          assertEquals("", 0, i);
    403 
    404      }
    405 
    406 
    407      //
    408      //  Port of Tests from ICU4C ...
    409      //
    410      //     setRanges array elements are
    411      //        {start Code point, limit CP, value, overwrite}
    412      //
    413      //     There must be an entry with limit 0 and with the intialValue.
    414      //     It may be preceded by an entry with negative limit and the errorValue.
    415      //
    416      //     checkRanges array elemets are
    417      //        { limit code point, value}
    418      //
    419      //     The expected value range is from the previous boundary's limit to before
    420      //        this boundary's limit
    421 
    422      //
    423      String[] trieNames = {"setRanges1", "setRanges2", "setRanges3", "setRangesEmpty", "setRangesSingleValue"};
    424      /* set consecutive ranges, even with value 0 */
    425 
    426 
    427 
    428      private static int[][] setRanges1 ={
    429          { 0,        0,        0,      0 },
    430          { 0,        0x40,     0,      0 },
    431          { 0x40,     0xe7,     0x1234, 0 },
    432          { 0xe7,     0x3400,   0,      0 },
    433          { 0x3400,   0x9fa6,   0x6162, 0 },
    434          { 0x9fa6,   0xda9e,   0x3132, 0 },
    435          { 0xdada,   0xeeee,   0x87ff, 0 },
    436          { 0xeeee,   0x11111,  1,      0 },
    437          { 0x11111,  0x44444,  0x6162, 0 },
    438          { 0x44444,  0x60003,  0,      0 },
    439          { 0xf0003,  0xf0004,  0xf,    0 },
    440          { 0xf0004,  0xf0006,  0x10,   0 },
    441          { 0xf0006,  0xf0007,  0x11,   0 },
    442          { 0xf0007,  0xf0040,  0x12,   0 },
    443          { 0xf0040,  0x110000, 0,      0 }
    444      };
    445 
    446      private static int[][]  checkRanges1 = {
    447          { 0,        0 },
    448          { 0x40,     0 },
    449          { 0xe7,     0x1234 },
    450          { 0x3400,   0 },
    451          { 0x9fa6,   0x6162 },
    452          { 0xda9e,   0x3132 },
    453          { 0xdada,   0 },
    454          { 0xeeee,   0x87ff },
    455          { 0x11111,  1 },
    456          { 0x44444,  0x6162 },
    457          { 0xf0003,  0 },
    458          { 0xf0004,  0xf },
    459          { 0xf0006,  0x10 },
    460          { 0xf0007,  0x11 },
    461          { 0xf0040,  0x12 },
    462          { 0x110000, 0 }
    463      };
    464 
    465      /* set some interesting overlapping ranges */
    466      private static  int [][] setRanges2={
    467          { 0,        0,        0,      0 },
    468          { 0x21,     0x7f,     0x5555, 1 },
    469          { 0x2f800,  0x2fedc,  0x7a,   1 },
    470          { 0x72,     0xdd,     3,      1 },
    471          { 0xdd,     0xde,     4,      0 },
    472          { 0x201,    0x240,    6,      1 },  /* 3 consecutive blocks with the same pattern but */
    473          { 0x241,    0x280,    6,      1 },  /* discontiguous value ranges, testing utrie2_enum() */
    474          { 0x281,    0x2c0,    6,      1 },
    475          { 0x2f987,  0x2fa98,  5,      1 },
    476          { 0x2f777,  0x2f883,  0,      1 },
    477          { 0x2f900,  0x2ffaa,  1,      0 },
    478          { 0x2ffaa,  0x2ffab,  2,      1 },
    479          { 0x2ffbb,  0x2ffc0,  7,      1 }
    480      };
    481 
    482      private static int[] [] checkRanges2={
    483          { 0,        0 },
    484          { 0x21,     0 },
    485          { 0x72,     0x5555 },
    486          { 0xdd,     3 },
    487          { 0xde,     4 },
    488          { 0x201,    0 },
    489          { 0x240,    6 },
    490          { 0x241,    0 },
    491          { 0x280,    6 },
    492          { 0x281,    0 },
    493          { 0x2c0,    6 },
    494          { 0x2f883,  0 },
    495          { 0x2f987,  0x7a },
    496          { 0x2fa98,  5 },
    497          { 0x2fedc,  0x7a },
    498          { 0x2ffaa,  1 },
    499          { 0x2ffab,  2 },
    500          { 0x2ffbb,  0 },
    501          { 0x2ffc0,  7 },
    502          { 0x110000, 0 }
    503      };
    504 
    505 /*
    506      private static int[] [] checkRanges2_d800={
    507          { 0x10000,  0 },
    508          { 0x10400,  0 }
    509      };
    510 
    511      private static int[][] checkRanges2_d87e={
    512          { 0x2f800,  6 },
    513          { 0x2f883,  0 },
    514          { 0x2f987,  0x7a },
    515          { 0x2fa98,  5 },
    516          { 0x2fc00,  0x7a }
    517      };
    518 
    519      private static int[][] checkRanges2_d87f={
    520          { 0x2fc00,  0 },
    521          { 0x2fedc,  0x7a },
    522          { 0x2ffaa,  1 },
    523          { 0x2ffab,  2 },
    524          { 0x2ffbb,  0 },
    525          { 0x2ffc0,  7 },
    526          { 0x30000,  0 }
    527      };
    528 
    529      private static int[][]  checkRanges2_dbff={
    530          { 0x10fc00, 0 },
    531          { 0x110000, 0 }
    532      };
    533 */
    534 
    535      /* use a non-zero initial value */
    536      private static int[][] setRanges3={
    537          { 0,        0,        9, 0 },     // non-zero initial value.
    538          { 0x31,     0xa4,     1, 0 },
    539          { 0x3400,   0x6789,   2, 0 },
    540          { 0x8000,   0x89ab,   9, 1 },
    541          { 0x9000,   0xa000,   4, 1 },
    542          { 0xabcd,   0xbcde,   3, 1 },
    543          { 0x55555,  0x110000, 6, 1 },  /* highStart<U+ffff with non-initialValue */
    544          { 0xcccc,   0x55555,  6, 1 }
    545      };
    546 
    547      private static int[][] checkRanges3={
    548          { 0,        9 },  /* non-zero initialValue */
    549          { 0x31,     9 },
    550          { 0xa4,     1 },
    551          { 0x3400,   9 },
    552          { 0x6789,   2 },
    553          { 0x9000,   9 },
    554          { 0xa000,   4 },
    555          { 0xabcd,   9 },
    556          { 0xbcde,   3 },
    557          { 0xcccc,   9 },
    558          { 0x110000, 6 }
    559      };
    560 
    561      /* empty or single-value tries, testing highStart==0 */
    562      private static int[][] setRangesEmpty={
    563          { 0,        0,        3, 0 }         // Only the element with the initial value.
    564      };
    565 
    566      private static int[][] checkRangesEmpty={
    567          { 0,        3 },
    568          { 0x110000, 3 }
    569      };
    570 
    571      private static int[][] setRangesSingleValue={
    572          { 0,        0,        3,  0 },   // Initial value = 3
    573          { 0,        0x110000, 5, 1 },
    574      };
    575 
    576      private static int[][] checkRangesSingleValue={
    577          { 0,        3 },
    578          { 0x110000, 5 }
    579      };
    580 
    581 
    582      //
    583      // Create a test Trie2 from a setRanges test array.
    584      //    Range data ported from C.
    585      //
    586      private Trie2Writable genTrieFromSetRanges(int [][] ranges) {
    587          int i = 0;
    588          int initialValue = 0;
    589          int errorValue   = 0x0bad;
    590 
    591          if (ranges[i][1] < 0) {
    592              errorValue = ranges[i][2];
    593              i++;
    594          }
    595          initialValue = ranges[i++][2];
    596          Trie2Writable trie = new Trie2Writable(initialValue, errorValue);
    597 
    598          for (; i<ranges.length; i++) {
    599              int     rangeStart = ranges[i][0];
    600              int     rangeEnd   = ranges[i][1]-1;
    601              int     value      = ranges[i][2];
    602              boolean overwrite = (ranges[i][3] != 0);
    603              trie.setRange(rangeStart, rangeEnd, value, overwrite);
    604          }
    605 
    606          // Insert some non-default values for lead surrogates.
    607          //   TODO:  this should be represented in the data.
    608          trie.setForLeadSurrogateCodeUnit((char)0xd800, 90);
    609          trie.setForLeadSurrogateCodeUnit((char)0xd999, 94);
    610          trie.setForLeadSurrogateCodeUnit((char)0xdbff, 99);
    611 
    612          return trie;
    613      }
    614 
    615 
    616      //
    617      //  Check the expected values from a single Trie2.
    618      //
    619      private void trieGettersTest(String           testName,
    620                                   Trie2            trie,         // The Trie2 to test.
    621                                   int[][]          checkRanges)  // Expected data.
    622                                                                  //   Tuples of (value, high limit code point)
    623                                                                  //   High limit is first code point following the range
    624                                                                  //   with the indicated value.
    625                                                                  //      (Structures copied from ICU4C tests.)
    626      {
    627          int countCheckRanges = checkRanges.length;
    628 
    629          int initialValue, errorValue;
    630          int value, value2;
    631          int start, limit;
    632          int i, countSpecials;
    633 
    634          countSpecials=0;  /*getSpecialValues(checkRanges, countCheckRanges, &initialValue, &errorValue);*/
    635          errorValue = 0x0bad;
    636          initialValue = 0;
    637          if (checkRanges[countSpecials][0] == 0) {
    638              initialValue = checkRanges[countSpecials][1];
    639              countSpecials++;
    640          }
    641 
    642          start=0;
    643          for(i=countSpecials; i<countCheckRanges; ++i) {
    644              limit=checkRanges[i][0];
    645              value=checkRanges[i][1];
    646 
    647              while(start<limit) {
    648                  value2=trie.get(start);
    649                  if (value != value2) {
    650                      // The redundant if, outside of the assert, is for speed.
    651                      // It makes a significant difference for this test.
    652                      assertEquals("wrong value for " + testName + " of " + Integer.toHexString(start), value, value2);
    653                  }
    654                  ++start;
    655              }
    656          }
    657 
    658 
    659          if(!testName.startsWith("dummy") && !testName.startsWith("trie1")) {
    660              /* Test values for lead surrogate code units.
    661               * For non-lead-surrogate code units,  getFromU16SingleLead() and get()
    662               *   should be the same.
    663               */
    664              for(start=0xd7ff; start<0xdc01; ++start) {
    665                  switch(start) {
    666                  case 0xd7ff:
    667                  case 0xdc00:
    668                      value=trie.get(start);
    669                      break;
    670                  case 0xd800:
    671                      value=90;
    672                      break;
    673                  case 0xd999:
    674                      value=94;
    675                      break;
    676                  case 0xdbff:
    677                      value=99;
    678                      break;
    679                  default:
    680                      value=initialValue;
    681                      break;
    682                  }
    683                  value2 = trie.getFromU16SingleLead((char)start);
    684                  if(value2!=value) {
    685                      errln(where() + " testName: " + testName + " getFromU16SingleLead() failed." +
    686                              "char, exected, actual = " + Integer.toHexString(start) + ", " +
    687                              Integer.toHexString(value) + ", " + Integer.toHexString(value2));
    688                  }
    689              }
    690          }
    691 
    692          /* test errorValue */
    693          value=trie.get(-1);
    694          value2=trie.get(0x110000);
    695          if(value!=errorValue || value2!=errorValue) {
    696              errln("trie2.get() error value test.  Expected, actual1, actual2 = " +
    697                      errorValue + ", " + value + ", " + value2);
    698          }
    699 
    700          // Check that Trie enumeration produces the same contents as simple get()
    701          for (Trie2.Range range: trie) {
    702              for (int cp=range.startCodePoint; cp<=range.endCodePoint; cp++) {
    703                  if (range.leadSurrogate) {
    704                      assertTrue(testName, cp>=(char)0xd800 && cp<(char)0xdc00);
    705                      assertEquals(testName, range.value, trie.getFromU16SingleLead((char)cp));
    706                  } else {
    707                      assertEquals(testName, range.value, trie.get(cp));
    708                  }
    709              }
    710          }
    711      }
    712 
    713      // Was testTrieRanges in ICU4C.  Renamed to not conflict with ICU4J test framework.
    714      private void checkTrieRanges(String testName, String serializedName, boolean withClone,
    715              int[][] setRanges, int [][] checkRanges) throws IOException {
    716 
    717          // Run tests against Tries that were built by ICU4C and serialized.
    718          String fileName16 = "Trie2Test." + serializedName + ".16.tri2";
    719          String fileName32 = "Trie2Test." + serializedName + ".32.tri2";
    720 
    721          InputStream is = Trie2Test.class.getResourceAsStream(fileName16);
    722          Trie2 trie16;
    723          try {
    724              trie16 = Trie2.createFromSerialized(ICUBinary.getByteBufferFromInputStreamAndCloseStream(is));
    725          } finally {
    726              is.close();
    727          }
    728          trieGettersTest(testName, trie16, checkRanges);
    729 
    730          is = Trie2Test.class.getResourceAsStream(fileName32);
    731          Trie2 trie32;
    732          try {
    733              trie32 = Trie2.createFromSerialized(ICUBinary.getByteBufferFromInputStreamAndCloseStream(is));
    734          } finally {
    735              is.close();
    736          }
    737          trieGettersTest(testName, trie32, checkRanges);
    738 
    739          // Run the same tests against locally contructed Tries.
    740          Trie2Writable trieW = genTrieFromSetRanges(setRanges);
    741          trieGettersTest(testName, trieW,  checkRanges);
    742          assertEquals("", trieW, trie16);   // Locally built tries must be
    743          assertEquals("", trieW, trie32);   //   the same as those imported from ICU4C
    744 
    745 
    746          Trie2_32 trie32a = trieW.toTrie2_32();
    747          trieGettersTest(testName, trie32a, checkRanges);
    748 
    749          Trie2_16 trie16a = trieW.toTrie2_16();
    750          trieGettersTest(testName, trie16a, checkRanges);
    751 
    752      }
    753 
    754      // Was "TrieTest" in trie2test.c
    755     @Test
    756      public void TestRanges() throws IOException {
    757          checkTrieRanges("set1",           "setRanges1",     false, setRanges1,     checkRanges1);
    758          checkTrieRanges("set2-overlap",   "setRanges2",     false, setRanges2,     checkRanges2);
    759          checkTrieRanges("set3-initial-9", "setRanges3",     false, setRanges3,     checkRanges3);
    760          checkTrieRanges("set-empty",      "setRangesEmpty", false, setRangesEmpty, checkRangesEmpty);
    761          checkTrieRanges("set-single-value", "setRangesSingleValue", false, setRangesSingleValue,
    762              checkRangesSingleValue);
    763          checkTrieRanges("set2-overlap.withClone", "setRanges2", true, setRanges2,     checkRanges2);
    764      }
    765 
    766 
    767      private String where() {
    768          StackTraceElement[] st = new Throwable().getStackTrace();
    769          String w = "File: " + st[1].getFileName() + ", Line " + st[1].getLineNumber();
    770          return w;
    771      }
    772 }
    773