1 /*
2  * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 /*
27  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28  * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
29  *
30  * The original version of this source code and documentation
31  * is copyrighted and owned by Taligent, Inc., a wholly-owned
32  * subsidiary of IBM. These materials are provided under terms
33  * of a License Agreement between Taligent and Sun. This technology
34  * is protected by multiple US and International patents.
35  *
36  * This notice and attribution to Taligent may not be removed.
37  * Taligent is a registered trademark of Taligent, Inc.
38  *
39  */
40 
41 package java.text;
42 
43 /**
44  * <code>StringCharacterIterator</code> implements the
45  * <code>CharacterIterator</code> protocol for a <code>String</code>.
46  * The <code>StringCharacterIterator</code> class iterates over the
47  * entire <code>String</code>.
48  *
49  * @see CharacterIterator
50  */
51 
52 public final class StringCharacterIterator implements CharacterIterator
53 {
54     private String text;
55     private int begin;
56     private int end;
57     // invariant: begin <= pos <= end
58     private int pos;
59 
60     /**
61      * Constructs an iterator with an initial index of 0.
62      *
63      * @param text the {@code String} to be iterated over
64      */
StringCharacterIterator(String text)65     public StringCharacterIterator(String text)
66     {
67         this(text, 0);
68     }
69 
70     /**
71      * Constructs an iterator with the specified initial index.
72      *
73      * @param  text   The String to be iterated over
74      * @param  pos    Initial iterator position
75      */
StringCharacterIterator(String text, int pos)76     public StringCharacterIterator(String text, int pos)
77     {
78     this(text, 0, text.length(), pos);
79     }
80 
81     /**
82      * Constructs an iterator over the given range of the given string, with the
83      * index set at the specified position.
84      *
85      * @param  text   The String to be iterated over
86      * @param  begin  Index of the first character
87      * @param  end    Index of the character following the last character
88      * @param  pos    Initial iterator position
89      */
StringCharacterIterator(String text, int begin, int end, int pos)90     public StringCharacterIterator(String text, int begin, int end, int pos) {
91         if (text == null)
92             throw new NullPointerException();
93         this.text = text;
94 
95         if (begin < 0 || begin > end || end > text.length())
96             throw new IllegalArgumentException("Invalid substring range");
97 
98         if (pos < begin || pos > end)
99             throw new IllegalArgumentException("Invalid position");
100 
101         this.begin = begin;
102         this.end = end;
103         this.pos = pos;
104     }
105 
106     /**
107      * Reset this iterator to point to a new string.  This package-visible
108      * method is used by other java.text classes that want to avoid allocating
109      * new StringCharacterIterator objects every time their setText method
110      * is called.
111      *
112      * @param  text   The String to be iterated over
113      * @since 1.2
114      */
setText(String text)115     public void setText(String text) {
116         if (text == null)
117             throw new NullPointerException();
118         this.text = text;
119         this.begin = 0;
120         this.end = text.length();
121         this.pos = 0;
122     }
123 
124     /**
125      * Implements CharacterIterator.first() for String.
126      * @see CharacterIterator#first
127      */
first()128     public char first()
129     {
130         pos = begin;
131         return current();
132     }
133 
134     /**
135      * Implements CharacterIterator.last() for String.
136      * @see CharacterIterator#last
137      */
last()138     public char last()
139     {
140         if (end != begin) {
141             pos = end - 1;
142         } else {
143             pos = end;
144         }
145         return current();
146      }
147 
148     /**
149      * Implements CharacterIterator.setIndex() for String.
150      * @see CharacterIterator#setIndex
151      */
setIndex(int p)152     public char setIndex(int p)
153     {
154     if (p < begin || p > end)
155             throw new IllegalArgumentException("Invalid index");
156         pos = p;
157         return current();
158     }
159 
160     /**
161      * Implements CharacterIterator.current() for String.
162      * @see CharacterIterator#current
163      */
current()164     public char current()
165     {
166         if (pos >= begin && pos < end) {
167             return text.charAt(pos);
168         }
169         else {
170             return DONE;
171         }
172     }
173 
174     /**
175      * Implements CharacterIterator.next() for String.
176      * @see CharacterIterator#next
177      */
next()178     public char next()
179     {
180         if (pos < end - 1) {
181             pos++;
182             return text.charAt(pos);
183         }
184         else {
185             pos = end;
186             return DONE;
187         }
188     }
189 
190     /**
191      * Implements CharacterIterator.previous() for String.
192      * @see CharacterIterator#previous
193      */
previous()194     public char previous()
195     {
196         if (pos > begin) {
197             pos--;
198             return text.charAt(pos);
199         }
200         else {
201             return DONE;
202         }
203     }
204 
205     /**
206      * Implements CharacterIterator.getBeginIndex() for String.
207      * @see CharacterIterator#getBeginIndex
208      */
getBeginIndex()209     public int getBeginIndex()
210     {
211         return begin;
212     }
213 
214     /**
215      * Implements CharacterIterator.getEndIndex() for String.
216      * @see CharacterIterator#getEndIndex
217      */
getEndIndex()218     public int getEndIndex()
219     {
220         return end;
221     }
222 
223     /**
224      * Implements CharacterIterator.getIndex() for String.
225      * @see CharacterIterator#getIndex
226      */
getIndex()227     public int getIndex()
228     {
229         return pos;
230     }
231 
232     /**
233      * Compares the equality of two StringCharacterIterator objects.
234      * @param obj the StringCharacterIterator object to be compared with.
235      * @return true if the given obj is the same as this
236      * StringCharacterIterator object; false otherwise.
237      */
equals(Object obj)238     public boolean equals(Object obj)
239     {
240         if (this == obj)
241             return true;
242         if (!(obj instanceof StringCharacterIterator))
243             return false;
244 
245         StringCharacterIterator that = (StringCharacterIterator) obj;
246 
247         if (hashCode() != that.hashCode())
248             return false;
249         if (!text.equals(that.text))
250             return false;
251         if (pos != that.pos || begin != that.begin || end != that.end)
252             return false;
253         return true;
254     }
255 
256     /**
257      * Computes a hashcode for this iterator.
258      * @return A hash code
259      */
hashCode()260     public int hashCode()
261     {
262         return text.hashCode() ^ pos ^ begin ^ end;
263     }
264 
265     /**
266      * Creates a copy of this iterator.
267      * @return A copy of this
268      */
clone()269     public Object clone()
270     {
271         try {
272             StringCharacterIterator other
273             = (StringCharacterIterator) super.clone();
274             return other;
275         }
276         catch (CloneNotSupportedException e) {
277             throw new InternalError(e);
278         }
279     }
280 
281 }
282