users@grizzly.java.net

Need help implementing ProtocolParser

From: ash2k! <ash2kk_at_gmail.com>
Date: Mon, 17 Mar 2008 03:32:33 -0700 (PDT)

Hi!

I am trying to implement a protocolparser but i am stuck and need some help,
please. Below is my code.

public class A1ProtocolParser implements ProtocolParser<IncomingPacket> {

    static final int HEADERLENGTH = 18;
    static final int STARTMARK = 0x12345678;
    private ByteBuffer byteBuffer, incomingPacketBuffer;
    private IncomingPacket incomingPacket;
    private boolean isExpectingMoreData;
    private int currentPosition;

    public boolean isExpectingMoreData() {
        return isExpectingMoreData;
    }

    public boolean hasMoreBytesToParse() {
        return byteBuffer == null ? false : byteBuffer.position() >
currentPosition;
    }

    public IncomingPacket getNextMessage() {
    IncomingPacket packet = incomingPacket;
    incomingPacket = null;
    return packet;
    }

    public boolean hasNextMessage() {
        ByteBuffer dup = byteBuffer.duplicate();
        dup.flip();
        dup.position(currentPosition);
        if (incomingPacket == null) {
            if (dup.remaining() < HEADERLENGTH) {
                isExpectingMoreData = true;
                return false;
            }
            int startmark = dup.getInt();
            if (startmark != STARTMARK) {
                //TODO: log exception and close connection
                return false;
            }
            incomingPacket = new IncomingPacket(dup.getShort());
            incomingPacket.attachment = dup.getLong();
            int len = dup.getInt();
            if (len == 0) {
                isExpectingMoreData = false;
                currentPosition = dup.position();
                return true;
                return false;
            }
            incomingPacket.data = new byte[len];
            incomingPacketBuffer = ByteBuffer.wrap(incomingPacket.data);
            currentPosition = dup.position();
        }
        if (dup.hasRemaining()) {
            int len = Math.min(incomingPacketBuffer.remaining(),
dup.remaining());
            incomingPacketBuffer.put(
                dup.array(),
                dup.position(),
                len);
            dup.position(currentPosition += len);

            if (incomingPacketBuffer.hasRemaining()) {
                isExpectingMoreData = true;
            } else {
                isExpectingMoreData = false;
                incomingPacketBuffer = null;
            }
        } else {
            isExpectingMoreData = true;
        }
        return !isExpectingMoreData;
    } //hasNextMessage

    public void startBuffer(ByteBuffer bb) {
        byteBuffer = bb;
    } //startBuffer

    public boolean releaseBuffer() {
        byteBuffer = null;
        currentPosition = 0;
        return isExpectingMoreData;
    } //releaseBuffer
}

When a big packet is about to arrive `byteBuffer` contains only 8k of data
(as it should according to grizly's implementation) - so i copy data into
incomingPacketBuffer and
set `isExpectingMoreData = true;`. The problem: instance that handled this
`byteBuffer` is not called for the second time! insted grizzly creates a new
instance of `A1ProtocolParser` through my own `ProtocolChainInstanceHandler`

controller.setProtocolChainInstanceHandler(new
DefaultProtocolChainInstanceHandler() {

    private final A1ParserProtocolFilter a1ParserProtocolFilter = new
A1ParserProtocolFilter();
    private final ProtocolFilter echoFilter = new ProtocolFilter() {

    public boolean execute(Context ctx) throws IOException {
        System.out.println(
            new
String(((IncomingPacket)ctx.getAttribute(ProtocolParser.MESSAGE)).data,
"UTF-8")
            );
        ctx.removeAttribute(ProtocolParser.MESSAGE);
        return false;
    }

    public boolean postExecute(Context ctx) throws IOException {
        return true;
    }
    };

    @Override
    public ProtocolChain poll() {
    ProtocolChain protocolChainX = protocolChains.poll();
    if (protocolChainX == null) {
        DefaultProtocolChain defaultProtocolChain = new
DefaultProtocolChain();
        defaultProtocolChain.setContinuousExecution(true);
        defaultProtocolChain.addFilter(a1ParserProtocolFilter);
        defaultProtocolChain.addFilter(echoFilter);
        protocolChainX = defaultProtocolChain;
        offer(protocolChainX);
    }
    return protocolChainX;
    }
});

The second question: line `offer(protocolChainX);` according to this post
(http://www.nabble.com/DefaultProtocolChainInstanceHandler-td15412709.html)
should exist, but it do not exist in the last (668 by now) revision of this
file
https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/test/java/com/sun/grizzly/ProtocolParserTest.java?rev=668&view=log
is this a bug in a test unit? by the way it don't exist in many blog posts
and samples i've seen.

p.s. sorry for my english-i'm from Russia :)
-- 
View this message in context: http://www.nabble.com/Need-help-implementing-ProtocolParser-tp16091789p16091789.html
Sent from the Grizzly - Users mailing list archive at Nabble.com.