import java.io.*;
import java.util.*;
/**
* This class implements a buffer that rectifies some
* problems with asynchronous receive of Lego messages.
* For reasons that are not completely clear, messages
* received over the IR interface, will sometimes be
* broken up into mutiple chunks. The MessageListener
* client will be notified upon reception of each chunk.
* To relieve the client of the burdon to buffer and
* later on assemble theses messages, this class is provided.
* Message chunks are appended to the buffer using the
* append() method. The buffer uses the 0x55ff00 message
* header as a frame sync to recognize message boundaries.
* Clients will be notified only upon reception of complete
* messages.
*/
public class MessageBuffer {
private byte[] buf = new byte[128];
int index = 0;
private boolean flush = false;
Vector listeners = new Vector();
/** add an asynchronous message listener */
public void addMessageListener(MessageListener l) {
listeners.addElement(l);
}
/** remove an asynchronous message listener */
public void removeMessageListener(MessageListener l) {
listeners.removeElement(l);
}
/** add a message chunk to the buffer */
public synchronized void append(byte[] suffix) throws IOException {
if (index + suffix.length >= buf.length) {
System.out.println("ERROR: MessageBuffer receive buf full!");
System.out.println("Probable cause: ambient light interference with IR.");
throw new RuntimeException("ReceiveBufferOverflow");
}
System.arraycopy(suffix, 0, buf, index, suffix.length);
index += suffix.length;
// Brick.printMessage("MessageBuffer.append(): buf is now", buf);
byte[] msg;
while ((msg = getMsg()) != null) {
for (int i=0; i= 3 && buf[i] == (byte)0x55
&& buf[i+1] == (byte)0xff && buf[i+2] == (byte)0x00) {
return i;
}
}
return -1;
}
private byte[] unwrap(byte[] wrapped) {
if (wrapped.length < 7) return null;
byte[] msg = new byte[(wrapped.length - 5)/2];
for (int i=0; i 0) {
int size = Math.min(buf.length, nextHeader);
byte[] msg = new byte[size];
System.arraycopy(buf, 0, msg, 0, size);
System.arraycopy(buf, size, buf, 0, buf.length - size);
index -= size;
// Brick.printMessage("MessageBuffer.getMsg(): buf is now", buf);
flush = false;
return unwrap(msg);
}
return null;
}
}