1 19 package org.netbeans.modules.java.source.save; 20 21 import java.io.*; 22 import java.util.BitSet ; 23 import javax.tools.JavaFileObject; 24 25 30 public class SourceBuffer implements CharSequence { 31 public char[] src; 32 LineMap lineMap; 33 int maxLines; 34 35 40 public SourceBuffer(char[] src, int length) { 41 this.src = src; 42 lineMap = new LineMap(src, src.length); 43 maxLines = lineMap.getLineNumber(src.length - 1); 44 } 45 46 50 public SourceBuffer (String path) throws IOException { 51 this(new FileReader(path)); 52 } 53 54 58 public SourceBuffer (InputStream input) throws IOException { 59 this(new InputStreamReader(input)); 60 } 61 62 67 public SourceBuffer (InputStream input, String encoding) throws IOException { 68 this(new InputStreamReader(input, encoding)); 69 } 70 71 75 public SourceBuffer(Reader input) throws IOException { 76 src = readInFile(input); 77 lineMap = new LineMap(src, src.length); 78 maxLines = lineMap.getLineNumber(src.length - 1); 79 } 80 81 85 public SourceBuffer(JavaFileObject sourceFile) throws IOException { 86 String s = sourceFile.getCharContent(true).toString(); 87 src = s.toCharArray(); 88 lineMap = new LineMap(src, src.length); 89 maxLines = lineMap.getLineNumber(src.length - 1); 90 } 91 92 private static char[] readInFile(Reader in) throws IOException { 93 CharArrayWriter out = new CharArrayWriter(4096); 94 char[] buf = new char[4096]; 95 int n; 96 while ((n = in.read(buf)) > 0) 97 out.write(buf, 0, n); 98 in.close(); 99 100 out.write(0); 102 103 return out.toCharArray(); 104 } 105 106 111 public char[] getChars() { 112 char[] buf = new char[src.length]; 113 System.arraycopy(src, 0, buf, 0, src.length); 114 return buf; 115 } 116 117 132 public char[] getChars(int start, int end) { 133 int len = end - start; 134 char[] buf = new char[len]; 135 System.arraycopy(src, start, buf, 0, len); 136 return buf; 137 } 138 139 154 public String getString(int start, int end) { 155 return new String (src, start, end - start); 156 } 157 158 168 public char[] getLine(int line) { 169 if (line <= 0 || line > maxLines) 170 throw new IndexOutOfBoundsException ("line out of range: " + line); 171 int start = lineMap.getStartPosition(line); 172 int end = ((line + 1 >= maxLines) ? src.length : lineMap.getStartPosition(line+1)) - 1; 173 174 if (src[end] == '\n') 177 --end; 178 if (src[end] == '\r') 179 --end; 180 181 return getChars(start, end + 1); 182 } 183 184 191 public int getLineNumber(int pos) { 192 return lineMap.getLineNumber(pos); 193 } 194 195 201 public int getColumnNumber(int pos) { 202 return lineMap.getColumnNumber(pos); 203 } 204 205 208 public int getPosition(int line, int column) { 209 return lineMap.getPosition(line, column); 210 } 211 212 215 public int getStartPosition(int line) { 216 return lineMap.getStartPosition(line); 217 } 218 219 222 public int length() { 223 return src.length - 1; } 225 226 238 public char charAt(int index) { 239 return src[index]; 240 } 241 242 255 public CharSequence subSequence(int start, int end) { 256 return getString(start, end); 257 } 258 259 public String toString() { 260 return new String (src, 0, length()); 261 } 262 263 271 static class LineMap { 272 private int[] startPosition; private BitSet tabMap; 275 public static final int FIRSTLINE = 1; 276 public static final int FIRSTCOLUMN = 1; 277 public final static int TabInc = 8; 278 private static final char SCANNER_SENTINEL = '\u0000'; 280 protected LineMap(char[] src, int max) { 281 if (src[max - 1] == SCANNER_SENTINEL) 282 max--; 283 tabMap = new BitSet (max); 284 int c = 0; 285 int i = 0; 286 int[] linebuf = new int[max]; 287 while (i < max) { 288 linebuf[c++] = i; 289 do { 290 char ch = src[i]; 291 if (ch == '\r' || ch == '\n') { 292 if (ch == '\r' && (i+1) < max && src[i+1] == '\n') 293 i += 2; 294 else 295 ++i; 296 break; 297 } 298 else if (ch == '\t') 299 setTabPosition(i); 300 } while (++i < max); 301 } 302 this.startPosition = new int[c]; 303 System.arraycopy(linebuf, 0, startPosition, 0, c); 304 } 305 306 public int getStartPosition(int line) { 307 return startPosition[line - FIRSTLINE]; 308 } 309 310 public int getPosition(int line, int column) { 311 int pos = startPosition[line - FIRSTLINE]; 312 column -= FIRSTCOLUMN; 313 int col = 0; 314 while (col < column) { 315 pos++; 316 if (tabMap.get(pos)) 317 col = (col / TabInc * TabInc) + TabInc; 318 else 319 col++; 320 } 321 return pos; 322 } 323 324 private int lastPosition = 0; 326 private int lastLine = FIRSTLINE; 327 328 public int getLineNumber(int pos) { 329 if (pos == lastPosition) { 330 return lastLine; 331 } 332 lastPosition = pos; 333 334 int low = 0; 335 int high = startPosition.length-1; 336 while (low <= high) { 337 int mid = (low + high) >> 1; 338 int midVal = startPosition[mid]; 339 340 if (midVal < pos) 341 low = mid + 1; 342 else if (midVal > pos) 343 high = mid - 1; 344 else { 345 lastLine = mid + 1; return lastLine; 347 } 348 } 349 lastLine = low; 350 return lastLine; } 352 353 public int getColumnNumber(int pos) { 354 int lineStart = startPosition[getLineNumber(pos) - FIRSTLINE]; 355 int column = 0; 356 for (int bp = lineStart; bp < pos; bp++) { 357 if (tabMap.get(bp)) 358 column = (column / TabInc * TabInc) + TabInc; 359 else 360 column++; 361 } 362 return column + FIRSTCOLUMN; 363 } 364 365 protected void setTabPosition(int offset) { 366 tabMap.set(offset); 367 } 368 } 369 } 370 | Popular Tags |