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 |