001/* Segment.java --
002   Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038package javax.swing.text;
039
040import java.text.CharacterIterator;
041
042/**
043 * A text fragment represented by a sequence of characters stored in an array.
044 */
045public class Segment implements Cloneable, CharacterIterator
046{
047  private boolean partialReturn;
048
049  /** The current index. */
050  private int current;
051
052  /** Storage for the characters (may contain additional characters). */
053  public char[] array;
054
055  /** The number of characters in the segment. */
056  public int count;
057
058  /** The offset of the first character in the segment. */
059  public int offset;
060
061  /**
062   * Creates a new <code>Segment</code>.
063   */
064  public Segment()
065  {
066    // Nothing to do here.
067  }
068
069  /**
070   * Creates a new <code>Segment</code>.
071   *
072   * @param array  the underlying character data.
073   * @param offset  the offset of the first character in the segment.
074   * @param count  the number of characters in the segment.
075   */
076  public Segment(char[] array, int offset, int count)
077  {
078    this.array = array;
079    this.offset = offset;
080    this.count = count;
081  }
082
083  /**
084   * Clones the segment (note that the underlying character array is not cloned,
085   * just the reference to it).
086   *
087   * @return A clone of the segment.
088   */
089  public Object clone()
090  {
091    try
092      {
093        return super.clone();
094      }
095    catch (CloneNotSupportedException e)
096      {
097        return null;
098      }
099  }
100
101  /**
102   * Returns the character at the current index.  If the segment consists of
103   * zero characters, or the current index has passed the end of the
104   * characters in the segment, this method returns {@link #DONE}.
105   *
106   * @return The character at the current index.
107   */
108  public char current()
109  {
110    if (count == 0
111        || current >= getEndIndex())
112      return DONE;
113
114    return array[current];
115  }
116
117  /**
118   * Sets the current index to the first character in the segment and returns
119   * that character.  If the segment contains zero characters, this method
120   * returns {@link #DONE}.
121   *
122   * @return The first character in the segment, or {@link #DONE} if the
123   *         segment contains zero characters.
124   */
125  public char first()
126  {
127    if (count == 0)
128      return DONE;
129
130    current = getBeginIndex();
131    return array[current];
132  }
133
134  /**
135   * Returns the index of the first character in the segment.
136   *
137   * @return The index of the first character.
138   */
139  public int getBeginIndex()
140  {
141    return offset;
142  }
143
144  /**
145   * Returns the end index for the segment (one position beyond the last
146   * character in the segment - note that this can be outside the range of the
147   * underlying character array).
148   *
149   * @return The end index for the segment.
150   */
151  public int getEndIndex()
152  {
153    return offset + count;
154  }
155
156  /**
157   * Returns the index of the current character in the segment.
158   *
159   * @return The index of the current character.
160   */
161  public int getIndex()
162  {
163    return current;
164  }
165
166  /**
167   * Sets the current index to point to the last character in the segment and
168   * returns that character.  If the segment contains zero characters, the
169   * current index is set to {@link #getEndIndex()} and this method returns
170   * {@link #DONE}.
171   *
172   * @return The last character in the segment, or {@link #DONE} if the
173   *         segment contains zero characters.
174   */
175  public char last()
176  {
177    if (count == 0)
178      {
179        current = getEndIndex();
180        return DONE;
181      }
182
183    current = getEndIndex() - 1;
184    return array[current];
185  }
186
187  /**
188   * Sets the current index to point to the next character in the segment and
189   * returns that character.  If the next character position is past the end of
190   * the segment, the index is set to {@link #getEndIndex()} and the method
191   * returns {@link #DONE}.  If the segment contains zero characters, this
192   * method returns {@link #DONE}.
193   *
194   * @return The next character in the segment or {@link #DONE} (if the next
195   *         character position is past the end of the segment or if the
196   *         segment contains zero characters).
197   */
198  public char next()
199  {
200    if (count == 0)
201      return DONE;
202
203    if ((current + 1) >= getEndIndex())
204      {
205        current = getEndIndex();
206        return DONE;
207      }
208
209    current++;
210    return array[current];
211  }
212
213  /**
214   * Sets the current index to point to the previous character in the segment
215   * and returns that character.  If the current index is equal to
216   * {@link #getBeginIndex()}, or if the segment contains zero characters, this
217   * method returns {@link #DONE}.
218   *
219   * @return The previous character in the segment or {@link #DONE} (if the
220   *         current character position is at the beginning of the segment or
221   *         if the segment contains zero characters).
222   */
223  public char previous()
224  {
225    if (count == 0
226        || current == getBeginIndex())
227      return DONE;
228
229    current--;
230    return array[current];
231  }
232
233  /**
234   * Sets the current index and returns the character at that position (or
235   * {@link #DONE} if the index is equal to {@link #getEndIndex()}.
236   *
237   * @param position  the current position.
238   *
239   * @return The character at the specified <code>position</code>, or
240   *         {@link #DONE} if <code>position</code> is equal to
241   *         {@link #getEndIndex()}.
242   *
243   * @throws IllegalArgumentException if <code>position</code> is not in the
244   *         range {@link #getBeginIndex()} to {@link #getEndIndex()}.
245   */
246  public char setIndex(int position)
247  {
248    if (position < getBeginIndex()
249        || position > getEndIndex())
250      throw new IllegalArgumentException("position: " + position
251                                         + ", beginIndex: " + getBeginIndex()
252                                         + ", endIndex: " + getEndIndex()
253                                         + ", text: " + toString());
254
255    current = position;
256
257    if (position == getEndIndex())
258      return DONE;
259
260    return array[current];
261  }
262
263  /**
264   * Returns a <code>String</code> containing the same characters as this
265   * <code>Segment</code>.
266   *
267   * @return A <code>String</code> containing the same characters as this
268   *         <code>Segment</code>.
269   */
270  public String toString()
271  {
272    return (array != null) ? new String(array, offset, count) : "";
273  }
274
275  /**
276   * Sets the partial return flag.
277   *
278   * @param p  the new value of the flag.
279   *
280   * @since 1.4
281   */
282  public void setPartialReturn(boolean p)
283  {
284    partialReturn = p;
285  }
286
287  /**
288   * Returns the partial return flag.
289   *
290   * @return The partial return flag.
291   * @since 1.4
292   */
293  public boolean isPartialReturn()
294  {
295    return partialReturn;
296  }
297}