001 /* StringCharacterIterator.java -- Iterate over a character range in a string 002 Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package java.text; 040 041 /** 042 * This class iterates over a range of characters in a <code>String</code>. 043 * For a given range of text, a beginning and ending index, 044 * as well as a current index are defined. These values can be queried 045 * by the methods in this interface. Additionally, various methods allow 046 * the index to be set. 047 * 048 * @author Aaron M. Renn (arenn@urbanophile.com) 049 * @author Tom Tromey (tromey@cygnus.com) 050 */ 051 public final class StringCharacterIterator implements CharacterIterator 052 { 053 /** 054 * This is the string to iterate over 055 */ 056 private String text; 057 058 /** 059 * This is the value of the start position of the text range. 060 */ 061 private int begin; 062 063 /** 064 * This is the value of the ending position of the text range. 065 */ 066 private int end; 067 068 /** 069 * This is the current value of the scan index. 070 */ 071 private int index; 072 073 /** 074 * This method initializes a new instance of 075 * <code>StringCharacterIterator</code> to iterate over the entire 076 * text of the specified <code>String</code>. The initial index 077 * value will be set to the first character in the string. 078 * 079 * @param text The <code>String</code> to iterate through (<code>null</code> 080 * not permitted). 081 * 082 * @throws NullPointerException if <code>text</code> is <code>null</code>. 083 */ 084 public StringCharacterIterator (String text) 085 { 086 this (text, 0, text.length (), 0); 087 } 088 089 /*************************************************************************/ 090 091 /** 092 * This method initializes a new instance of 093 * <code>StringCharacterIterator</code> to iterate over the entire 094 * text of the specified <code>String</code>. The initial index 095 * value will be set to the specified value. 096 * 097 * @param text The <code>String</code> to iterate through. 098 * @param index The initial index position. 099 */ 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 }