Frames | No Frames |
1: /* StringCharacterIterator.java -- Iterate over a character range in a string 2: Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.text; 40: 41: /** 42: * This class iterates over a range of characters in a <code>String</code>. 43: * For a given range of text, a beginning and ending index, 44: * as well as a current index are defined. These values can be queried 45: * by the methods in this interface. Additionally, various methods allow 46: * the index to be set. 47: * 48: * @author Aaron M. Renn (arenn@urbanophile.com) 49: * @author Tom Tromey (tromey@cygnus.com) 50: */ 51: public final class StringCharacterIterator implements CharacterIterator 52: { 53: /** 54: * This is the string to iterate over 55: */ 56: private String text; 57: 58: /** 59: * This is the value of the start position of the text range. 60: */ 61: private int begin; 62: 63: /** 64: * This is the value of the ending position of the text range. 65: */ 66: private int end; 67: 68: /** 69: * This is the current value of the scan index. 70: */ 71: private int index; 72: 73: /** 74: * This method initializes a new instance of 75: * <code>StringCharacterIterator</code> to iterate over the entire 76: * text of the specified <code>String</code>. The initial index 77: * value will be set to the first character in the string. 78: * 79: * @param text The <code>String</code> to iterate through (<code>null</code> 80: * not permitted). 81: * 82: * @throws NullPointerException if <code>text</code> is <code>null</code>. 83: */ 84: public StringCharacterIterator (String text) 85: { 86: this (text, 0, text.length (), 0); 87: } 88: 89: /*************************************************************************/ 90: 91: /** 92: * This method initializes a new instance of 93: * <code>StringCharacterIterator</code> to iterate over the entire 94: * text of the specified <code>String</code>. The initial index 95: * value will be set to the specified value. 96: * 97: * @param text The <code>String</code> to iterate through. 98: * @param index The initial index position. 99: */ 100: public StringCharacterIterator (String text, int index) 101: { 102: this (text, 0, text.length (), index); 103: } 104: 105: /*************************************************************************/ 106: 107: /** 108: * This method initializes a new instance of 109: * <code>StringCharacterIterator</code> that iterates over the text 110: * in a subrange of the specified <code>String</code>. The 111: * beginning and end of the range are specified by the caller, as is 112: * the initial index position. 113: * 114: * @param text The <code>String</code> to iterate through. 115: * @param begin The beginning position in the character range. 116: * @param end The ending position in the character range. 117: * @param index The initial index position. 118: * 119: * @throws IllegalArgumentException If any of the range values are 120: * invalid. 121: */ 122: public StringCharacterIterator (String text, int begin, int end, int index) 123: { 124: int len = text.length (); 125: 126: if ((begin < 0) || (begin > len)) 127: throw new IllegalArgumentException ("Bad begin position"); 128: 129: if ((end < begin) || (end > len)) 130: throw new IllegalArgumentException ("Bad end position"); 131: 132: if ((index < begin) || (index > end)) 133: throw new IllegalArgumentException ("Bad initial index position"); 134: 135: this.text = text; 136: this.begin = begin; 137: this.end = end; 138: this.index = index; 139: } 140: 141: /** 142: * This is a package level constructor that copies the text out of 143: * an existing StringCharacterIterator and resets the beginning and 144: * ending index. 145: * 146: * @param sci The StringCharacterIterator to copy the info from 147: * @param begin The beginning index of the range we are interested in. 148: * @param end The ending index of the range we are interested in. 149: */ 150: StringCharacterIterator (StringCharacterIterator sci, int begin, int end) 151: { 152: this (sci.text, begin, end, begin); 153: } 154: 155: /** 156: * This method returns the character at the current index position 157: * 158: * @return The character at the current index position. 159: */ 160: public char current () 161: { 162: return (index < end) ? text.charAt (index) : DONE; 163: } 164: 165: /*************************************************************************/ 166: 167: /** 168: * This method increments the current index and then returns the 169: * character at the new index value. If the index is already at 170: * <code>getEndIndex () - 1</code>, it will not be incremented. 171: * 172: * @return The character at the position of the incremented index 173: * value, or <code>DONE</code> if the index has reached 174: * getEndIndex () - 1. 175: */ 176: public char next () 177: { 178: if (index == end) 179: return DONE; 180: 181: ++index; 182: return current (); 183: } 184: 185: /*************************************************************************/ 186: 187: /** 188: * This method decrements the current index and then returns the 189: * character at the new index value. If the index value is already 190: * at the beginning index, it will not be decremented. 191: * 192: * @return The character at the position of the decremented index 193: * value, or <code>DONE</code> if index was already equal to the 194: * beginning index value. 195: */ 196: public char previous () 197: { 198: if (index == begin) 199: return DONE; 200: 201: --index; 202: return current (); 203: } 204: 205: /*************************************************************************/ 206: 207: /** 208: * This method sets the index value to the beginning of the range and returns 209: * the character there. 210: * 211: * @return The character at the beginning of the range, or 212: * <code>DONE</code> if the range is empty. 213: */ 214: public char first () 215: { 216: index = begin; 217: return current (); 218: } 219: 220: /*************************************************************************/ 221: 222: /** 223: * This method sets the index value to <code>getEndIndex () - 1</code> and 224: * returns the character there. If the range is empty, then the index value 225: * will be set equal to the beginning index. 226: * 227: * @return The character at the end of the range, or 228: * <code>DONE</code> if the range is empty. 229: */ 230: public char last () 231: { 232: if (end == begin) 233: return DONE; 234: 235: index = end - 1; 236: return current (); 237: } 238: 239: /*************************************************************************/ 240: 241: /** 242: * This method returns the current value of the index. 243: * 244: * @return The current index value 245: */ 246: public int getIndex () 247: { 248: return index; 249: } 250: 251: /*************************************************************************/ 252: 253: /** 254: * This method sets the value of the index to the specified value, then 255: * returns the character at that position. 256: * 257: * @param index The new index value. 258: * 259: * @return The character at the new index value or <code>DONE</code> 260: * if the index value is equal to <code>getEndIndex</code>. 261: * 262: * @exception IllegalArgumentException If the specified index is not valid 263: */ 264: public char setIndex (int index) 265: { 266: if ((index < begin) || (index > end)) 267: throw new IllegalArgumentException ("Bad index specified"); 268: 269: this.index = index; 270: return current (); 271: } 272: 273: /*************************************************************************/ 274: 275: /** 276: * This method returns the character position of the first character in the 277: * range. 278: * 279: * @return The index of the first character in the range. 280: */ 281: public int getBeginIndex () 282: { 283: return begin; 284: } 285: 286: /*************************************************************************/ 287: 288: /** 289: * This method returns the character position of the end of the text range. 290: * This will actually be the index of the first character following the 291: * end of the range. In the event the text range is empty, this will be 292: * equal to the first character in the range. 293: * 294: * @return The index of the end of the range. 295: */ 296: public int getEndIndex () 297: { 298: return end; 299: } 300: 301: /*************************************************************************/ 302: 303: /** 304: * This method creates a copy of this <code>CharacterIterator</code>. 305: * 306: * @return A copy of this <code>CharacterIterator</code>. 307: */ 308: public Object clone () 309: { 310: return new StringCharacterIterator (text, begin, end, index); 311: } 312: 313: /*************************************************************************/ 314: 315: /** 316: * This method tests this object for equality againt the specified 317: * object. This will be true if and only if the specified object: 318: * <p> 319: * <ul> 320: * <li>is not <code>null</code>.</li> 321: * <li>is an instance of <code>StringCharacterIterator</code></li> 322: * <li>has the same text as this object</li> 323: * <li>has the same beginning, ending, and current index as this object.</li> 324: * </ul> 325: * 326: * @param obj The object to test for equality against. 327: * 328: * @return <code>true</code> if the specified object is equal to this 329: * object, <code>false</code> otherwise. 330: */ 331: public boolean equals (Object obj) 332: { 333: if (! (obj instanceof StringCharacterIterator)) 334: return false; 335: 336: StringCharacterIterator sci = (StringCharacterIterator) obj; 337: 338: return (begin == sci.begin 339: && end == sci.end 340: && index == sci.index 341: && text.equals (sci.text)); 342: } 343: 344: /** 345: * Return the hash code for this object. 346: * @return the hash code 347: */ 348: public int hashCode() 349: { 350: // Incorporate all the data in a goofy way. 351: return begin ^ end ^ index ^ text.hashCode(); 352: } 353: 354: /*************************************************************************/ 355: 356: /** 357: * This method allows other classes in java.text to change the value 358: * of the underlying text being iterated through. 359: * 360: * @param text The new <code>String</code> to iterate through. 361: */ 362: public void setText (String text) 363: { 364: this.text = text; 365: this.begin = 0; 366: this.end = text.length (); 367: this.index = 0; 368: } 369: }