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