1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 1996-2016, International Business Machines Corporation and 7 * others. All Rights Reserved. 8 ******************************************************************************* 9 */ 10 package android.icu.text; 11 12 import java.text.CharacterIterator; 13 14 import android.icu.impl.CharacterIteratorWrapper; 15 import android.icu.impl.ReplaceableUCharacterIterator; 16 import android.icu.impl.UCharArrayIterator; 17 import android.icu.impl.UCharacterIteratorWrapper; 18 19 /** 20 * Abstract class that defines an API for iteration on text objects.This is an interface for forward and backward 21 * iteration and random access into a text object. Forward iteration is done with post-increment and backward iteration 22 * is done with pre-decrement semantics, while the <code>java.text.CharacterIterator</code> interface methods provided 23 * forward iteration with "pre-increment" and backward iteration with pre-decrement semantics. This API is more 24 * efficient for forward iteration over code points. The other major difference is that this API can do both code unit 25 * and code point iteration, <code>java.text.CharacterIterator</code> can only iterate over code units and is limited to 26 * BMP (0 - 0xFFFF) 27 * 28 * @author Ram 29 */ 30 public abstract class UCharacterIterator implements Cloneable, UForwardCharacterIterator { 31 32 /** 33 * Protected default constructor for the subclasses 34 */ 35 protected UCharacterIterator() { 36 } 37 38 // static final methods ---------------------------------------------------- 39 40 /** 41 * Returns a <code>UCharacterIterator</code> object given a <code>Replaceable</code> object. 42 * 43 * @param source 44 * a valid source as a <code>Replaceable</code> object 45 * @return UCharacterIterator object 46 * @exception IllegalArgumentException 47 * if the argument is null 48 */ 49 public static final UCharacterIterator getInstance(Replaceable source) { 50 return new ReplaceableUCharacterIterator(source); 51 } 52 53 /** 54 * Returns a <code>UCharacterIterator</code> object given a source string. 55 * 56 * @param source 57 * a string 58 * @return UCharacterIterator object 59 * @exception IllegalArgumentException 60 * if the argument is null 61 */ 62 public static final UCharacterIterator getInstance(String source) { 63 return new ReplaceableUCharacterIterator(source); 64 } 65 66 /** 67 * Returns a <code>UCharacterIterator</code> object given a source character array. 68 * 69 * @param source 70 * an array of UTF-16 code units 71 * @return UCharacterIterator object 72 * @exception IllegalArgumentException 73 * if the argument is null 74 */ 75 public static final UCharacterIterator getInstance(char[] source) { 76 return getInstance(source, 0, source.length); 77 } 78 79 /** 80 * Returns a <code>UCharacterIterator</code> object given a source character array. 81 * 82 * @param source 83 * an array of UTF-16 code units 84 * @return UCharacterIterator object 85 * @exception IllegalArgumentException 86 * if the argument is null 87 */ 88 public static final UCharacterIterator getInstance(char[] source, int start, int limit) { 89 return new UCharArrayIterator(source, start, limit); 90 } 91 92 /** 93 * Returns a <code>UCharacterIterator</code> object given a source StringBuffer. 94 * 95 * @param source 96 * an string buffer of UTF-16 code units 97 * @return UCharacterIterator object 98 * @exception IllegalArgumentException 99 * if the argument is null 100 */ 101 public static final UCharacterIterator getInstance(StringBuffer source) { 102 return new ReplaceableUCharacterIterator(source); 103 } 104 105 /** 106 * Returns a <code>UCharacterIterator</code> object given a CharacterIterator. 107 * 108 * @param source 109 * a valid CharacterIterator object. 110 * @return UCharacterIterator object 111 * @exception IllegalArgumentException 112 * if the argument is null 113 */ 114 public static final UCharacterIterator getInstance(CharacterIterator source) { 115 return new CharacterIteratorWrapper(source); 116 } 117 118 // public methods ---------------------------------------------------------- 119 /** 120 * Returns a <code>java.text.CharacterIterator</code> object for the underlying text of this iterator. The returned 121 * iterator is independent of this iterator. 122 * 123 * @return java.text.CharacterIterator object 124 */ 125 public CharacterIterator getCharacterIterator() { 126 return new UCharacterIteratorWrapper(this); 127 } 128 129 /** 130 * Returns the code unit at the current index. If index is out of range, returns DONE. Index is not changed. 131 * 132 * @return current code unit 133 */ 134 public abstract int current(); 135 136 /** 137 * Returns the codepoint at the current index. If the current index is invalid, DONE is returned. If the current 138 * index points to a lead surrogate, and there is a following trail surrogate, then the code point is returned. 139 * Otherwise, the code unit at index is returned. Index is not changed. 140 * 141 * @return current codepoint 142 */ 143 public int currentCodePoint() { 144 int ch = current(); 145 if (UTF16.isLeadSurrogate((char) ch)) { 146 // advance the index to get the 147 // next code point 148 next(); 149 // due to post increment semantics 150 // current() after next() actually 151 // returns the char we want 152 int ch2 = current(); 153 // current should never change 154 // the current index so back off 155 previous(); 156 157 if (UTF16.isTrailSurrogate((char) ch2)) { 158 // we found a surrogate pair 159 // return the codepoint 160 return Character.toCodePoint((char) ch, (char) ch2); 161 } 162 } 163 return ch; 164 } 165 166 /** 167 * Returns the length of the text 168 * 169 * @return length of the text 170 */ 171 public abstract int getLength(); 172 173 /** 174 * Gets the current index in text. 175 * 176 * @return current index in text. 177 */ 178 public abstract int getIndex(); 179 180 /** 181 * Returns the UTF16 code unit at index, and increments to the next code unit (post-increment semantics). If index 182 * is out of range, DONE is returned, and the iterator is reset to the limit of the text. 183 * 184 * @return the next UTF16 code unit, or DONE if the index is at the limit of the text. 185 */ 186 @Override 187 public abstract int next(); 188 189 /** 190 * Returns the code point at index, and increments to the next code point (post-increment semantics). If index does 191 * not point to a valid surrogate pair, the behavior is the same as <code>next()</code>. Otherwise the iterator is 192 * incremented past the surrogate pair, and the code point represented by the pair is returned. 193 * 194 * @return the next codepoint in text, or DONE if the index is at the limit of the text. 195 */ 196 @Override 197 public int nextCodePoint() { 198 int ch1 = next(); 199 if (UTF16.isLeadSurrogate((char) ch1)) { 200 int ch2 = next(); 201 if (UTF16.isTrailSurrogate((char) ch2)) { 202 return Character.toCodePoint((char) ch1, (char) ch2); 203 } else if (ch2 != DONE) { 204 // unmatched surrogate so back out 205 previous(); 206 } 207 } 208 return ch1; 209 } 210 211 /** 212 * Decrement to the position of the previous code unit in the text, and return it (pre-decrement semantics). If the 213 * resulting index is less than 0, the index is reset to 0 and DONE is returned. 214 * 215 * @return the previous code unit in the text, or DONE if the new index is before the start of the text. 216 */ 217 public abstract int previous(); 218 219 /** 220 * Retreat to the start of the previous code point in the text, and return it (pre-decrement semantics). If the 221 * index is not preceeded by a valid surrogate pair, the behavior is the same as <code>previous()</code>. Otherwise 222 * the iterator is decremented to the start of the surrogate pair, and the code point represented by the pair is 223 * returned. 224 * 225 * @return the previous code point in the text, or DONE if the new index is before the start of the text. 226 */ 227 public int previousCodePoint() { 228 int ch1 = previous(); 229 if (UTF16.isTrailSurrogate((char) ch1)) { 230 int ch2 = previous(); 231 if (UTF16.isLeadSurrogate((char) ch2)) { 232 return Character.toCodePoint((char) ch2, (char) ch1); 233 } else if (ch2 != DONE) { 234 // unmatched trail surrogate so back out 235 next(); 236 } 237 } 238 return ch1; 239 } 240 241 /** 242 * Sets the index to the specified index in the text. 243 * 244 * @param index 245 * the index within the text. 246 * @exception IndexOutOfBoundsException 247 * is thrown if an invalid index is supplied 248 */ 249 public abstract void setIndex(int index); 250 251 /** 252 * Sets the current index to the limit. 253 */ 254 public void setToLimit() { 255 setIndex(getLength()); 256 } 257 258 /** 259 * Sets the current index to the start. 260 */ 261 public void setToStart() { 262 setIndex(0); 263 } 264 265 /** 266 * Fills the buffer with the underlying text storage of the iterator If the buffer capacity is not enough a 267 * exception is thrown. The capacity of the fill in buffer should at least be equal to length of text in the 268 * iterator obtained by calling <code>getLength()</code>). <b>Usage:</b> 269 * 270 * <pre> 271 * UChacterIterator iter = new UCharacterIterator.getInstance(text); 272 * char[] buf = new char[iter.getLength()]; 273 * iter.getText(buf); 274 * 275 * OR 276 * char[] buf= new char[1]; 277 * int len = 0; 278 * for(;;){ 279 * try{ 280 * len = iter.getText(buf); 281 * break; 282 * }catch(IndexOutOfBoundsException e){ 283 * buf = new char[iter.getLength()]; 284 * } 285 * } 286 * </pre> 287 * 288 * @param fillIn 289 * an array of chars to fill with the underlying UTF-16 code units. 290 * @param offset 291 * the position within the array to start putting the data. 292 * @return the number of code units added to fillIn, as a convenience 293 * @exception IndexOutOfBoundsException 294 * exception if there is not enough room after offset in the array, or if offset < 0. 295 */ 296 public abstract int getText(char[] fillIn, int offset); 297 298 /** 299 * Convenience override for <code>getText(char[], int)</code> that provides an offset of 0. 300 * 301 * @param fillIn 302 * an array of chars to fill with the underlying UTF-16 code units. 303 * @return the number of code units added to fillIn, as a convenience 304 * @exception IndexOutOfBoundsException 305 * exception if there is not enough room in the array. 306 */ 307 public final int getText(char[] fillIn) { 308 return getText(fillIn, 0); 309 } 310 311 /** 312 * Convenience method for returning the underlying text storage as as string 313 * 314 * @return the underlying text storage in the iterator as a string 315 */ 316 public String getText() { 317 char[] text = new char[getLength()]; 318 getText(text); 319 return new String(text); 320 } 321 322 /** 323 * Moves the current position by the number of code units specified, either forward or backward depending on the 324 * sign of delta (positive or negative respectively). If the resulting index would be less than zero, the index is 325 * set to zero, and if the resulting index would be greater than limit, the index is set to limit. 326 * 327 * @param delta 328 * the number of code units to move the current index. 329 * @return the new index. 330 * @exception IndexOutOfBoundsException 331 * is thrown if an invalid index is supplied 332 * 333 */ 334 public int moveIndex(int delta) { 335 int x = Math.max(0, Math.min(getIndex() + delta, getLength())); 336 setIndex(x); 337 return x; 338 } 339 340 /** 341 * Moves the current position by the number of code points specified, either forward or backward depending on the 342 * sign of delta (positive or negative respectively). If the current index is at a trail surrogate then the first 343 * adjustment is by code unit, and the remaining adjustments are by code points. If the resulting index would be 344 * less than zero, the index is set to zero, and if the resulting index would be greater than limit, the index is 345 * set to limit. 346 * 347 * @param delta 348 * the number of code units to move the current index. 349 * @return the new index 350 * @exception IndexOutOfBoundsException 351 * is thrown if an invalid delta is supplied 352 */ 353 public int moveCodePointIndex(int delta) { 354 if (delta > 0) { 355 while (delta > 0 && nextCodePoint() != DONE) { 356 delta--; 357 } 358 } else { 359 while (delta < 0 && previousCodePoint() != DONE) { 360 delta++; 361 } 362 } 363 if (delta != 0) { 364 throw new IndexOutOfBoundsException(); 365 } 366 367 return getIndex(); 368 } 369 370 /** 371 * Creates a copy of this iterator, independent from other iterators. If it is not possible to clone the iterator, 372 * returns null. 373 * 374 * @return copy of this iterator 375 */ 376 @Override 377 public Object clone() throws CloneNotSupportedException { 378 return super.clone(); 379 } 380 381 } 382