Index: javax/swing/text/GapContent.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/text/GapContent.java,v retrieving revision 1.25 diff -u -r1.25 GapContent.java --- javax/swing/text/GapContent.java 8 Sep 2005 09:54:30 -0000 1.25 +++ javax/swing/text/GapContent.java 13 Sep 2005 23:21:49 -0000 @@ -41,7 +41,9 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.ListIterator; +import java.util.Vector; import javax.swing.undo.UndoableEdit; @@ -114,7 +116,9 @@ public int getOffset() { // Check precondition. - assert(mark <= gapStart || mark > gapEnd); + assert mark <= gapStart || mark > gapEnd : "mark: " + mark + + ", gapStart: " + gapStart + + ", gapEnd: " + gapEnd; if (mark <= gapStart) return mark; @@ -130,7 +134,7 @@ * 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; + static final int DEFAULT_BUFSIZE = 10; /** * The text buffer. @@ -169,9 +173,9 @@ public GapContent(int size) { buffer = (char[]) allocateArray(size); - gapStart = 0; - gapEnd = size - 1; - buffer[size - 1] = '\n'; + gapStart = 1; + gapEnd = size; + buffer[0] = '\n'; positions = new ArrayList(); } @@ -389,7 +393,19 @@ */ protected void shiftEnd(int newSize) { - int delta = (gapEnd - gapStart) - newSize; + assert newSize > (gapEnd - gapStart) : "The new gap size must be greater " + + "than the old gap size"; + + int delta = newSize - gapEnd + gapStart; + // Update the marks after the gapEnd. + Vector v = getPositionsInRange(null, gapEnd, buffer.length - gapEnd); + for (Iterator i = v.iterator(); i.hasNext();) + { + GapContentPosition p = (GapContentPosition) i.next(); + p.mark += delta; + } + + // Copy the data around. char[] newBuf = (char[]) allocateArray(length() + newSize); System.arraycopy(buffer, 0, newBuf, 0, gapStart); System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize, buffer.length @@ -397,18 +413,6 @@ gapEnd = gapStart + newSize; buffer = newBuf; - // Update the marks after the gapEnd. - int index = Collections.binarySearch(positions, new GapContentPosition( - gapEnd)); - if (index < 0) - { - index = -(index + 1); - } - for (ListIterator i = positions.listIterator(index); i.hasNext();) - { - GapContentPosition p = (GapContentPosition) i.next(); - p.mark += delta; - } } /** @@ -421,30 +425,19 @@ if (newGapStart == gapStart) return; - int newGapEnd = newGapStart + (gapEnd - gapStart); + int newGapEnd = newGapStart + gapEnd - gapStart; - // Update the positions between newGapEnd and (old) gapEnd. The marks - // must be shifted by (gapEnd - newGapEnd). - int index1 = Collections.binarySearch(positions, - new GapContentPosition(gapEnd)); - int index2 = Collections.binarySearch(positions, - new GapContentPosition(newGapEnd)); - if (index1 > 0 && index2 > 0) + if (newGapStart < gapStart) { - int i1 = Math.min(index1, index2); - int i2 = Math.max(index1, index2); - for (ListIterator i = positions.listIterator(i1); i.hasNext();) + // Update the positions between newGapStart and (old) gapStart. The marks + // must be shifted by (gapEnd - gapStart). + Vector v = getPositionsInRange(null, newGapStart + 1, + gapStart - newGapStart + 1); + for (Iterator i = v.iterator(); i.hasNext();) { - if (i.nextIndex() > i2) - break; - GapContentPosition p = (GapContentPosition) i.next(); - p.mark += gapEnd - newGapEnd; + p.mark += gapEnd - gapStart; } - } - - if (newGapStart < gapStart) - { System.arraycopy(buffer, newGapStart, buffer, newGapEnd, gapStart - newGapStart); gapStart = newGapStart; @@ -452,6 +445,15 @@ } else { + // Update the positions between newGapEnd and (old) gapEnd. The marks + // must be shifted by (gapEnd - gapStart). + Vector v = getPositionsInRange(null, gapEnd, + newGapEnd - gapEnd); + for (Iterator i = v.iterator(); i.hasNext();) + { + GapContentPosition p = (GapContentPosition) i.next(); + p.mark -= gapEnd - gapStart; + } System.arraycopy(buffer, gapEnd, buffer, gapStart, newGapStart - gapStart); gapStart = newGapStart; @@ -460,6 +462,54 @@ } /** + * Shifts the gap start downwards. This does not affect the content of the + * buffer. This only updates the gap start and all the marks that are between + * the old gap start and the new gap start. They all are squeezed to the start + * of the gap, because their location has been removed. + * + * @param newGapStart the new gap start + */ + protected void shiftGapStartDown(int newGapStart) + { + if (newGapStart == gapStart) + return; + + assert newGapStart < gapStart : "The new gap start must be less than the " + + "old gap start."; + Vector v = getPositionsInRange(null, newGapStart, gapStart - newGapStart); + for (Iterator i = v.iterator(); i.hasNext();) + { + GapContentPosition p = (GapContentPosition) i.next(); + p.mark = gapStart; + } + gapStart = newGapStart; + } + + /** + * Shifts the gap end upwards. This does not affect the content of the + * buffer. This only updates the gap end and all the marks that are between + * the old gap end and the new end start. They all are squeezed to the end + * of the gap, because their location has been removed. + * + * @param newGapEnd the new gap start + */ + protected void shiftGapEndUp(int newGapEnd) + { + if (newGapEnd == gapEnd) + return; + + assert newGapEnd > gapEnd : "The new gap end must be greater than the " + + "old gap end."; + Vector v = getPositionsInRange(null, gapEnd, newGapEnd - gapEnd); + for (Iterator i = v.iterator(); i.hasNext();) + { + GapContentPosition p = (GapContentPosition) i.next(); + p.mark = newGapEnd + 1; + } + gapEnd = newGapEnd; + } + + /** * Returns the allocated buffer array. * * @return the allocated buffer array @@ -482,11 +532,11 @@ { // Remove content shiftGap(position); - gapEnd += rmSize; + shiftGapEndUp(gapEnd + rmSize); // If gap is too small, enlarge the gap. - if ((gapEnd - gapStart) < addSize) - shiftEnd(addSize); + if ((gapEnd - gapStart) <= addSize) + shiftEnd((addSize - gapEnd + gapStart + 1) * 2 + gapEnd + DEFAULT_BUFSIZE); // Add new items to the buffer. if (addItems != null) @@ -494,5 +544,65 @@ System.arraycopy(addItems, 0, buffer, gapStart, addSize); gapStart += addSize; } + } + + /** + * Returns the start index of the gap within the buffer array. + * + * @return the start index of the gap within the buffer array + */ + protected final int getGapStart() + { + return gapStart; + } + + /** + * Returns the end index of the gap within the buffer array. + * + * @return the end index of the gap within the buffer array + */ + protected final int getGapEnd() + { + return gapEnd; + } + + /** + * Returns all Positions that are in the range specified by + * offset and length within the buffer array. + * + * @param v the vector to use; if null, a new Vector is allocated + * @param offset the start offset of the range to search + * @param length the length of the range to search + * + * @return the positions within the specified range + */ + protected Vector getPositionsInRange(Vector v, int offset, int length) + { + Vector res = v; + if (res == null) + res = new Vector(); + else + res.clear(); + + int endOffset = offset + length; + + int index1 = Collections.binarySearch(positions, + new GapContentPosition(offset)); + int index2 = Collections.binarySearch(positions, + new GapContentPosition(endOffset)); + if (index1 < 0) + index1 = -(index1 + 1); + if (index2 < 0) + index2 = -(index2 + 1); + for (ListIterator i = positions.listIterator(index1); i.hasNext();) + { + if (i.nextIndex() > index2) + break; + + GapContentPosition p = (GapContentPosition) i.next(); + if (p.mark >= offset && p.mark <= endOffset) + res.add(p); + } + return res; } }