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
41package 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 * @since 1.1
51 */
52
53public final class StringCharacterIterator implements CharacterIterator
54{
55    private String text;
56    private int begin;
57    private int end;
58    // invariant: begin <= pos <= end
59    private int pos;
60
61    /**
62     * Constructs an iterator with an initial index of 0.
63     *
64     * @param text the {@code String} to be iterated over
65     */
66    public StringCharacterIterator(String text)
67    {
68        this(text, 0);
69    }
70
71    /**
72     * Constructs an iterator with the specified initial index.
73     *
74     * @param  text   The String to be iterated over
75     * @param  pos    Initial iterator position
76     */
77    public StringCharacterIterator(String text, int pos)
78    {
79    this(text, 0, text.length(), pos);
80    }
81
82    /**
83     * Constructs an iterator over the given range of the given string, with the
84     * index set at the specified position.
85     *
86     * @param  text   The String to be iterated over
87     * @param  begin  Index of the first character
88     * @param  end    Index of the character following the last character
89     * @param  pos    Initial iterator position
90     */
91    public StringCharacterIterator(String text, int begin, int end, int pos) {
92        if (text == null)
93            throw new NullPointerException();
94        this.text = text;
95
96        if (begin < 0 || begin > end || end > text.length())
97            throw new IllegalArgumentException("Invalid substring range");
98
99        if (pos < begin || pos > end)
100            throw new IllegalArgumentException("Invalid position");
101
102        this.begin = begin;
103        this.end = end;
104        this.pos = pos;
105    }
106
107    /**
108     * Reset this iterator to point to a new string.  This package-visible
109     * method is used by other java.text classes that want to avoid allocating
110     * new StringCharacterIterator objects every time their setText method
111     * is called.
112     *
113     * @param  text   The String to be iterated over
114     * @since 1.2
115     */
116    public void setText(String text) {
117        if (text == null)
118            throw new NullPointerException();
119        this.text = text;
120        this.begin = 0;
121        this.end = text.length();
122        this.pos = 0;
123    }
124
125    /**
126     * Implements CharacterIterator.first() for String.
127     * @see CharacterIterator#first
128     */
129    public char first()
130    {
131        pos = begin;
132        return current();
133    }
134
135    /**
136     * Implements CharacterIterator.last() for String.
137     * @see CharacterIterator#last
138     */
139    public char last()
140    {
141        if (end != begin) {
142            pos = end - 1;
143        } else {
144            pos = end;
145        }
146        return current();
147     }
148
149    /**
150     * Implements CharacterIterator.setIndex() for String.
151     * @see CharacterIterator#setIndex
152     */
153    public char setIndex(int p)
154    {
155    if (p < begin || p > end)
156            throw new IllegalArgumentException("Invalid index");
157        pos = p;
158        return current();
159    }
160
161    /**
162     * Implements CharacterIterator.current() for String.
163     * @see CharacterIterator#current
164     */
165    public char current()
166    {
167        if (pos >= begin && pos < end) {
168            return text.charAt(pos);
169        }
170        else {
171            return DONE;
172        }
173    }
174
175    /**
176     * Implements CharacterIterator.next() for String.
177     * @see CharacterIterator#next
178     */
179    public char next()
180    {
181        if (pos < end - 1) {
182            pos++;
183            return text.charAt(pos);
184        }
185        else {
186            pos = end;
187            return DONE;
188        }
189    }
190
191    /**
192     * Implements CharacterIterator.previous() for String.
193     * @see CharacterIterator#previous
194     */
195    public char previous()
196    {
197        if (pos > begin) {
198            pos--;
199            return text.charAt(pos);
200        }
201        else {
202            return DONE;
203        }
204    }
205
206    /**
207     * Implements CharacterIterator.getBeginIndex() for String.
208     * @see CharacterIterator#getBeginIndex
209     */
210    public int getBeginIndex()
211    {
212        return begin;
213    }
214
215    /**
216     * Implements CharacterIterator.getEndIndex() for String.
217     * @see CharacterIterator#getEndIndex
218     */
219    public int getEndIndex()
220    {
221        return end;
222    }
223
224    /**
225     * Implements CharacterIterator.getIndex() for String.
226     * @see CharacterIterator#getIndex
227     */
228    public int getIndex()
229    {
230        return pos;
231    }
232
233    /**
234     * Compares the equality of two StringCharacterIterator objects.
235     * @param obj the StringCharacterIterator object to be compared with.
236     * @return true if the given obj is the same as this
237     * StringCharacterIterator object; false otherwise.
238     */
239    public boolean equals(Object obj)
240    {
241        if (this == obj)
242            return true;
243        if (!(obj instanceof StringCharacterIterator))
244            return false;
245
246        StringCharacterIterator that = (StringCharacterIterator) obj;
247
248        if (hashCode() != that.hashCode())
249            return false;
250        if (!text.equals(that.text))
251            return false;
252        if (pos != that.pos || begin != that.begin || end != that.end)
253            return false;
254        return true;
255    }
256
257    /**
258     * Computes a hashcode for this iterator.
259     * @return A hash code
260     */
261    public int hashCode()
262    {
263        return text.hashCode() ^ pos ^ begin ^ end;
264    }
265
266    /**
267     * Creates a copy of this iterator.
268     * @return A copy of this
269     */
270    public Object clone()
271    {
272        try {
273            StringCharacterIterator other
274            = (StringCharacterIterator) super.clone();
275            return other;
276        }
277        catch (CloneNotSupportedException e) {
278            throw new InternalError(e);
279        }
280    }
281
282}
283