1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html#License
3 /*
4  *******************************************************************************
5  * Copyright (C) 2014, International Business Machines Corporation and         *
6  * others. All Rights Reserved.                                                *
7  *******************************************************************************
8  */
9 package com.ibm.icu.text;
10 
11 import java.text.CharacterIterator;
12 
13 import com.ibm.icu.impl.Assert;
14 import com.ibm.icu.util.BytesTrie;
15 import com.ibm.icu.util.BytesTrie.Result;
16 
17 class BytesDictionaryMatcher extends DictionaryMatcher {
18     private final byte[] characters;
19     private final int transform;
20 
BytesDictionaryMatcher(byte[] chars, int transform)21     public BytesDictionaryMatcher(byte[] chars, int transform) {
22         characters = chars;
23         Assert.assrt((transform & DictionaryData.TRANSFORM_TYPE_MASK) == DictionaryData.TRANSFORM_TYPE_OFFSET);
24         // while there is only one transform type so far, save the entire transform constant so that
25         // if we add any others, we need only change code in transform() and the assert above rather
26         // than adding a "transform type" variable
27         this.transform = transform;
28     }
29 
transform(int c)30     private int transform(int c) {
31         if (c == 0x200D) {
32             return 0xFF;
33         } else if (c == 0x200C) {
34             return 0xFE;
35         }
36 
37         int delta = c - (transform & DictionaryData.TRANSFORM_OFFSET_MASK);
38         if (delta < 0 || 0xFD < delta) {
39             return -1;
40         }
41         return delta;
42     }
43 
44     @Override
matches(CharacterIterator text_, int maxLength, int[] lengths, int[] count_, int limit, int[] values)45     public int matches(CharacterIterator text_, int maxLength, int[] lengths, int[] count_, int limit, int[] values) {
46         UCharacterIterator text = UCharacterIterator.getInstance(text_);
47         BytesTrie bt = new BytesTrie(characters, 0);
48         int c = text.nextCodePoint();
49         if (c == UCharacterIterator.DONE) {
50             return 0;
51         }
52         Result result = bt.first(transform(c));
53         // TODO: should numChars count Character.charCount() ?
54         int numChars = 1;
55         int count = 0;
56         for (;;) {
57             if (result.hasValue()) {
58                 if (count < limit) {
59                     if (values != null) {
60                         values[count] = bt.getValue();
61                     }
62                     lengths[count] = numChars;
63                     count++;
64                 }
65                 if (result == Result.FINAL_VALUE) {
66                     break;
67                 }
68             } else if (result == Result.NO_MATCH) {
69                 break;
70             }
71 
72             if (numChars >= maxLength) {
73                 break;
74             }
75 
76             c = text.nextCodePoint();
77             if (c == UCharacterIterator.DONE) {
78                 break;
79             }
80             ++numChars;
81             result = bt.next(transform(c));
82         }
83         count_[0] = count;
84         return numChars;
85     }
86 
87     @Override
getType()88     public int getType() {
89         return DictionaryData.TRIE_TYPE_BYTES;
90     }
91 }
92 
93 
94