On 9/1/11 6:48 AM, Mikael Fernandus S wrote:
Hi,

I am new to Mina so please bear with me if this issue is obvious. I
use Mina 1.1.7
I'm seriously enaging ypu to switch to MINA 2.0.4. MINA 1.1.7 is seriously lagging, and is probably not maintained anymore...

and am developing a protocol codec that extends
DemuxingProtocolCodecFactory. What this codec does basicly is reading
the in buffer, validating the header and writing valid message to the
decoder output. This should be straightforward. However, when I tested
the codec, I got the following exception even though the codec
properly writes to the decoder oupt:

org.apache.mina.filter.codec.ProtocolDecoderException:
java.lang.IllegalStateException: doDecode() can't return true when
buffer is not consumed.

This error appears consistently for single buffer decoding process or
multiple buffer decoding process. I attach relevant source code below:

public class MyDecoder implements MessageDecoder {
     private messageLengthExists = false;
     private boolean multipleBuffer = false;
     private messageStartPosition = 0;
     private int bufferOffset = 0;
     private ByteBuffer msg = ByteBuffer.wrap(new byte[0]);
     private String error = null;

     public MessageDecoderResult decodable(IoSession, ByteBuffer in) {
         return readInputStreamHeader(in);
     }

     public MessagedecoderResult decode(IoSession session, ByteBuffer
in, ProtocolDecoderOutput out) throws Exception {
         if(error != null) {
             session.close();
             return MessageDecoderResult.NOT_OK;
         }
         if(messageLengthExists) {
                 return decodeWithMessageLength(session, in, out);
         }
         return decodeWithoutMessageLength(session,in,out);
     }

     public MessageDecoderResult decodeWithMessageLength(IoSession
session, ByteBuffer in, ProtocolDecoderOutput out) {
         byte[] currentBytes = getBufferBytes(in);
         if(multipleBuffer) {
             int remaining = Math.min(msg.remaining(), in.remaining());
             if(remaining>  0) {
                 msg.put(currentBytes,bufferOffset * (in.capacity() /
bufferOffset+1)) + messageStartPosition, (remaining -
messageStartPosition));
             }
             messageStartPosition = 0;
             currentBytes = null;
             if(msg.remaining()>  0) {
                  bufferOffset++;
                  return MessageDecoderResult.NEED_DATA;
             }
             else {
                 out.write(msg);
                 msg.clear();
                 session.close();
                 return MessageDecoderResult.OK;
             }
         }
         msg.put(currentBytes, messageStartPosition, (in.limit() -
messageStartPosition));
         out.write(msg);
         currentBytes = null;
         msg.clear();
         session.close();
         return MessageDecoderResult.OK;
     }

     private byte[] getBufferBytes(ByteBuffer in) {
         return getBufferBytes(in,0);
     }

     private byte[] getBufferBytes(ByteBuffer in, int startPosition) {
         byte[] mfsBytes = new byte[in.limit() - startPosition];
         int i = 0;
         while(i<  (in.limit() - startPosition)) {
             byte b = in.get(startPosition + i);
             char c = (char) (b&  0xff);
             mfsBytes[i] = (byte) c;
             i++;
         }
         return mfsBytes;
     }

     ...
}

As a side note, i could not invoke the method in.array() and
in.arrayOffset(), which is pretty strange. I got
UnsupportedOperationException. By analyzing java.nio.ByteBuffer class,
I found that this is because the internal array hb is null.

Could anybody please show me what is not right with my approach above?

Thanks,
Mike



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com

Reply via email to