Ahh -- I might just have an older version checked out, although I'm not
seeing anything newer in the repository.
Below is the whole class regardless. The key is the isTerminator abstract
method. A more efficient way might be to pass however many terminators you
want in a varargs constructor to avoid the abstract method call -- I think I
did that at one point.
Good luck.
-Adam
public abstract class ConsumeToDynamicTerminatorDecodingState implements
DecodingState {
private ByteBuffer buffer;
/**
* Creates a new instance.
*/
public ConsumeToDynamicTerminatorDecodingState() {
}
public DecodingState decode(ByteBuffer in, ProtocolDecoderOutput out)
throws Exception {
int beginPos = in.position();
int terminatorPos = -1;
int limit = in.limit();
for (int i = beginPos; i < limit; i ++) {
byte b = in.get(i);
if (isTerminator(b)) {
terminatorPos = i;
break;
}
}
if (terminatorPos >= 0) {
ByteBuffer product;
if (beginPos < terminatorPos) {
in.limit(terminatorPos);
if (buffer == null) {
product = in.slice();
} else {
buffer.put(in);
product = buffer.flip();
buffer = null;
}
in.limit(limit);
} else {
// When input contained only terminator rather than actual data...
if (buffer == null) {
product = ByteBuffer.allocate(1);
product.limit(0);
} else {
product = buffer.flip();
buffer = null;
}
}
in.position(terminatorPos + 1);
return finishDecode(product, out);
} else {
if (buffer == null) {
buffer = ByteBuffer.allocate(in.remaining());
buffer.setAutoExpand(true);
}
buffer.put(in);
return this;
}
}
protected abstract boolean isTerminator(byte b);
protected abstract DecodingState finishDecode(ByteBuffer product,
ProtocolDecoderOutput out) throws Exception;
}
On 8/13/07, Yigal Rachman <[EMAIL PROTECTED]> wrote:
>
> Hi, Adam:
>
> Thank you for pointing me to AsyncWeb - really interesting stuff! I found
> ConsumeToCRLFDecoder and ConsumeToCharacterDecoder, but no
> ConsumeToDynamicTerminatorDecodingState. Any idea where I might find this?
>
> BTW, I have already coded some of my driver using state machines, and am
> 100% sold on this way of doing things. It is amazingly efficient for
> managing i/o transactions of arbitrary duration because it does not keep
> threads waiting.
>
> - Yigal
>
>
> Adam Fisk wrote:
>
> I'd give the state machine in AsyncWeb a look, as well as some of the helper
> classes. The state machine approach takes awhile to wrap your head around
> if you're not used to it, but it works well. The
> "ConsumeToDynamicTerminatorDecodingState" helper class will do exactly what
> you want. You would need to write a fair bit of custom state machine code
> for your protocol going this route, but I think it's worth it.
>
> http://docs.safehaus.org/display/ASYNCWEB/Home
>
> -Adam
>
>
> On 8/9/07, Yigal Rachman <[EMAIL PROTECTED]> <[EMAIL PROTECTED]> wrote:
>
> Hi, Folks:
>
> I have a MINA client that acts as a driver for a scientific instrument.
> The communication is via a serial link using ASCII. The messages from
> the instrument are usually terminated with a line feed, but are
> sometimes terminated with a ">" instead (when it is prompting for
> commands).
>
> Could you please suggest a design pattern that would do this elegantly
> in MINA? I expect it will use the TextLineCodec and possibly some other
> filters, but I am fuzzy on the details.
>
> Best regards,
> Yigal Rachman
>
> DMAS Data Acquisition Developer
> NEPTUNE Canada
> University of Victoria,
> Victoria, BC, Canada
> www.neptunecanada.ca
>
>
>