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