Source for java.text.StringCharacterIterator

   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: }