mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Adam Fisk"...@lastbamboo.org>
Subject Re: How to deal with dynamically changing line terminators?
Date Mon, 13 Aug 2007 18:26:13 GMT
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 <yigal@uvic.ca> 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 <yigal@uvic.ca> <yigal@uvic.ca> 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
>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message