/*
* @(#) $Id: NettyDecoder.java 389055 2006-03-27 08:06:27Z trustin $
*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.mina.filter.codec.netty;
import net.gleamynode.netty2.Message;
import net.gleamynode.netty2.MessageParseException;
import net.gleamynode.netty2.MessageRecognizer;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderException;
/**
* A MINA <tt>ProtocolDecoder</tt> that decodes byte buffers into
* Netty2 {@link Message}s using specified {@link MessageRecognizer}s.
*
* @author The Apache Directory Project (mina-dev@directory.apache.org)
* @version $Rev: 389055 $, $Date: 2006-03-27 17:06:27 +0900 (Mon, 27 Mar 2006) $,
*/
public class NettyDecoder implements org.apache.mina.filter.codec.ProtocolDecoder
{
private final MessageRecognizer recognizer;
private java.nio.ByteBuffer readBuf = java.nio.ByteBuffer.allocate( 1024 );
private Message readingMessage;
/**
* Creates a new instance with the specified {@link MessageRecognizer}.
*/
public NettyDecoder( MessageRecognizer recognizer )
{
if( recognizer == null )
throw new NullPointerException();
this.recognizer = recognizer;
}
private void put( ByteBuffer in )
{
// copy to read buffer
if( in.remaining() > readBuf.remaining() )
expand( ( readBuf.position() + in.remaining() ) * 3 / 2 );
readBuf.put( in.buf() );
}
private void expand( int newCapacity )
{
java.nio.ByteBuffer newBuf = java.nio.ByteBuffer
.allocate( newCapacity );
readBuf.flip();
newBuf.put( readBuf );
readBuf = newBuf;
}
public void decode(IoSession session, ByteBuffer in, org.apache.mina.filter.codec.ProtocolDecoderOutput out) throws Exception {
put( in );
Message m = readingMessage;
try
{
for( ;; )
{
readBuf.flip();
if( m == null )
{
int limit = readBuf.limit();
boolean failed = true;
try
{
m = recognizer.recognize( readBuf );
failed = false;
}
finally
{
if( failed )
{
// clear the read buffer if failed to recognize
readBuf.clear();
break;
}
else
{
if( m == null )
{
readBuf.limit( readBuf.capacity() );
readBuf.position( limit );
break; // finish decoding
}
else
{
// reset buffer for read
readBuf.limit( limit );
readBuf.position( 0 );
}
}
}
}
if( m != null )
{
try
{
//System.err.println("NETTY trying to decode : "+m);
if( m.read( readBuf ) )
{
out.write( m );
m = null;
} else {
break;
}
}
finally
{
if( readBuf.hasRemaining() )
{
readBuf.compact();
}
else
{
readBuf.clear();
break;
}
}
}
}
}
catch( MessageParseException e )
{
m = null; // discard reading message
throw new ProtocolDecoderException( "Failed to decode.", e );
}
finally
{
readingMessage = m;
}
}
public void dispose(IoSession session) throws Exception {
}
}