1 19 20 package org.netbeans.modules.editor.lib2.highlighting; 21 22 import java.util.Collection ; 23 import org.netbeans.lib.editor.util.GapList; 24 25 80 81 public abstract class AbstractOffsetGapList<E> extends GapList<E> { 82 83 private int offsetGapStart; 85 private int offsetGapLength = Integer.MAX_VALUE / 2; 87 public AbstractOffsetGapList() { 88 } 89 90 98 public final boolean add(E element) { 99 int originalOffset = attachElement(element); 100 setElementRawOffset(element, offset2raw(originalOffset)); 101 int index = findOffsetIndex(originalOffset); 102 super.add(index, element); 103 return true; 104 } 105 106 117 public final void add(int index, E element) { 118 if (index < 0 || index > size()) { 119 throw new IndexOutOfBoundsException ("index = " + index + " size = " + size()); } 121 122 int originalOffset = attachElement(element); 123 setElementRawOffset(element, offset2raw(originalOffset)); 124 125 boolean ok = true; 126 127 if (index > 0 && elementOffset(index - 1) > originalOffset) { 129 System.out.println("[" + (index - 1) + "] = " + elementOffset(index - 1) + " > {" + index + "} = "+ originalOffset); 130 ok = false; 131 } 132 133 if (index < size() && elementOffset(index) < originalOffset) { 135 System.out.println("[" + index + "] = " + elementOffset(index) + " < {" + index + "} = "+ originalOffset); 136 ok = false; 137 } 138 139 if (ok) { 140 super.add(index, element); 142 } else { 143 detachElement(element); 145 throw new IllegalStateException ("Can't insert element at index: " + index); } 147 } 148 149 155 public final boolean addAll(Collection <? extends E> c) { 156 for (E e : c) { 157 add(e); 158 } 159 return true; 160 } 161 162 167 public final boolean addAll(int index, Collection <? extends E> c) { 168 throw new UnsupportedOperationException ("This is an illegal operation on OffsetGapList."); } 170 171 176 public final boolean addArray(int index, Object [] elements) { 177 throw new UnsupportedOperationException ("This is an illegal operation on OffsetGapList."); } 179 180 185 public final boolean addArray(int index, Object [] elements, int off, int len) { 186 throw new UnsupportedOperationException ("This is an illegal operation on OffsetGapList."); } 188 189 195 public final int indexOf(Object o) { 196 E element = getAttachedElement(o); 197 if (element != null) { 198 int offset = elementOffset(element); 199 int idx = findElementIndex(offset); 200 if (idx >= 0) { 201 for (int i = idx; i < size() && elementOffset(i) == offset; i++) { 202 if (element == get(i)) { 203 return i; 204 } 205 } 206 } 207 } 208 return -1; 209 } 210 211 218 public final int lastIndexOf(Object element) { 219 return indexOf(element); 220 } 221 222 233 public final E set(int index, E element) { 234 if (index < 0 || index >= size()) { 235 throw new IndexOutOfBoundsException ("index = " + index + " size = " + size()); } 237 238 int originalOffset = attachElement(element); 239 setElementRawOffset(element, offset2raw(originalOffset)); 240 241 boolean ok = true; 242 243 if (index > 0 && elementOffset(index - 1) > originalOffset) { 245 System.out.println("[" + (index - 1) + "] = " + elementOffset(index - 1) + " > {" + index + "} = "+ originalOffset); 246 ok = false; 247 } 248 249 if (index + 1 < size() && elementOffset(index + 1) < originalOffset) { 251 System.out.println("[" + (index + 1) + "] = " + elementOffset(index + 1) + " < {" + index + "} = "+ originalOffset); 252 ok = false; 253 } 254 255 if (ok) { 256 E oldElement = super.set(index, element); 258 detachElement(oldElement); 259 return oldElement; 260 } else { 261 detachElement(element); 263 throw new IllegalStateException ("Can't insert element at index: " + index); } 265 } 266 267 272 public final void swap(int index1, int index2) { 273 throw new UnsupportedOperationException ("This is an illegal operation on OffsetGapList."); } 275 276 282 protected abstract int elementRawOffset(E elem); 283 284 290 protected abstract void setElementRawOffset(E elem, int rawOffset); 291 292 305 protected abstract int attachElement(E elem); 306 307 316 protected abstract void detachElement(E elem); 317 318 328 protected abstract E getAttachedElement(Object o); 329 330 338 protected int elementOffset(E elem) { 339 return raw2Offset(elementRawOffset(elem)); 340 } 341 342 350 protected int elementOffset(int index) { 351 return elementOffset(get(index)); 352 } 353 354 366 public void defaultInsertUpdate(int offset, int length) { 367 assert (length >= 0); 368 if (offset != offsetGapStart()) { 369 moveOffsetGap(offset, findOffsetIndex(offset)); 370 } 371 updateOffsetGapLength(-length); updateOffsetGapStart(length); 378 } 379 380 393 public void defaultRemoveUpdate(int offset, int length) { 394 assert (length >= 0); 395 int index = findOffsetIndex(offset); 396 if (offset != offsetGapStart()) { 397 moveOffsetGap(offset, index); 398 } 399 int size = size(); 400 int removeAreaEndRawOffset = offset + offsetGapLength + length; 401 while (index < size) { 405 E elem = get(index++); 406 if (elementRawOffset(elem) < removeAreaEndRawOffset) { 407 setElementRawOffset(elem, removeAreaEndRawOffset); 408 } else { break; 410 } 411 } 412 updateOffsetGapLength(+length); 413 } 414 415 432 protected final void moveOffsetGap(int offset, int index) { 433 if (offset < offsetGapStart) { int bound = size(); 435 for (int i = index; i < bound; i++) { 436 E elem = get(i); 437 int rawOffset = elementRawOffset(elem); 438 if (rawOffset < offsetGapStart) { 439 setElementRawOffset(elem, rawOffset + offsetGapLength); 440 } else { 441 break; 442 } 443 } 444 445 } else { for (int i = index - 1; i >= 0; i--) { 447 E elem = get(i); 448 int rawOffset = elementRawOffset(elem); 449 if (rawOffset >= offsetGapStart) { 450 setElementRawOffset(elem, rawOffset - offsetGapLength); 451 } else { 452 break; 453 } 454 } 455 } 456 offsetGapStart = offset; 457 } 458 459 464 protected final int offsetGapStart() { 465 return offsetGapStart; 466 } 467 468 478 protected final void updateOffsetGapStart(int offsetDelta) { 479 offsetGapStart += offsetDelta; 480 } 481 482 487 protected final int offsetGapLength() { 488 return offsetGapLength; 489 } 490 491 501 protected final void updateOffsetGapLength(int offsetGapLengthDelta) { 502 offsetGapLength += offsetGapLengthDelta; 503 assert (offsetGapLength >= 0); } 505 506 518 protected final int findOffsetIndex(int offset) { 519 int index = findElementIndex(offset); 520 return index < 0 ? -index - 1 : index; 521 } 522 523 543 public final int findElementIndex(int offset, int lowIdx, int highIdx) { 544 if (lowIdx < 0 || highIdx > size() - 1) { 545 throw new IndexOutOfBoundsException ("lowIdx = " + lowIdx + ", highIdx = " + highIdx + ", size = " + size()); 546 } 547 548 int low = lowIdx; 549 int high = highIdx; 550 551 while (low <= high) { 552 int index = (low + high) >> 1; int elemOffset = elementOffset(index); 554 555 if (elemOffset < offset) { 556 low = index + 1; 557 558 } else if (elemOffset > offset) { 559 high = index - 1; 560 561 } else { while (index > 0) { 563 index--; 564 if (elementOffset(index) < offset) { 565 index++; 566 break; 567 } 568 } 569 return index; 570 } 571 } 572 573 return -(low + 1); 574 } 575 576 public final int findElementIndex(int offset) { 577 return findElementIndex(offset, 0, size() - 1); 578 } 579 580 588 protected void updateElementOffsetAdd(E elem) { 589 int rawOffset = elementRawOffset(elem); 590 if (rawOffset >= offsetGapStart) { 591 setElementRawOffset(elem, rawOffset + offsetGapLength); 592 } 593 } 594 595 606 protected void updateElementOffsetRemove(E elem) { 607 int rawOffset = elementRawOffset(elem); 608 if (rawOffset >= offsetGapStart) { 609 setElementRawOffset(elem, rawOffset - offsetGapLength); 610 } 611 } 612 613 619 protected final int raw2Offset(int rawOffset) { 620 return (rawOffset < offsetGapStart) 621 ? rawOffset 622 : rawOffset - offsetGapLength; 623 } 624 625 631 protected final int offset2raw(int offset) { 632 return (offset < offsetGapStart) 633 ? offset 634 : offset + offsetGapLength; 635 } 636 637 protected void consistencyCheck() { 638 super.consistencyCheck(); 639 640 if (offsetGapLength < 0) { 641 consistencyError("offsetGapLength < 0"); } 643 644 int lastRawOffset = Integer.MIN_VALUE; 645 int lastOffset = Integer.MIN_VALUE; 646 int size = size(); 647 for (int i = 0; i < size; i++) { 648 E elem = get(i); 649 int rawOffset = elementRawOffset(elem); 650 int offset = raw2Offset(rawOffset); 651 if (rawOffset < lastRawOffset) { 652 consistencyError("Invalid rawOffset=" + rawOffset + " >= lastRawOffset=" + lastRawOffset + " at index=" + i ); 656 } 657 if (offset < lastOffset) { 658 consistencyError("Invalid offset=" + offset + " >= lastOffset=" + lastOffset + " at index=" + i ); 662 } 663 lastRawOffset = rawOffset; 664 lastOffset = offset; 665 } 666 } 667 668 protected String dumpInternals() { 669 return super.dumpInternals() + ", offGap(s=" + offsetGapStart 670 + ", l=" + offsetGapLength + ")"; 671 } 672 } 673 | Popular Tags |