|                                                                                                              1
 19
 20  package org.netbeans.lib.editor.util;
 21
 22
 55
 56  public abstract class OffsetGapList<E> extends GapList<E> {
 57
 58      private int offsetGapStart;
 60      private int offsetGapLength = Integer.MAX_VALUE / 2;
 62      public OffsetGapList() {
 63      }
 64
 65
 72      protected abstract int elementRawOffset(E elem);
 73
 74
 80      protected abstract void setElementRawOffset(E elem, int rawOffset);
 81
 82
 90      protected int elementOffset(E elem) {
 91          return raw2Offset(elementRawOffset(elem));
 92      }
 93
 94
 103     protected int elementOffset(int index) {
 104         return elementOffset(get(index));
 105     }
 106
 107
 119     public void defaultInsertUpdate(int offset, int length) {
 120         assert (length >= 0);
 121         if (offset != offsetGapStart()) {
 122             moveOffsetGap(offset, findElementIndex(offset));
 123         }
 124         updateOffsetGapLength(-length);                                                 updateOffsetGapStart(length);
 131     }
 132
 133
 146     public void defaultRemoveUpdate(int offset, int length) {
 147         assert (length >= 0);
 148         int index = findElementIndex(offset);
 149         if (offset != offsetGapStart()) {
 150             moveOffsetGap(offset, index);
 151         }
 152         int size = size();
 153         int removeAreaEndRawOffset = offset + offsetGapLength + length;
 154                                 while (index < size) {
 158             E elem = get(index++);
 159             if (elementRawOffset(elem) < removeAreaEndRawOffset) {
 160                 setElementRawOffset(elem, removeAreaEndRawOffset);
 161             } else {                 break;
 163             }
 164         }
 165         updateOffsetGapLength(+length);
 166     }
 167
 168
 185     protected final void moveOffsetGap(int offset, int index) {
 186         if (offset < offsetGapStart) {             int bound = size();
 188             for (int i = index; i < bound; i++) {
 189                 E elem = get(i);
 190                 int rawOffset = elementRawOffset(elem);
 191                 if (rawOffset < offsetGapStart) {
 192                     setElementRawOffset(elem, rawOffset + offsetGapLength);
 193                 } else {
 194                     break;
 195                 }
 196             }
 197
 198         } else {              for (int i = index - 1; i >= 0; i--) {
 200                 E elem = get(i);
 201                 int rawOffset = elementRawOffset(elem);
 202                 if (rawOffset >= offsetGapStart) {
 203                     setElementRawOffset(elem, rawOffset - offsetGapLength);
 204                 } else {
 205                     break;
 206                 }
 207             }
 208         }
 209         offsetGapStart = offset;
 210     }
 211
 212
 217     protected final int offsetGapStart() {
 218         return offsetGapStart;
 219     }
 220
 221
 231     protected final void updateOffsetGapStart(int offsetDelta) {
 232         offsetGapStart += offsetDelta;
 233     }
 234
 235
 240     protected final int offsetGapLength() {
 241         return offsetGapLength;
 242     }
 243
 244
 254     protected final void updateOffsetGapLength(int offsetGapLengthDelta) {
 255         offsetGapLength += offsetGapLengthDelta;
 256         assert (offsetGapLength >= 0);     }
 258
 259
 271     protected final int findElementIndex(int offset) {
 272         int low = 0;
 273         int high = size() - 1;
 274
 275         while (low <= high) {
 276             int index = (low + high) / 2;             int elemOffset = elementOffset(index);
 278
 279             if (elemOffset < offset) {
 280                 low = index + 1;
 281
 282             } else if (elemOffset > offset) {
 283                 high = index - 1;
 284
 285             } else {                 while (index > 0) {
 287                     index--;
 288                     if (elementOffset(index) < offset) {
 289                         index++;
 290                         break;
 291                     }
 292                 }
 293                 low = index;
 294                 break;
 295             }
 296         }
 297         return low;
 298     }
 299
 300
 308     protected void updateElementOffsetAdd(E elem) {
 309         int rawOffset = elementRawOffset(elem);
 310         if (rawOffset >= offsetGapStart) {
 311             setElementRawOffset(elem, rawOffset + offsetGapLength);
 312         }
 313     }
 314
 315
 326     protected void updateElementOffsetRemove(E elem) {
 327         int rawOffset = elementRawOffset(elem);
 328         if (rawOffset >= offsetGapStart) {
 329             setElementRawOffset(elem, rawOffset - offsetGapLength);
 330         }
 331     }
 332
 333
 339     protected final int raw2Offset(int rawOffset) {
 340         return (rawOffset < offsetGapStart)
 341             ? rawOffset
 342             : rawOffset - offsetGapLength;
 343     }
 344
 345
 351     protected final int offset2raw(int offset) {
 352         return (offset < offsetGapStart)
 353             ? offset
 354             : offset + offsetGapLength;
 355     }
 356
 357     protected void consistencyCheck() {
 358         super.consistencyCheck();
 359
 360         if (offsetGapLength < 0) {
 361             consistencyError("offsetGapLength < 0");         }
 363
 364         int lastRawOffset = Integer.MIN_VALUE;
 365         int lastOffset = Integer.MIN_VALUE;
 366         int size = size();
 367         for (int i = 0; i < size; i++) {
 368             E elem = get(i);
 369             int rawOffset = elementRawOffset(elem);
 370             int offset = raw2Offset(rawOffset);
 371             if (rawOffset < lastRawOffset) {
 372                 consistencyError("Invalid rawOffset="                     + rawOffset + " >= lastRawOffset=" + lastRawOffset                     + " at index=" + i                 );
 376             }
 377             if (offset < lastOffset) {
 378                 consistencyError("Invalid offset="                     + offset + " >= lastOffset=" + lastOffset                     + " at index=" + i                 );
 382             }
 383             lastRawOffset = rawOffset;
 384             lastOffset = offset;
 385         }
 386     }
 387
 388     protected String
  dumpInternals() { 389         return super.dumpInternals() + ", offGap(s=" + offsetGapStart
 390         + ", l=" + offsetGapLength + ")";
 391     }
 392
 393 }
 394
                                                                                                                                                                                                             |                                                                       
 
 
 
 
 
                                                                                   Popular Tags                                                                                                                                                                                              |