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);

Reply via email to