directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject svn commit: r400067 [2/7] - in /directory/trunks: apacheds/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/ clients/ldap/ mina/core/src/main/java/org/apache/mina/filter/ mina/core/src/main/java/org/apache/mina/handler/mult...
Date Fri, 05 May 2006 12:52:54 GMT
Modified: directory/trunks/mina/core/src/test/java/org/apache/mina/filter/StreamWriteFilterTest.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/core/src/test/java/org/apache/mina/filter/StreamWriteFilterTest.java?rev=400067&r1=400066&r2=400067&view=diff
==============================================================================
--- directory/trunks/mina/core/src/test/java/org/apache/mina/filter/StreamWriteFilterTest.java (original)
+++ directory/trunks/mina/core/src/test/java/org/apache/mina/filter/StreamWriteFilterTest.java Fri May  5 05:52:49 2006
@@ -1,584 +1,584 @@
-/*
- *   @(#) $Id$
- *
- *   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;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.security.MessageDigest;
-import java.util.Random;
-
-import junit.framework.TestCase;
-
-import org.apache.mina.common.ByteBuffer;
-import org.apache.mina.common.IdleStatus;
-import org.apache.mina.common.IoAcceptor;
-import org.apache.mina.common.IoConnector;
-import org.apache.mina.common.IoHandlerAdapter;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.common.WriteFuture;
-import org.apache.mina.common.IoFilter.NextFilter;
-import org.apache.mina.common.IoFilter.WriteRequest;
-import org.apache.mina.transport.socket.nio.SocketAcceptor;
-import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
-import org.apache.mina.transport.socket.nio.SocketConnector;
-import org.apache.mina.util.AvailablePortFinder;
-import org.apache.mina.util.Queue;
-import org.easymock.AbstractMatcher;
-import org.easymock.MockControl;
-
-/**
- * Tests {@link StreamWriteFilter}.
- * 
- * @author The Apache Directory Project (mina-dev@directory.apache.org)
- * @version $Rev$, $Date$
- */
-public class StreamWriteFilterTest extends TestCase {
-    MockControl mockSession;
-    MockControl mockNextFilter;
-    IoSession session;
-    NextFilter nextFilter;
-
-    protected void setUp() throws Exception
-    {
-        super.setUp();
-
-        /*
-         * Create the mocks.
-         */
-        mockSession = MockControl.createControl( IoSession.class );
-        mockNextFilter = MockControl.createControl( NextFilter.class );
-        session = ( IoSession ) mockSession.getMock();
-        nextFilter = ( NextFilter ) mockNextFilter.getMock();
-        
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( null );
-    }
-
-    public void testWriteEmptyStream() throws Exception
-    {
-        StreamWriteFilter filter = new StreamWriteFilter();
-        
-        InputStream stream = new ByteArrayInputStream( new byte[ 0 ] );
-        WriteRequest writeRequest = new WriteRequest( stream );
-        
-        /*
-         * Record expectations
-         */
-        nextFilter.messageSent( session, stream );
-        
-        /*
-         * Replay.
-         */
-        mockNextFilter.replay();
-        mockSession.replay();
-        
-        filter.filterWrite( nextFilter, session, writeRequest );
-        
-        /*
-         * Verify.
-         */
-        mockNextFilter.verify();
-        mockSession.verify();
-        
-        assertTrue( writeRequest.getFuture().isWritten() );
-    }
-
-    /**
-     * Tests that the filter just passes objects which aren't InputStreams
-     * through to the next filter.
-     */
-    public void testWriteNonStreamMessage() throws Exception
-    {
-        StreamWriteFilter filter = new StreamWriteFilter();
-        
-        Object message = new Object();
-        WriteRequest writeRequest = new WriteRequest( message );
-        
-        /*
-         * Record expectations
-         */
-        nextFilter.filterWrite( session, writeRequest );
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( null );
-        nextFilter.messageSent( session, message );
-        
-        /*
-         * Replay.
-         */
-        mockNextFilter.replay();
-        mockSession.replay();
-        
-        filter.filterWrite( nextFilter, session, writeRequest );
-        filter.messageSent( nextFilter, session, message );
-        
-        /*
-         * Verify.
-         */
-        mockNextFilter.verify();
-        mockSession.verify();
-        
-        assertTrue( writeRequest.getFuture().isWritten() );
-    }
-    
-    /**
-     * Tests when the contents of the stream fits into one write buffer.
-     */
-    public void testWriteSingleBufferStream() throws Exception
-    {
-        StreamWriteFilter filter = new StreamWriteFilter();
-        
-        byte[] data = new byte[] { 1, 2, 3, 4 };
-        
-        InputStream stream = new ByteArrayInputStream( data );
-        WriteRequest writeRequest = new WriteRequest( stream );
-        
-        /*
-         * Record expectations
-         */
-        session.setAttribute( StreamWriteFilter.CURRENT_STREAM, stream );
-        mockSession.setReturnValue(null);
-        session.setAttribute( StreamWriteFilter.INITIAL_WRITE_FUTURE, writeRequest.getFuture() );
-        mockSession.setReturnValue(null);
-        nextFilter.filterWrite( session, new WriteRequest( ByteBuffer.wrap( data ) ) );
-        mockNextFilter.setMatcher( new WriteRequestMatcher() );
-        
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( stream );
-        session.removeAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( stream );
-        session.removeAttribute( StreamWriteFilter.INITIAL_WRITE_FUTURE );
-        mockSession.setReturnValue( writeRequest.getFuture() );
-        session.removeAttribute( StreamWriteFilter.WRITE_REQUEST_QUEUE );
-        mockSession.setReturnValue( null );
-        nextFilter.messageSent( session, stream );
-        
-        /*
-         * Replay.
-         */
-        mockNextFilter.replay();
-        mockSession.replay();
-        
-        filter.filterWrite( nextFilter, session, writeRequest );
-        filter.messageSent( nextFilter, session, data );
-        
-        /*
-         * Verify.
-         */
-        mockNextFilter.verify();
-        mockSession.verify();
-        
-        assertTrue( writeRequest.getFuture().isWritten() );
-    }
-    
-    /**
-     * Tests when the contents of the stream doesn't fit into one write buffer.
-     */
-    public void testWriteSeveralBuffersStream() throws Exception
-    {
-        StreamWriteFilter filter = new StreamWriteFilter();
-        filter.setWriteBufferSize( 4 );
-        
-        byte[] data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
-        byte[] chunk1 = new byte[] { 1, 2, 3, 4 };
-        byte[] chunk2 = new byte[] { 5, 6, 7, 8 };
-        byte[] chunk3 = new byte[] { 9, 10 };
-        
-        InputStream stream = new ByteArrayInputStream( data );
-        WriteRequest writeRequest = new WriteRequest( stream );
-        
-        /*
-         * Record expectations
-         */
-        session.setAttribute( StreamWriteFilter.CURRENT_STREAM, stream );
-        mockSession.setReturnValue(null);
-        session.setAttribute( StreamWriteFilter.INITIAL_WRITE_FUTURE, writeRequest.getFuture() );
-        mockSession.setReturnValue(null);
-        nextFilter.filterWrite( session, new WriteRequest( ByteBuffer.wrap( chunk1 ) ) );
-        mockNextFilter.setMatcher( new WriteRequestMatcher() );
-        
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( stream );
-        nextFilter.filterWrite( session, new WriteRequest( ByteBuffer.wrap( chunk2 ) ) );
-        
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( stream );
-        nextFilter.filterWrite( session, new WriteRequest( ByteBuffer.wrap( chunk3 ) ) );
-        
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( stream );
-        session.removeAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( stream );
-        session.removeAttribute( StreamWriteFilter.INITIAL_WRITE_FUTURE );
-        mockSession.setReturnValue( writeRequest.getFuture() );
-        session.removeAttribute( StreamWriteFilter.WRITE_REQUEST_QUEUE );
-        mockSession.setReturnValue( null );
-        nextFilter.messageSent( session, stream );
-        
-        /*
-         * Replay.
-         */
-        mockNextFilter.replay();
-        mockSession.replay();
-        
-        filter.filterWrite( nextFilter, session, writeRequest );
-        filter.messageSent( nextFilter, session, chunk1 );
-        filter.messageSent( nextFilter, session, chunk2 );
-        filter.messageSent( nextFilter, session, chunk3 );
-        
-        /*
-         * Verify.
-         */
-        mockNextFilter.verify();
-        mockSession.verify();
-        
-        assertTrue( writeRequest.getFuture().isWritten() );
-    }
-    
-    public void testWriteWhileWriteInProgress() throws Exception
-    {
-        StreamWriteFilter filter = new StreamWriteFilter();
-        
-        Queue queue = new Queue();
-        InputStream stream = new ByteArrayInputStream( new byte[ 5 ] );
-        
-        /*
-         * Record expectations
-         */
-        mockSession.reset();
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( stream );
-        session.getAttribute( StreamWriteFilter.WRITE_REQUEST_QUEUE );
-        mockSession.setReturnValue( queue );
-        
-        /*
-         * Replay.
-         */
-        mockNextFilter.replay();
-        mockSession.replay();
-
-        WriteRequest wr = new WriteRequest( new Object() );
-        filter.filterWrite( nextFilter, session, wr );
-        assertEquals( 1, queue.size() );
-        assertSame( wr, queue.pop() );
-        
-        /*
-         * Verify.
-         */
-        mockNextFilter.verify();
-        mockSession.verify();
-    }
-    
-    public void testWritesWriteRequestQueueWhenFinished() throws Exception
-    {
-        StreamWriteFilter filter = new StreamWriteFilter();
-
-        WriteRequest wrs[] = new WriteRequest[] { 
-                new WriteRequest( new Object() ),
-                new WriteRequest( new Object() ),
-                new WriteRequest( new Object() )
-        };
-        Queue queue = new Queue();
-        queue.push( wrs[ 0 ] );
-        queue.push( wrs[ 1 ] );
-        queue.push( wrs[ 2 ] );
-        InputStream stream = new ByteArrayInputStream( new byte[ 0 ] );
-        
-        /*
-         * Record expectations
-         */
-        mockSession.reset();
-        
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( stream );
-        session.removeAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( stream );
-        session.removeAttribute( StreamWriteFilter.INITIAL_WRITE_FUTURE );
-        mockSession.setReturnValue( new WriteFuture() );
-        session.removeAttribute( StreamWriteFilter.WRITE_REQUEST_QUEUE );
-        mockSession.setReturnValue( queue );
-        
-        nextFilter.filterWrite( session, wrs[ 0 ] );
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( null );
-        nextFilter.filterWrite( session, wrs[ 1 ] );
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( null );
-        nextFilter.filterWrite( session, wrs[ 2 ] );
-        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
-        mockSession.setReturnValue( null );
-        
-        nextFilter.messageSent( session, stream );
-        
-        /*
-         * Replay.
-         */
-        mockNextFilter.replay();
-        mockSession.replay();
-
-        filter.messageSent( nextFilter, session, new Object() );
-        assertEquals( 0, queue.size() );
-        
-        /*
-         * Verify.
-         */
-        mockNextFilter.verify();
-        mockSession.verify();
-    }    
-    
-    /**
-     * Tests that {@link StreamWriteFilter#setWriteBufferSize(int)} checks the
-     * specified size.
-     */
-    public void testSetWriteBufferSize() throws Exception
-    {
-        StreamWriteFilter filter = new StreamWriteFilter();
-        
-        try
-        {
-            filter.setWriteBufferSize( 0 );
-            fail( "0 writeBuferSize specified. IllegalArgumentException expected." );
-        }
-        catch ( IllegalArgumentException iae )
-        {
-        }
-        
-        try
-        {
-            filter.setWriteBufferSize( -100 );
-            fail( "Negative writeBuferSize specified. IllegalArgumentException expected." );
-        }
-        catch ( IllegalArgumentException iae )
-        {
-        }
-
-        filter.setWriteBufferSize( 1 );
-        assertEquals( 1, filter.getWriteBufferSize() );
-        filter.setWriteBufferSize( 1024 );
-        assertEquals( 1024, filter.getWriteBufferSize() );
-    }
-    
-    public void testWriteUsingSocketTransport() throws Exception
-    {
-        IoAcceptor acceptor = new SocketAcceptor();
-        ( ( SocketAcceptorConfig ) acceptor.getDefaultConfig() ).setReuseAddress( true );
-        SocketAddress address = new InetSocketAddress( "localhost", AvailablePortFinder.getNextAvailable() );
-
-        IoConnector connector = new SocketConnector();
-        
-        FixedRandomInputStream stream = new FixedRandomInputStream( 4 * 1024 * 1024 );
-        
-        SenderHandler sender = new SenderHandler( stream );
-        ReceiverHandler receiver = new ReceiverHandler( stream.size );
-        
-        acceptor.bind( address, sender );
-        
-        synchronized( sender.lock )
-        {
-            synchronized( receiver.lock )
-            {
-                connector.connect( address, receiver );
-                
-                sender.lock.wait();
-                receiver.lock.wait();
-            }
-        }
-        
-        acceptor.unbind( address );
-        
-        assertEquals( stream.bytesRead, receiver.bytesRead );
-        assertEquals( stream.size, receiver.bytesRead );
-        byte[] expectedMd5 = stream.digest.digest();
-        byte[] actualMd5 = receiver.digest.digest();
-        assertEquals( expectedMd5.length, actualMd5.length );
-        for( int i = 0; i < expectedMd5.length; i++ )
-        {
-            assertEquals( expectedMd5[ i ], actualMd5[ i ] );
-        }
-    }
-
-    private static class FixedRandomInputStream extends InputStream
-    {
-        long size;
-        long bytesRead = 0;
-        Random random = new Random();
-        MessageDigest digest;
-
-        public FixedRandomInputStream( long size ) throws Exception
-        {
-            this.size = size;
-            digest = MessageDigest.getInstance( "MD5" );
-        }
-
-        public int read() throws IOException
-        {
-            if ( isAllWritten() )
-                return -1;
-            bytesRead++;
-            byte b = ( byte ) random.nextInt( 255 );
-            digest.update( b );
-            return b;
-        }
-        
-        public long getBytesRead()
-        {
-            return bytesRead;
-        }
-
-        public long getSize()
-        {
-            return size;
-        }
-
-        public boolean isAllWritten()
-        {
-            return bytesRead >= size;
-        }
-    }
-
-    private static class SenderHandler extends IoHandlerAdapter
-    {
-        Object lock = new Object();
-        InputStream inputStream;
-        StreamWriteFilter streamWriteFilter = new StreamWriteFilter();
-
-        public SenderHandler( InputStream inputStream )
-        {
-            this.inputStream = inputStream;
-        }
-
-        public void sessionCreated( IoSession session ) throws Exception {
-            super.sessionCreated( session );
-            session.getFilterChain().addLast( "codec", streamWriteFilter );
-        }
-
-        public void sessionOpened( IoSession session ) throws Exception {
-            session.write( inputStream );
-        }
-
-        public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
-        {
-            synchronized( lock )
-            {
-                lock.notifyAll();
-            }
-        }
-
-        public void sessionClosed( IoSession session ) throws Exception
-        {
-            synchronized( lock )
-            {
-                lock.notifyAll();
-            }
-        }
-
-        public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
-        {
-            synchronized( lock )
-            {
-                lock.notifyAll();
-            }
-        }
-
-        public void messageSent( IoSession session, Object message ) throws Exception
-        {
-            if( message == inputStream )
-            {
-                synchronized( lock )
-                {
-                    lock.notifyAll();
-                }
-            }
-        }
-    }
-
-    private static class ReceiverHandler extends IoHandlerAdapter
-    {
-        Object lock = new Object();
-        long bytesRead = 0;
-        long size = 0;
-        MessageDigest digest;
-
-        public ReceiverHandler( long size ) throws Exception
-        {
-            this.size = size;
-            digest = MessageDigest.getInstance( "MD5" );
-        }
-
-        public void sessionCreated( IoSession session ) throws Exception
-        {
-            super.sessionCreated(session);
-            
-            session.setIdleTime( IdleStatus.READER_IDLE, 5 );
-        }
-
-        public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
-        {
-            session.close();
-        }
-
-        public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
-        {
-            synchronized( lock )
-            {
-                lock.notifyAll();
-            }
-        }
-        
-        public void sessionClosed( IoSession session ) throws Exception
-        {
-            synchronized( lock )
-            {
-                lock.notifyAll();
-            }
-        }
-
-        public void messageReceived( IoSession session, Object message ) throws Exception
-        {
-            ByteBuffer buf = ( ByteBuffer ) message;
-            while( buf.hasRemaining() )
-            {
-                digest.update( buf.get() );
-                bytesRead++;
-            }
-            if( bytesRead >= size )
-            {
-                session.close();
-            }
-        }
-    }
-    
-    public static class WriteRequestMatcher extends AbstractMatcher
-    {
-        protected boolean argumentMatches( Object expected, Object actual )
-        {
-            if( expected instanceof WriteRequest && expected instanceof WriteRequest )
-            {
-                WriteRequest w1 = ( WriteRequest ) expected;
-                WriteRequest w2 = ( WriteRequest ) actual;
-                
-                return w1.getMessage().equals( w2.getMessage() ) 
-                    && w1.getFuture().isWritten() == w2.getFuture().isWritten();
-            }
-            return super.argumentMatches( expected, actual );
-        }
-    }
-}
+/*
+ *   @(#) $Id$
+ *
+ *   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;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.security.MessageDigest;
+import java.util.Random;
+
+import junit.framework.TestCase;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IdleStatus;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.WriteFuture;
+import org.apache.mina.common.IoFilter.NextFilter;
+import org.apache.mina.common.IoFilter.WriteRequest;
+import org.apache.mina.transport.socket.nio.SocketAcceptor;
+import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
+import org.apache.mina.transport.socket.nio.SocketConnector;
+import org.apache.mina.util.AvailablePortFinder;
+import org.apache.mina.util.Queue;
+import org.easymock.AbstractMatcher;
+import org.easymock.MockControl;
+
+/**
+ * Tests {@link StreamWriteFilter}.
+ * 
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev$, $Date$
+ */
+public class StreamWriteFilterTest extends TestCase {
+    MockControl mockSession;
+    MockControl mockNextFilter;
+    IoSession session;
+    NextFilter nextFilter;
+
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+
+        /*
+         * Create the mocks.
+         */
+        mockSession = MockControl.createControl( IoSession.class );
+        mockNextFilter = MockControl.createControl( NextFilter.class );
+        session = ( IoSession ) mockSession.getMock();
+        nextFilter = ( NextFilter ) mockNextFilter.getMock();
+        
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( null );
+    }
+
+    public void testWriteEmptyStream() throws Exception
+    {
+        StreamWriteFilter filter = new StreamWriteFilter();
+        
+        InputStream stream = new ByteArrayInputStream( new byte[ 0 ] );
+        WriteRequest writeRequest = new WriteRequest( stream );
+        
+        /*
+         * Record expectations
+         */
+        nextFilter.messageSent( session, stream );
+        
+        /*
+         * Replay.
+         */
+        mockNextFilter.replay();
+        mockSession.replay();
+        
+        filter.filterWrite( nextFilter, session, writeRequest );
+        
+        /*
+         * Verify.
+         */
+        mockNextFilter.verify();
+        mockSession.verify();
+        
+        assertTrue( writeRequest.getFuture().isWritten() );
+    }
+
+    /**
+     * Tests that the filter just passes objects which aren't InputStreams
+     * through to the next filter.
+     */
+    public void testWriteNonStreamMessage() throws Exception
+    {
+        StreamWriteFilter filter = new StreamWriteFilter();
+        
+        Object message = new Object();
+        WriteRequest writeRequest = new WriteRequest( message );
+        
+        /*
+         * Record expectations
+         */
+        nextFilter.filterWrite( session, writeRequest );
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( null );
+        nextFilter.messageSent( session, message );
+        
+        /*
+         * Replay.
+         */
+        mockNextFilter.replay();
+        mockSession.replay();
+        
+        filter.filterWrite( nextFilter, session, writeRequest );
+        filter.messageSent( nextFilter, session, message );
+        
+        /*
+         * Verify.
+         */
+        mockNextFilter.verify();
+        mockSession.verify();
+        
+        assertTrue( writeRequest.getFuture().isWritten() );
+    }
+    
+    /**
+     * Tests when the contents of the stream fits into one write buffer.
+     */
+    public void testWriteSingleBufferStream() throws Exception
+    {
+        StreamWriteFilter filter = new StreamWriteFilter();
+        
+        byte[] data = new byte[] { 1, 2, 3, 4 };
+        
+        InputStream stream = new ByteArrayInputStream( data );
+        WriteRequest writeRequest = new WriteRequest( stream );
+        
+        /*
+         * Record expectations
+         */
+        session.setAttribute( StreamWriteFilter.CURRENT_STREAM, stream );
+        mockSession.setReturnValue(null);
+        session.setAttribute( StreamWriteFilter.INITIAL_WRITE_FUTURE, writeRequest.getFuture() );
+        mockSession.setReturnValue(null);
+        nextFilter.filterWrite( session, new WriteRequest( ByteBuffer.wrap( data ) ) );
+        mockNextFilter.setMatcher( new WriteRequestMatcher() );
+        
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( stream );
+        session.removeAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( stream );
+        session.removeAttribute( StreamWriteFilter.INITIAL_WRITE_FUTURE );
+        mockSession.setReturnValue( writeRequest.getFuture() );
+        session.removeAttribute( StreamWriteFilter.WRITE_REQUEST_QUEUE );
+        mockSession.setReturnValue( null );
+        nextFilter.messageSent( session, stream );
+        
+        /*
+         * Replay.
+         */
+        mockNextFilter.replay();
+        mockSession.replay();
+        
+        filter.filterWrite( nextFilter, session, writeRequest );
+        filter.messageSent( nextFilter, session, data );
+        
+        /*
+         * Verify.
+         */
+        mockNextFilter.verify();
+        mockSession.verify();
+        
+        assertTrue( writeRequest.getFuture().isWritten() );
+    }
+    
+    /**
+     * Tests when the contents of the stream doesn't fit into one write buffer.
+     */
+    public void testWriteSeveralBuffersStream() throws Exception
+    {
+        StreamWriteFilter filter = new StreamWriteFilter();
+        filter.setWriteBufferSize( 4 );
+        
+        byte[] data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+        byte[] chunk1 = new byte[] { 1, 2, 3, 4 };
+        byte[] chunk2 = new byte[] { 5, 6, 7, 8 };
+        byte[] chunk3 = new byte[] { 9, 10 };
+        
+        InputStream stream = new ByteArrayInputStream( data );
+        WriteRequest writeRequest = new WriteRequest( stream );
+        
+        /*
+         * Record expectations
+         */
+        session.setAttribute( StreamWriteFilter.CURRENT_STREAM, stream );
+        mockSession.setReturnValue(null);
+        session.setAttribute( StreamWriteFilter.INITIAL_WRITE_FUTURE, writeRequest.getFuture() );
+        mockSession.setReturnValue(null);
+        nextFilter.filterWrite( session, new WriteRequest( ByteBuffer.wrap( chunk1 ) ) );
+        mockNextFilter.setMatcher( new WriteRequestMatcher() );
+        
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( stream );
+        nextFilter.filterWrite( session, new WriteRequest( ByteBuffer.wrap( chunk2 ) ) );
+        
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( stream );
+        nextFilter.filterWrite( session, new WriteRequest( ByteBuffer.wrap( chunk3 ) ) );
+        
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( stream );
+        session.removeAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( stream );
+        session.removeAttribute( StreamWriteFilter.INITIAL_WRITE_FUTURE );
+        mockSession.setReturnValue( writeRequest.getFuture() );
+        session.removeAttribute( StreamWriteFilter.WRITE_REQUEST_QUEUE );
+        mockSession.setReturnValue( null );
+        nextFilter.messageSent( session, stream );
+        
+        /*
+         * Replay.
+         */
+        mockNextFilter.replay();
+        mockSession.replay();
+        
+        filter.filterWrite( nextFilter, session, writeRequest );
+        filter.messageSent( nextFilter, session, chunk1 );
+        filter.messageSent( nextFilter, session, chunk2 );
+        filter.messageSent( nextFilter, session, chunk3 );
+        
+        /*
+         * Verify.
+         */
+        mockNextFilter.verify();
+        mockSession.verify();
+        
+        assertTrue( writeRequest.getFuture().isWritten() );
+    }
+    
+    public void testWriteWhileWriteInProgress() throws Exception
+    {
+        StreamWriteFilter filter = new StreamWriteFilter();
+        
+        Queue queue = new Queue();
+        InputStream stream = new ByteArrayInputStream( new byte[ 5 ] );
+        
+        /*
+         * Record expectations
+         */
+        mockSession.reset();
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( stream );
+        session.getAttribute( StreamWriteFilter.WRITE_REQUEST_QUEUE );
+        mockSession.setReturnValue( queue );
+        
+        /*
+         * Replay.
+         */
+        mockNextFilter.replay();
+        mockSession.replay();
+
+        WriteRequest wr = new WriteRequest( new Object() );
+        filter.filterWrite( nextFilter, session, wr );
+        assertEquals( 1, queue.size() );
+        assertSame( wr, queue.pop() );
+        
+        /*
+         * Verify.
+         */
+        mockNextFilter.verify();
+        mockSession.verify();
+    }
+    
+    public void testWritesWriteRequestQueueWhenFinished() throws Exception
+    {
+        StreamWriteFilter filter = new StreamWriteFilter();
+
+        WriteRequest wrs[] = new WriteRequest[] { 
+                new WriteRequest( new Object() ),
+                new WriteRequest( new Object() ),
+                new WriteRequest( new Object() )
+        };
+        Queue queue = new Queue();
+        queue.push( wrs[ 0 ] );
+        queue.push( wrs[ 1 ] );
+        queue.push( wrs[ 2 ] );
+        InputStream stream = new ByteArrayInputStream( new byte[ 0 ] );
+        
+        /*
+         * Record expectations
+         */
+        mockSession.reset();
+        
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( stream );
+        session.removeAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( stream );
+        session.removeAttribute( StreamWriteFilter.INITIAL_WRITE_FUTURE );
+        mockSession.setReturnValue( new WriteFuture() );
+        session.removeAttribute( StreamWriteFilter.WRITE_REQUEST_QUEUE );
+        mockSession.setReturnValue( queue );
+        
+        nextFilter.filterWrite( session, wrs[ 0 ] );
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( null );
+        nextFilter.filterWrite( session, wrs[ 1 ] );
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( null );
+        nextFilter.filterWrite( session, wrs[ 2 ] );
+        session.getAttribute( StreamWriteFilter.CURRENT_STREAM );
+        mockSession.setReturnValue( null );
+        
+        nextFilter.messageSent( session, stream );
+        
+        /*
+         * Replay.
+         */
+        mockNextFilter.replay();
+        mockSession.replay();
+
+        filter.messageSent( nextFilter, session, new Object() );
+        assertEquals( 0, queue.size() );
+        
+        /*
+         * Verify.
+         */
+        mockNextFilter.verify();
+        mockSession.verify();
+    }    
+    
+    /**
+     * Tests that {@link StreamWriteFilter#setWriteBufferSize(int)} checks the
+     * specified size.
+     */
+    public void testSetWriteBufferSize() throws Exception
+    {
+        StreamWriteFilter filter = new StreamWriteFilter();
+        
+        try
+        {
+            filter.setWriteBufferSize( 0 );
+            fail( "0 writeBuferSize specified. IllegalArgumentException expected." );
+        }
+        catch ( IllegalArgumentException iae )
+        {
+        }
+        
+        try
+        {
+            filter.setWriteBufferSize( -100 );
+            fail( "Negative writeBuferSize specified. IllegalArgumentException expected." );
+        }
+        catch ( IllegalArgumentException iae )
+        {
+        }
+
+        filter.setWriteBufferSize( 1 );
+        assertEquals( 1, filter.getWriteBufferSize() );
+        filter.setWriteBufferSize( 1024 );
+        assertEquals( 1024, filter.getWriteBufferSize() );
+    }
+    
+    public void testWriteUsingSocketTransport() throws Exception
+    {
+        IoAcceptor acceptor = new SocketAcceptor();
+        ( ( SocketAcceptorConfig ) acceptor.getDefaultConfig() ).setReuseAddress( true );
+        SocketAddress address = new InetSocketAddress( "localhost", AvailablePortFinder.getNextAvailable() );
+
+        IoConnector connector = new SocketConnector();
+        
+        FixedRandomInputStream stream = new FixedRandomInputStream( 4 * 1024 * 1024 );
+        
+        SenderHandler sender = new SenderHandler( stream );
+        ReceiverHandler receiver = new ReceiverHandler( stream.size );
+        
+        acceptor.bind( address, sender );
+        
+        synchronized( sender.lock )
+        {
+            synchronized( receiver.lock )
+            {
+                connector.connect( address, receiver );
+                
+                sender.lock.wait();
+                receiver.lock.wait();
+            }
+        }
+        
+        acceptor.unbind( address );
+        
+        assertEquals( stream.bytesRead, receiver.bytesRead );
+        assertEquals( stream.size, receiver.bytesRead );
+        byte[] expectedMd5 = stream.digest.digest();
+        byte[] actualMd5 = receiver.digest.digest();
+        assertEquals( expectedMd5.length, actualMd5.length );
+        for( int i = 0; i < expectedMd5.length; i++ )
+        {
+            assertEquals( expectedMd5[ i ], actualMd5[ i ] );
+        }
+    }
+
+    private static class FixedRandomInputStream extends InputStream
+    {
+        long size;
+        long bytesRead = 0;
+        Random random = new Random();
+        MessageDigest digest;
+
+        public FixedRandomInputStream( long size ) throws Exception
+        {
+            this.size = size;
+            digest = MessageDigest.getInstance( "MD5" );
+        }
+
+        public int read() throws IOException
+        {
+            if ( isAllWritten() )
+                return -1;
+            bytesRead++;
+            byte b = ( byte ) random.nextInt( 255 );
+            digest.update( b );
+            return b;
+        }
+        
+        public long getBytesRead()
+        {
+            return bytesRead;
+        }
+
+        public long getSize()
+        {
+            return size;
+        }
+
+        public boolean isAllWritten()
+        {
+            return bytesRead >= size;
+        }
+    }
+
+    private static class SenderHandler extends IoHandlerAdapter
+    {
+        Object lock = new Object();
+        InputStream inputStream;
+        StreamWriteFilter streamWriteFilter = new StreamWriteFilter();
+
+        public SenderHandler( InputStream inputStream )
+        {
+            this.inputStream = inputStream;
+        }
+
+        public void sessionCreated( IoSession session ) throws Exception {
+            super.sessionCreated( session );
+            session.getFilterChain().addLast( "codec", streamWriteFilter );
+        }
+
+        public void sessionOpened( IoSession session ) throws Exception {
+            session.write( inputStream );
+        }
+
+        public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
+        {
+            synchronized( lock )
+            {
+                lock.notifyAll();
+            }
+        }
+
+        public void sessionClosed( IoSession session ) throws Exception
+        {
+            synchronized( lock )
+            {
+                lock.notifyAll();
+            }
+        }
+
+        public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
+        {
+            synchronized( lock )
+            {
+                lock.notifyAll();
+            }
+        }
+
+        public void messageSent( IoSession session, Object message ) throws Exception
+        {
+            if( message == inputStream )
+            {
+                synchronized( lock )
+                {
+                    lock.notifyAll();
+                }
+            }
+        }
+    }
+
+    private static class ReceiverHandler extends IoHandlerAdapter
+    {
+        Object lock = new Object();
+        long bytesRead = 0;
+        long size = 0;
+        MessageDigest digest;
+
+        public ReceiverHandler( long size ) throws Exception
+        {
+            this.size = size;
+            digest = MessageDigest.getInstance( "MD5" );
+        }
+
+        public void sessionCreated( IoSession session ) throws Exception
+        {
+            super.sessionCreated(session);
+            
+            session.setIdleTime( IdleStatus.READER_IDLE, 5 );
+        }
+
+        public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
+        {
+            session.close();
+        }
+
+        public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
+        {
+            synchronized( lock )
+            {
+                lock.notifyAll();
+            }
+        }
+        
+        public void sessionClosed( IoSession session ) throws Exception
+        {
+            synchronized( lock )
+            {
+                lock.notifyAll();
+            }
+        }
+
+        public void messageReceived( IoSession session, Object message ) throws Exception
+        {
+            ByteBuffer buf = ( ByteBuffer ) message;
+            while( buf.hasRemaining() )
+            {
+                digest.update( buf.get() );
+                bytesRead++;
+            }
+            if( bytesRead >= size )
+            {
+                session.close();
+            }
+        }
+    }
+    
+    public static class WriteRequestMatcher extends AbstractMatcher
+    {
+        protected boolean argumentMatches( Object expected, Object actual )
+        {
+            if( expected instanceof WriteRequest && expected instanceof WriteRequest )
+            {
+                WriteRequest w1 = ( WriteRequest ) expected;
+                WriteRequest w2 = ( WriteRequest ) actual;
+                
+                return w1.getMessage().equals( w2.getMessage() ) 
+                    && w1.getFuture().isWritten() == w2.getFuture().isWritten();
+            }
+            return super.argumentMatches( expected, actual );
+        }
+    }
+}

Modified: directory/trunks/mina/filter-codec-asn1/src/main/java/org/apache/mina/filter/codec/asn1/Asn1CodecDecoder.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/filter-codec-asn1/src/main/java/org/apache/mina/filter/codec/asn1/Asn1CodecDecoder.java?rev=400067&r1=400066&r2=400067&view=diff
==============================================================================
--- directory/trunks/mina/filter-codec-asn1/src/main/java/org/apache/mina/filter/codec/asn1/Asn1CodecDecoder.java (original)
+++ directory/trunks/mina/filter-codec-asn1/src/main/java/org/apache/mina/filter/codec/asn1/Asn1CodecDecoder.java Fri May  5 05:52:49 2006
@@ -1,68 +1,68 @@
-/*
- *   @(#) $Id$
- *
- *   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.asn1;
-
-import org.apache.directory.shared.asn1.codec.DecoderException;
-import org.apache.directory.shared.asn1.codec.stateful.DecoderCallback;
-import org.apache.directory.shared.asn1.codec.stateful.StatefulDecoder;
-import org.apache.mina.common.ByteBuffer;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.filter.codec.ProtocolDecoder;
-import org.apache.mina.filter.codec.ProtocolDecoderOutput;
-
-/**
- * Adapts {@link StatefulDecoder} to MINA <tt>ProtocolDecoder</tt>
- * 
- * @author The Apache Directory Project (mina-dev@directory.apache.org)
- * @version $Rev$, $Date$, 
- */
-public class Asn1CodecDecoder implements ProtocolDecoder
-{
-
-    private final StatefulDecoder decoder;
-
-    private final DecoderCallbackImpl callback = new DecoderCallbackImpl();
-
-    public Asn1CodecDecoder( StatefulDecoder decoder )
-    {
-        decoder.setCallback( callback );
-        this.decoder = decoder;
-    }
-
-    public void decode( IoSession session, ByteBuffer in,
-                        ProtocolDecoderOutput out ) throws DecoderException
-    {
-        callback.decOut = out;
-        decoder.decode( in.buf() );
-    }
-
-    public void dispose( IoSession session ) throws Exception
-    {
-    }
-
-    private class DecoderCallbackImpl implements DecoderCallback
-    {
-        private ProtocolDecoderOutput decOut;
-
-        public void decodeOccurred( StatefulDecoder decoder, Object decoded )
-        {
-            decOut.write( decoded );
-        }
-    }
-}
+/*
+ *   @(#) $Id$
+ *
+ *   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.asn1;
+
+import org.apache.directory.shared.asn1.codec.DecoderException;
+import org.apache.directory.shared.asn1.codec.stateful.DecoderCallback;
+import org.apache.directory.shared.asn1.codec.stateful.StatefulDecoder;
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.codec.ProtocolDecoder;
+import org.apache.mina.filter.codec.ProtocolDecoderOutput;
+
+/**
+ * Adapts {@link StatefulDecoder} to MINA <tt>ProtocolDecoder</tt>
+ * 
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev$, $Date$, 
+ */
+public class Asn1CodecDecoder implements ProtocolDecoder
+{
+
+    private final StatefulDecoder decoder;
+
+    private final DecoderCallbackImpl callback = new DecoderCallbackImpl();
+
+    public Asn1CodecDecoder( StatefulDecoder decoder )
+    {
+        decoder.setCallback( callback );
+        this.decoder = decoder;
+    }
+
+    public void decode( IoSession session, ByteBuffer in,
+                        ProtocolDecoderOutput out ) throws DecoderException
+    {
+        callback.decOut = out;
+        decoder.decode( in.buf() );
+    }
+
+    public void dispose( IoSession session ) throws Exception
+    {
+    }
+
+    private class DecoderCallbackImpl implements DecoderCallback
+    {
+        private ProtocolDecoderOutput decOut;
+
+        public void decodeOccurred( StatefulDecoder decoder, Object decoded )
+        {
+            decOut.write( decoded );
+        }
+    }
+}

Modified: directory/trunks/mina/filter-codec-asn1/src/main/java/org/apache/mina/filter/codec/asn1/Asn1CodecEncoder.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/filter-codec-asn1/src/main/java/org/apache/mina/filter/codec/asn1/Asn1CodecEncoder.java?rev=400067&r1=400066&r2=400067&view=diff
==============================================================================
--- directory/trunks/mina/filter-codec-asn1/src/main/java/org/apache/mina/filter/codec/asn1/Asn1CodecEncoder.java (original)
+++ directory/trunks/mina/filter-codec-asn1/src/main/java/org/apache/mina/filter/codec/asn1/Asn1CodecEncoder.java Fri May  5 05:52:49 2006
@@ -1,123 +1,123 @@
-/*
- *   @(#) $Id$
- *
- *   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.asn1;
-
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Iterator;
-
-import org.apache.directory.shared.asn1.codec.EncoderException;
-import org.apache.directory.shared.asn1.codec.stateful.EncoderCallback;
-import org.apache.directory.shared.asn1.codec.stateful.StatefulEncoder;
-import org.apache.mina.common.ByteBuffer;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.filter.codec.ProtocolEncoder;
-import org.apache.mina.filter.codec.ProtocolEncoderOutput;
-
-/**
- * Adapts {@link StatefulEncoder} to MINA <tt>ProtocolEncoder</tt>
- * 
- * @author The Apache Directory Project (mina-dev@directory.apache.org)
- * @version $Rev$, $Date$, 
- */
-public class Asn1CodecEncoder implements ProtocolEncoder
-{
-    private final StatefulEncoder encoder;
-
-    private final EncoderCallbackImpl callback = new EncoderCallbackImpl();
-
-    public Asn1CodecEncoder( StatefulEncoder encoder )
-    {
-        encoder.setCallback( callback );
-        this.encoder = encoder;
-    }
-
-    public void encode( IoSession session, Object message,
-                        ProtocolEncoderOutput out ) throws EncoderException
-    {
-        callback.encOut = out;
-        encoder.encode( message );
-    }
-
-    public void dispose( IoSession session ) throws Exception
-    {
-    }
-
-    private class EncoderCallbackImpl implements EncoderCallback
-    {
-        private ProtocolEncoderOutput encOut;
-
-        public void encodeOccurred( StatefulEncoder codec, Object encoded )
-        {
-            if( encoded instanceof java.nio.ByteBuffer )
-            {
-                java.nio.ByteBuffer buf = ( java.nio.ByteBuffer ) encoded;
-                ByteBuffer wrappedBuf = ByteBuffer.wrap( buf );
-                wrappedBuf.acquire();  // acquire once more to prvent leak
-                encOut.write( wrappedBuf );
-            }
-            else if( encoded instanceof Object[] )
-            {
-                Object[] bufArray = ( Object[] ) encoded;
-                for( int i = 0; i < bufArray.length; i ++ )
-                {
-                    this.encodeOccurred( codec, bufArray[ i ] );
-                }
-
-                encOut.mergeAll();
-            }
-            else if( encoded instanceof Iterator )
-            {
-                Iterator it = ( Iterator ) encoded;
-                while( it.hasNext() )
-                {
-                    this.encodeOccurred( codec, it.next() );
-                }
-                
-                encOut.mergeAll();
-            }
-            else if( encoded instanceof Collection )
-            {
-                Iterator it = ( ( Collection ) encoded ).iterator();
-                while( it.hasNext() )
-                {
-                    this.encodeOccurred( codec, it.next() );
-                }
-                
-                encOut.mergeAll();
-            }
-            else if( encoded instanceof Enumeration )
-            {
-                Enumeration e = ( Enumeration ) encoded;
-                while( e.hasMoreElements() )
-                {
-                    this.encodeOccurred( codec, e.nextElement() );
-                }
-                
-                encOut.mergeAll();
-            }
-            else
-            {
-                throw new IllegalArgumentException(
-                        "Encoded result is not a ByteBuffer: " +
-                        encoded.getClass() );
-            }
-        }
-    }
-}
+/*
+ *   @(#) $Id$
+ *
+ *   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.asn1;
+
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+
+import org.apache.directory.shared.asn1.codec.EncoderException;
+import org.apache.directory.shared.asn1.codec.stateful.EncoderCallback;
+import org.apache.directory.shared.asn1.codec.stateful.StatefulEncoder;
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.codec.ProtocolEncoder;
+import org.apache.mina.filter.codec.ProtocolEncoderOutput;
+
+/**
+ * Adapts {@link StatefulEncoder} to MINA <tt>ProtocolEncoder</tt>
+ * 
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev$, $Date$, 
+ */
+public class Asn1CodecEncoder implements ProtocolEncoder
+{
+    private final StatefulEncoder encoder;
+
+    private final EncoderCallbackImpl callback = new EncoderCallbackImpl();
+
+    public Asn1CodecEncoder( StatefulEncoder encoder )
+    {
+        encoder.setCallback( callback );
+        this.encoder = encoder;
+    }
+
+    public void encode( IoSession session, Object message,
+                        ProtocolEncoderOutput out ) throws EncoderException
+    {
+        callback.encOut = out;
+        encoder.encode( message );
+    }
+
+    public void dispose( IoSession session ) throws Exception
+    {
+    }
+
+    private class EncoderCallbackImpl implements EncoderCallback
+    {
+        private ProtocolEncoderOutput encOut;
+
+        public void encodeOccurred( StatefulEncoder codec, Object encoded )
+        {
+            if( encoded instanceof java.nio.ByteBuffer )
+            {
+                java.nio.ByteBuffer buf = ( java.nio.ByteBuffer ) encoded;
+                ByteBuffer wrappedBuf = ByteBuffer.wrap( buf );
+                wrappedBuf.acquire();  // acquire once more to prvent leak
+                encOut.write( wrappedBuf );
+            }
+            else if( encoded instanceof Object[] )
+            {
+                Object[] bufArray = ( Object[] ) encoded;
+                for( int i = 0; i < bufArray.length; i ++ )
+                {
+                    this.encodeOccurred( codec, bufArray[ i ] );
+                }
+
+                encOut.mergeAll();
+            }
+            else if( encoded instanceof Iterator )
+            {
+                Iterator it = ( Iterator ) encoded;
+                while( it.hasNext() )
+                {
+                    this.encodeOccurred( codec, it.next() );
+                }
+                
+                encOut.mergeAll();
+            }
+            else if( encoded instanceof Collection )
+            {
+                Iterator it = ( ( Collection ) encoded ).iterator();
+                while( it.hasNext() )
+                {
+                    this.encodeOccurred( codec, it.next() );
+                }
+                
+                encOut.mergeAll();
+            }
+            else if( encoded instanceof Enumeration )
+            {
+                Enumeration e = ( Enumeration ) encoded;
+                while( e.hasMoreElements() )
+                {
+                    this.encodeOccurred( codec, e.nextElement() );
+                }
+                
+                encOut.mergeAll();
+            }
+            else
+            {
+                throw new IllegalArgumentException(
+                        "Encoded result is not a ByteBuffer: " +
+                        encoded.getClass() );
+            }
+        }
+    }
+}

Modified: directory/trunks/mina/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java?rev=400067&r1=400066&r2=400067&view=diff
==============================================================================
--- directory/trunks/mina/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java (original)
+++ directory/trunks/mina/filter-compression/src/main/java/org/apache/mina/filter/CompressionFilter.java Fri May  5 05:52:49 2006
@@ -1,274 +1,274 @@
-/*
- *   @(#) $Id$
- *
- *   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;
-
-import java.io.IOException;
-
-import org.apache.mina.common.ByteBuffer;
-import org.apache.mina.common.IoFilter;
-import org.apache.mina.common.IoFilterAdapter;
-import org.apache.mina.common.IoFilterChain;
-import org.apache.mina.common.IoSession;
-import org.apache.mina.filter.support.Zlib;
-
-/**
- * An {@link IoFilter} which compresses all data using
- * <a href="http://www.jcraft.com/jzlib/">JZlib</a>.
- * Support for the LZW (DLCZ) algorithm is also planned.
- * <p>
- * This filter only supports compression using the <tt>PARTIAL FLUSH</tt> method,
- * since that is the only method useful when doing stream level compression.
- * <p>
- * This filter supports compression/decompression of the input and output
- * channels selectively.  It can also be enabled/disabled on the fly.
- * <p>
- * This filter does not discard the zlib objects, keeping them around for the
- * entire life of the filter.  This is because the zlib dictionary needs to
- * be built up over time, which is used during compression and decompression.
- * Over time, as repetitive data is sent over the wire, the compression efficiency
- * steadily increases.
- * <p>
- * Note that the zlib header is written only once. It is not necessary that
- * the data received after processing by this filter may not be complete due
- * to packet fragmentation.
- * <p>
- * It goes without saying that the other end of this stream should also have a
- * compatible compressor/decompressor using the same algorithm.
- *
- * @author The Apache Directory Project (mina-dev@directory.apache.org)
- * @version $Rev$, $Date$
- */
-public class CompressionFilter extends IoFilterAdapter
-{
-    /**
-     * Max compression level.  Will give the highest compression ratio, but
-     * will also take more cpu time and is the slowest.
-     */
-    public static final int COMPRESSION_MAX = Zlib.COMPRESSION_MAX;
-
-    /**
-     * Provides the best speed at the price of a low compression ratio.
-     */
-    public static final int COMPRESSION_MIN = Zlib.COMPRESSION_MIN;
-
-    /**
-     * No compression done on the data.
-     */
-    public static final int COMPRESSION_NONE = Zlib.COMPRESSION_NONE;
-
-    /**
-     * The default compression level used. Provides the best balance
-     * between speed and compression
-     */
-    public static final int COMPRESSION_DEFAULT = Zlib.COMPRESSION_DEFAULT;
-
-    /**
-     * A session attribute that stores the {@link Zlib} object used for compression.
-     */
-    private static final String DEFLATER = CompressionFilter.class.getName()
-            + ".Deflater";
-
-    /**
-     * A session attribute that stores the {@link Zlib} object used for decompression.
-     */
-    private static final String INFLATER = CompressionFilter.class.getName()
-            + ".Inflater";
-
-    /**
-     * A flag that allows you to disable compression once.
-     */
-    public static final String DISABLE_COMPRESSION_ONCE = CompressionFilter.class
-            .getName()
-            + ".DisableCompressionOnce";
-
-    private boolean compressInbound = true;
-    private boolean compressOutbound = true;
-    private int compressionLevel;
-
-    /**
-     * Creates a new instance which compresses outboud data and decompresses
-     * inbound data with default compression level.
-     */
-    public CompressionFilter()
-    {
-        this( true, true, COMPRESSION_DEFAULT );
-    }
-
-    /**
-     * Creates a new instance which compresses outboud data and decompresses
-     * inbound data with the specified <tt>compressionLevel</tt>.
-     * 
-     * @param compressionLevel the level of compression to be used. Must
-     *                         be one of {@link #COMPRESSION_DEFAULT},
-     *                         {@link #COMPRESSION_MAX},
-     *                         {@link #COMPRESSION_MIN}, and
-     *                         {@link #COMPRESSION_NONE}.
-     */
-    public CompressionFilter( final int compressionLevel )
-    {
-        this( true, true, compressionLevel );
-    }
-
-    /**
-     * Creates a new instance.
-     * 
-     * @param compressInbound <tt>true</tt> if data read is to be decompressed
-     * @param compressOutbound <tt>true</tt> if data written is to be compressed
-     * @param compressionLevel the level of compression to be used. Must
-     *                         be one of {@link #COMPRESSION_DEFAULT},
-     *                         {@link #COMPRESSION_MAX},
-     *                         {@link #COMPRESSION_MIN}, and
-     *                         {@link #COMPRESSION_NONE}.
-     */
-    public CompressionFilter(
-            final boolean compressInbound,
-            final boolean compressOutbound,
-            final int compressionLevel )
-    {
-        this.compressionLevel = compressionLevel;
-        this.compressInbound = compressInbound;
-        this.compressOutbound = compressOutbound;
-    }
-
-    public void messageReceived( NextFilter nextFilter,
-            IoSession session, Object message ) throws Exception
-    {
-        if( !compressInbound )
-        {
-            nextFilter.messageReceived( session, message );
-            return;
-        }
-
-        Zlib inflater = ( Zlib ) session.getAttribute( INFLATER );
-        if( inflater == null )
-        {
-            throw new IllegalStateException();
-        }
-
-        ByteBuffer inBuffer = ( ByteBuffer ) message;
-        ByteBuffer outBuffer = inflater.inflate( inBuffer );
-
-        nextFilter.messageReceived( session, outBuffer );
-    }
-
-    /*
-     * @see org.apache.mina.common.IoFilter#filterWrite(org.apache.mina.common.IoFilter.NextFilter, org.apache.mina.common.IoSession, org.apache.mina.common.IoFilter.WriteRequest)
-     */
-    public void filterWrite( NextFilter nextFilter,
-            IoSession session, WriteRequest writeRequest ) throws IOException
-    {
-        if( !compressOutbound )
-        {
-            nextFilter.filterWrite( session, writeRequest );
-            return;
-        }
-
-        if( session.containsAttribute( DISABLE_COMPRESSION_ONCE ) )
-        {
-            // Remove the marker attribute because it is temporary.
-            session.removeAttribute( DISABLE_COMPRESSION_ONCE );
-            nextFilter.filterWrite( session, writeRequest );
-            return;
-        }
-
-        Zlib deflater = ( Zlib ) session.getAttribute( DEFLATER );
-        if( deflater == null )
-        {
-            throw new IllegalStateException();
-        }
-
-        ByteBuffer inBuffer = ( ByteBuffer ) writeRequest.getMessage();
-
-        ByteBuffer outBuf = deflater.deflate( inBuffer );
-
-        nextFilter.filterWrite( session, new WriteRequest( outBuf, writeRequest
-                .getFuture() ) );
-    }
-
-    public void onPreAdd( IoFilterChain parent, String name, NextFilter nextFilter ) throws Exception
-    {
-        if( parent.contains( CompressionFilter.class ) )
-        {
-            throw new IllegalStateException( "A filter chain cannot contain more than" +
-                    " one Stream Compression filter." );
-        }
-
-        Zlib deflater = new Zlib( compressionLevel, Zlib.MODE_DEFLATER );
-        Zlib inflater = new Zlib( compressionLevel, Zlib.MODE_INFLATER );
-
-        IoSession session = parent.getSession();
-
-        session.setAttribute( DEFLATER, deflater );
-        session.setAttribute( INFLATER, inflater );
-    }
-
-    /**
-     * Returns <tt>true</tt> if incoming data is being compressed.
-     */
-    public boolean isCompressInbound()
-    {
-        return compressInbound;
-    }
-
-    /**
-     * Sets if incoming data has to be compressed.
-     */
-    public void setCompressInbound( boolean compressInbound )
-    {
-        this.compressInbound = compressInbound;
-    }
-
-    /**
-     * Returns <tt>true</tt> if the filter is compressing data being written.
-     */
-    public boolean isCompressOutbound()
-    {
-        return compressOutbound;
-    }
-
-    /**
-     * Set if outgoing data has to be compressed.
-     */
-    public void setCompressOutbound( boolean compressOutbound )
-    {
-        this.compressOutbound = compressOutbound;
-    }
-
-    public void onPostRemove( IoFilterChain parent, String name, NextFilter nextFilter ) throws Exception
-    {
-        super.onPostRemove( parent, name, nextFilter );
-        IoSession session = parent.getSession();
-        if( session == null )
-        {
-            return;
-        }
-
-        Zlib inflater = ( Zlib ) session.getAttribute( INFLATER );
-        Zlib deflater = ( Zlib ) session.getAttribute( DEFLATER );
-        if( deflater != null )
-        {
-            deflater.cleanUp();
-        }
-
-        if( inflater != null )
-        {
-            inflater.cleanUp();
-        }
-    }
-}
+/*
+ *   @(#) $Id$
+ *
+ *   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;
+
+import java.io.IOException;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoFilter;
+import org.apache.mina.common.IoFilterAdapter;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.support.Zlib;
+
+/**
+ * An {@link IoFilter} which compresses all data using
+ * <a href="http://www.jcraft.com/jzlib/">JZlib</a>.
+ * Support for the LZW (DLCZ) algorithm is also planned.
+ * <p>
+ * This filter only supports compression using the <tt>PARTIAL FLUSH</tt> method,
+ * since that is the only method useful when doing stream level compression.
+ * <p>
+ * This filter supports compression/decompression of the input and output
+ * channels selectively.  It can also be enabled/disabled on the fly.
+ * <p>
+ * This filter does not discard the zlib objects, keeping them around for the
+ * entire life of the filter.  This is because the zlib dictionary needs to
+ * be built up over time, which is used during compression and decompression.
+ * Over time, as repetitive data is sent over the wire, the compression efficiency
+ * steadily increases.
+ * <p>
+ * Note that the zlib header is written only once. It is not necessary that
+ * the data received after processing by this filter may not be complete due
+ * to packet fragmentation.
+ * <p>
+ * It goes without saying that the other end of this stream should also have a
+ * compatible compressor/decompressor using the same algorithm.
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev$, $Date$
+ */
+public class CompressionFilter extends IoFilterAdapter
+{
+    /**
+     * Max compression level.  Will give the highest compression ratio, but
+     * will also take more cpu time and is the slowest.
+     */
+    public static final int COMPRESSION_MAX = Zlib.COMPRESSION_MAX;
+
+    /**
+     * Provides the best speed at the price of a low compression ratio.
+     */
+    public static final int COMPRESSION_MIN = Zlib.COMPRESSION_MIN;
+
+    /**
+     * No compression done on the data.
+     */
+    public static final int COMPRESSION_NONE = Zlib.COMPRESSION_NONE;
+
+    /**
+     * The default compression level used. Provides the best balance
+     * between speed and compression
+     */
+    public static final int COMPRESSION_DEFAULT = Zlib.COMPRESSION_DEFAULT;
+
+    /**
+     * A session attribute that stores the {@link Zlib} object used for compression.
+     */
+    private static final String DEFLATER = CompressionFilter.class.getName()
+            + ".Deflater";
+
+    /**
+     * A session attribute that stores the {@link Zlib} object used for decompression.
+     */
+    private static final String INFLATER = CompressionFilter.class.getName()
+            + ".Inflater";
+
+    /**
+     * A flag that allows you to disable compression once.
+     */
+    public static final String DISABLE_COMPRESSION_ONCE = CompressionFilter.class
+            .getName()
+            + ".DisableCompressionOnce";
+
+    private boolean compressInbound = true;
+    private boolean compressOutbound = true;
+    private int compressionLevel;
+
+    /**
+     * Creates a new instance which compresses outboud data and decompresses
+     * inbound data with default compression level.
+     */
+    public CompressionFilter()
+    {
+        this( true, true, COMPRESSION_DEFAULT );
+    }
+
+    /**
+     * Creates a new instance which compresses outboud data and decompresses
+     * inbound data with the specified <tt>compressionLevel</tt>.
+     * 
+     * @param compressionLevel the level of compression to be used. Must
+     *                         be one of {@link #COMPRESSION_DEFAULT},
+     *                         {@link #COMPRESSION_MAX},
+     *                         {@link #COMPRESSION_MIN}, and
+     *                         {@link #COMPRESSION_NONE}.
+     */
+    public CompressionFilter( final int compressionLevel )
+    {
+        this( true, true, compressionLevel );
+    }
+
+    /**
+     * Creates a new instance.
+     * 
+     * @param compressInbound <tt>true</tt> if data read is to be decompressed
+     * @param compressOutbound <tt>true</tt> if data written is to be compressed
+     * @param compressionLevel the level of compression to be used. Must
+     *                         be one of {@link #COMPRESSION_DEFAULT},
+     *                         {@link #COMPRESSION_MAX},
+     *                         {@link #COMPRESSION_MIN}, and
+     *                         {@link #COMPRESSION_NONE}.
+     */
+    public CompressionFilter(
+            final boolean compressInbound,
+            final boolean compressOutbound,
+            final int compressionLevel )
+    {
+        this.compressionLevel = compressionLevel;
+        this.compressInbound = compressInbound;
+        this.compressOutbound = compressOutbound;
+    }
+
+    public void messageReceived( NextFilter nextFilter,
+            IoSession session, Object message ) throws Exception
+    {
+        if( !compressInbound )
+        {
+            nextFilter.messageReceived( session, message );
+            return;
+        }
+
+        Zlib inflater = ( Zlib ) session.getAttribute( INFLATER );
+        if( inflater == null )
+        {
+            throw new IllegalStateException();
+        }
+
+        ByteBuffer inBuffer = ( ByteBuffer ) message;
+        ByteBuffer outBuffer = inflater.inflate( inBuffer );
+
+        nextFilter.messageReceived( session, outBuffer );
+    }
+
+    /*
+     * @see org.apache.mina.common.IoFilter#filterWrite(org.apache.mina.common.IoFilter.NextFilter, org.apache.mina.common.IoSession, org.apache.mina.common.IoFilter.WriteRequest)
+     */
+    public void filterWrite( NextFilter nextFilter,
+            IoSession session, WriteRequest writeRequest ) throws IOException
+    {
+        if( !compressOutbound )
+        {
+            nextFilter.filterWrite( session, writeRequest );
+            return;
+        }
+
+        if( session.containsAttribute( DISABLE_COMPRESSION_ONCE ) )
+        {
+            // Remove the marker attribute because it is temporary.
+            session.removeAttribute( DISABLE_COMPRESSION_ONCE );
+            nextFilter.filterWrite( session, writeRequest );
+            return;
+        }
+
+        Zlib deflater = ( Zlib ) session.getAttribute( DEFLATER );
+        if( deflater == null )
+        {
+            throw new IllegalStateException();
+        }
+
+        ByteBuffer inBuffer = ( ByteBuffer ) writeRequest.getMessage();
+
+        ByteBuffer outBuf = deflater.deflate( inBuffer );
+
+        nextFilter.filterWrite( session, new WriteRequest( outBuf, writeRequest
+                .getFuture() ) );
+    }
+
+    public void onPreAdd( IoFilterChain parent, String name, NextFilter nextFilter ) throws Exception
+    {
+        if( parent.contains( CompressionFilter.class ) )
+        {
+            throw new IllegalStateException( "A filter chain cannot contain more than" +
+                    " one Stream Compression filter." );
+        }
+
+        Zlib deflater = new Zlib( compressionLevel, Zlib.MODE_DEFLATER );
+        Zlib inflater = new Zlib( compressionLevel, Zlib.MODE_INFLATER );
+
+        IoSession session = parent.getSession();
+
+        session.setAttribute( DEFLATER, deflater );
+        session.setAttribute( INFLATER, inflater );
+    }
+
+    /**
+     * Returns <tt>true</tt> if incoming data is being compressed.
+     */
+    public boolean isCompressInbound()
+    {
+        return compressInbound;
+    }
+
+    /**
+     * Sets if incoming data has to be compressed.
+     */
+    public void setCompressInbound( boolean compressInbound )
+    {
+        this.compressInbound = compressInbound;
+    }
+
+    /**
+     * Returns <tt>true</tt> if the filter is compressing data being written.
+     */
+    public boolean isCompressOutbound()
+    {
+        return compressOutbound;
+    }
+
+    /**
+     * Set if outgoing data has to be compressed.
+     */
+    public void setCompressOutbound( boolean compressOutbound )
+    {
+        this.compressOutbound = compressOutbound;
+    }
+
+    public void onPostRemove( IoFilterChain parent, String name, NextFilter nextFilter ) throws Exception
+    {
+        super.onPostRemove( parent, name, nextFilter );
+        IoSession session = parent.getSession();
+        if( session == null )
+        {
+            return;
+        }
+
+        Zlib inflater = ( Zlib ) session.getAttribute( INFLATER );
+        Zlib deflater = ( Zlib ) session.getAttribute( DEFLATER );
+        if( deflater != null )
+        {
+            deflater.cleanUp();
+        }
+
+        if( inflater != null )
+        {
+            inflater.cleanUp();
+        }
+    }
+}

Modified: directory/trunks/mina/filter-compression/src/main/java/org/apache/mina/filter/support/Zlib.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/filter-compression/src/main/java/org/apache/mina/filter/support/Zlib.java?rev=400067&r1=400066&r2=400067&view=diff
==============================================================================
--- directory/trunks/mina/filter-compression/src/main/java/org/apache/mina/filter/support/Zlib.java (original)
+++ directory/trunks/mina/filter-compression/src/main/java/org/apache/mina/filter/support/Zlib.java Fri May  5 05:52:49 2006
@@ -1,196 +1,196 @@
-/*
- *   @(#) $Id$
- *
- *   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.support;
-
-import java.io.IOException;
-
-import org.apache.mina.common.ByteBuffer;
-
-import com.jcraft.jzlib.JZlib;
-import com.jcraft.jzlib.ZStream;
-
-/**
- * A helper class for interfacing with the JZlib library. This class acts both
- * as a compressor and decompressor, but only as one at a time.  The only
- * flush method supported is <tt>Z_SYNC_FLUSH</tt> also known as <tt>Z_PARTIAL_FLUSH</tt>
- *
- * @author The Apache Directory Project (mina-dev@directory.apache.org)
- * @version $Rev$, $Date$
- */
-public class Zlib
-{
-    public static final int COMPRESSION_MAX = JZlib.Z_BEST_COMPRESSION;
-    public static final int COMPRESSION_MIN = JZlib.Z_BEST_SPEED;
-    public static final int COMPRESSION_NONE = JZlib.Z_NO_COMPRESSION;
-    public static final int COMPRESSION_DEFAULT = JZlib.Z_DEFAULT_COMPRESSION;
-
-    public static final int MODE_DEFLATER = 1;
-    public static final int MODE_INFLATER = 2;
-
-    private int compressionLevel;
-    private ZStream zStream = null;
-    private int mode = -1;
-
-    /**
-     * @param compressionLevel the level of compression that should be used
-     * @param mode the mode in which the instance will operate. Can be either 
-     * of <tt>MODE_DEFLATER</tt> or <tt>MODE_INFLATER</tt>
-     */
-    public Zlib( int compressionLevel, int mode )
-    {
-        switch( compressionLevel )
-        {
-        case COMPRESSION_MAX:
-        case COMPRESSION_MIN:
-        case COMPRESSION_NONE:
-        case COMPRESSION_DEFAULT:
-            this.compressionLevel = compressionLevel;
-            break;
-        default:
-            throw new IllegalArgumentException( "invalid compression level specified" );
-        }
-
-        // create a new instance of ZStream. This will be done only once.
-        zStream = new ZStream();
-
-        switch( mode )
-        {
-        case MODE_DEFLATER:
-            zStream.deflateInit( this.compressionLevel );
-            break;
-        case MODE_INFLATER:
-            zStream.inflateInit();
-            break;
-        default:
-            throw new IllegalArgumentException( "invalid mode specified" );
-        }
-        this.mode = mode;
-    }
-
-    /**
-     * @param inBuffer the {@link ByteBuffer} to be decompressed. The contents
-     * of the buffer are transferred into a local byte array and the buffer is
-     * flipped and returned intact.
-     * @return the decompressed data. If not passed to the MINA methods that 
-     * release the buffer automatically, the buffer has to be manually released 
-     * @throws IOException if the decompression of the data failed for some reason.
-     */
-    public ByteBuffer inflate( ByteBuffer inBuffer ) throws IOException
-    {
-        if( mode == MODE_DEFLATER )
-        {
-            throw new IllegalStateException( "not initialized as INFLATER" );
-        }
-
-        byte[] inBytes = new byte[ inBuffer.limit() ];
-        inBuffer.get( inBytes ).flip();
-
-        byte[] outBytes = new byte[ inBytes.length * 2 ];
-        ByteBuffer outBuffer = ByteBuffer.allocate( outBytes.length );
-        outBuffer.setAutoExpand( true );
-
-        zStream.next_in = inBytes;
-        zStream.next_in_index = 0;
-        zStream.avail_in = inBytes.length;
-        zStream.next_out = outBytes;
-        zStream.next_out_index = 0;
-        zStream.avail_out = outBytes.length;
-        int retval = 0;
-
-        do
-        {
-            retval = zStream.inflate( JZlib.Z_SYNC_FLUSH );
-            switch( retval )
-            {
-            case JZlib.Z_OK:
-                // completed decompression, lets copy data and get out
-            case JZlib.Z_BUF_ERROR:
-                // need more space for output. store current output and get more
-                outBuffer.put( outBytes, 0, zStream.next_out_index );
-                zStream.next_out_index = 0;
-                zStream.avail_out = outBytes.length;
-                break;
-            default:
-                // unknown error
-                outBuffer.release();
-                outBuffer = null;
-                if( zStream.msg == null )
-                    throw new IOException( "Unknown error. Error code : " + retval );
-                else
-                    throw new IOException( "Unknown error. Error code : " + retval
-                            + " and message : " + zStream.msg );
-            }
-        } while( zStream.avail_in > 0 );
-
-        return outBuffer.flip();
-    }
-
-    /**
-     * @param inBuffer the buffer to be compressed. The contents are transferred
-     * into a local byte array and the buffer is flipped and returned intact.
-     * @return the buffer with the compressed data. If not passed to any of the
-     * MINA methods that automatically release the buffer, the buffer has to be
-     * released manually.
-     * @throws IOException if the compression of teh buffer failed for some reason
-     */
-    public ByteBuffer deflate( ByteBuffer inBuffer ) throws IOException
-    {
-        if( mode == MODE_INFLATER )
-        {
-            throw new IllegalStateException( "not initialized as DEFLATER" );
-        }
-
-        byte[] inBytes = new byte[ inBuffer.limit() ];
-        inBuffer.get( inBytes ).flip();
-
-        // according to spec, destination buffer should be 0.1% larger
-        // than source length plus 12 bytes. We add a single byte to safeguard
-        // against rounds that round down to the smaller value
-        int outLen = (int) Math.round( inBytes.length * 1.001 ) + 1 + 12;
-        byte[] outBytes = new byte[ outLen ];
-
-        zStream.next_in = inBytes;
-        zStream.next_in_index = 0;
-        zStream.avail_in = inBytes.length;
-        zStream.next_out = outBytes;
-        zStream.next_out_index = 0;
-        zStream.avail_out = outBytes.length;
-
-        int retval = zStream.deflate( JZlib.Z_SYNC_FLUSH );
-        if( retval != JZlib.Z_OK )
-        {
-            outBytes = null;
-            inBytes = null;
-            throw new IOException( "Compression failed with return value : " + retval );
-        }
-
-        ByteBuffer outBuf = ByteBuffer.wrap( outBytes, 0, zStream.next_out_index );
-
-        return outBuf;
-    }
-
-    /**
-     * Cleans up the resources used by the compression library.
-     */
-    public void cleanUp()
-    {
-        if( zStream != null )
-            zStream.free();
-    }
-}
\ No newline at end of file
+/*
+ *   @(#) $Id$
+ *
+ *   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.support;
+
+import java.io.IOException;
+
+import org.apache.mina.common.ByteBuffer;
+
+import com.jcraft.jzlib.JZlib;
+import com.jcraft.jzlib.ZStream;
+
+/**
+ * A helper class for interfacing with the JZlib library. This class acts both
+ * as a compressor and decompressor, but only as one at a time.  The only
+ * flush method supported is <tt>Z_SYNC_FLUSH</tt> also known as <tt>Z_PARTIAL_FLUSH</tt>
+ *
+ * @author The Apache Directory Project (mina-dev@directory.apache.org)
+ * @version $Rev$, $Date$
+ */
+public class Zlib
+{
+    public static final int COMPRESSION_MAX = JZlib.Z_BEST_COMPRESSION;
+    public static final int COMPRESSION_MIN = JZlib.Z_BEST_SPEED;
+    public static final int COMPRESSION_NONE = JZlib.Z_NO_COMPRESSION;
+    public static final int COMPRESSION_DEFAULT = JZlib.Z_DEFAULT_COMPRESSION;
+
+    public static final int MODE_DEFLATER = 1;
+    public static final int MODE_INFLATER = 2;
+
+    private int compressionLevel;
+    private ZStream zStream = null;
+    private int mode = -1;
+
+    /**
+     * @param compressionLevel the level of compression that should be used
+     * @param mode the mode in which the instance will operate. Can be either 
+     * of <tt>MODE_DEFLATER</tt> or <tt>MODE_INFLATER</tt>
+     */
+    public Zlib( int compressionLevel, int mode )
+    {
+        switch( compressionLevel )
+        {
+        case COMPRESSION_MAX:
+        case COMPRESSION_MIN:
+        case COMPRESSION_NONE:
+        case COMPRESSION_DEFAULT:
+            this.compressionLevel = compressionLevel;
+            break;
+        default:
+            throw new IllegalArgumentException( "invalid compression level specified" );
+        }
+
+        // create a new instance of ZStream. This will be done only once.
+        zStream = new ZStream();
+
+        switch( mode )
+        {
+        case MODE_DEFLATER:
+            zStream.deflateInit( this.compressionLevel );
+            break;
+        case MODE_INFLATER:
+            zStream.inflateInit();
+            break;
+        default:
+            throw new IllegalArgumentException( "invalid mode specified" );
+        }
+        this.mode = mode;
+    }
+
+    /**
+     * @param inBuffer the {@link ByteBuffer} to be decompressed. The contents
+     * of the buffer are transferred into a local byte array and the buffer is
+     * flipped and returned intact.
+     * @return the decompressed data. If not passed to the MINA methods that 
+     * release the buffer automatically, the buffer has to be manually released 
+     * @throws IOException if the decompression of the data failed for some reason.
+     */
+    public ByteBuffer inflate( ByteBuffer inBuffer ) throws IOException
+    {
+        if( mode == MODE_DEFLATER )
+        {
+            throw new IllegalStateException( "not initialized as INFLATER" );
+        }
+
+        byte[] inBytes = new byte[ inBuffer.limit() ];
+        inBuffer.get( inBytes ).flip();
+
+        byte[] outBytes = new byte[ inBytes.length * 2 ];
+        ByteBuffer outBuffer = ByteBuffer.allocate( outBytes.length );
+        outBuffer.setAutoExpand( true );
+
+        zStream.next_in = inBytes;
+        zStream.next_in_index = 0;
+        zStream.avail_in = inBytes.length;
+        zStream.next_out = outBytes;
+        zStream.next_out_index = 0;
+        zStream.avail_out = outBytes.length;
+        int retval = 0;
+
+        do
+        {
+            retval = zStream.inflate( JZlib.Z_SYNC_FLUSH );
+            switch( retval )
+            {
+            case JZlib.Z_OK:
+                // completed decompression, lets copy data and get out
+            case JZlib.Z_BUF_ERROR:
+                // need more space for output. store current output and get more
+                outBuffer.put( outBytes, 0, zStream.next_out_index );
+                zStream.next_out_index = 0;
+                zStream.avail_out = outBytes.length;
+                break;
+            default:
+                // unknown error
+                outBuffer.release();
+                outBuffer = null;
+                if( zStream.msg == null )
+                    throw new IOException( "Unknown error. Error code : " + retval );
+                else
+                    throw new IOException( "Unknown error. Error code : " + retval
+                            + " and message : " + zStream.msg );
+            }
+        } while( zStream.avail_in > 0 );
+
+        return outBuffer.flip();
+    }
+
+    /**
+     * @param inBuffer the buffer to be compressed. The contents are transferred
+     * into a local byte array and the buffer is flipped and returned intact.
+     * @return the buffer with the compressed data. If not passed to any of the
+     * MINA methods that automatically release the buffer, the buffer has to be
+     * released manually.
+     * @throws IOException if the compression of teh buffer failed for some reason
+     */
+    public ByteBuffer deflate( ByteBuffer inBuffer ) throws IOException
+    {
+        if( mode == MODE_INFLATER )
+        {
+            throw new IllegalStateException( "not initialized as DEFLATER" );
+        }
+
+        byte[] inBytes = new byte[ inBuffer.limit() ];
+        inBuffer.get( inBytes ).flip();
+
+        // according to spec, destination buffer should be 0.1% larger
+        // than source length plus 12 bytes. We add a single byte to safeguard
+        // against rounds that round down to the smaller value
+        int outLen = (int) Math.round( inBytes.length * 1.001 ) + 1 + 12;
+        byte[] outBytes = new byte[ outLen ];
+
+        zStream.next_in = inBytes;
+        zStream.next_in_index = 0;
+        zStream.avail_in = inBytes.length;
+        zStream.next_out = outBytes;
+        zStream.next_out_index = 0;
+        zStream.avail_out = outBytes.length;
+
+        int retval = zStream.deflate( JZlib.Z_SYNC_FLUSH );
+        if( retval != JZlib.Z_OK )
+        {
+            outBytes = null;
+            inBytes = null;
+            throw new IOException( "Compression failed with return value : " + retval );
+        }
+
+        ByteBuffer outBuf = ByteBuffer.wrap( outBytes, 0, zStream.next_out_index );
+
+        return outBuf;
+    }
+
+    /**
+     * Cleans up the resources used by the compression library.
+     */
+    public void cleanUp()
+    {
+        if( zStream != null )
+            zStream.free();
+    }
+}



Mime
View raw message