Methods Summary |
---|
private void | __processChar(int ch)
// Critical section because we're altering __bytesAvailable,
// __queueTail, and the contents of _queue.
synchronized (__queue)
{
while (__bytesAvailable >= __queue.length - 1)
{
if(__threaded)
{
__queue.notify();
try
{
__queue.wait();
}
catch (InterruptedException e)
{
throw e;
}
}
}
// Need to do this in case we're not full, but block on a read
if (__readIsWaiting && __threaded)
{
__queue.notify();
}
__queue[__queueTail] = ch;
++__bytesAvailable;
if (++__queueTail >= __queue.length)
__queueTail = 0;
}
|
private int | __read()
int ch;
_loop:
while (true)
{
// Exit only when we reach end of stream.
if ((ch = super.read()) < 0)
return -1;
ch = (ch & 0xff);
/* Code Section added for supporting AYT (start)*/
synchronized (__client)
{
__client._processAYTResponse();
}
/* Code Section added for supporting AYT (end)*/
/* Code Section added for supporting spystreams (start)*/
__client._spyRead(ch);
/* Code Section added for supporting spystreams (end)*/
_mainSwitch:
switch (__receiveState)
{
case _STATE_CR:
if (ch == '\0")
{
// Strip null
continue;
}
// How do we handle newline after cr?
// else if (ch == '\n' && _requestedDont(TelnetOption.ECHO) &&
// Handle as normal data by falling through to _STATE_DATA case
case _STATE_DATA:
if (ch == TelnetCommand.IAC)
{
__receiveState = _STATE_IAC;
continue;
}
if (ch == '\r")
{
synchronized (__client)
{
if (__client._requestedDont(TelnetOption.BINARY))
__receiveState = _STATE_CR;
else
__receiveState = _STATE_DATA;
}
}
else
__receiveState = _STATE_DATA;
break;
case _STATE_IAC:
switch (ch)
{
case TelnetCommand.WILL:
__receiveState = _STATE_WILL;
continue;
case TelnetCommand.WONT:
__receiveState = _STATE_WONT;
continue;
case TelnetCommand.DO:
__receiveState = _STATE_DO;
continue;
case TelnetCommand.DONT:
__receiveState = _STATE_DONT;
continue;
/* TERMINAL-TYPE option (start)*/
case TelnetCommand.SB:
__suboption_count = 0;
__receiveState = _STATE_SB;
continue;
/* TERMINAL-TYPE option (end)*/
case TelnetCommand.IAC:
__receiveState = _STATE_DATA;
break;
default:
break;
}
__receiveState = _STATE_DATA;
continue;
case _STATE_WILL:
synchronized (__client)
{
__client._processWill(ch);
__client._flushOutputStream();
}
__receiveState = _STATE_DATA;
continue;
case _STATE_WONT:
synchronized (__client)
{
__client._processWont(ch);
__client._flushOutputStream();
}
__receiveState = _STATE_DATA;
continue;
case _STATE_DO:
synchronized (__client)
{
__client._processDo(ch);
__client._flushOutputStream();
}
__receiveState = _STATE_DATA;
continue;
case _STATE_DONT:
synchronized (__client)
{
__client._processDont(ch);
__client._flushOutputStream();
}
__receiveState = _STATE_DATA;
continue;
/* TERMINAL-TYPE option (start)*/
case _STATE_SB:
switch (ch)
{
case TelnetCommand.IAC:
__receiveState = _STATE_IAC_SB;
continue;
default:
// store suboption char
__suboption[__suboption_count++] = ch;
break;
}
__receiveState = _STATE_SB;
continue;
case _STATE_IAC_SB:
switch (ch)
{
case TelnetCommand.SE:
synchronized (__client)
{
__client._processSuboption(__suboption, __suboption_count);
__client._flushOutputStream();
}
__receiveState = _STATE_DATA;
continue;
default:
__receiveState = _STATE_SB;
break;
}
__receiveState = _STATE_DATA;
continue;
/* TERMINAL-TYPE option (end)*/
}
break;
}
return ch;
|
void | _start()
if(__thread == null)
return;
int priority;
__isClosed = false;
// Need to set a higher priority in case JVM does not use pre-emptive
// threads. This should prevent scheduler induced deadlock (rather than
// deadlock caused by a bug in this code).
priority = Thread.currentThread().getPriority() + 1;
if (priority > Thread.MAX_PRIORITY)
priority = Thread.MAX_PRIORITY;
__thread.setPriority(priority);
__thread.setDaemon(true);
__thread.start();
__threaded = true;
|
public int | available()
// Critical section because run() may change __bytesAvailable
synchronized (__queue)
{
return __bytesAvailable;
}
|
public void | close()
// Completely disregard the fact thread may still be running.
// We can't afford to block on this close by waiting for
// thread to terminate because few if any JVM's will actually
// interrupt a system read() from the interrupt() method.
super.close();
synchronized (__queue)
{
__hasReachedEOF = true;
__isClosed = true;
if (__thread != null && __thread.isAlive())
{
__thread.interrupt();
}
__queue.notifyAll();
}
__threaded = false;
|
public boolean | markSupported()Returns false. Mark is not supported.
return false;
|
public int | read()
// Critical section because we're altering __bytesAvailable,
// __queueHead, and the contents of _queue in addition to
// testing value of __hasReachedEOF.
synchronized (__queue)
{
while (true)
{
if (__ioException != null)
{
IOException e;
e = __ioException;
__ioException = null;
throw e;
}
if (__bytesAvailable == 0)
{
// Return -1 if at end of file
if (__hasReachedEOF)
return -1;
// Otherwise, we have to wait for queue to get something
if(__threaded)
{
__queue.notify();
try
{
__readIsWaiting = true;
__queue.wait();
__readIsWaiting = false;
}
catch (InterruptedException e)
{
throw new IOException("Fatal thread interruption during read.");
}
}
else
{
//__alreadyread = false;
__readIsWaiting = true;
int ch;
do
{
try
{
if ((ch = __read()) < 0)
if(ch != -2)
return (ch);
}
catch (InterruptedIOException e)
{
synchronized (__queue)
{
__ioException = e;
__queue.notifyAll();
try
{
__queue.wait(100);
}
catch (InterruptedException interrupted)
{
}
}
return (-1);
}
try
{
if(ch != -2)
{
__processChar(ch);
}
}
catch (InterruptedException e)
{
if (__isClosed)
return (-1);
}
}
while (super.available() > 0);
__readIsWaiting = false;
}
continue;
}
else
{
int ch;
ch = __queue[__queueHead];
if (++__queueHead >= __queue.length)
__queueHead = 0;
--__bytesAvailable;
// Need to explicitly notify() so available() works properly
if(__bytesAvailable == 0 && __threaded) {
__queue.notify();
}
return ch;
}
}
}
|
public int | read(byte[] buffer)Reads the next number of bytes from the stream into an array and
returns the number of bytes read. Returns -1 if the end of the
stream has been reached.
return read(buffer, 0, buffer.length);
|
public int | read(byte[] buffer, int offset, int length)Reads the next number of bytes from the stream into an array and returns
the number of bytes read. Returns -1 if the end of the
message has been reached. The characters are stored in the array
starting from the given offset and up to the length specified.
int ch, off;
if (length < 1)
return 0;
// Critical section because run() may change __bytesAvailable
synchronized (__queue)
{
if (length > __bytesAvailable)
length = __bytesAvailable;
}
if ((ch = read()) == -1)
return -1;
off = offset;
do
{
buffer[offset++] = (byte)ch;
}
while (--length > 0 && (ch = read()) != -1);
//__client._spyRead(buffer, off, offset - off);
return (offset - off);
|
public void | run()
int ch;
try
{
_outerLoop:
while (!__isClosed)
{
try
{
if ((ch = __read()) < 0)
break;
}
catch (InterruptedIOException e)
{
synchronized (__queue)
{
__ioException = e;
__queue.notifyAll();
try
{
__queue.wait(100);
}
catch (InterruptedException interrupted)
{
if (__isClosed)
break _outerLoop;
}
continue;
}
} catch(RuntimeException re) {
// We treat any runtime exceptions as though the
// stream has been closed. We close the
// underlying stream just to be sure.
super.close();
// Breaking the loop has the effect of setting
// the state to closed at the end of the method.
break _outerLoop;
}
try
{
__processChar(ch);
}
catch (InterruptedException e)
{
if (__isClosed)
break _outerLoop;
}
}
}
catch (IOException ioe)
{
synchronized (__queue)
{
__ioException = ioe;
}
}
synchronized (__queue)
{
__isClosed = true; // Possibly redundant
__hasReachedEOF = true;
__queue.notify();
}
__threaded = false;
|