1 19 package org.openide.text; 20 21 import org.openide.util.RequestProcessor; 22 23 import java.io.*; 24 25 import java.util.*; 26 27 28 34 final class LineStruct extends Object { 35 36 private static final int MAX = Integer.MAX_VALUE / 2; 37 38 39 private static final RequestProcessor PROCESSOR = new RequestProcessor("LineStruct Processor"); 41 42 private List<Info> list; 43 44 46 public LineStruct() { 47 list = new LinkedList<Info>(); 48 list.add(new Info(MAX, MAX)); 49 } 50 51 55 public int convert(int line, final boolean currentToOriginal) { 56 class Compute extends Object implements Runnable { 58 public int result; 59 60 public Compute(int i) { 61 result = i; 62 } 63 64 public void run() { 65 if (currentToOriginal) { 66 result = originalToCurrentImpl(result); 67 } else { 68 result = currentToOriginalImpl(result); 69 } 70 } 71 } 72 73 Compute c = new Compute(line); 74 75 PROCESSOR.post(c).waitFinished(); 77 78 return c.result; 80 } 81 82 86 public void insertLines(final int line, final int count) { 87 PROCESSOR.post( 88 new Runnable () { 89 public void run() { 90 insertLinesImpl(line, count); 91 } 92 } 93 ); 94 } 95 96 102 public void deleteLines(final int line, final int count) { 103 PROCESSOR.post( 104 new Runnable () { 105 public void run() { 106 deleteLinesImpl(line, count); 107 } 108 } 109 ); 110 } 111 112 116 private int originalToCurrentImpl(int line) { 117 Iterator it = list.iterator(); 118 int cur = 0; 119 120 for (;;) { 121 Info i = (Info) it.next(); 122 123 if (i.original > line) { 124 return (line > i.current) ? (cur + i.current) : (cur + line); 126 } 127 128 cur += i.current; 129 line -= i.original; 130 } 131 } 132 133 137 private int currentToOriginalImpl(int line) { 138 Iterator it = list.iterator(); 139 int cur = 0; 140 141 for (;;) { 142 Info i = (Info) it.next(); 143 144 if (i.current > line) { 145 return (line > i.original) ? (cur + i.original) : (cur + line); 147 } 148 149 cur += i.original; 150 line -= i.current; 151 } 152 } 153 154 158 private void insertLinesImpl(int line, int count) { 159 ListIterator<Info> it = list.listIterator(); 160 161 for (;;) { 162 Info i = it.next(); 163 164 if (i.current >= line) { 165 for (;;) { 166 count = i.insert(line, count, it); 167 168 if (count == 0) { 169 return; 170 } 171 172 i = it.next(); 173 line = 0; 174 } 175 } 176 177 line -= i.current; 178 } 179 } 180 181 187 private void deleteLinesImpl(int line, int count) { 188 ListIterator<Info> it = list.listIterator(); 189 190 for (;;) { 191 Info i = it.next(); 192 193 if (i.current >= line) { 194 Info stat = new Info(count, 0); 197 198 for (;;) { 199 stat = i.delete(line, stat, it); 200 201 if (stat.original == 0) { 202 break; 203 } 204 205 i = it.next(); 206 line = 0; 207 } 208 209 if ((stat.current > 0) && it.hasPrevious()) { 211 Info prev = it.previous(); 212 boolean hasPrev = it.hasPrevious(); 213 214 if (hasPrev) { 215 prev = it.previous(); 216 } 217 218 if (prev.current == 0) { 219 prev.original += stat.current; 220 } else { 221 if (hasPrev) { 222 it.next(); 223 } 224 225 it.add(new Info(stat.current, 0)); 226 } 227 } 228 229 return; 230 } 231 232 line -= i.current; 233 } 234 } 235 236 238 private static final class Info extends Object { 239 240 public static final int AREA_ORIGINAL = 0; 241 public static final int AREA_INSERT = 1; 242 public static final int AREA_REMOVE = -1; 243 244 245 public int original; 246 247 248 public int current; 249 250 public Info(int o, int c) { 251 original = o; 252 current = c; 253 } 254 255 257 public int type() { 258 if (current == original) { 259 return AREA_ORIGINAL; 260 } 261 262 if (current == 0) { 263 return AREA_REMOVE; 264 } 265 266 if (original == 0) { 267 return AREA_INSERT; 268 } 269 270 throw new IllegalStateException ("Original: " + original + " current: " + current); } 272 273 279 public int insert(int pos, int count, ListIterator<Info> it) { 280 switch (type()) { 281 case AREA_INSERT: 282 283 current += count; 285 286 return 0; 287 288 case AREA_ORIGINAL: 289 290 if (pos == current) { 291 return count; 295 } 296 297 if (pos == 0) { 298 Info ni = new Info(original, original); 301 original = 0; 302 current = count; 303 it.add(ni); 304 305 return 0; 307 } 308 309 Info ni = new Info(original - pos, original - pos); 312 313 original = current = pos; 315 316 it.add(new Info(0, count)); 318 319 it.add(ni); 321 322 return 0; 323 324 case AREA_REMOVE: 325 326 if (pos != 0) { 328 throw new IllegalStateException ("Pos: " + pos); } 330 331 Info prev = it.previous(); 334 if (it.hasPrevious()) { 335 prev = it.previous(); it.next(); } 338 339 it.next(); 341 if (count < original) { 342 if (prev.type() == AREA_ORIGINAL) { 343 prev.original += count; 344 prev.current += count; 345 346 original -= count; 348 } else { 349 ni = new Info(original - count, 0); 350 351 original = current = count; 353 354 it.add(ni); 356 } 357 358 return 0; 360 } else { 361 if (prev.type() == AREA_ORIGINAL) { 362 prev.current += original; 363 prev.original += original; 364 it.remove(); 365 366 return count - original; 367 } else { 368 current = original; 370 371 return count - current; 373 } 374 } 375 376 default: 377 throw new IllegalStateException ("Type: " + type()); } 379 } 380 381 392 public Info delete(int pos, Info info, ListIterator<Info> it) { 393 switch (type()) { 394 case AREA_ORIGINAL: 395 396 if (pos != 0) { 397 int size = current - pos; 399 current = original = pos; 400 401 if (size >= info.original) { 402 Info ni = new Info(size, size); 404 it.add(ni); 405 info.current += info.original; 406 info.original = 0; 407 408 return info; 409 } else { 410 info.original -= size; 412 info.current += size; 413 414 return info; 415 } 416 } else { 417 if (current >= info.original) { 419 info.current += info.original; 422 423 current -= info.original; 425 original = current; 426 427 info.original = 0; 429 430 return info; 431 } else { 432 it.remove(); 434 435 info.current += current; 437 info.original -= current; 438 439 return info; 440 } 441 } 442 443 case AREA_INSERT: 444 445 if (pos != 0) { 446 int size = current - pos; 448 449 if (size >= info.original) { 450 current -= info.original; 452 453 info.original = 0; 454 455 return info; 456 } else { 457 current = pos; 459 460 info.original -= size; 461 462 return info; 463 } 464 } else { 465 if (current >= info.original) { 467 current -= info.original; 470 471 info.original = 0; 473 474 it.remove(); 475 476 return info; 477 } else { 478 it.remove(); 480 481 info.original -= current; 483 484 return info; 485 } 486 } 487 488 case AREA_REMOVE: 489 490 original += info.current; 493 info.current = 0; 494 495 return info; 496 497 default: 498 throw new IllegalStateException ("Type: " + type()); } 500 } 501 } 502 } 503 | Popular Tags |