Howdy all!
I've implemented a protocol parser using Ash2K:s case as a template and I
get the same result. I send a message of somehting like 15k bytes.
I save the buffer, return wants_more_data = true and I expect the same
parser to be called again but instead a new one is created and so I lose my
saved buffer.
Running 1.7.2 with the debugger I notice that the return value from
releaseBuffer() is ignored.
Here's my protocol parser:
public class ProtocolParser implements
com.sun.grizzly.ProtocolParser<SimpleMessage> {
private ByteBuffer saved,retain_buffer;
private int position;
private int limit;
private SimpleMessage mess;
private boolean wants_more_data = false;
private boolean has_unparsed_data = false;
public ProtocolParser() {
System.out.println("Creating a new ProtocolParser");
retain_buffer = ByteBuffer.allocateDirect(18000);
}
public boolean isExpectingMoreData() {
System.out.println("isExpectingMoreData : "+wants_more_data);
return wants_more_data;
}
public boolean hasMoreBytesToParse() {
return has_unparsed_data;
}
public SimpleMessage getNextMessage() {
// the call pattern should be:
// hasNextMessage() == true
// getNextMessage()
// but if not:
if (null == mess) {
mess = extractMessage();
}
SimpleMessage tmp = mess;
mess = null;
return tmp;
}
public boolean hasNextMessage() {
if (null == mess) {
mess = extractMessage();
}
return ( mess != null);
}
public void startBuffer(ByteBuffer bb) {
saved = bb;
saved.flip(); // flip the byte buffer for reading. (should have been
done already)
if ((saved.remaining() > retain_buffer.remaining())) {
// grow the retain buffer...
System.out.println("Grow retain buffer not implemented");
return;
}
retain_buffer.put(saved);
retain_buffer.flip();
bb.clear();
}
public boolean releaseBuffer() {
System.out.println("releaseBuffer : ");
if (wants_more_data) {
System.out.println("releaseBuffer : Doing compact");
retain_buffer.compact();
} else {
retain_buffer.clear();
}
return wants_more_data;
}
private SimpleMessage extractMessage() {
SimpleMessage message = null;
if (!retain_buffer.hasRemaining()) {
// there are no more readable bytes in the buffer
// this should mean that we've read all messages in the buffer
wants_more_data = false;
has_unparsed_data = false;
saved.clear(); // clean up our byte buffer. No one else will do it for
us
return message;
}
// save the position before we send it off to the parser
position = retain_buffer.position();
message = SimpleMessage.parse(retain_buffer);
System.out.println("parsed message is null ? "+(message == null ? "YES"
: "NO"));
if (message == null) {
// not enough bytes for a message
// but we know there are bytes so there must be
// an incomplete message there
if (retain_buffer.position() != position) {
retain_buffer.position(position);
}
wants_more_data = true;
has_unparsed_data = false;
} else {
// here we have a complete message
if (retain_buffer.limit() == retain_buffer.position()) {
// the end of the buffer is reached.
wants_more_data = false;
has_unparsed_data = false;
} else {
has_unparsed_data = true;
// here we can't accuratly set wants_more_data.
// since we don't know if the bytes in the buffer is a
// complete message or not
}
}
return message;
}
}
cheers
/Erik