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 */ 9package com.ibm.icu.text; 10 11import java.text.CharacterIterator; 12 13import com.ibm.icu.impl.Assert; 14import com.ibm.icu.util.BytesTrie; 15import com.ibm.icu.util.BytesTrie.Result; 16 17class BytesDictionaryMatcher extends DictionaryMatcher { 18 private final byte[] characters; 19 private final int transform; 20 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 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 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 88 public int getType() { 89 return DictionaryData.TRIE_TYPE_BYTES; 90 } 91} 92 93 94