1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License.
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License.
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
17c27a366a89e470690e99374b15270e7b9169ade1Elliott Hughespackage libcore.icu;
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
199672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughesimport java.text.CharacterIterator;
209672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughesimport java.text.StringCharacterIterator;
219672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughesimport java.util.Locale;
229672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
239672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughespublic final class NativeBreakIterator implements Cloneable {
249672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    // Acceptable values for the 'type' field.
259672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    private static final int BI_CHAR_INSTANCE = 1;
269672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    private static final int BI_WORD_INSTANCE = 2;
279672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    private static final int BI_LINE_INSTANCE = 3;
289672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    private static final int BI_SENT_INSTANCE = 4;
299672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
30866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private final int address;
319672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    private final int type;
329672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    private CharacterIterator charIter;
339672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
34866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private NativeBreakIterator(int address, int type) {
35866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        this.address = address;
369672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        this.type = type;
379672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        this.charIter = new StringCharacterIterator("");
389672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
399672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
409672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    @Override
419672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public Object clone() {
42866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        int cloneAddr = cloneImpl(this.address);
439672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        NativeBreakIterator clone = new NativeBreakIterator(cloneAddr, this.type);
449672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        // The RI doesn't clone the CharacterIterator.
459672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        clone.charIter = this.charIter;
469672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        return clone;
479672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
489672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
499672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    @Override
509672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public boolean equals(Object object) {
51ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes        if (object == this) {
52ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes            return true;
53ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes        }
54ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes        if (!(object instanceof NativeBreakIterator)) {
559672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes            return false;
569672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        }
579672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        // TODO: is this sufficient? shouldn't we be checking the underlying rules?
589672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        NativeBreakIterator rhs = (NativeBreakIterator) object;
599672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        return type == rhs.type && charIter.equals(rhs.charIter);
609672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
619672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
629672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    @Override
639672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public int hashCode() {
649672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        return 42; // No-one uses BreakIterator as a hash key.
659672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
669672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
67e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom    @Override protected void finalize() throws Throwable {
68e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom        try {
69866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes            closeBreakIteratorImpl(this.address);
70e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom        } finally {
71e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom            super.finalize();
72e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom        }
739672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
749672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
759672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public int current() {
76866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        return currentImpl(this.address);
779672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
789672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
799672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public int first() {
80866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        return firstImpl(this.address);
819672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
829672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
839672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public int following(int offset) {
84866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        return followingImpl(this.address, offset);
859672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
869672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
879672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public CharacterIterator getText() {
88866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        int newLoc = currentImpl(this.address);
899672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        this.charIter.setIndex(newLoc);
909672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        return this.charIter;
919672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
929672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
939672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public int last() {
94866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        return lastImpl(this.address);
959672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
969672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
979672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public int next(int n) {
98866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        return nextImpl(this.address, n);
999672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
1009672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
1019672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public int next() {
102866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        return nextImpl(this.address, 1);
1039672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
1049672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes
1059672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public int previous() {
106866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        return previousImpl(this.address);
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1099672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public void setText(CharacterIterator newText) {
1109672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        StringBuilder sb = new StringBuilder();
1119672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        for (char c = newText.first(); c != CharacterIterator.DONE; c = newText.next()) {
1129672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes            sb.append(c);
1139672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        }
11452dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes        setText(sb.toString(), newText);
1159672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1179672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public void setText(String newText) {
11852dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes        setText(newText, new StringCharacterIterator(newText));
11952dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes    }
12052dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes
12152dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes    private void setText(String s, CharacterIterator it) {
12252dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes        this.charIter = it;
12352dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes        setTextImpl(this.address, s);
1249672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1269672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public boolean isBoundary(int offset) {
127866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        return isBoundaryImpl(this.address, offset);
1289672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1309672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public int preceding(int offset) {
131866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes        return precedingImpl(this.address, offset);
1329672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1349672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public static NativeBreakIterator getCharacterInstance(Locale where) {
1359672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        return new NativeBreakIterator(getCharacterInstanceImpl(where.toString()), BI_CHAR_INSTANCE);
1369672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1389672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public static NativeBreakIterator getLineInstance(Locale where) {
1399672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        return new NativeBreakIterator(getLineInstanceImpl(where.toString()), BI_LINE_INSTANCE);
1409672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1429672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public static NativeBreakIterator getSentenceInstance(Locale where) {
1439672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        return new NativeBreakIterator(getSentenceInstanceImpl(where.toString()), BI_SENT_INSTANCE);
1449672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1469672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    public static NativeBreakIterator getWordInstance(Locale where) {
1479672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes        return new NativeBreakIterator(getWordInstanceImpl(where.toString()), BI_WORD_INSTANCE);
1489672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    }
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1509672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    private static native int getCharacterInstanceImpl(String locale);
1519672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    private static native int getWordInstanceImpl(String locale);
1529672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    private static native int getLineInstanceImpl(String locale);
1539672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes    private static native int getSentenceInstanceImpl(String locale);
154866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native void closeBreakIteratorImpl(int address);
155866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native void setTextImpl(int address, String text);
156866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native int cloneImpl(int address);
157866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native int precedingImpl(int address, int offset);
158866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native boolean isBoundaryImpl(int address, int offset);
159866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native int nextImpl(int address, int n);
160866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native int previousImpl(int address);
161866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native int currentImpl(int address);
162866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native int firstImpl(int address);
163866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native int followingImpl(int address, int offset);
164866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes    private static native int lastImpl(int address);
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
166