1 7 8 package java.io; 9 10 11 44 45 public class BufferedReader extends Reader { 46 47 private Reader in; 48 49 private char cb[]; 50 private int nChars, nextChar; 51 52 private static final int INVALIDATED = -2; 53 private static final int UNMARKED = -1; 54 private int markedChar = UNMARKED; 55 private int readAheadLimit = 0; 56 57 58 private boolean skipLF = false; 59 60 61 private boolean markedSkipLF = false; 62 63 private static int defaultCharBufferSize = 8192; 64 private static int defaultExpectedLineLength = 80; 65 66 75 public BufferedReader(Reader in, int sz) { 76 super(in); 77 if (sz <= 0) 78 throw new IllegalArgumentException ("Buffer size <= 0"); 79 this.in = in; 80 cb = new char[sz]; 81 nextChar = nChars = 0; 82 } 83 84 90 public BufferedReader(Reader in) { 91 this(in, defaultCharBufferSize); 92 } 93 94 95 private void ensureOpen() throws IOException { 96 if (in == null) 97 throw new IOException ("Stream closed"); 98 } 99 100 103 private void fill() throws IOException { 104 int dst; 105 if (markedChar <= UNMARKED) { 106 107 dst = 0; 108 } else { 109 110 int delta = nextChar - markedChar; 111 if (delta >= readAheadLimit) { 112 113 markedChar = INVALIDATED; 114 readAheadLimit = 0; 115 dst = 0; 116 } else { 117 if (readAheadLimit <= cb.length) { 118 119 System.arraycopy(cb, markedChar, cb, 0, delta); 120 markedChar = 0; 121 dst = delta; 122 } else { 123 124 char ncb[] = new char[readAheadLimit]; 125 System.arraycopy(cb, markedChar, ncb, 0, delta); 126 cb = ncb; 127 markedChar = 0; 128 dst = delta; 129 } 130 nextChar = nChars = delta; 131 } 132 } 133 134 int n; 135 do { 136 n = in.read(cb, dst, cb.length - dst); 137 } while (n == 0); 138 if (n > 0) { 139 nChars = dst + n; 140 nextChar = dst; 141 } 142 } 143 144 152 public int read() throws IOException { 153 synchronized (lock) { 154 ensureOpen(); 155 for (;;) { 156 if (nextChar >= nChars) { 157 fill(); 158 if (nextChar >= nChars) 159 return -1; 160 } 161 if (skipLF) { 162 skipLF = false; 163 if (cb[nextChar] == '\n') { 164 nextChar++; 165 continue; 166 } 167 } 168 return cb[nextChar++]; 169 } 170 } 171 } 172 173 177 private int read1(char[] cbuf, int off, int len) throws IOException { 178 if (nextChar >= nChars) { 179 184 if (len >= cb.length && markedChar <= UNMARKED && !skipLF) { 185 return in.read(cbuf, off, len); 186 } 187 fill(); 188 } 189 if (nextChar >= nChars) return -1; 190 if (skipLF) { 191 skipLF = false; 192 if (cb[nextChar] == '\n') { 193 nextChar++; 194 if (nextChar >= nChars) 195 fill(); 196 if (nextChar >= nChars) 197 return -1; 198 } 199 } 200 int n = Math.min(len, nChars - nextChar); 201 System.arraycopy(cb, nextChar, cbuf, off, n); 202 nextChar += n; 203 return n; 204 } 205 206 251 public int read(char cbuf[], int off, int len) throws IOException { 252 synchronized (lock) { 253 ensureOpen(); 254 if ((off < 0) || (off > cbuf.length) || (len < 0) || 255 ((off + len) > cbuf.length) || ((off + len) < 0)) { 256 throw new IndexOutOfBoundsException (); 257 } else if (len == 0) { 258 return 0; 259 } 260 261 int n = read1(cbuf, off, len); 262 if (n <= 0) return n; 263 while ((n < len) && in.ready()) { 264 int n1 = read1(cbuf, off + n, len - n); 265 if (n1 <= 0) break; 266 n += n1; 267 } 268 return n; 269 } 270 } 271 272 287 String readLine(boolean ignoreLF) throws IOException { 288 StringBuffer s = null; 289 int startChar; 290 boolean omitLF = ignoreLF || skipLF; 291 292 synchronized (lock) { 293 ensureOpen(); 294 295 bufferLoop: 296 for (;;) { 297 298 if (nextChar >= nChars) 299 fill(); 300 if (nextChar >= nChars) { 301 if (s != null && s.length() > 0) 302 return s.toString(); 303 else 304 return null; 305 } 306 boolean eol = false; 307 char c = 0; 308 int i; 309 310 311 if (omitLF && (cb[nextChar] == '\n')) 312 nextChar++; 313 skipLF = false; 314 omitLF = false; 315 316 charLoop: 317 for (i = nextChar; i < nChars; i++) { 318 c = cb[i]; 319 if ((c == '\n') || (c == '\r')) { 320 eol = true; 321 break charLoop; 322 } 323 } 324 325 startChar = nextChar; 326 nextChar = i; 327 328 if (eol) { 329 String str; 330 if (s == null) { 331 str = new String (cb, startChar, i - startChar); 332 } else { 333 s.append(cb, startChar, i - startChar); 334 str = s.toString(); 335 } 336 nextChar++; 337 if (c == '\r') { 338 skipLF = true; 339 } 340 return str; 341 } 342 343 if (s == null) 344 s = new StringBuffer (defaultExpectedLineLength); 345 s.append(cb, startChar, i - startChar); 346 } 347 } 348 } 349 350 361 public String readLine() throws IOException { 362 return readLine(false); 363 } 364 365 375 public long skip(long n) throws IOException { 376 if (n < 0L) { 377 throw new IllegalArgumentException ("skip value is negative"); 378 } 379 synchronized (lock) { 380 ensureOpen(); 381 long r = n; 382 while (r > 0) { 383 if (nextChar >= nChars) 384 fill(); 385 if (nextChar >= nChars) 386 break; 387 if (skipLF) { 388 skipLF = false; 389 if (cb[nextChar] == '\n') { 390 nextChar++; 391 } 392 } 393 long d = nChars - nextChar; 394 if (r <= d) { 395 nextChar += r; 396 r = 0; 397 break; 398 } 399 else { 400 r -= d; 401 nextChar = nChars; 402 } 403 } 404 return n - r; 405 } 406 } 407 408 415 public boolean ready() throws IOException { 416 synchronized (lock) { 417 ensureOpen(); 418 419 423 if (skipLF) { 424 427 if (nextChar >= nChars && in.ready()) { 428 fill(); 429 } 430 if (nextChar < nChars) { 431 if (cb[nextChar] == '\n') 432 nextChar++; 433 skipLF = false; 434 } 435 } 436 return (nextChar < nChars) || in.ready(); 437 } 438 } 439 440 443 public boolean markSupported() { 444 return true; 445 } 446 447 463 public void mark(int readAheadLimit) throws IOException { 464 if (readAheadLimit < 0) { 465 throw new IllegalArgumentException ("Read-ahead limit < 0"); 466 } 467 synchronized (lock) { 468 ensureOpen(); 469 this.readAheadLimit = readAheadLimit; 470 markedChar = nextChar; 471 markedSkipLF = skipLF; 472 } 473 } 474 475 481 public void reset() throws IOException { 482 synchronized (lock) { 483 ensureOpen(); 484 if (markedChar < 0) 485 throw new IOException ((markedChar == INVALIDATED) 486 ? "Mark invalid" 487 : "Stream not marked"); 488 nextChar = markedChar; 489 skipLF = markedSkipLF; 490 } 491 } 492 493 498 public void close() throws IOException { 499 synchronized (lock) { 500 if (in == null) 501 return; 502 in.close(); 503 in = null; 504 cb = null; 505 } 506 } 507 508 } 509 | Popular Tags |