001    /* Segment.java --
002       Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package javax.swing.text;
039    
040    import java.text.CharacterIterator;
041    
042    /**
043     * A text fragment represented by a sequence of characters stored in an array.
044     */
045    public 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    }