Files
i2p.itoopie/router/java/src/net/i2p/data/i2np/I2NPMessageReader.java

149 lines
5.3 KiB
Java
Raw Normal View History

2004-04-08 04:41:54 +00:00
package net.i2p.data.i2np;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2003 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
2004-04-08 04:41:54 +00:00
* your children, but it might. Use at your own risk.
*
*/
import java.io.IOException;
import java.io.InputStream;
import net.i2p.router.RouterContext;
2004-04-08 04:41:54 +00:00
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
* The I2NPMessageReader reads an InputStream (using
2004-04-08 04:41:54 +00:00
* {@link I2NPMessageHandler I2NPMessageHandler}) and passes out events to a registered
* listener, where events are either messages being received, exceptions being
* thrown, or the connection being closed. Routers should use this rather
* than read from the stream themselves.
*
* @author jrandom
*/
public class I2NPMessageReader {
private Log _log;
private RouterContext _context;
2004-04-08 04:41:54 +00:00
private InputStream _stream;
private I2NPMessageEventListener _listener;
private I2NPMessageReaderRunner _reader;
private Thread _readerThread;
public I2NPMessageReader(RouterContext context, InputStream stream, I2NPMessageEventListener lsnr) {
this(context, stream, lsnr, "I2NP Reader");
2004-04-08 04:41:54 +00:00
}
public I2NPMessageReader(RouterContext context, InputStream stream, I2NPMessageEventListener lsnr, String name) {
_context = context;
_log = context.logManager().getLog(I2NPMessageReader.class);
_stream = stream;
2004-04-08 04:41:54 +00:00
setListener(lsnr);
_reader = new I2NPMessageReaderRunner();
_readerThread = new I2PThread(_reader);
_readerThread.setName(name);
_readerThread.setDaemon(true);
2004-04-08 04:41:54 +00:00
}
public void setListener(I2NPMessageEventListener lsnr) { _listener = lsnr; }
public I2NPMessageEventListener getListener() { return _listener; }
/**
* Instruct the reader to begin reading messages off the stream
*
*/
public void startReading() { _readerThread.start(); }
2004-04-08 04:41:54 +00:00
/**
* Have the already started reader pause its reading indefinitely
*
*/
public void pauseReading() { _reader.pauseRunner(); }
/**
* Resume reading after a pause
*
*/
public void resumeReading() { _reader.resumeRunner(); }
/**
* Cancel reading.
2004-04-08 04:41:54 +00:00
*
*/
public void stopReading() { _reader.cancelRunner(); }
/**
* Defines the different events the reader produces while reading the stream
*
*/
public static interface I2NPMessageEventListener {
/**
* Notify the listener that a message has been received from the given
* reader
*
*/
public void messageReceived(I2NPMessageReader reader, I2NPMessage message, long msToRead);
/**
* Notify the listener that an exception was thrown while reading from the given
* reader
*
*/
public void readError(I2NPMessageReader reader, Exception error);
/**
* Notify the listener that the stream the given reader was running off
* closed
*
*/
public void disconnected(I2NPMessageReader reader);
}
2004-04-08 04:41:54 +00:00
private class I2NPMessageReaderRunner implements Runnable {
private boolean _doRun;
2004-04-08 04:41:54 +00:00
private boolean _stayAlive;
private I2NPMessageHandler _handler;
2004-04-08 04:41:54 +00:00
public I2NPMessageReaderRunner() {
_doRun = true;
_stayAlive = true;
_handler = new I2NPMessageHandler(_context);
2004-04-08 04:41:54 +00:00
}
public void pauseRunner() { _doRun = false; }
public void resumeRunner() { _doRun = true; }
public void cancelRunner() {
2004-04-08 04:41:54 +00:00
_doRun = false;
_stayAlive = false;
2004-04-08 04:41:54 +00:00
}
public void run() {
while (_stayAlive) {
while (_doRun) {
while (!_context.throttle().acceptNetworkMessage()) {
try { Thread.sleep(500 + _context.random().nextInt(512)); } catch (InterruptedException ie) {}
}
2004-04-08 04:41:54 +00:00
// do read
try {
I2NPMessage msg = _handler.readMessage(_stream);
if (msg != null) {
long msToRead = _handler.getLastReadTime();
2004-04-08 04:41:54 +00:00
_listener.messageReceived(I2NPMessageReader.this, msg, msToRead);
}
2004-04-08 04:41:54 +00:00
} catch (I2NPMessageException ime) {
2004-06-25 17:02:22 +00:00
if (_log.shouldLog(Log.WARN))
_log.warn("Error handling message", ime);
2004-04-08 04:41:54 +00:00
_listener.readError(I2NPMessageReader.this, ime);
_listener.disconnected(I2NPMessageReader.this);
cancelRunner();
2004-04-08 04:41:54 +00:00
} catch (IOException ioe) {
2004-06-25 17:02:22 +00:00
if (_log.shouldLog(Log.WARN))
_log.warn("IO Error handling message", ioe);
2004-04-08 04:41:54 +00:00
_listener.disconnected(I2NPMessageReader.this);
cancelRunner();
}
}
if (!_doRun) {
// pause .5 secs when we're paused
try { Thread.sleep(500); } catch (InterruptedException ie) {}
}
}
// boom bye bye bad bwoy
}
}
}