001: /*
002: * @(#)TerminalInputStream.java 1.2 04/12/06
003: *
004: * Copyright (c) 1997-2003 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.tools;
010:
011: import java.io.FilterInputStream;
012: import java.io.IOException;
013: import java.io.InputStream;
014:
015: /**
016: * InputStream of Terminal. To avoid blocking it runs background. When the Enter
017: * key is pressed or EOF is read the current line is sent to the InputStream.
018: *
019: * @version 1.1
020: * @author Toyokazu Tomatsu
021: */
022: class TerminalInputStream extends FilterInputStream implements Runnable {
023: private Thread runner;
024: private byte result[];
025: private int reslen;
026: private boolean EOF;
027: private IOException IOError;
028: private boolean enterred = false;
029:
030: TerminalInputStream(InputStream in, int bufsize) {
031: super (in);
032: result = new byte[bufsize];
033: reslen = 0;
034: EOF = false;
035: IOError = null;
036: runner = new Thread(this , "Terminal");
037: runner.setPriority(2);
038: runner.setDaemon(true);
039: runner.start();
040: }
041:
042: TerminalInputStream(InputStream in) {
043: this (in, 1024);
044: }
045:
046: public void setPriority(int prio) {
047: runner.setPriority(prio);
048: }
049:
050: public synchronized int read() throws IOException {
051: while (reslen == 0 || !enterred) {
052: try {
053: if (EOF) {
054: return -1;
055: }
056: if (IOError != null) {
057: throw IOError;
058: }
059: wait();
060: } catch (InterruptedException e) {
061: }
062: }
063: return (int) getChar();
064: }
065:
066: public synchronized int read(byte b[]) throws IOException {
067: return read(b, 0, b.length);
068: }
069:
070: public synchronized int read(byte b[], int off, int len)
071: throws IOException {
072: while (reslen == 0 || !enterred) {
073: try {
074: if (EOF)
075: return -1;
076: if (IOError != null)
077: throw IOError;
078: wait();
079: } catch (InterruptedException e) {
080: }
081: }
082: int sizeread = Math.min(reslen, len);
083: byte c[] = getChars(sizeread);
084: System.arraycopy(c, 0, b, off, sizeread);
085: return sizeread;
086: }
087:
088: public synchronized long skip(long n) throws IOException {
089: int sizeskip = Math.min(reslen, (int) n);
090: if (sizeskip > 0) {
091: getChars(sizeskip);
092: }
093: return ((long) sizeskip);
094: }
095:
096: public synchronized int available() throws IOException {
097: return reslen;
098: }
099:
100: public synchronized void close() throws IOException {
101: reslen = 0;
102: in.close();
103: EOF = true;
104: notifyAll();
105: }
106:
107: public synchronized void reset() throws IOException {
108: super .reset();
109: reslen = 0;
110: enterred = false;
111: }
112:
113: public boolean markSupported() {
114: return false;
115: }
116:
117: public void run() {
118: try {
119: while (true) {
120: int c = in.read();
121: synchronized (this ) {
122: if ((c == -1) || EOF) {
123: EOF = true;
124: enterred = true;
125: notifyAll();
126: return;
127: } else {
128: putChar((byte) c);
129: }
130: }
131: }
132: } catch (IOException e) {
133: synchronized (this ) {
134: IOError = e;
135: }
136: return;
137: } finally {
138: synchronized (this ) {
139: notifyAll();
140: }
141: }
142: }
143:
144: private synchronized void putChar(byte c) {
145: if (c == 10 || c == 13) {
146: enterred = true;
147: }
148: if (reslen >= result.length) {
149: byte[] result2 = new byte[result.length * 2];
150: System.arraycopy(result, 0, result2, 0, result.length);
151: result = result2;
152: }
153: result[reslen++] = c;
154: if (enterred) {
155: notifyAll();
156: }
157: }
158:
159: private synchronized byte getChar() {
160: byte c = result[0];
161: if (--reslen > 0) {
162: System.arraycopy(result, 1, result, 0, reslen);
163: } else {
164: enterred = false;
165: }
166: return c;
167: }
168:
169: private synchronized byte[] getChars(int chars) {
170: byte c[] = new byte[chars];
171: System.arraycopy(result, 0, c, 0, chars);
172: reslen -= chars;
173: if (reslen > 0) {
174: System.arraycopy(result, chars, result, 0, reslen);
175: } else {
176: enterred = false;
177: }
178: return c;
179: }
180: }
|