Mario pointed out a regression in GapContent. Last time I change quite a
bit in this class but obviously forgot to adjust getPositionsInRange().
Now this method was hit by the Position object beeing weakly referenced
in the Mark and possibly beeing null. I rewrote this method to use the
(more efficient) binary search from searchFirst() which checks for this
case and thus avoids the NPE.
2006-11-25 Roman Kennke <[EMAIL PROTECTED]>
* javax/swing/text/GapContent.java
(getPositionsInRange): Rewritten to use the more efficient
binary search searchFirst() and avoid an NPE that was caused
by GC'ed positions.
/Roman
Index: javax/swing/text/GapContent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/GapContent.java,v
retrieving revision 1.58
diff -u -1 -5 -r1.58 GapContent.java
--- javax/swing/text/GapContent.java 20 Nov 2006 10:27:11 -0000 1.58
+++ javax/swing/text/GapContent.java 25 Nov 2006 20:29:46 -0000
@@ -876,46 +876,56 @@
return gapEnd;
}
/**
* Returns all <code>Position</code>s that are in the range specified by
* <code>offset</code> and </code>length</code> within the buffer array.
*
* @param v the vector to use; if <code>null</code>, 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();
-
- int endOffs = offset + length;
-
- for (Iterator i = marks.iterator(); i.hasNext();)
+ int end = offset + length;
+ int startIndex;
+ int endIndex;
+ if (offset < gapStart)
{
- Mark m = (Mark) i.next();
- GapContentPosition p = m.getPosition();
- int offs = p.getOffset();
- if (offs >= offset && offs <= endOffs)
- res.add(new UndoPosRef(p.mark));
+ if (offset == 0)
+ startIndex = 0;
+ else
+ startIndex = searchFirst(offset);
+ if (end >= gapStart)
+ endIndex = searchFirst(end + (gapEnd - gapStart) + 1);
+ else
+ endIndex = searchFirst(end + 1);
}
-
- return res;
+ else
+ {
+ startIndex = searchFirst(offset + (gapEnd - gapStart));
+ endIndex = searchFirst(end + (gapEnd - gapStart) + 1);
+ }
+ if (v == null)
+ v = new Vector();
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ v.add(new UndoPosRef((Mark) marks.get(i)));
+ }
+ return v;
}
/**
* Resets all <code>Position</code> that have an offset of <code>0</code>,
* to also have an array index of <code>0</code>. This might be necessary
* after a call to <code>shiftGap(0)</code>, since then the marks at offset
* <code>0</code> get shifted to <code>gapEnd</code>.
*/
protected void resetMarksAtZero()
{
if (gapStart != 0)
return;
for (int i = 0; i < marks.size(); i++)
{
@@ -981,31 +991,30 @@
{
System.out.print("positionMarks: ");
for (int i = 0; i < marks.size(); i++)
System.out.print(((Mark) marks.get(i)).mark + ", ");
System.out.println();
}
/**
* Searches the first occurance of object <code>o</code> in list
* <code>l</code>. This performs a binary search by calling
* [EMAIL PROTECTED] Collections#binarySearch(List, Object)} and when an object has been
* found, it searches backwards to the first occurance of that object in the
* list. The meaning of the return value is the same as in
* <code>Collections.binarySearch()</code>.
*
- * @param l the list to search through
* @param o the object to be searched
*
* @return the index of the first occurance of o in l, or -i + 1 if not found
*/
int search(Mark o)
{
int foundInd = 0;
boolean found = false;
int low = 0;
int up = marks.size() - 1;
int mid = 0;
if (up > -1)
{
int cmp = 0;
Mark last = (Mark) marks.get(up);