diff options
Diffstat (limited to 'libjava/classpath/javax/swing/text/GapContent.java')
-rw-r--r-- | libjava/classpath/javax/swing/text/GapContent.java | 167 |
1 files changed, 136 insertions, 31 deletions
diff --git a/libjava/classpath/javax/swing/text/GapContent.java b/libjava/classpath/javax/swing/text/GapContent.java index 80dcfa56e06..28d1d6ee01f 100644 --- a/libjava/classpath/javax/swing/text/GapContent.java +++ b/libjava/classpath/javax/swing/text/GapContent.java @@ -1,5 +1,5 @@ /* GapContent.java -- - Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -39,8 +39,10 @@ exception statement from your version. */ package javax.swing.text; import java.io.Serializable; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.Iterator; import java.util.ListIterator; import java.util.Vector; @@ -68,8 +70,8 @@ public class GapContent /** * A {@link Position} implementation for <code>GapContent</code>. */ - class GapContentPosition - implements Position, Comparable + private class GapContentPosition + implements Position, Comparable { /** The index within the buffer array. */ @@ -130,7 +132,7 @@ public class GapContent } } - class InsertUndo extends AbstractUndoableEdit + private class InsertUndo extends AbstractUndoableEdit { public int where, length; String text; @@ -169,7 +171,7 @@ public class GapContent } - class UndoRemove extends AbstractUndoableEdit + private class UndoRemove extends AbstractUndoableEdit { public int where; String text; @@ -206,7 +208,41 @@ public class GapContent } } - + + /** + * Compares WeakReference objects in a List by comparing the referenced + * objects instead. + * + * @author Roman Kennke (kennke@aicas.com) + */ + private class WeakPositionComparator + implements Comparator + { + + /** + * Compares two objects of type WeakReference. The objects are compared + * using the referenced objects compareTo() method. + */ + public int compare(Object o1, Object o2) + { + // Unwrap references. + if (o1 instanceof WeakReference) + o1 = ((WeakReference) o1).get(); + if (o2 instanceof WeakReference) + o2 = ((WeakReference) o2).get(); + + GapContentPosition p1 = (GapContentPosition) o1; + GapContentPosition p2 = (GapContentPosition) o2; + + int retVal; + if (p1 == null || p2 == null) + retVal = -1; + else + retVal = p1.compareTo(p2); + return retVal; + } + } + /** The serialization UID (compatible with JDK1.5). */ private static final long serialVersionUID = -6226052713477823730L; @@ -233,9 +269,10 @@ public class GapContent /** * The positions generated by this GapContent. They are kept in an ordered - * fashion, so they can be looked up easily. + * fashion, so they can be looked up easily. The value objects will be + * WeakReference objects that in turn hold GapContentPosition objects. */ - ArrayList positions; + private ArrayList positions; /** * Creates a new GapContent object. @@ -310,8 +347,12 @@ public class GapContent int length = length(); int strLen = str.length(); + if (where < 0) + throw new BadLocationException("The where argument cannot be smaller" + + " than the zero", where); + if (where >= length) - throw new BadLocationException("the where argument cannot be greater" + throw new BadLocationException("The where argument cannot be greater" + " than the content length", where); replace(where, 0, str.toCharArray(), strLen); @@ -446,18 +487,22 @@ public class GapContent throw new BadLocationException("The offset was out of the bounds of this" + " buffer", offset); + clearPositionReferences(); + // 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); + WeakReference r = new WeakReference(pos); // Add this into our list in a sorted fashion. - int index = Collections.binarySearch(positions, pos); + int index = Collections.binarySearch(positions, r, + new WeakPositionComparator()); if (index < 0) index = -(index + 1); - positions.add(index, pos); + positions.add(index, r); return pos; } @@ -557,7 +602,7 @@ public class GapContent assert newGapEnd > gapEnd : "The new gap end must be greater than the " + "old gap end."; - setPositionsInRange(gapEnd, newGapEnd - gapEnd, newGapEnd + 1); + setPositionsInRange(gapEnd, newGapEnd - gapEnd, newGapEnd); gapEnd = newGapEnd; } @@ -566,7 +611,7 @@ public class GapContent * * @return the allocated buffer array */ - protected Object getArray() + protected final Object getArray() { return buffer; } @@ -642,19 +687,30 @@ public class GapContent int endOffset = offset + length; int index1 = Collections.binarySearch(positions, - new GapContentPosition(offset)); + new GapContentPosition(offset), + new WeakPositionComparator()); if (index1 < 0) index1 = -(index1 + 1); // Search the first index with the specified offset. The binarySearch does // not necessarily find the first one. - while (index1 > 0 - && ((GapContentPosition) positions.get(index1 - 1)).mark == offset) - index1--; + while (index1 > 0) + { + WeakReference r = (WeakReference) positions.get(index1 - 1); + GapContentPosition p = (GapContentPosition) r.get(); + if (p != null && p.mark == offset || p == null) + index1--; + else + break; + } for (ListIterator i = positions.listIterator(index1); i.hasNext();) { - GapContentPosition p = (GapContentPosition) i.next(); + WeakReference r = (WeakReference) i.next(); + GapContentPosition p = (GapContentPosition) r.get(); + if (p == null) + continue; + if (p.mark > endOffset) break; if (p.mark >= offset && p.mark <= endOffset) @@ -672,24 +728,35 @@ public class GapContent * @param length the length of the range to search * @param value the new value for each mark */ - void setPositionsInRange(int offset, int length, int value) + private void setPositionsInRange(int offset, int length, int value) { int endOffset = offset + length; int index1 = Collections.binarySearch(positions, - new GapContentPosition(offset)); + new GapContentPosition(offset), + new WeakPositionComparator()); if (index1 < 0) index1 = -(index1 + 1); // Search the first index with the specified offset. The binarySearch does // not necessarily find the first one. - while (index1 > 0 - && ((GapContentPosition) positions.get(index1 - 1)).mark == offset) - index1--; + while (index1 > 0) + { + WeakReference r = (WeakReference) positions.get(index1 - 1); + GapContentPosition p = (GapContentPosition) r.get(); + if (p != null && p.mark == offset || p == null) + index1--; + else + break; + } for (ListIterator i = positions.listIterator(index1); i.hasNext();) { - GapContentPosition p = (GapContentPosition) i.next(); + WeakReference r = (WeakReference) i.next(); + GapContentPosition p = (GapContentPosition) r.get(); + if (p == null) + continue; + if (p.mark > endOffset) break; @@ -707,23 +774,35 @@ public class GapContent * @param length the length of the range to search * @param incr the increment */ - void adjustPositionsInRange(int offset, int length, int incr) + private void adjustPositionsInRange(int offset, int length, int incr) { int endOffset = offset + length; int index1 = Collections.binarySearch(positions, - new GapContentPosition(offset)); + new GapContentPosition(offset), + new WeakPositionComparator()); if (index1 < 0) index1 = -(index1 + 1); // Search the first index with the specified offset. The binarySearch does // not necessarily find the first one. - while (index1 > 0 - && ((GapContentPosition) positions.get(index1 - 1)).mark == offset) - index1--; + while (index1 > 0) + { + WeakReference r = (WeakReference) positions.get(index1 - 1); + GapContentPosition p = (GapContentPosition) r.get(); + if (p != null && p.mark == offset || p == null) + index1--; + else + break; + } + for (ListIterator i = positions.listIterator(index1); i.hasNext();) { - GapContentPosition p = (GapContentPosition) i.next(); + WeakReference r = (WeakReference) i.next(); + GapContentPosition p = (GapContentPosition) r.get(); + if (p == null) + continue; + if (p.mark > endOffset) break; @@ -747,6 +826,17 @@ public class GapContent } /** + * @specnote This method is not very well specified and the positions vector + * is implementation specific. The undo positions are managed + * differently in this implementation, this method is only here + * for binary compatibility. + */ + protected void updateUndoPositions(Vector positions, int offset, int length) + { + // We do nothing here. + } + + /** * Outputs debugging info to System.err. It prints out the buffer array, * the gapStart is marked by a < sign, the gapEnd is marked by a > * sign and each position is marked by a # sign. @@ -776,8 +866,23 @@ public class GapContent { for (Iterator i = positions.iterator(); i.hasNext();) { - GapContentPosition pos = (GapContentPosition) i.next(); + WeakReference r = (WeakReference) i.next(); + GapContentPosition pos = (GapContentPosition) r.get(); System.err.println("position at: " + pos.mark); } } + + /** + * Clears all GC'ed references in the positions array. + */ + private void clearPositionReferences() + { + Iterator i = positions.iterator(); + while (i.hasNext()) + { + WeakReference r = (WeakReference) i.next(); + if (r.get() == null) + i.remove(); + } + } } |