package dk.silverbullet.telemed.device.continua;
import java.io.IOException;
public class PacketCollector {
private static final int NUMBER_OF_HEADER_BYTES = 4;
private final PacketParser parser;
private int counter;
private int tagValue;
private ContinuaPacketTag tag;
private int length;
private byte[] contents;
public PacketCollector(PacketParser parser) {
this.parser = parser;
}
public void receive(byte b) {
switch (counter) {
case 0:
tagValue = (b & 0xFF) << 8;
break;
case 1:
tagValue |= (b & 0xFF);
if (!ContinuaPacketTag.isKnownTagValue(tagValue)) {
reset();
return;
}
tag = ContinuaPacketTag.packetTagForValue(tagValue);
break;
case 2:
length = (b & 0xFF) << 8;
break;
case 3:
length |= (b & 0xFF);
if (!reasonableLength(length)) {
reset();
return;
}
contents = new byte[length];
break;
default:
contents[counter - NUMBER_OF_HEADER_BYTES] = b;
}
counter++;
if (hasReceivedWholeBody()) {
try {
parser.handle(tag, contents);
} catch (IOException ex) {
error(ex);
} finally {
resetBuffer();
}
}
}
public void error(IOException e) {
parser.errorReceived(e);
}
public void reset() {
resetBuffer();
parser.reset();
}
private boolean hasReceivedWholeBody() {
int receivedNumberOfBodyBytes = counter - NUMBER_OF_HEADER_BYTES;
return receivedNumberOfBodyBytes == length;
}
private void resetBuffer() {
counter = 0;
}
private boolean reasonableLength(int length) {
return length >= 2 && length < 1000;
}
}