NativeBreakIterator.java revision c27a366a89e470690e99374b15270e7b9169ade1
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.icu;
18
19import java.text.CharacterIterator;
20import java.text.StringCharacterIterator;
21import java.util.Locale;
22
23public final class NativeBreakIterator implements Cloneable {
24    // Acceptable values for the 'type' field.
25    private static final int BI_CHAR_INSTANCE = 1;
26    private static final int BI_WORD_INSTANCE = 2;
27    private static final int BI_LINE_INSTANCE = 3;
28    private static final int BI_SENT_INSTANCE = 4;
29
30    private final int addr;
31    private final int type;
32    private CharacterIterator charIter;
33
34    private NativeBreakIterator(int iterAddr, int type) {
35        this.addr = iterAddr;
36        this.type = type;
37        this.charIter = new StringCharacterIterator("");
38    }
39
40    @Override
41    public Object clone() {
42        int cloneAddr = cloneImpl(this.addr);
43        NativeBreakIterator clone = new NativeBreakIterator(cloneAddr, this.type);
44        // The RI doesn't clone the CharacterIterator.
45        clone.charIter = this.charIter;
46        return clone;
47    }
48
49    @Override
50    public boolean equals(Object object) {
51        if (object == this) {
52            return true;
53        }
54        if (!(object instanceof NativeBreakIterator)) {
55            return false;
56        }
57        // TODO: is this sufficient? shouldn't we be checking the underlying rules?
58        NativeBreakIterator rhs = (NativeBreakIterator) object;
59        return type == rhs.type && charIter.equals(rhs.charIter);
60    }
61
62    @Override
63    public int hashCode() {
64        return 42; // No-one uses BreakIterator as a hash key.
65    }
66
67    @Override protected void finalize() throws Throwable {
68        try {
69            closeBreakIteratorImpl(this.addr);
70        } finally {
71            super.finalize();
72        }
73    }
74
75    public int current() {
76        return currentImpl(this.addr);
77    }
78
79    public int first() {
80        return firstImpl(this.addr);
81    }
82
83    public int following(int offset) {
84        return followingImpl(this.addr, offset);
85    }
86
87    public CharacterIterator getText() {
88        int newLoc = currentImpl(this.addr);
89        this.charIter.setIndex(newLoc);
90        return this.charIter;
91    }
92
93    public int last() {
94        return lastImpl(this.addr);
95    }
96
97    public int next(int n) {
98        return nextImpl(this.addr, n);
99    }
100
101    public int next() {
102        return nextImpl(this.addr, 1);
103    }
104
105    public int previous() {
106        return previousImpl(this.addr);
107    }
108
109    public void setText(CharacterIterator newText) {
110        this.charIter = newText;
111        StringBuilder sb = new StringBuilder();
112        for (char c = newText.first(); c != CharacterIterator.DONE; c = newText.next()) {
113            sb.append(c);
114        }
115        setTextImpl(this.addr, sb.toString());
116    }
117
118    public void setText(String newText) {
119        setText(new StringCharacterIterator(newText));
120    }
121
122    public boolean isBoundary(int offset) {
123        return isBoundaryImpl(this.addr, offset);
124    }
125
126    public int preceding(int offset) {
127        return precedingImpl(this.addr, offset);
128    }
129
130    public static NativeBreakIterator getCharacterInstance(Locale where) {
131        return new NativeBreakIterator(getCharacterInstanceImpl(where.toString()), BI_CHAR_INSTANCE);
132    }
133
134    public static NativeBreakIterator getLineInstance(Locale where) {
135        return new NativeBreakIterator(getLineInstanceImpl(where.toString()), BI_LINE_INSTANCE);
136    }
137
138    public static NativeBreakIterator getSentenceInstance(Locale where) {
139        return new NativeBreakIterator(getSentenceInstanceImpl(where.toString()), BI_SENT_INSTANCE);
140    }
141
142    public static NativeBreakIterator getWordInstance(Locale where) {
143        return new NativeBreakIterator(getWordInstanceImpl(where.toString()), BI_WORD_INSTANCE);
144    }
145
146    private static native int getCharacterInstanceImpl(String locale);
147    private static native int getWordInstanceImpl(String locale);
148    private static native int getLineInstanceImpl(String locale);
149    private static native int getSentenceInstanceImpl(String locale);
150    private static native void closeBreakIteratorImpl(int addr);
151    private static native void setTextImpl(int addr, String text);
152    private static native int cloneImpl(int addr);
153    private static native int precedingImpl(int addr, int offset);
154    private static native boolean isBoundaryImpl(int addr, int offset);
155    private static native int nextImpl(int addr, int n);
156    private static native int previousImpl(int addr);
157    private static native int currentImpl(int addr);
158    private static native int firstImpl(int addr);
159    private static native int followingImpl(int addr, int offset);
160    private static native int lastImpl(int addr);
161}
162