5ebad5b3bbe9f4fe8ec890e0c87dcdc23ea27096
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpdt / internal / ui / text / DocumentCharacterIterator.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.text;
12
13 import java.text.CharacterIterator;
14
15 //incastrix
16 //import org.eclipse.jface.text.Assert;
17 import org.eclipse.core.runtime.Assert;
18 import org.eclipse.jface.text.BadLocationException;
19 import org.eclipse.jface.text.IDocument;
20
21 /**
22  * An <code>IDocument</code> based implementation of
23  * <code>CharacterIterator</code> and <code>CharSequence</code>. Note that
24  * the supplied document is not copied; if the document is modified during the
25  * lifetime of a <code>DocumentCharacterIterator</code>, the methods
26  * returning document content may not always return the same values. Also, if
27  * accessing the document fails with a {@link BadLocationException}, any of
28  * <code>CharacterIterator</code> methods as well as <code>charAt</code>may
29  * return {@link CharacterIterator#DONE}.
30  * 
31  * @since 3.0
32  */
33 public class DocumentCharacterIterator implements CharacterIterator,
34                 CharSequence {
35
36         private int fIndex = -1;
37
38         private final IDocument fDocument;
39
40         private final int fFirst;
41
42         private final int fLast;
43
44         private void invariant() {
45                 Assert.isTrue(fIndex >= fFirst);
46                 Assert.isTrue(fIndex <= fLast);
47         }
48
49         /**
50          * Creates an iterator for the entire document.
51          * 
52          * @param document
53          *            the document backing this iterator
54          */
55         public DocumentCharacterIterator(IDocument document) {
56                 this(document, 0);
57         }
58
59         /**
60          * Creates an iterator, starting at offset <code>first</code>.
61          * 
62          * @param document
63          *            the document backing this iterator
64          * @param first
65          *            the first character to consider
66          * @throws IllegalArgumentException
67          *             if the indices are out of bounds
68          */
69         public DocumentCharacterIterator(IDocument document, int first)
70                         throws IllegalArgumentException {
71                 this(document, first, document.getLength());
72         }
73
74         /**
75          * Creates an iterator for the document contents from <code>first</code>
76          * (inclusive) to <code>last</code> (exclusive).
77          * 
78          * @param document
79          *            the document backing this iterator
80          * @param first
81          *            the first character to consider
82          * @param last
83          *            the last character index to consider
84          * @throws IllegalArgumentException
85          *             if the indices are out of bounds
86          */
87         public DocumentCharacterIterator(IDocument document, int first, int last)
88                         throws IllegalArgumentException {
89                 if (document == null)
90                         throw new NullPointerException();
91                 if (first < 0 || first > last)
92                         throw new IllegalArgumentException();
93                 if (last > document.getLength())
94                         throw new IllegalArgumentException();
95                 fDocument = document;
96                 fFirst = first;
97                 fLast = last;
98                 fIndex = first;
99                 invariant();
100         }
101
102         /*
103          * @see java.text.CharacterIterator#first()
104          */
105         public char first() {
106                 return setIndex(getBeginIndex());
107         }
108
109         /*
110          * @see java.text.CharacterIterator#last()
111          */
112         public char last() {
113                 if (fFirst == fLast)
114                         return setIndex(getEndIndex());
115                 else
116                         return setIndex(getEndIndex() - 1);
117         }
118
119         /*
120          * @see java.text.CharacterIterator#current()
121          */
122         public char current() {
123                 if (fIndex >= fFirst && fIndex < fLast)
124                         try {
125                                 return fDocument.getChar(fIndex);
126                         } catch (BadLocationException e) {
127                                 // ignore
128                         }
129                 return DONE;
130         }
131
132         /*
133          * @see java.text.CharacterIterator#next()
134          */
135         public char next() {
136                 return setIndex(Math.min(fIndex + 1, getEndIndex()));
137         }
138
139         /*
140          * @see java.text.CharacterIterator#previous()
141          */
142         public char previous() {
143                 if (fIndex > getBeginIndex()) {
144                         return setIndex(fIndex - 1);
145                 } else {
146                         return DONE;
147                 }
148         }
149
150         /*
151          * @see java.text.CharacterIterator#setIndex(int)
152          */
153         public char setIndex(int position) {
154                 if (position >= getBeginIndex() && position <= getEndIndex())
155                         fIndex = position;
156                 else
157                         throw new IllegalArgumentException();
158
159                 invariant();
160                 return current();
161         }
162
163         /*
164          * @see java.text.CharacterIterator#getBeginIndex()
165          */
166         public int getBeginIndex() {
167                 return fFirst;
168         }
169
170         /*
171          * @see java.text.CharacterIterator#getEndIndex()
172          */
173         public int getEndIndex() {
174                 return fLast;
175         }
176
177         /*
178          * @see java.text.CharacterIterator#getIndex()
179          */
180         public int getIndex() {
181                 return fIndex;
182         }
183
184         /*
185          * @see java.text.CharacterIterator#clone()
186          */
187         public Object clone() {
188                 try {
189                         return super.clone();
190                 } catch (CloneNotSupportedException e) {
191                         throw new InternalError();
192                 }
193         }
194
195         /*
196          * @see java.lang.CharSequence#length()
197          */
198         public int length() {
199                 return getEndIndex() - getBeginIndex();
200         }
201
202         /**
203          * {@inheritDoc}
204          * <p>
205          * Note that, if the document is modified concurrently, this method may
206          * return {@link CharacterIterator#DONE} if a {@link BadLocationException}
207          * was thrown when accessing the backing document.
208          * </p>
209          * 
210          * @param index
211          *            {@inheritDoc}
212          * @return {@inheritDoc}
213          */
214         public char charAt(int index) {
215                 if (index >= 0 && index < length())
216                         try {
217                                 return fDocument.getChar(getBeginIndex() + index);
218                         } catch (BadLocationException e) {
219                                 // ignore and return DONE
220                                 return DONE;
221                         }
222                 else
223                         throw new IndexOutOfBoundsException();
224         }
225
226         /*
227          * @see java.lang.CharSequence#subSequence(int, int)
228          */
229         public CharSequence subSequence(int start, int end) {
230                 if (start < 0)
231                         throw new IndexOutOfBoundsException();
232                 if (end < start)
233                         throw new IndexOutOfBoundsException();
234                 if (end > length())
235                         throw new IndexOutOfBoundsException();
236                 return new DocumentCharacterIterator(fDocument,
237                                 getBeginIndex() + start, getBeginIndex() + end);
238         }
239 }