package net.i2p.data.i2cp; /* * 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 java.io.InputStream; import java.io.OutputStream; import java.util.Date; import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.DateAndFlags; /** * Same as SendMessageMessage, but with an expiration to be passed to the router * * As of 0.8.4, retrofitted to use DateAndFlags. Backwards compatible. * * @author zzz */ public class SendMessageExpiresMessage extends SendMessageMessage { /* FIXME hides another field FIXME */ public final static int MESSAGE_TYPE = 36; private final DateAndFlags _daf; public SendMessageExpiresMessage() { this(new DateAndFlags()); } /** @since 0.9.2 */ public SendMessageExpiresMessage(DateAndFlags options) { super(); _daf = options; } /** * The Date object is created here, it is not cached. * Use getExpirationTime() if you only need the long value. */ public Date getExpiration() { return _daf.getDate(); } /** * Use this instead of getExpiration().getTime() * @since 0.8.4 */ public long getExpirationTime() { return _daf.getTime(); } public void setExpiration(Date d) { _daf.setDate(d); } /** * @since 0.8.4 */ public void setExpiration(long d) { _daf.setDate(d); } /** * @since 0.8.4 */ public int getFlags() { return _daf.getFlags(); } /** * @since 0.8.4 */ public void setFlags(int f) { _daf.setFlags(f); } /** * Read the body into the data structures * * @throws IOException */ @Override public void readMessage(InputStream in, int length, int type) throws I2CPMessageException, IOException { super.readMessage(in, length, type); try { _daf.readBytes(in); } catch (DataFormatException dfe) { throw new I2CPMessageException("Unable to load the message data", dfe); } } /** * Write out the full message to the stream, including the 4 byte size and 1 * byte type header. Override the parent so we can be more mem efficient * * @throws IOException */ @Override public void writeMessage(OutputStream out) throws I2CPMessageException, IOException { if (_sessionId == null) throw new I2CPMessageException("No session ID"); if (_destination == null) throw new I2CPMessageException("No dest"); if (_payload == null) throw new I2CPMessageException("No payload"); if (_nonce < 0) throw new I2CPMessageException("No nonce"); int len = 2 + _destination.size() + _payload.getSize() + 4 + 4 + DataHelper.DATE_LENGTH; try { DataHelper.writeLong(out, 4, len); out.write((byte) MESSAGE_TYPE); _sessionId.writeBytes(out); _destination.writeBytes(out); _payload.writeBytes(out); DataHelper.writeLong(out, 4, _nonce); _daf.writeBytes(out); } catch (DataFormatException dfe) { throw new I2CPMessageException("Error writing the msg", dfe); } } @Override public int getType() { return MESSAGE_TYPE; } @Override public String toString() { StringBuilder buf = new StringBuilder(); buf.append("[SendMessageExpiresMessage: "); buf.append("\n\tSessionId: ").append(_sessionId); buf.append("\n\tNonce: ").append(_nonce); buf.append("\n\tDestination: ").append(_destination); buf.append("\n\tExpiration: ").append(getExpiration()); buf.append("\n\tPayload: ").append(_payload); buf.append("]"); return buf.toString(); } }