net.i2p.data.i2np.I2NPMessageHandler Maven / Gradle / Ivy
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
* your children, but it might. Use at your own risk.
*
*/
import java.io.IOException;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
/**
* Handle messages from router to router. This class is NOT threadsafe
*
*/
public class I2NPMessageHandler {
private final Log _log;
private final I2PAppContext _context;
private I2NPMessage _lastRead;
public I2NPMessageHandler(I2PAppContext context) {
_context = context;
_log = context.logManager().getLog(I2NPMessageHandler.class);
}
/** clear the last message read from a byte array with an offset */
public I2NPMessage lastRead() {
I2NPMessage rv = _lastRead;
_lastRead = null;
return rv;
}
/**
* Read an I2NPMessage from the byte array and return the fully populated object.
*
* @throws I2NPMessageException if there is a problem handling the particular
* message - if it is an unknown type or has improper formatting, etc.
*/
public I2NPMessage readMessage(byte data[]) throws I2NPMessageException {
readMessage(data, 0, data.length);
return lastRead();
}
/**
* Result is retreived with lastRead()
*/
public int readMessage(byte data[], int offset) throws I2NPMessageException {
return readMessage(data, offset, data.length - offset);
}
/**
* Set a limit on the max to read from the data buffer, so that
* we can use a large buffer but prevent the reader from reading off the end.
*
* Result is retreived with lastRead()
*
* @param maxLen read no more than this many bytes from data starting at offset, even if it is longer
* must be at least 16
* @since 0.8.12
*/
public int readMessage(byte data[], int offset, int maxLen) throws I2NPMessageException {
int cur = offset;
// we will assume that maxLen is >= 1 here. It's checked to be >= 16 in readBytes()
int type = data[cur] & 0xff;
cur++;
I2NPMessage msg = I2NPMessageImpl.createMessage(_context, type);
try {
int lastSize = msg.readBytes(data, type, cur, maxLen - 1);
cur += lastSize;
} catch (I2NPMessageException ime) {
throw ime;
} catch (RuntimeException e) {
if (_log.shouldLog(Log.WARN))
_log.warn("Error reading the stream", e);
throw new I2NPMessageException("Unknown error reading the " + msg.getClass().getSimpleName(), e);
}
_lastRead = msg;
return cur - offset;
}
}