1 /* StringCharacterIterator.java -- Iterate over a character range in a string
2    Copyright (C) 1998, 1999, 2001 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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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.
80    */
StringCharacterIterator(String text)81   public StringCharacterIterator (String text)
82   {
83     this (text, 0, text.length (), 0);
84   }
85 
86   /*************************************************************************/
87 
88   /**
89    * This method initializes a new instance of
90    * <code>StringCharacterIterator</code> to iterate over the entire
91    * text of the specified <code>String</code>.  The initial index
92    * value will be set to the specified value.
93    *
94    * @param text The <code>String</code> to iterate through.
95    * @param index The initial index position.
96    */
StringCharacterIterator(String text, int index)97   public StringCharacterIterator (String text, int index)
98   {
99     this (text, 0, text.length (), index);
100   }
101 
102   /*************************************************************************/
103 
104   /**
105    * This method initializes a new instance of
106    * <code>StringCharacterIterator</code> that iterates over the text
107    * in a subrange of the specified <code>String</code>.  The
108    * beginning and end of the range are specified by the caller, as is
109    * the initial index position.
110    *
111    * @param text The <code>String</code> to iterate through.
112    * @param begin The beginning position in the character range.
113    * @param end The ending position in the character range.
114    * @param index The initial index position.
115    *
116    * @param IllegalArgumentException If any of the range values are
117    * invalid.
118    */
StringCharacterIterator(String text, int begin, int end, int index)119   public StringCharacterIterator (String text, int begin, int end, int index)
120   {
121     int len = text.length ();
122 
123     if ((begin < 0) || (begin > len))
124       throw new IllegalArgumentException ("Bad begin position");
125 
126     if ((end < begin) || (end > len))
127       throw new IllegalArgumentException ("Bad end position");
128 
129     if ((index < begin) || (index > end))
130       throw new IllegalArgumentException ("Bad initial index position");
131 
132     this.text = text;
133     this.begin = begin;
134     this.end = end;
135     this.index = index;
136   }
137 
138   /**
139    * This is a package level constructor that copies the text out of
140    * an existing StringCharacterIterator and resets the beginning and
141    * ending index.
142    *
143    * @param scci The StringCharacterIterator to copy the info from
144    * @param begin The beginning index of the range we are interested in.
145    * @param end The ending index of the range we are interested in.
146    */
StringCharacterIterator(StringCharacterIterator sci, int begin, int end)147   StringCharacterIterator (StringCharacterIterator sci, int begin, int end)
148   {
149     this (sci.text, begin, end, begin);
150   }
151 
152   /**
153    * This method returns the character at the current index position
154    *
155    * @return The character at the current index position.
156    */
current()157   public char current ()
158   {
159     return (index < end) ? text.charAt (index) : DONE;
160   }
161 
162   /*************************************************************************/
163 
164   /**
165    * This method increments the current index and then returns the
166    * character at the new index value.  If the index is already at
167    * <code>getEndIndex () - 1</code>, it will not be incremented.
168    *
169    * @return The character at the position of the incremented index
170    * value, or <code>DONE</code> if the index has reached
171    * getEndIndex () - 1.
172    */
next()173   public char next ()
174   {
175     if (index == end)
176       return DONE;
177 
178     ++index;
179     return current ();
180   }
181 
182   /*************************************************************************/
183 
184   /**
185    * This method decrements the current index and then returns the
186    * character at the new index value.  If the index value is already
187    * at the beginning index, it will not be decremented.
188    *
189    * @return The character at the position of the decremented index
190    * value, or <code>DONE</code> if index was already equal to the
191    * beginning index value.
192    */
previous()193   public char previous ()
194   {
195     if (index == begin)
196       return DONE;
197 
198     --index;
199     return current ();
200   }
201 
202   /*************************************************************************/
203 
204   /**
205    * This method sets the index value to the beginning of the range and returns
206    * the character there.
207    *
208    * @return The character at the beginning of the range, or
209    * <code>DONE</code> if the range is empty.
210    */
first()211   public char first ()
212   {
213     index = begin;
214     return current ();
215   }
216 
217   /*************************************************************************/
218 
219   /**
220    * This method sets the index value to <code>getEndIndex () - 1</code> and
221    * returns the character there.  If the range is empty, then the index value
222    * will be set equal to the beginning index.
223    *
224    * @return The character at the end of the range, or
225    * <code>DONE</code> if the range is empty.
226    */
last()227   public char last ()
228   {
229     if (end == begin)
230       return DONE;
231 
232     index = end - 1;
233     return current ();
234   }
235 
236   /*************************************************************************/
237 
238   /**
239    * This method returns the current value of the index.
240    *
241    * @return The current index value
242    */
getIndex()243   public int getIndex ()
244   {
245     return index;
246   }
247 
248   /*************************************************************************/
249 
250   /**
251    * This method sets the value of the index to the specified value, then
252    * returns the character at that position.
253    *
254    * @param index The new index value.
255    *
256    * @return The character at the new index value or <code>DONE</code>
257    * if the index value is equal to <code>getEndIndex</code>.
258    *
259    * @exception IllegalArgumentException If the specified index is not valid
260    */
setIndex(int index)261   public char setIndex (int index)
262   {
263     if ((index < begin) || (index > end))
264       throw new IllegalArgumentException ("Bad index specified");
265 
266     this.index = index;
267     return current ();
268   }
269 
270   /*************************************************************************/
271 
272   /**
273    * This method returns the character position of the first character in the
274    * range.
275    *
276    * @return The index of the first character in the range.
277    */
getBeginIndex()278   public int getBeginIndex ()
279   {
280     return begin;
281   }
282 
283   /*************************************************************************/
284 
285   /**
286    * This method returns the character position of the end of the text range.
287    * This will actually be the index of the first character following the
288    * end of the range.  In the event the text range is empty, this will be
289    * equal to the first character in the range.
290    *
291    * @return The index of the end of the range.
292    */
getEndIndex()293   public int getEndIndex ()
294   {
295     return end;
296   }
297 
298   /*************************************************************************/
299 
300   /**
301    * This method creates a copy of this <code>CharacterIterator</code>.
302    *
303    * @return A copy of this <code>CharacterIterator</code>.
304    */
clone()305   public Object clone ()
306   {
307     return new StringCharacterIterator (text, begin, end, index);
308   }
309 
310   /*************************************************************************/
311 
312   /**
313    * This method tests this object for equality againt the specified
314    * object.  This will be true if and only if the specified object:
315    * <p>
316    * <ul>
317    * <li>is not <code>null</code>.
318    * <li>is an instance of <code>StringCharacterIterator</code>
319    * <li>has the same text as this object
320    * <li>has the same beginning, ending, and current index as this object.
321    * </ul>
322    *
323    * @param obj The object to test for equality against.
324    *
325    * @return <code>true</code> if the specified object is equal to this
326    * object, <code>false</code> otherwise.
327    */
equals(Object obj)328   public boolean equals (Object obj)
329   {
330     if (! (obj instanceof StringCharacterIterator))
331       return false;
332 
333     StringCharacterIterator sci = (StringCharacterIterator) obj;
334 
335     return (begin == sci.begin
336 	    && end == sci.end
337 	    && index == sci.index
338 	    && text.equals (sci.text));
339   }
340 
341   /*************************************************************************/
342 
343   /**
344    * This method allows other classes in java.text to change the value
345    * of the underlying text being iterated through.
346    *
347    * @param text The new <code>String</code> to iterate through.
348    */
setText(String text)349   public void setText (String text)
350   {
351     this.text = text;
352     this.begin = 0;
353     this.end = text.length ();
354     this.index = 0;
355   }
356 }
357