1 7 8 package java.io; 9 10 import java.util.*; 11 import java.nio.charset.Charset ; 12 import sun.nio.cs.StreamDecoder; 13 import sun.nio.cs.StreamEncoder; 14 15 74 75 public final class Console implements Flushable 76 { 77 83 public PrintWriter writer() { 84 return pw; 85 } 86 87 116 public Reader reader() { 117 return reader; 118 } 119 120 150 public Console format(String fmt, Object ...args) { 151 formatter.format(fmt, args).flush(); 152 return this; 153 } 154 155 189 public Console printf(String format, Object ... args) { 190 return format(format, args); 191 } 192 193 225 public String readLine(String fmt, Object ... args) { 226 String line = null; 227 synchronized (writeLock) { 228 synchronized(readLock) { 229 if (fmt.length() != 0) 230 pw.format(fmt, args); 231 try { 232 char[] ca = readline(false); 233 if (ca != null) 234 line = new String (ca); 235 } catch (IOException x) { 236 throw new IOError (x); 237 } 238 } 239 } 240 return line; 241 } 242 243 253 public String readLine() { 254 return readLine(""); 255 } 256 257 290 public char[] readPassword(String fmt, Object ... args) { 291 char[] passwd = null; 292 synchronized (writeLock) { 293 synchronized(readLock) { 294 if (fmt.length() != 0) 295 pw.format(fmt, args); 296 try { 297 echoOff = echo(false); 298 passwd = readline(true); 299 } catch (IOException x) { 300 throw new IOError (x); 301 } finally { 302 try { 303 echoOff = echo(true); 304 } catch (IOException xx) {} 305 } 306 pw.println(); 307 } 308 } 309 return passwd; 310 } 311 312 322 public char[] readPassword() { 323 return readPassword(""); 324 } 325 326 330 public void flush() { 331 pw.flush(); 332 } 333 334 private Object readLock; 335 private Object writeLock; 336 private Reader reader; 337 private Writer out; 338 private PrintWriter pw; 339 private Formatter formatter; 340 private Charset cs; 341 private char[] rcb; 342 private static native String encoding(); 343 private static native boolean echo(boolean on) throws IOException ; 344 private static boolean echoOff; 345 346 private char[] readline(boolean zeroOut) throws IOException { 347 int len = reader.read(rcb, 0, rcb.length); 348 if (len < 0) 349 return null; if (rcb[len-1] == '\r') 351 len--; else if (rcb[len-1] == '\n') { 353 len--; if (len > 0 && rcb[len-1] == '\r') 355 len--; } 357 char[] b = new char[len]; 358 if (len > 0) { 359 System.arraycopy(rcb, 0, b, 0, len); 360 if (zeroOut) { 361 Arrays.fill(rcb, 0, len, ' '); 362 } 363 } 364 return b; 365 } 366 367 private char[] grow() { 368 assert Thread.holdsLock(readLock); 369 char[] t = new char[rcb.length * 2]; 370 System.arraycopy(rcb, 0, t, 0, rcb.length); 371 rcb = t; 372 return rcb; 373 } 374 375 class LineReader extends Reader { 376 private Reader in; 377 private char[] cb; 378 private int nChars, nextChar; 379 boolean leftoverLF; 380 LineReader(Reader in) { 381 this.in = in; 382 cb = new char[1024]; 383 nextChar = nChars = 0; 384 leftoverLF = false; 385 } 386 public void close () {} 387 public boolean ready() throws IOException { 388 return in.ready(); 390 } 391 392 public int read(char cbuf[], int offset, int length) 393 throws IOException 394 { 395 int off = offset; 396 int end = offset + length; 397 if (offset < 0 || offset > cbuf.length || length < 0 || 398 end < 0 || end > cbuf.length) { 399 throw new IndexOutOfBoundsException (); 400 } 401 synchronized(readLock) { 402 boolean eof = false; 403 char c = 0; 404 for (;;) { 405 if (nextChar >= nChars) { int n = 0; 407 do { 408 n = in.read(cb, 0, cb.length); 409 } while (n == 0); 410 if (n > 0) { 411 nChars = n; 412 nextChar = 0; 413 if (n < cb.length && 414 cb[n-1] != '\n' && cb[n-1] != '\r') { 415 420 eof = true; 421 } 422 } else { 423 if (off - offset == 0) 424 return -1; 425 return off - offset; 426 } 427 } 428 if (leftoverLF && cbuf == rcb && cb[nextChar] == '\n') { 429 433 nextChar++; 434 } 435 leftoverLF = false; 436 while (nextChar < nChars) { 437 c = cbuf[off++] = cb[nextChar]; 438 cb[nextChar++] = 0; 439 if (c == '\n') { 440 return off - offset; 441 } else if (c == '\r') { 442 if (off == end) { 443 447 if (cbuf == rcb) { 448 cbuf = grow(); 449 end = cbuf.length; 450 } else { 451 leftoverLF = true; 452 return off - offset; 453 } 454 } 455 if (nextChar == nChars && in.ready()) { 456 463 nChars = in.read(cb, 0, cb.length); 464 nextChar = 0; 465 } 466 if (nextChar < nChars && cb[nextChar] == '\n') { 467 cbuf[off++] = '\n'; 468 nextChar++; 469 } 470 return off - offset; 471 } else if (off == end) { 472 if (cbuf == rcb) { 473 cbuf = grow(); 474 end = cbuf.length; 475 } else { 476 return off - offset; 477 } 478 } 479 } 480 if (eof) 481 return off - offset; 482 } 483 } 484 } 485 } 486 487 static { 489 sun.misc.SharedSecrets.setJavaIOAccess(new sun.misc.JavaIOAccess() { 490 public Console console() { 491 if (istty()) { 492 if (cons == null) 493 cons = new Console (); 494 return cons; 495 } 496 return null; 497 } 498 499 public Runnable consoleRestoreHook() { 502 return new Runnable () { 503 public void run() { 504 try { 505 if (echoOff) { 506 echo(true); 507 } 508 } catch (IOException x) {} 509 } 510 }; 511 } 512 513 public Charset charset() { 514 return cons.cs; 517 } 518 }); 519 } 520 private static Console cons; 521 private native static boolean istty(); 522 private Console() { 523 readLock = new Object (); 524 writeLock = new Object (); 525 String csname = encoding(); 526 if (csname != null) { 527 try { 528 cs = Charset.forName(csname); 529 } catch (Exception x) {} 530 } 531 if (cs == null) 532 cs = Charset.defaultCharset(); 533 out = StreamEncoder.forOutputStreamWriter( 534 new FileOutputStream (FileDescriptor.out), 535 writeLock, 536 cs); 537 pw = new PrintWriter (out, true) { public void close() {} }; 538 formatter = new Formatter(out); 539 reader = new LineReader(StreamDecoder.forInputStreamReader( 540 new FileInputStream (FileDescriptor.in), 541 readLock, 542 cs)); 543 rcb = new char[1024]; 544 } 545 } 546 547 | Popular Tags |