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