You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by tr...@apache.org on 2008/03/17 15:50:51 UTC

svn commit: r637919 - in /mina/trunk/core/src: main/java/org/apache/mina/common/UnderivableBuffer.java main/java/org/apache/mina/filter/codec/CumulativeProtocolDecoder.java test/java/org/apache/mina/filter/codec/CumulativeProtocolDecoderTest.java

Author: trustin
Date: Mon Mar 17 07:50:47 2008
New Revision: 637919

URL: http://svn.apache.org/viewvc?rev=637919&view=rev
Log:
Resolved issue: DIRMINA-548 - subclass of CumulativeDecoder throws an UnsupportedOperationException if IoBuffer.slice() is used
* Modified CumulativeProtocolDecoder to reallocate its internal buffer if it detects auto-expansion has been disabled.
* Added the related test case, and it passed
* Removed unnecessary class - UnderivableBuffer


Removed:
    mina/trunk/core/src/main/java/org/apache/mina/common/UnderivableBuffer.java
Modified:
    mina/trunk/core/src/main/java/org/apache/mina/filter/codec/CumulativeProtocolDecoder.java
    mina/trunk/core/src/test/java/org/apache/mina/filter/codec/CumulativeProtocolDecoderTest.java

Modified: mina/trunk/core/src/main/java/org/apache/mina/filter/codec/CumulativeProtocolDecoder.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/codec/CumulativeProtocolDecoder.java?rev=637919&r1=637918&r2=637919&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filter/codec/CumulativeProtocolDecoder.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/filter/codec/CumulativeProtocolDecoder.java Mon Mar 17 07:50:47 2008
@@ -23,7 +23,6 @@
 import org.apache.mina.common.IoBuffer;
 import org.apache.mina.common.IoSession;
 import org.apache.mina.common.TransportMetadata;
-import org.apache.mina.common.UnderivableBuffer;
 
 /**
  * A {@link ProtocolDecoder} that cumulates the content of received
@@ -133,8 +132,37 @@
         // If we have a session buffer, append data to that; otherwise
         // use the buffer read from the network directly.
         if (buf != null) {
-            buf.put(in);
-            buf.flip();
+            boolean appended = false;
+            // Make sure that the buffer is auto-expanded.
+            if (buf.isAutoExpand()) {
+                try {
+                    buf.put(in);
+                    appended = true;
+                } catch (IllegalStateException e) {
+                    // A user called derivation method (e.g. slice()),
+                    // which disables auto-expansion of the parent buffer.
+                } catch (IndexOutOfBoundsException e) {
+                    // A user disabled auto-expansion.
+                }
+            }
+
+            if (appended) {
+                buf.flip();
+            } else {
+                // Reallocate the buffer if append operation failed due to
+                // derivation or disabled auto-expansion.
+                buf.flip();
+                IoBuffer newBuf = IoBuffer.allocate(
+                        buf.remaining() + in.remaining()).setAutoExpand(true);
+                newBuf.order(buf.order());
+                newBuf.put(buf);
+                newBuf.put(in);
+                newBuf.flip();
+                buf = newBuf;
+                
+                // Update the session attribute.
+                session.setAttribute(BUFFER, buf);
+            }
         } else {
             buf = in;
             usingSessionBuffer = false;
@@ -202,8 +230,7 @@
     }
 
     private void storeRemainingInSession(IoBuffer buf, IoSession session) {
-        final IoBuffer remainingBuf = new UnderivableBuffer(
-                IoBuffer.allocate(buf.capacity()).setAutoExpand(true));
+        final IoBuffer remainingBuf = IoBuffer.allocate(buf.capacity()).setAutoExpand(true);
         
         remainingBuf.order(buf.order());
         remainingBuf.put(buf);

Modified: mina/trunk/core/src/test/java/org/apache/mina/filter/codec/CumulativeProtocolDecoderTest.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/filter/codec/CumulativeProtocolDecoderTest.java?rev=637919&r1=637918&r2=637919&view=diff
==============================================================================
--- mina/trunk/core/src/test/java/org/apache/mina/filter/codec/CumulativeProtocolDecoderTest.java (original)
+++ mina/trunk/core/src/test/java/org/apache/mina/filter/codec/CumulativeProtocolDecoderTest.java Mon Mar 17 07:50:47 2008
@@ -107,6 +107,42 @@
             // OK
         }
     }
+    
+    public void testBufferDerivation() throws Exception {
+        decoder = new DuplicatingIntegerDecoder();
+        
+        buf.putInt(1);
+        
+        // Put some extra byte to make the decoder create an internal buffer.
+        buf.put((byte) 0);
+        buf.flip();
+
+        decoder.decode(session, buf, session.getDecoderOutput());
+        Assert.assertEquals(1, session.getDecoderOutputQueue().size());
+        Assert.assertEquals(1, session.getDecoderOutputQueue().poll());
+        Assert.assertEquals(buf.limit(), buf.position());
+
+        // Keep appending to the internal buffer.
+        // DuplicatingIntegerDecoder will keep duplicating the internal
+        // buffer to disable auto-expansion, and CumulativeProtocolDecoder
+        // should detect that user derived its internal buffer.
+        // Consequently, CumulativeProtocolDecoder will perform 
+        // reallocation to avoid putting incoming data into
+        // the internal buffer with auto-expansion disabled.
+        for (int i = 2; i < 10; i ++) {
+            buf.clear();
+            buf.putInt(i);
+            // Put some extra byte to make the decoder keep the internal buffer.
+            buf.put((byte) 0);
+            buf.flip();
+            buf.position(1);
+    
+            decoder.decode(session, buf, session.getDecoderOutput());
+            Assert.assertEquals(1, session.getDecoderOutputQueue().size());
+            Assert.assertEquals(i, session.getDecoderOutputQueue().poll());
+            Assert.assertEquals(buf.limit(), buf.position());
+        }
+    }
 
     private static class IntegerDecoder extends CumulativeProtocolDecoder {
 
@@ -124,11 +160,9 @@
 
         public void dispose() throws Exception {
         }
-
     }
-
+    
     private static class WrongDecoder extends CumulativeProtocolDecoder {
-
         @Override
         protected boolean doDecode(IoSession session, IoBuffer in,
                 ProtocolDecoderOutput out) throws Exception {
@@ -138,4 +172,18 @@
         public void dispose() throws Exception {
         }
     }
+
+    private static class DuplicatingIntegerDecoder extends IntegerDecoder {
+        @Override
+        protected boolean doDecode(IoSession session, IoBuffer in,
+                ProtocolDecoderOutput out) throws Exception {
+            in.duplicate(); // Will disable auto-expansion.
+            Assert.assertFalse(in.isAutoExpand());
+            return super.doDecode(session, in, out);
+        }
+
+        public void dispose() throws Exception {
+        }
+    }
+
 }