Need help implementing ProtocolParser

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Need help implementing ProtocolParser

Ash2k
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 :)

p.p.s. after fixin' my class i will consider making (and posting here) at example of paket constructor based on the code above.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

RE: Need help implementing ProtocolParser

CigarMan
Maybe looking at this post could provide you a starting point,

http://www.nabble.com/A-new-user-API-enhancement-proposal-for-Grizzly-Pr
otocolParser-td15920331.html

Simon

-----Original Message-----
From: Ash2k [mailto:[hidden email]]
Sent: March-16-08 5:17 AM
To: [hidden email]
Subject: Need help implementing ProtocolParser

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.ht
ml) 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 :)

p.p.s. after fixin' my class i will consider making (and posting here)
at example of paket constructor based on the code above.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]