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 30eb9689bf8aee71f16fbe22a2c90d25628dd431ecElliott Hughes // The address of the native peer. 31eb9689bf8aee71f16fbe22a2c90d25628dd431ecElliott Hughes // Uses of this must be manually synchronized to avoid native crashes. 321e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private final long address; 33eb9689bf8aee71f16fbe22a2c90d25628dd431ecElliott Hughes 349672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes private final int type; 35015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes private String string; 36015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes private CharacterIterator charIterator; 379672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 381e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private NativeBreakIterator(long address, int type) { 39866e7ae17a3da81a02b0b144e0c9c2b3196d293aElliott Hughes this.address = address; 409672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes this.type = type; 41015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes this.charIterator = new StringCharacterIterator(""); 429672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 439672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 449672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes @Override 459672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public Object clone() { 461e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes long cloneAddr = cloneImpl(this.address); 479672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes NativeBreakIterator clone = new NativeBreakIterator(cloneAddr, this.type); 48015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes clone.string = this.string; 499672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes // The RI doesn't clone the CharacterIterator. 50015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes clone.charIterator = this.charIterator; 519672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes return clone; 529672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 539672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 549672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes @Override 559672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public boolean equals(Object object) { 56ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (object == this) { 57ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes return true; 58ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes } 59ebe438a0734f24ded1772778e5e712c820981234Elliott Hughes if (!(object instanceof NativeBreakIterator)) { 609672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes return false; 619672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 629672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes // TODO: is this sufficient? shouldn't we be checking the underlying rules? 639672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes NativeBreakIterator rhs = (NativeBreakIterator) object; 64015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return type == rhs.type && charIterator.equals(rhs.charIterator); 659672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 669672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 679672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes @Override 689672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public int hashCode() { 699672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes return 42; // No-one uses BreakIterator as a hash key. 709672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 719672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 72e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom @Override protected void finalize() throws Throwable { 73e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom try { 74015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes closeImpl(this.address); 75e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } finally { 76e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom super.finalize(); 77e2f58c9501eac730d048199906dc41fe8e4cd6e9Brian Carlstrom } 789672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 799672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 809672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public int current() { 81015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return currentImpl(this.address, this.string); 829672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 839672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 849672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public int first() { 85015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return firstImpl(this.address, this.string); 869672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 879672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 889672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public int following(int offset) { 89015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return followingImpl(this.address, this.string, offset); 909672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 919672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 929672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public CharacterIterator getText() { 93015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes int newLocation = currentImpl(this.address, this.string); 94015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes this.charIterator.setIndex(newLocation); 95015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return this.charIterator; 969672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 979672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 989672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public int last() { 99015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return lastImpl(this.address, this.string); 1009672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 1019672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 1029672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public int next(int n) { 103015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return nextImpl(this.address, this.string, n); 1049672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 1059672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 1069672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public int next() { 107015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return nextImpl(this.address, this.string, 1); 1089672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 1099672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes 1109672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public int previous() { 111015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return previousImpl(this.address, this.string); 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1149672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public void setText(CharacterIterator newText) { 1159672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes StringBuilder sb = new StringBuilder(); 1169672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes for (char c = newText.first(); c != CharacterIterator.DONE; c = newText.next()) { 1179672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes sb.append(c); 1189672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 11952dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes setText(sb.toString(), newText); 1209672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1229672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public void setText(String newText) { 12352dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes setText(newText, new StringCharacterIterator(newText)); 12452dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes } 12552dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes 12652dfb928ffdae183b91805bb6983f6e6aa87c9afElliott Hughes private void setText(String s, CharacterIterator it) { 127015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes this.string = s; 128015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes this.charIterator = it; 129015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes setTextImpl(this.address, this.string); 130015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes } 131015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes 132015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes public boolean hasText() { 133015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return (string != null); 1349672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1369672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public boolean isBoundary(int offset) { 137015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return isBoundaryImpl(this.address, this.string, offset); 1389672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1409672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public int preceding(int offset) { 141015843683630bd8e8f060c052ecd2e5a804a8396Elliott Hughes return precedingImpl(this.address, this.string, offset); 1429672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1449672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public static NativeBreakIterator getCharacterInstance(Locale where) { 1459672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes return new NativeBreakIterator(getCharacterInstanceImpl(where.toString()), BI_CHAR_INSTANCE); 1469672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1489672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public static NativeBreakIterator getLineInstance(Locale where) { 1499672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes return new NativeBreakIterator(getLineInstanceImpl(where.toString()), BI_LINE_INSTANCE); 1509672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1529672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public static NativeBreakIterator getSentenceInstance(Locale where) { 1539672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes return new NativeBreakIterator(getSentenceInstanceImpl(where.toString()), BI_SENT_INSTANCE); 1549672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1569672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes public static NativeBreakIterator getWordInstance(Locale where) { 1579672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes return new NativeBreakIterator(getWordInstanceImpl(where.toString()), BI_WORD_INSTANCE); 1589672b4887f2972c1b7c5f3d1a6cf882deccf857fElliott Hughes } 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1601e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static native long getCharacterInstanceImpl(String locale); 1611e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static native long getWordInstanceImpl(String locale); 1621e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static native long getLineInstanceImpl(String locale); 1631e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static native long getSentenceInstanceImpl(String locale); 1641e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native long cloneImpl(long address); 165eb9689bf8aee71f16fbe22a2c90d25628dd431ecElliott Hughes 1661e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native void closeImpl(long address); 167eb9689bf8aee71f16fbe22a2c90d25628dd431ecElliott Hughes 1681e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native void setTextImpl(long address, String text); 1691e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native int precedingImpl(long address, String text, int offset); 1701e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native boolean isBoundaryImpl(long address, String text, int offset); 1711e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native int nextImpl(long address, String text, int n); 1721e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native int previousImpl(long address, String text); 1731e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native int currentImpl(long address, String text); 1741e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native int firstImpl(long address, String text); 1751e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native int followingImpl(long address, String text, int offset); 1761e5d730e58d94c3bfa14b7dde5ab3981fe5a170bElliott Hughes private static synchronized native int lastImpl(long address, String text); 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 178