/[classpath]/classpath/javax/swing/text/GapContent.java
ViewVC logotype

Diff of /classpath/javax/swing/text/GapContent.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.17 by langel, Tue Aug 2 14:24:46 2005 UTC revision 1.18 by langel, Tue Aug 2 14:25:09 2005 UTC
# Line 46  import java.util.ListIterator; Line 46  import java.util.ListIterator;
46  import javax.swing.undo.UndoableEdit;  import javax.swing.undo.UndoableEdit;
47    
48  /**  /**
49   * This implementation of {@link AbstractDocument.Content} uses a gapped   * This implementation of {@link AbstractDocument.Content} uses a gapped buffer.
50   * buffer. This takes advantage of the fact that text area content is   * This takes advantage of the fact that text area content is mostly inserted
51   * mostly inserted sequentially. The buffer is a char array that maintains   * sequentially. The buffer is a char array that maintains a gap at the current
52   * a gap at the current insertion point. If characters a inserted at   * insertion point. If characters a inserted at gap boundaries, the cost is
53   * gap boundaries, the cost is minimal (simple array access). The array only   * minimal (simple array access). The array only has to be shifted around when
54   * has to be shifted around when the insertion point moves (then the gap also   * the insertion point moves (then the gap also moves and one array copy is
55   * moves and one array copy is necessary) or when the gap is filled up and   * necessary) or when the gap is filled up and the buffer has to be enlarged.
56   * the buffer has to be enlarged.   *
  *  
57   * TODO: Implement UndoableEdit support stuff   * TODO: Implement UndoableEdit support stuff
58   */   */
59  public class GapContent  public class GapContent
60    implements AbstractDocument.Content, Serializable        implements AbstractDocument.Content, Serializable
61  {  {
62    
63    /**     /**
64     * A {@link Position} implementation for <code>GapContent</code>.      * A {@link Position} implementation for <code>GapContent</code>.
65     */      */
66    class GapContentPosition implements Position, Comparable     class GapContentPosition
67    {           implements Position, Comparable
68       {
69      /** The index within the buffer array. */  
70      int mark;        /** The index within the buffer array. */
71          int mark;
72      /**  
73       * Creates a new GapContentPosition object.        /**
74       *         * Creates a new GapContentPosition object.
75       * @param mark the mark of this Position         *
76       */         * @param mark the mark of this Position
77      GapContentPosition(int mark)         */
78      {        GapContentPosition(int mark)
79        this.mark = mark;        {
80      }           this.mark = mark;
81          }
     /**  
      * Comparable interface implementation. This is used to store all  
      * positions in an ordered fashion.  
      *  
      * @param o the object to be compared to this  
      *  
      * @return a negative integer if this is less than <code>o</code>, zero  
      *         if both are equal or a positive integer if this is greater  
      *         than <code>o</code>  
      *  
      * @throws ClassCastException if <code>o</code> is not a GapContentPosition  
      *         or Integer object  
      */  
     public int compareTo(Object o)  
     {  
       if (o instanceof Integer)  
         {  
           int otherMark = ((Integer) o).intValue();  
           return mark - otherMark;  
         }  
       else  
         {  
           GapContentPosition other = (GapContentPosition) o;  
           return mark - other.mark;  
         }  
     }  
   
     /**  
      * Returns the current offset of this Position within the content.  
      *  
      * @return the current offset of this Position within the content.  
      */  
     public int getOffset()  
     {  
       if (mark <= gapStart)  
         return mark;  
       else  
         return mark - (gapEnd - gapStart);  
     }  
   }  
       
   private static final long serialVersionUID = 8374645204155842629L;  
   
   /**  
    * This is the default buffer size and the amount of bytes that  
    * a buffer is extended if it is full.  
    */  
   static final int DEFAULT_BUFSIZE = 64;  
   
   /**  
    * The text buffer.  
    */  
   char[] buffer;  
   
   /**  
    * The index of the first character of the gap.  
    */  
   int gapStart;  
   
   /**  
    * The index of the character after the last character of the gap.  
    */  
   int gapEnd;  
   
   /**  
    * The positions generated by this GapContent. They are kept in an  
    * ordered fashion, so they can be looked up easily.  
    */  
   LinkedList positions;  
   
   /**  
    * Creates a new GapContent object.  
    */  
   public GapContent()  
   {  
     this(DEFAULT_BUFSIZE);  
   }  
   
   /**  
    * Creates a new GapContent object with a specified initial size.  
    *  
    * @param size the initial size of the buffer  
    */  
   public GapContent(int size)  
   {  
     buffer = (char[]) allocateArray(size);  
     gapStart = 0;  
     gapEnd = size - 1;  
     buffer[size - 1] = '\n';  
     positions = new LinkedList();  
   }  
   
   /**  
    * Allocates an array of the specified length that can then be used as  
    * buffer.  
    *  
    * @param size the size of the array to be allocated  
    *  
    * @return the allocated array  
    */  
   protected Object allocateArray(int size)  
   {  
     return new char[size];  
   }  
   
   /**  
    * Returns the length of the allocated buffer array.  
    *  
    * @return the length of the allocated buffer array  
    */  
   protected int getArrayLength()  
   {  
     return buffer.length;  
   }  
   
   /**  
    * Returns the length of the content.  
    *  
    * @return the length of the content  
    */  
   public int length()  
   {  
     return buffer.length - (gapEnd - gapStart);  
   }  
   
   /**  
    * Inserts a string at the specified position.  
    *  
    * @param where the position where the string is inserted  
    * @param str the string that is to be inserted  
    *  
    * @return an UndoableEdit object (currently not supported, so  
    *         <code>null</code> is returned)  
    *  
    * @throws BadLocationException if <code>where</code> is not a valid location  
    *         in the buffer  
    */  
   public UndoableEdit insertString(int where, String str)  
     throws BadLocationException  
   {  
     // check arguments  
     int length = length();  
     int strLen = str.length();  
   
     if (where >= length)  
       throw new BadLocationException("the where argument cannot be greater"  
                                      + " than the content length", where);  
   
     // check if the gap is big enough to hold the string  
     if ((gapEnd - gapStart) < strLen)  
       // make room for this string and some more  
       shiftEnd(strLen + DEFAULT_BUFSIZE);  
   
     // are we at the gap boundary?  
     if (where != gapStart)  
       shiftGap(where);  
   
     // now we can simple copy the string into the gap and adjust the  
     // gap boundaries  
     System.arraycopy(str.toCharArray(), 0, buffer, gapStart, strLen);  
     gapStart += strLen;  
     return null;  
   }  
   
   /**  
    * Removes a piece of content at th specified position.  
    *  
    * @param where the position where the content is to be removed  
    * @param nitems number of characters to be removed  
    *  
    * @return an UndoableEdit object (currently not supported, so  
    *         <code>null</code> is returned)  
    *  
    * @throws BadLocationException if <code>where</code> is not a valid location  
    *         in the buffer  
    */  
   public UndoableEdit remove(int where, int nitems)  
     throws BadLocationException  
   {  
     // check arguments  
     int length = length();  
   
     if (where >= length)  
       throw new BadLocationException("the where argument cannot be greater"  
                                      + " than the content length", where);  
     if ((where + nitems) > length)  
       throw new BadLocationException("where + nitems cannot be greater"  
                                      + " than the content length",  
                                      where + nitems);  
   
     // check if we are at the gap boundary  
     if (where != gapStart)  
       shiftGap(where);  
   
     // now we simply have to enlarge the gap  
     gapEnd += nitems;  
     return null;  
   }  
   
   /**  
    * Returns a piece of content as String.  
    *  
    * @param where the start location of the fragment  
    * @param len the length of the fragment  
    *  
    * @throws BadLocationException if <code>where</code> or  
    *         <code>where + len</code> are no valid locations in the buffer  
    */  
   public String getString(int where, int len) throws BadLocationException  
   {  
     Segment seg = new Segment();  
     getChars(where, len, seg);  
     return new String(seg.array, seg.offset, seg.count);  
   }  
   
   /**  
    * Fetches a piece of content and stores it in a {@link Segment} object.  
    *  
    * If the requested piece of text spans the gap, the content is copied  
    * into a new array. If it doesn't then it is contiguous and the  
    * actual content store is returned.  
    *  
    * @param where the start location of the fragment  
    * @param len the length of the fragment  
    * @param txt the Segment object to store the fragment in  
    *  
    * @throws BadLocationException if <code>where</code> or  
    *         <code>where + len</code> are no valid locations in the buffer  
    */  
   public void getChars(int where, int len, Segment txt)  
     throws BadLocationException  
   {  
     // check arguments  
     int length = length();  
     if (where >= length)  
       throw new BadLocationException("the where argument cannot be greater"  
                                      + " than the content length", where);  
     if ((where + len) > length)  
       throw new BadLocationException("len plus where cannot be greater"  
                                      + " than the content length",  
                                      len + where);  
82    
83      // check if requested segment is contiguous        /**
84      if ((where < gapStart) && ((gapStart - where) < len))         * Comparable interface implementation. This is used to store all
85           * positions in an ordered fashion.
86           *
87           * @param o the object to be compared to this
88           *
89           * @return a negative integer if this is less than <code>o</code>, zero
90           *         if both are equal or a positive integer if this is greater than
91           *         <code>o</code>
92           *
93           * @throws ClassCastException if <code>o</code> is not a
94           *         GapContentPosition or Integer object
95           */
96          public int compareTo(Object o)
97        {        {
98          // requested segment is not contiguous -> copy the pieces together           if (o instanceof Integer)
99          char[] copy = new char[len];           {
100          int lenFirst = gapStart - where; // the length of the first segment              int otherMark = ((Integer) o).intValue();
101          System.arraycopy(buffer, where, copy, 0, lenFirst);              return mark - otherMark;
102          System.arraycopy(buffer, gapEnd, copy, lenFirst, len - lenFirst);           }
103          txt.array = copy;           else
104          txt.offset = 0;           {
105          txt.count = len;              GapContentPosition other = (GapContentPosition) o;
106                return mark - other.mark;
107             }
108        }        }
109      else  
110          /**
111           * Returns the current offset of this Position within the content.
112           *
113           * @return the current offset of this Position within the content.
114           */
115          public int getOffset()
116        {        {
117          // requested segment is contiguous -> we can simply return the           if (mark <= gapStart)
118          // actual content              return mark;
119          txt.array = buffer;           else
120          if (where < gapStart)              return mark - (gapEnd - gapStart);
           txt.offset = where;  
         else  
           txt.offset = where + (gapEnd - gapStart);  
         txt.count = len;  
121        }        }
122    }     }
123    
124       private static final long serialVersionUID = 8374645204155842629L;
125    
126       /**
127        * This is the default buffer size and the amount of bytes that a buffer is
128        * extended if it is full.
129        */
130       static final int DEFAULT_BUFSIZE = 64;
131    
132       /**
133        * The text buffer.
134        */
135       char[] buffer;
136    
137       /**
138        * The index of the first character of the gap.
139        */
140       int gapStart;
141    
142       /**
143        * The index of the character after the last character of the gap.
144        */
145       int gapEnd;
146    
147       /**
148        * The positions generated by this GapContent. They are kept in an ordered
149        * fashion, so they can be looked up easily.
150        */
151       LinkedList positions;
152    
153       /**
154        * Creates a new GapContent object.
155        */
156       public GapContent()
157       {
158          this(DEFAULT_BUFSIZE);
159       }
160    
161       /**
162        * Creates a new GapContent object with a specified initial size.
163        *
164        * @param size the initial size of the buffer
165        */
166       public GapContent(int size)
167       {
168          buffer = (char[]) allocateArray(size);
169          gapStart = 0;
170          gapEnd = size - 1;
171          buffer[size - 1] = '\n';
172          positions = new LinkedList();
173       }
174    
175       /**
176        * Allocates an array of the specified length that can then be used as
177        * buffer.
178        *
179        * @param size the size of the array to be allocated
180        *
181        * @return the allocated array
182        */
183       protected Object allocateArray(int size)
184       {
185          return new char[size];
186       }
187    
188       /**
189        * Returns the length of the allocated buffer array.
190        *
191        * @return the length of the allocated buffer array
192        */
193       protected int getArrayLength()
194       {
195          return buffer.length;
196       }
197    
198       /**
199        * Returns the length of the content.
200        *
201        * @return the length of the content
202        */
203       public int length()
204       {
205          return buffer.length - (gapEnd - gapStart);
206       }
207    
208       /**
209        * Inserts a string at the specified position.
210        *
211        * @param where the position where the string is inserted
212        * @param str the string that is to be inserted
213        *
214        * @return an UndoableEdit object (currently not supported, so
215        *         <code>null</code> is returned)
216        *
217        * @throws BadLocationException if <code>where</code> is not a valid
218        *         location in the buffer
219        */
220       public UndoableEdit insertString(int where, String str)
221             throws BadLocationException
222       {
223          // check arguments
224          int length = length();
225          int strLen = str.length();
226    
227          if (where >= length)
228             throw new BadLocationException("the where argument cannot be greater"
229                   + " than the content length", where);
230    
231          // check if the gap is big enough to hold the string
232          if ((gapEnd - gapStart) < strLen)
233             // make room for this string and some more
234             shiftEnd(strLen + DEFAULT_BUFSIZE);
235    
236          // are we at the gap boundary?
237          if (where != gapStart)
238             shiftGap(where);
239    
240          // now we can simple copy the string into the gap and adjust the
241          // gap boundaries
242          System.arraycopy(str.toCharArray(), 0, buffer, gapStart, strLen);
243          gapStart += strLen;
244          return null;
245       }
246    
247       /**
248        * Removes a piece of content at th specified position.
249        *
250        * @param where the position where the content is to be removed
251        * @param nitems number of characters to be removed
252        *
253        * @return an UndoableEdit object (currently not supported, so
254        *         <code>null</code> is returned)
255        *
256        * @throws BadLocationException if <code>where</code> is not a valid
257        *         location in the buffer
258        */
259       public UndoableEdit remove(int where, int nitems)
260             throws BadLocationException
261       {
262          // check arguments
263          int length = length();
264    
265          if (where >= length)
266             throw new BadLocationException("the where argument cannot be greater"
267                   + " than the content length", where);
268          if ((where + nitems) > length)
269             throw new BadLocationException("where + nitems cannot be greater"
270                   + " than the content length", where + nitems);
271    
272          // check if we are at the gap boundary
273          if (where != gapStart)
274             shiftGap(where);
275    
276          // now we simply have to enlarge the gap
277          gapEnd += nitems;
278          return null;
279       }
280    
281       /**
282        * Returns a piece of content as String.
283        *
284        * @param where the start location of the fragment
285        * @param len the length of the fragment
286        *
287        * @throws BadLocationException if <code>where</code> or
288        *         <code>where + len</code> are no valid locations in the buffer
289        */
290       public String getString(int where, int len) throws BadLocationException
291       {
292          Segment seg = new Segment();
293          getChars(where, len, seg);
294          return new String(seg.array, seg.offset, seg.count);
295       }
296    
297       /**
298        * Fetches a piece of content and stores it in a {@link Segment} object.
299        *
300        * If the requested piece of text spans the gap, the content is copied into a
301        * new array. If it doesn't then it is contiguous and the actual content
302        * store is returned.
303        *
304        * @param where the start location of the fragment
305        * @param len the length of the fragment
306        * @param txt the Segment object to store the fragment in
307        *
308        * @throws BadLocationException if <code>where</code> or
309        *         <code>where + len</code> are no valid locations in the buffer
310        */
311       public void getChars(int where, int len, Segment txt)
312             throws BadLocationException
313       {
314          // check arguments
315          int length = length();
316          if (where >= length)
317             throw new BadLocationException("the where argument cannot be greater"
318                   + " than the content length", where);
319          if ((where + len) > length)
320             throw new BadLocationException("len plus where cannot be greater"
321                   + " than the content length", len + where);
322    
323    /**        // check if requested segment is contiguous
324     * Creates and returns a mark at the specified position.        if ((where < gapStart) && ((gapStart - where) < len))
    *  
    * @param offset the position at which to create the mark  
    *  
    * @return the create Position object for the mark  
    *  
    * @throws BadLocationException if the offset is not a valid position in  
    *         the buffer  
    */  
   public Position createPosition(final int offset) throws BadLocationException  
   {  
     if (offset < 0 || offset > length())  
       throw new BadLocationException("The offset was out of the bounds of this"  
                                      + " buffer", offset);  
   
     // We store the actual array index in the GapContentPosition. The real  
     // offset is then calculated in the GapContentPosition.  
     int mark = offset;  
     if (offset > gapStart)  
       mark += gapEnd - gapStart;  
     GapContentPosition pos = new GapContentPosition(mark);  
   
     // Add this into our list in a sorted fashion.  
     int index = Collections.binarySearch(positions, pos);  
     if (index < 0)  
       index = -(index + 1);  
     positions.add(index, pos);  
       
     return pos;  
   }  
   
   /**  
    * Enlarges the gap. This allocates a new bigger buffer array, copy the  
    * segment before the gap as it is and the segment after the gap at  
    * the end of the new buffer array. This does change the gapEnd mark  
    * but not the gapStart mark.  
    *  
    * @param newSize the new size of the gap  
    */  
   protected void shiftEnd(int newSize)  
   {  
     int delta = (gapEnd - gapStart) - newSize;  
     char[] newBuf = (char[]) allocateArray(length() + newSize);  
     System.arraycopy(buffer, 0, newBuf, 0, gapStart);  
     System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize,  
                      buffer.length - gapEnd);  
     gapEnd = gapStart + newSize;  
     buffer = newBuf;  
   
     // Update the marks after the gapEnd.  
     int index = Collections.binarySearch(positions,  
                                          new GapContentPosition(gapEnd));  
     if (index < 0)  
325        {        {
326          index = -(index + 1);           // requested segment is not contiguous -> copy the pieces together
327             char[] copy = new char[len];
328             int lenFirst = gapStart - where; // the length of the first segment
329             System.arraycopy(buffer, where, copy, 0, lenFirst);
330             System.arraycopy(buffer, gapEnd, copy, lenFirst, len - lenFirst);
331             txt.array = copy;
332             txt.offset = 0;
333             txt.count = len;
334        }        }
335      for (ListIterator i = positions.listIterator(index); i.hasNext();)        else
336        {        {
337          GapContentPosition p = (GapContentPosition) i.next();           // requested segment is contiguous -> we can simply return the
338          p.mark += delta;           // actual content
339             txt.array = buffer;
340             if (where < gapStart)
341                txt.offset = where;
342             else
343                txt.offset = where + (gapEnd - gapStart);
344             txt.count = len;
345        }        }
346    }     }
347    
348    /**     /**
349     * Shifts the gap to the specified position.      * Creates and returns a mark at the specified position.
350     *      *
351     * @param newGapStart the new start position of the gap      * @param offset the position at which to create the mark
352     */      *
353    protected void shiftGap(int newGapStart)      * @return the create Position object for the mark
354    {      *
355      int newGapEnd = newGapStart + (gapEnd - gapStart);      * @throws BadLocationException if the offset is not a valid position in the
356        *         buffer
357        */
358      // Update the positions between newGapEnd and (old) gapEnd. The marks     public Position createPosition(final int offset) throws BadLocationException
359      // must be shifted by (gapEnd - newGapEnd).     {
360      int index1 = Collections.binarySearch(positions,        if (offset < 0 || offset > length())
361                                            new GapContentPosition(gapEnd));           throw new BadLocationException(
362      int index2 = Collections.binarySearch(positions,                 "The offset was out of the bounds of this" + " buffer", offset);
363                                            new GapContentPosition(newGapEnd));  
364  if (index1 > 0 || index2 > 0)        // We store the actual array index in the GapContentPosition. The real
365  {        // offset is then calculated in the GapContentPosition.
366      int i1 = Math.min(index1, index2);        int mark = offset;
367      int i2 = Math.max(index1, index2);        if (offset > gapStart)
368      for (ListIterator i = positions.listIterator(i1); i.hasNext();)           mark += gapEnd - gapStart;
369          GapContentPosition pos = new GapContentPosition(mark);
370    
371          // Add this into our list in a sorted fashion.
372          int index = Collections.binarySearch(positions, pos);
373          if (index < 0)
374             index = -(index + 1);
375          positions.add(index, pos);
376    
377          return pos;
378       }
379    
380       /**
381        * Enlarges the gap. This allocates a new bigger buffer array, copy the
382        * segment before the gap as it is and the segment after the gap at the end
383        * of the new buffer array. This does change the gapEnd mark but not the
384        * gapStart mark.
385        *
386        * @param newSize the new size of the gap
387        */
388       protected void shiftEnd(int newSize)
389       {
390          int delta = (gapEnd - gapStart) - newSize;
391          char[] newBuf = (char[]) allocateArray(length() + newSize);
392          System.arraycopy(buffer, 0, newBuf, 0, gapStart);
393          System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize,
394                buffer.length - gapEnd);
395          gapEnd = gapStart + newSize;
396          buffer = newBuf;
397    
398          // Update the marks after the gapEnd.
399          int index = Collections.binarySearch(positions, new GapContentPosition(
400                gapEnd));
401          if (index < 0)
402        {        {
403          if (i.nextIndex() > i2)           index = -(index + 1);
           break;  
   
         GapContentPosition p = (GapContentPosition) i.next();  
         p.mark += gapEnd - newGapEnd;  
404        }        }
405          for (ListIterator i = positions.listIterator(index); i.hasNext();)
     if (newGapStart == gapStart)  
       return;  
     else if (newGapStart < gapStart)  
406        {        {
407          System.arraycopy(buffer, newGapStart, buffer, newGapEnd,           GapContentPosition p = (GapContentPosition) i.next();
408                           gapStart - newGapStart);           p.mark += delta;
         gapStart = newGapStart;  
         gapEnd = newGapEnd;  
409        }        }
410      else     }
411    
412       /**
413        * Shifts the gap to the specified position.
414        *
415        * @param newGapStart the new start position of the gap
416        */
417       protected void shiftGap(int newGapStart)
418       {
419          int newGapEnd = newGapStart + (gapEnd - gapStart);
420    
421          // Update the positions between newGapEnd and (old) gapEnd. The marks
422          // must be shifted by (gapEnd - newGapEnd).
423          int index1 = Collections.binarySearch(positions, new GapContentPosition(
424                gapEnd));
425          int index2 = Collections.binarySearch(positions, new GapContentPosition(
426                newGapEnd));
427          if (index1 > 0 || index2 > 0)
428        {        {
429          System.arraycopy(buffer, gapEnd, buffer, gapStart,           int i1 = Math.min(index1, index2);
430                           newGapStart - gapStart);           int i2 = Math.max(index1, index2);
431          gapStart = newGapStart;           for (ListIterator i = positions.listIterator(i1); i.hasNext();)
432          gapEnd = newGapEnd;           {
433                if (i.nextIndex() > i2)
434                   break;
435    
436                GapContentPosition p = (GapContentPosition) i.next();
437                p.mark += gapEnd - newGapEnd;
438             }
439    
440             if (newGapStart == gapStart)
441                return;
442             else if (newGapStart < gapStart)
443             {
444                System.arraycopy(buffer, newGapStart, buffer, newGapEnd, gapStart
445                      - newGapStart);
446                gapStart = newGapStart;
447                gapEnd = newGapEnd;
448             }
449             else
450             {
451                System.arraycopy(buffer, gapEnd, buffer, gapStart, newGapStart
452                      - gapStart);
453                gapStart = newGapStart;
454                gapEnd = newGapEnd;
455             }
456        }        }
457  }     }
   }  
458    
459    /**     /**
460     * Returns the allocated buffer array.      * Returns the allocated buffer array.
461     *      *
462     * @return the allocated buffer array      * @return the allocated buffer array
463     */      */
464    protected Object getArray()     protected Object getArray()
465    {     {
466      return buffer;        return buffer;
467    }     }
468    
469    /**     /**
470     * Replaces a portion of the storage with the specified items.      * Replaces a portion of the storage with the specified items.
471     *      *
472     * @param position the position at which to remove items      * @param position the position at which to remove items
473     * @param rmSize the number of items to remove      * @param rmSize the number of items to remove
474     * @param addItems the items to add at location      * @param addItems the items to add at location
475     * @param addSize the number of items to add      * @param addSize the number of items to add
476     */      */
477    protected void replace(int position, int rmSize, Object addItems,     protected void replace(int position, int rmSize, Object addItems, int addSize)
478                           int addSize)     {
479    {        // Remove content
480      // Remove content        shiftGap(position);
481      shiftGap(position);        gapEnd += rmSize;
482      gapEnd += rmSize;  
483          // If gap is too small, enlarge the gap.
484      // If gap is too small, enlarge the gap.        if ((gapEnd - gapStart) < addSize)
485      if ((gapEnd - gapStart) < addSize)           shiftEnd(addSize);
486        shiftEnd(addSize);  
487          // Add new items to the buffer.
488      // Add new items to the buffer.        System.arraycopy(addItems, 0, buffer, gapStart, addSize);
489      System.arraycopy(addItems, 0, buffer, gapStart, addSize);        gapStart += addSize;
490      gapStart += addSize;     }
   }  
491  }  }

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.18

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26