package com.tecspy.protocol;
import java.io.IOException;
import org.apache.log4j.Logger;
/**
* Is fed with bytes from an input stream and issues complete messages. The
* messages are terminated by a single end byte, "etx".
*
* @author Michael Erskine
*
*/
public abstract class EtxMessageByteSink implements ByteSink {
/** Standard log4j logger */
protected static Logger log = Logger.getLogger(EtxMessageByteSink.class);
/**
* Currently forming message buffer - should be constructed to the expected
* size of typical messages rather than the maximum
*/
protected StringBuilder msg;
/** Message end byte */
protected byte etx = (byte) 0x03;
/** Maximum message length */
protected int maxmsg = 1000;
/**
* An indication of the number of bytes read. NB: not necessarily 100%
* correct.
*/
public long byteTotal = 0;
/**
* A subclass constructor must create the message buffer e.g.: -
*
* <code>
* super();
* etx = (byte) 0xFE;
* maxmsg = 1000;
* msg = new StringBuilder(1000);
* </code>
*
*/
public EtxMessageByteSink() {
}
protected abstract void handleMsg();
/*
* (non-Javadoc)
*
* @see com.ketech.swim.ByteSink#processBytes(byte[], int)
*/
public int processBytes(byte[] buf, int len) {
// incrementing the byte total here rather than for each byte
byteTotal += len;
for (int i = 0; i < len; i++) { // foreach byte
// we are waiting for data or etx
if (buf[i] == etx) {
// etx is a normal condition - flush
handleMsg();
msg.setLength(0);
} else {
// normal condition add byte to message
char c = (char) buf[i];
if (msg.length() >= maxmsg) {
// interested in how this condition is unit tested - somehow
// have a log4j logger log to somewhere inparticular that
// can be examined
log.error("maximum message length exceeded (" + maxmsg
+ "): buffered data discarded");
msg.setLength(0);
}
msg.append(c);
}
}
return len;
}
/*
* (non-Javadoc)
*
* @see com.ketech.swim.ByteSink#processEof()
*/
public abstract void processEof();
/*
* (non-Javadoc)
*
* @see com.ketech.swim.ByteSink#processException(java.io.IOException)
*/
public abstract void processException(IOException e);
}