1 22 23 package org.gjt.sp.jedit.buffer; 24 25 import org.gjt.sp.jedit.syntax.*; 27 import org.gjt.sp.jedit.Debug; 28 import org.gjt.sp.util.IntegerArray; 29 import org.gjt.sp.util.Log; 30 32 43 public class LineManager 44 { 45 public LineManager() 47 { 48 endOffsets = new int[1]; 49 endOffsets[0] = 1; 50 foldLevels = new short[1]; 51 lineContext = new TokenMarker.LineContext[1]; 52 lineCount = 1; 53 } 55 public final int getLineCount() 57 { 58 return lineCount; 59 } 61 public int getLineOfOffset(int offset) 63 { 64 int start = 0; 65 int end = lineCount - 1; 66 67 for(;;) 68 { 69 switch(end - start) 70 { 71 case 0: 72 if(getLineEndOffset(start) <= offset) 73 return start + 1; 74 else 75 return start; 76 case 1: 77 if(getLineEndOffset(start) <= offset) 78 { 79 if(getLineEndOffset(end) <= offset) 80 return end + 1; 81 else 82 return end; 83 } 84 else 85 return start; 86 default: 87 int pivot = (end + start) / 2; 88 int value = getLineEndOffset(pivot); 89 if(value == offset) 90 return pivot + 1; 91 else if(value < offset) 92 start = pivot + 1; 93 else 94 end = pivot - 1; 95 break; 96 } 97 } 98 } 100 public final int getLineEndOffset(int line) 102 { 103 if(gapLine != -1 && line >= gapLine) 104 return endOffsets[line] + gapWidth; 105 else 106 return endOffsets[line]; 107 } 109 public final int getFoldLevel(int line) 111 { 112 return foldLevels[line]; 113 } 115 public final void setFoldLevel(int line, int level) 118 { 119 if(level > 0xffff) 120 { 121 level = 0xffff; 123 } 124 125 foldLevels[line] = (short)level; 126 } 128 public void setFirstInvalidFoldLevel(int firstInvalidFoldLevel) 130 { 131 this.firstInvalidFoldLevel = firstInvalidFoldLevel; 132 } 134 public int getFirstInvalidFoldLevel() 136 { 137 return firstInvalidFoldLevel; 138 } 140 public final TokenMarker.LineContext getLineContext(int line) 142 { 143 return lineContext[line]; 144 } 146 public final void setLineContext(int line, TokenMarker.LineContext context) 148 { 149 lineContext[line] = context; 150 } 152 public void setFirstInvalidLineContext(int firstInvalidLineContext) 154 { 155 this.firstInvalidLineContext = firstInvalidLineContext; 156 } 158 public int getFirstInvalidLineContext() 160 { 161 return firstInvalidLineContext; 162 } 164 public void _contentInserted(IntegerArray endOffsets) 166 { 167 gapLine = -1; 168 gapWidth = 0; 169 firstInvalidLineContext = firstInvalidFoldLevel = 0; 170 lineCount = endOffsets.getSize(); 171 this.endOffsets = endOffsets.getArray(); 172 foldLevels = new short[lineCount]; 173 174 lineContext = new TokenMarker.LineContext[lineCount]; 175 } 177 public void contentInserted(int startLine, int offset, 179 int numLines, int length, IntegerArray endOffsets) 180 { 181 int endLine = startLine + numLines; 182 183 if(numLines > 0) 185 { 186 188 lineCount += numLines; 189 190 if(this.endOffsets.length <= lineCount) 191 { 192 int[] endOffsetsN = new int[(lineCount + 1) * 2]; 193 System.arraycopy(this.endOffsets,0,endOffsetsN,0, 194 this.endOffsets.length); 195 this.endOffsets = endOffsetsN; 196 } 197 198 if(foldLevels.length <= lineCount) 199 { 200 short[] foldLevelsN = new short[(lineCount + 1) * 2]; 201 System.arraycopy(foldLevels,0,foldLevelsN,0, 202 foldLevels.length); 203 foldLevels = foldLevelsN; 204 } 205 206 if(lineContext.length <= lineCount) 207 { 208 TokenMarker.LineContext[] lineContextN 209 = new TokenMarker.LineContext[(lineCount + 1) * 2]; 210 System.arraycopy(lineContext,0,lineContextN,0, 211 lineContext.length); 212 lineContext = lineContextN; 213 } 214 215 System.arraycopy(this.endOffsets,startLine, 216 this.endOffsets,endLine,lineCount - endLine); 217 System.arraycopy(foldLevels,startLine,foldLevels, 218 endLine,lineCount - endLine); 219 System.arraycopy(lineContext,startLine,lineContext, 220 endLine,lineCount - endLine); 221 222 if(startLine <= gapLine) 223 gapLine += numLines; 224 else if(gapLine != -1) 225 offset -= gapWidth; 226 227 if(startLine < firstInvalidLineContext) 228 firstInvalidLineContext += numLines; 229 230 for(int i = 0; i < numLines; i++) 231 { 232 this.endOffsets[startLine + i] = (offset + endOffsets.get(i)); 233 foldLevels[startLine + i] = 0; 234 } 235 } 237 if(firstInvalidFoldLevel == -1 || firstInvalidFoldLevel > startLine) 238 firstInvalidFoldLevel = startLine; 239 moveGap(endLine,length,"contentInserted"); 240 } 242 public void contentRemoved(int startLine, int offset, 244 int numLines, int length) 245 { 246 int endLine = startLine + numLines; 247 248 if(numLines > 0) 250 { 251 253 if(startLine + numLines < gapLine) 254 gapLine -= numLines; 255 else if(startLine < gapLine) 256 gapLine = startLine; 257 258 if(startLine + numLines < firstInvalidLineContext) 259 firstInvalidLineContext -= numLines; 260 else if(startLine < firstInvalidLineContext) 261 firstInvalidLineContext = startLine - 1; 262 263 lineCount -= numLines; 264 265 System.arraycopy(endOffsets,endLine,endOffsets, 266 startLine,lineCount - startLine); 267 System.arraycopy(foldLevels,endLine,foldLevels, 268 startLine,lineCount - startLine); 269 System.arraycopy(lineContext,endLine,lineContext, 270 startLine,lineCount - startLine); 271 } 273 if(firstInvalidFoldLevel == -1 || firstInvalidFoldLevel > startLine) 274 firstInvalidFoldLevel = startLine; 275 moveGap(startLine,-length,"contentRemoved"); 276 } 278 280 private int[] endOffsets; 282 private short[] foldLevels; 283 private TokenMarker.LineContext[] lineContext; 284 285 private int lineCount; 286 287 292 private int gapLine; 293 private int gapWidth; 294 295 299 private int firstInvalidLineContext; 300 301 305 private int firstInvalidFoldLevel; 306 308 private final void setLineEndOffset(int line, int end) 310 { 311 endOffsets[line] = end; 312 } 314 private final void moveGap(int newGapLine, int newGapWidth, String method) 316 { 317 if(gapLine == -1) 318 gapWidth = newGapWidth; 319 else if(newGapLine == -1) 320 { 321 if(gapWidth != 0) 322 { 323 if(Debug.OFFSET_DEBUG && gapLine != lineCount) 324 Log.log(Log.DEBUG,this,method + ": update from " + gapLine + " to " + lineCount + " width " + gapWidth); 325 for(int i = gapLine; i < lineCount; i++) 326 setLineEndOffset(i,getLineEndOffset(i)); 327 } 328 329 gapWidth = newGapWidth; 330 } 331 else if(newGapLine < gapLine) 332 { 333 if(gapWidth != 0) 334 { 335 if(Debug.OFFSET_DEBUG && newGapLine != gapLine) 336 Log.log(Log.DEBUG,this,method + ": update from " + newGapLine + " to " + gapLine + " width " + gapWidth); 337 for(int i = newGapLine; i < gapLine; i++) 338 setLineEndOffset(i,getLineEndOffset(i) - gapWidth); 339 } 340 gapWidth += newGapWidth; 341 } 342 else { 344 if(gapWidth != 0) 345 { 346 if(Debug.OFFSET_DEBUG && gapLine != newGapLine) 347 Log.log(Log.DEBUG,this,method + ": update from " + gapLine + " to " + newGapLine + " width " + gapWidth); 348 for(int i = gapLine; i < newGapLine; i++) 349 setLineEndOffset(i,getLineEndOffset(i)); 350 } 351 352 gapWidth += newGapWidth; 353 } 354 355 if(newGapLine == lineCount) 356 gapLine = -1; 357 else 358 gapLine = newGapLine; 359 } 361 } 363 | Popular Tags |