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