blob: 0186c900d4eb110586c62430692ceb56ccf536aa [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package javax.swing.text;
26
27import java.text.CharacterIterator;
28
29/**
30 * A segment of a character array representing a fragment
31 * of text. It should be treated as immutable even though
32 * the array is directly accessible. This gives fast access
33 * to fragments of text without the overhead of copying
34 * around characters. This is effectively an unprotected
35 * String.
36 * <p>
37 * The Segment implements the java.text.CharacterIterator
38 * interface to support use with the i18n support without
39 * copying text into a string.
40 *
41 * @author Timothy Prinzing
42 */
43public class Segment implements Cloneable, CharacterIterator, CharSequence {
44
45 /**
46 * This is the array containing the text of
47 * interest. This array should never be modified;
48 * it is available only for efficiency.
49 */
50 public char[] array;
51
52 /**
53 * This is the offset into the array that
54 * the desired text begins.
55 */
56 public int offset;
57
58 /**
59 * This is the number of array elements that
60 * make up the text of interest.
61 */
62 public int count;
63
64 private boolean partialReturn;
65
66 /**
67 * Creates a new segment.
68 */
69 public Segment() {
70 this(null, 0, 0);
71 }
72
73 /**
74 * Creates a new segment referring to an existing array.
75 *
76 * @param array the array to refer to
77 * @param offset the offset into the array
78 * @param count the number of characters
79 */
80 public Segment(char[] array, int offset, int count) {
81 this.array = array;
82 this.offset = offset;
83 this.count = count;
84 partialReturn = false;
85 }
86
87 /**
88 * Flag to indicate that partial returns are valid. If the flag is true,
89 * an implementation of the interface method Document.getText(position,length,Segment)
90 * should return as much text as possible without making a copy. The default
91 * state of the flag is false which will cause Document.getText(position,length,Segment)
92 * to provide the same return behavior it always had, which may or may not
93 * make a copy of the text depending upon the request.
94 *
95 * @param p whether or not partial returns are valid.
96 * @since 1.4
97 */
98 public void setPartialReturn(boolean p) {
99 partialReturn = p;
100 }
101
102 /**
103 * Flag to indicate that partial returns are valid.
104 *
105 * @return whether or not partial returns are valid.
106 * @since 1.4
107 */
108 public boolean isPartialReturn() {
109 return partialReturn;
110 }
111
112 /**
113 * Converts a segment into a String.
114 *
115 * @return the string
116 */
117 public String toString() {
118 if (array != null) {
119 return new String(array, offset, count);
120 }
121 return new String();
122 }
123
124 // --- CharacterIterator methods -------------------------------------
125
126 /**
127 * Sets the position to getBeginIndex() and returns the character at that
128 * position.
129 * @return the first character in the text, or DONE if the text is empty
130 * @see #getBeginIndex
131 * @since 1.3
132 */
133 public char first() {
134 pos = offset;
135 if (count != 0) {
136 return array[pos];
137 }
138 return DONE;
139 }
140
141 /**
142 * Sets the position to getEndIndex()-1 (getEndIndex() if the text is empty)
143 * and returns the character at that position.
144 * @return the last character in the text, or DONE if the text is empty
145 * @see #getEndIndex
146 * @since 1.3
147 */
148 public char last() {
149 pos = offset + count;
150 if (count != 0) {
151 pos -= 1;
152 return array[pos];
153 }
154 return DONE;
155 }
156
157 /**
158 * Gets the character at the current position (as returned by getIndex()).
159 * @return the character at the current position or DONE if the current
160 * position is off the end of the text.
161 * @see #getIndex
162 * @since 1.3
163 */
164 public char current() {
165 if (count != 0 && pos < offset + count) {
166 return array[pos];
167 }
168 return DONE;
169 }
170
171 /**
172 * Increments the iterator's index by one and returns the character
173 * at the new index. If the resulting index is greater or equal
174 * to getEndIndex(), the current index is reset to getEndIndex() and
175 * a value of DONE is returned.
176 * @return the character at the new position or DONE if the new
177 * position is off the end of the text range.
178 * @since 1.3
179 */
180 public char next() {
181 pos += 1;
182 int end = offset + count;
183 if (pos >= end) {
184 pos = end;
185 return DONE;
186 }
187 return current();
188 }
189
190 /**
191 * Decrements the iterator's index by one and returns the character
192 * at the new index. If the current index is getBeginIndex(), the index
193 * remains at getBeginIndex() and a value of DONE is returned.
194 * @return the character at the new position or DONE if the current
195 * position is equal to getBeginIndex().
196 * @since 1.3
197 */
198 public char previous() {
199 if (pos == offset) {
200 return DONE;
201 }
202 pos -= 1;
203 return current();
204 }
205
206 /**
207 * Sets the position to the specified position in the text and returns that
208 * character.
209 * @param position the position within the text. Valid values range from
210 * getBeginIndex() to getEndIndex(). An IllegalArgumentException is thrown
211 * if an invalid value is supplied.
212 * @return the character at the specified position or DONE if the specified position is equal to getEndIndex()
213 * @since 1.3
214 */
215 public char setIndex(int position) {
216 int end = offset + count;
217 if ((position < offset) || (position > end)) {
218 throw new IllegalArgumentException("bad position: " + position);
219 }
220 pos = position;
221 if ((pos != end) && (count != 0)) {
222 return array[pos];
223 }
224 return DONE;
225 }
226
227 /**
228 * Returns the start index of the text.
229 * @return the index at which the text begins.
230 * @since 1.3
231 */
232 public int getBeginIndex() {
233 return offset;
234 }
235
236 /**
237 * Returns the end index of the text. This index is the index of the first
238 * character following the end of the text.
239 * @return the index after the last character in the text
240 * @since 1.3
241 */
242 public int getEndIndex() {
243 return offset + count;
244 }
245
246 /**
247 * Returns the current index.
248 * @return the current index.
249 * @since 1.3
250 */
251 public int getIndex() {
252 return pos;
253 }
254
255 // --- CharSequence methods -------------------------------------
256
257 /**
258 * {@inheritDoc}
259 * @since 1.6
260 */
261 public char charAt(int index) {
262 if (index < 0
263 || index >= count) {
264 throw new StringIndexOutOfBoundsException(index);
265 }
266 return array[offset + index];
267 }
268
269 /**
270 * {@inheritDoc}
271 * @since 1.6
272 */
273 public int length() {
274 return count;
275 }
276
277 /**
278 * {@inheritDoc}
279 * @since 1.6
280 */
281 public CharSequence subSequence(int start, int end) {
282 if (start < 0) {
283 throw new StringIndexOutOfBoundsException(start);
284 }
285 if (end > count) {
286 throw new StringIndexOutOfBoundsException(end);
287 }
288 if (start > end) {
289 throw new StringIndexOutOfBoundsException(end - start);
290 }
291 Segment segment = new Segment();
292 segment.array = this.array;
293 segment.offset = this.offset + start;
294 segment.count = end - start;
295 return segment;
296 }
297
298 /**
299 * Creates a shallow copy.
300 *
301 * @return the copy
302 */
303 public Object clone() {
304 Object o;
305 try {
306 o = super.clone();
307 } catch (CloneNotSupportedException cnse) {
308 o = null;
309 }
310 return o;
311 }
312
313 private int pos;
314
315
316}