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