You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2007/04/23 23:12:16 UTC

svn commit: r531601 - in /jakarta/httpcomponents/httpcore/trunk: ./ module-nio/src/main/java/org/apache/http/impl/nio/codecs/ module-nio/src/main/java/org/apache/http/nio/ module-nio/src/test/java/org/apache/http/impl/nio/codecs/

Author: olegk
Date: Mon Apr 23 14:12:15 2007
New Revision: 531601

URL: http://svn.apache.org/viewvc?view=rev&rev=531601
Log:
HTTPCORE-43: Added support for FileChannel#transferFrom() and FileChannel#transferTo() methods. Direct coping from and to FileChannel is expected to improve performance of file bound operations

Contributed by Andrea Selva <selva.andre at gmail.com>
Reviewed by Oleg Kalnichevski

Added:
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentDecoder.java   (with props)
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java   (with props)
Modified:
    jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityDecoder.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityEncoder.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedDecoder.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedEncoder.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityDecoder.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedDecoder.java
    jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java

Modified: jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt?view=diff&rev=531601&r1=531600&r2=531601
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt (original)
+++ jakarta/httpcomponents/httpcore/trunk/RELEASE_NOTES.txt Mon Apr 23 14:12:15 2007
@@ -1,5 +1,10 @@
 Changes since 4.0 Alpha 4
 
+* [HTTPCORE-43]: Support for FileChannel#transferFrom() and 
+  FileChannel#transferTo() methods. Direct coping from and to FileChannel is 
+  expected to improve performance of file bound operations
+  Andrea Selva <selva.andre at gmail.com>
+
 * [HTTPCORE-66]: Fixed handling of HTTP HEAD methods
   Contributed by Steffen Pingel <spingel at limewire.com> and 
   Oleg Kalnichevski <olegk at apache.org>

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityDecoder.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityDecoder.java?view=diff&rev=531601&r1=531600&r2=531601
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityDecoder.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityDecoder.java Mon Apr 23 14:12:15 2007
@@ -33,11 +33,14 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
 import java.nio.channels.ReadableByteChannel;
 
 import org.apache.http.impl.nio.reactor.SessionInputBuffer;
+import org.apache.http.nio.FileContentDecoder;
 
-public class IdentityDecoder extends AbstractContentDecoder {
+public class IdentityDecoder extends AbstractContentDecoder 
+        implements FileContentDecoder {
     
     public IdentityDecoder(final ReadableByteChannel channel, final SessionInputBuffer buffer) {
         super(channel, buffer);
@@ -58,6 +61,29 @@
             bytesRead = this.channel.read(dst);
         }
         if (bytesRead == -1) {
+            this.completed = true;
+        }
+        return bytesRead;
+    }
+    
+    public long read(final FileChannel fileChannel, long position, long count) throws IOException {
+        if (fileChannel == null) {
+            return 0;
+        }
+        if (this.completed) {
+            return 0;
+        }
+        
+        long bytesRead;
+        if (this.buffer.hasData()) {
+            ByteBuffer tmpDst = ByteBuffer.allocate((int)count);
+            this.buffer.read(tmpDst);
+            tmpDst.flip();
+            bytesRead = fileChannel.write(tmpDst);
+        } else {
+            bytesRead = fileChannel.transferFrom(this.channel, position, count);
+        }
+        if (bytesRead == 0) {
             this.completed = true;
         }
         return bytesRead;

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityEncoder.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityEncoder.java?view=diff&rev=531601&r1=531600&r2=531601
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityEncoder.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/IdentityEncoder.java Mon Apr 23 14:12:15 2007
@@ -33,9 +33,12 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
 import java.nio.channels.WritableByteChannel;
+import org.apache.http.nio.FileContentEncoder;
 
-public class IdentityEncoder extends AbstractContentEncoder {
+public class IdentityEncoder extends AbstractContentEncoder 
+        implements FileContentEncoder {
     
     private final WritableByteChannel channel;
     
@@ -55,6 +58,14 @@
         return this.channel.write(src);
     }
  
+    public long write(final FileChannel filechannel, long position, long count) throws IOException {
+        if (channel == null) {
+            return 0;
+        }
+        assertNotCompleted();
+        return filechannel.transferTo(position, count, this.channel);
+    } 
+    
     public String toString() {
         StringBuffer buffer = new StringBuffer();
         buffer.append("[identity; completed: ");

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedDecoder.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedDecoder.java?view=diff&rev=531601&r1=531600&r2=531601
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedDecoder.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedDecoder.java Mon Apr 23 14:12:15 2007
@@ -33,11 +33,14 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
 import java.nio.channels.ReadableByteChannel;
 
 import org.apache.http.impl.nio.reactor.SessionInputBuffer;
+import org.apache.http.nio.FileContentDecoder;
 
-public class LengthDelimitedDecoder extends AbstractContentDecoder {
+public class LengthDelimitedDecoder extends AbstractContentDecoder 
+        implements FileContentDecoder {
     
     private final long contentLength;
     
@@ -88,6 +91,40 @@
         }
         return bytesRead;
     }
+    
+    public long read(final FileChannel fileChannel, long position, long count) throws IOException {
+        if (fileChannel == null) {
+            return 0;
+        }
+        if (this.completed) {
+            return 0;
+        }
+        
+        int lenRemaining = (int) (this.contentLength - this.len);
+        
+        long bytesRead;
+        if (this.buffer.hasData()) {
+            int maxLen = Math.min(lenRemaining, this.buffer.length());
+            ByteBuffer tmpDst = ByteBuffer.allocate(maxLen);
+            this.buffer.read(tmpDst, maxLen);
+            bytesRead = fileChannel.write(tmpDst);
+        } else {
+            if (count > lenRemaining) {
+                bytesRead = fileChannel.transferFrom(this.channel, position, lenRemaining);
+            } else {
+                bytesRead = fileChannel.transferFrom(this.channel, position, count);
+            }
+        }
+        if (bytesRead == 0) {
+            this.completed = true;
+            return 0;
+        }
+        this.len += bytesRead;
+        if (this.len >= this.contentLength) {
+            this.completed = true;
+        }
+        return bytesRead;
+    }
 
     public String toString() {
         StringBuffer buffer = new StringBuffer();
@@ -100,5 +137,4 @@
         buffer.append("]");
         return buffer.toString();
     }
-    
 }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedEncoder.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedEncoder.java?view=diff&rev=531601&r1=531600&r2=531601
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedEncoder.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/impl/nio/codecs/LengthDelimitedEncoder.java Mon Apr 23 14:12:15 2007
@@ -33,9 +33,12 @@
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
 import java.nio.channels.WritableByteChannel;
+import org.apache.http.nio.FileContentEncoder;
 
-public class LengthDelimitedEncoder extends AbstractContentEncoder {
+public class LengthDelimitedEncoder extends AbstractContentEncoder 
+        implements FileContentEncoder {
     
     private final WritableByteChannel channel;
     private final long contentLength;
@@ -79,6 +82,26 @@
         return bytesWritten;
     }
 
+    public long write(final FileChannel fileChannel, long position, long count) throws IOException {
+        if (fileChannel == null) {
+            return 0;
+        }
+        assertNotCompleted();
+        int lenRemaining = (int) (this.contentLength - this.len);
+        
+        long bytesWritten;
+        if (count > lenRemaining) {
+            bytesWritten = fileChannel.transferTo(position, lenRemaining, this.channel);
+        } else {
+            bytesWritten = fileChannel.transferTo(position, count, this.channel);
+        }
+        this.len += bytesWritten;
+        if (this.len >= this.contentLength) {
+            this.completed = true;
+        }
+        return bytesWritten;
+    }
+    
     public String toString() {
         StringBuffer buffer = new StringBuffer();
         buffer.append("[content length: ");

Added: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentDecoder.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentDecoder.java?view=auto&rev=531601
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentDecoder.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentDecoder.java Mon Apr 23 14:12:15 2007
@@ -0,0 +1,59 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+/**
+ * A content decoder capable of reading data directly from a {@link FileChannel}
+ */
+public interface FileContentDecoder extends ContentDecoder {
+    
+    /**
+     * Transfers a portion of entity content from the underlying network channel
+     * into the given file channel.
+     * 
+     * @param channel, the target FileChannel to transfer data into.
+     * @param  position
+     *         The position within the file at which the transfer is to begin;
+     *         must be non-negative
+     * @param  count
+     *         The maximum number of bytes to be transferred; must be
+     *         non-negative
+     * @throws IOException, if some I/O error occurs.
+     * @return  The number of bytes, possibly zero,
+     *          that were actually transferred
+     */
+    long read(FileChannel channel, long position, long count) throws IOException;
+    
+}

Propchange: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentDecoder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentDecoder.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentDecoder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java?view=auto&rev=531601
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java (added)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java Mon Apr 23 14:12:15 2007
@@ -0,0 +1,60 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.nio;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import org.apache.http.nio.ContentEncoder;
+
+/**
+ * A content encoder capable of writing data directly to a {@link FileChannel}
+ */
+public interface FileContentEncoder extends ContentEncoder {
+    
+    /**
+     * Transfers a portion of entity content from the given file channel 
+     * to the underlying network channel.
+     * 
+     * @param channel, the source FileChannel to transfer data from.
+     * @param  position
+     *         The position within the file at which the transfer is to begin;
+     *         must be non-negative
+     * @param  count
+     *         The maximum number of bytes to be transferred; must be
+     *         non-negative
+     *@throws IOException, if some I/O error occurs.
+     * @return  The number of bytes, possibly zero,
+     *          that were actually transferred
+     */
+    long write(FileChannel channel, long position, long count) throws IOException;
+    
+}
\ No newline at end of file

Propchange: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/httpcore/trunk/module-nio/src/main/java/org/apache/http/nio/FileContentEncoder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityDecoder.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityDecoder.java?view=diff&rev=531601&r1=531600&r2=531601
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityDecoder.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestIdentityDecoder.java Mon Apr 23 14:12:15 2007
@@ -30,7 +30,13 @@
 
 package org.apache.http.impl.nio.codecs;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
 import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.FileChannel;
 import java.nio.channels.ReadableByteChannel;
 
 import junit.framework.Test;
@@ -74,6 +80,17 @@
         }
         return buffer.toString();
     }
+    
+    private static String readFromFile(File file, int numChars) throws Exception {
+        FileInputStream fin = new FileInputStream(file);
+        InputStreamReader rdin = new InputStreamReader(fin);
+                
+        CharBuffer cb = CharBuffer.allocate(numChars);
+        rdin.read(cb);
+        
+        fin.close();
+        return cb.flip().toString();
+    }
 
     public void testBasicDecoding() throws Exception {
         ReadableByteChannel channel = new ReadableByteChannelMockup(
@@ -155,6 +172,74 @@
         } catch (IllegalArgumentException ex) {
             // expected
         }
+    }
+    
+    
+    
+    public void testBasicDecodingFile() throws Exception {
+        ReadableByteChannel channel = new ReadableByteChannelMockup(
+                new String[] {"stuff;", "more stuff"}, "US-ASCII"); 
+        
+        SessionInputBuffer inbuf = new SessionInputBuffer(1024, 256); 
+        IdentityDecoder decoder = new IdentityDecoder(channel, inbuf); 
+        
+        File tmpFile = File.createTempFile("testFile", ".txt");
+        FileChannel fchannel = new FileOutputStream(tmpFile).getChannel();
+            
+        long bytesRead = decoder.read(fchannel, 0, 6);
+        assertEquals(6, bytesRead);
+        assertEquals("stuff;", readFromFile(tmpFile, 6));
+        assertFalse(decoder.isCompleted());
+        
+        bytesRead = decoder.read(fchannel,0 , 10);
+        assertEquals(10, bytesRead);
+        assertEquals("more stuff", readFromFile(tmpFile, 10));
+        assertFalse(decoder.isCompleted());
+        
+        bytesRead = decoder.read(fchannel, 0, 1);
+        assertEquals(0, bytesRead);
+        assertTrue(decoder.isCompleted());
+        
+        bytesRead = decoder.read(fchannel, 0, 1);
+        assertEquals(0, bytesRead);
+        assertTrue(decoder.isCompleted());
+        
+        tmpFile.delete();
+    }
+    
+    public void testDecodingFromSessionBufferFile() throws Exception {
+        ReadableByteChannel channel = new ReadableByteChannelMockup(
+                new String[] {"stuff;", "more stuff"}, "US-ASCII"); 
+        
+        SessionInputBuffer inbuf = new SessionInputBuffer(1024, 256);
+        inbuf.fill(channel);
+        
+        assertEquals(6, inbuf.length());
+        
+        IdentityDecoder decoder = new IdentityDecoder(channel, inbuf); 
+        
+        File tmpFile = File.createTempFile("testFile", ".txt");
+        FileChannel fchannel = new FileOutputStream(tmpFile).getChannel();
+            
+        long bytesRead = decoder.read(fchannel, 0, 6);
+        assertEquals(6, bytesRead);
+        assertEquals("stuff;", readFromFile(tmpFile, 6));
+        assertFalse(decoder.isCompleted());
+        
+        bytesRead = decoder.read(fchannel,0 , 10);
+        assertEquals(10, bytesRead);
+        assertEquals("more stuff", readFromFile(tmpFile, 10));
+        assertFalse(decoder.isCompleted());
+        
+        bytesRead = decoder.read(fchannel, 0, 1);
+        assertEquals(0, bytesRead);
+        assertTrue(decoder.isCompleted());
+        
+        bytesRead = decoder.read(fchannel, 0, 1);
+        assertEquals(0, bytesRead);
+        assertTrue(decoder.isCompleted());
+        
+        tmpFile.delete();
     }
     
 }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedDecoder.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedDecoder.java?view=diff&rev=531601&r1=531600&r2=531601
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedDecoder.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedDecoder.java Mon Apr 23 14:12:15 2007
@@ -30,7 +30,13 @@
 
 package org.apache.http.impl.nio.codecs;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
 import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.FileChannel;
 import java.nio.channels.ReadableByteChannel;
 
 import junit.framework.Test;
@@ -74,6 +80,17 @@
         }
         return buffer.toString();
     }
+    
+    private static String readFromFile(File file, int numChars) throws Exception {
+        FileInputStream fin = new FileInputStream(file);
+        InputStreamReader rdin = new InputStreamReader(fin);
+                
+        CharBuffer cb = CharBuffer.allocate(numChars);
+        rdin.read(cb);
+        
+        fin.close();
+        return cb.flip().toString();
+    }
 
     public void testBasicDecoding() throws Exception {
         ReadableByteChannel channel = new ReadableByteChannelMockup(
@@ -270,5 +287,64 @@
             // expected
         }
     }
+    
+    
+    // ----------------------------------------------------- Test read
+    public void testBasicDecodingFile() throws Exception {
+        ReadableByteChannel channel = new ReadableByteChannelMockup(
+                new String[] {"stuff;", "more stuff"}, "US-ASCII"); 
+        
+        SessionInputBuffer inbuf = new SessionInputBuffer(1024, 256); 
+        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(channel, inbuf, 16); 
+        
+        File tmpFile = File.createTempFile("testFile", ".txt");
+        FileChannel fchannel = new FileOutputStream(tmpFile).getChannel();
+        
+        long bytesRead = decoder.read(fchannel, 0, 6);
+        assertEquals(6, bytesRead);
+        assertEquals("stuff;", readFromFile(tmpFile, 6));
+        assertFalse(decoder.isCompleted());
+        
+        bytesRead = decoder.read(fchannel,0 , 10);
+        assertEquals(10, bytesRead);
+        assertEquals("more stuff", readFromFile(tmpFile, 10));
+        assertTrue(decoder.isCompleted());
+        
+        bytesRead = decoder.read(fchannel, 0, 1);
+        assertEquals(0, bytesRead);
+        assertTrue(decoder.isCompleted());
+        
+        tmpFile.delete();
+    }
+    
+    public void testCodingBeyondContentLimitFile() throws Exception {
+        ReadableByteChannel channel = new ReadableByteChannelMockup(
+                new String[] {
+                        "stuff;", 
+                        "more stuff; and a lot more stuff"}, "US-ASCII"); 
+        
+        SessionInputBuffer inbuf = new SessionInputBuffer(1024, 256); 
+        LengthDelimitedDecoder decoder = new LengthDelimitedDecoder(channel, inbuf, 16); 
+        
+        File tmpFile = File.createTempFile("testFile", ".txt");
+        FileChannel fchannel = new FileOutputStream(tmpFile).getChannel();
+        
+        long bytesRead = decoder.read(fchannel, 0, 6);
+        assertEquals(6, bytesRead);
+        assertEquals("stuff;", readFromFile(tmpFile, 6));
+        assertFalse(decoder.isCompleted());
+        
+        bytesRead = decoder.read(fchannel,0 , 10);
+        assertEquals(10, bytesRead);
+        assertEquals("more stuff", readFromFile(tmpFile, 10));
+        assertTrue(decoder.isCompleted());
+        
+        bytesRead = decoder.read(fchannel, 0, 1);
+        assertEquals(0, bytesRead);
+        assertTrue(decoder.isCompleted());
+        
+        tmpFile.delete();
+    }
+    
     
 }

Modified: jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java?view=diff&rev=531601&r1=531600&r2=531601
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-nio/src/test/java/org/apache/http/impl/nio/codecs/TestLengthDelimitedEncoder.java Mon Apr 23 14:12:15 2007
@@ -31,8 +31,13 @@
 package org.apache.http.impl.nio.codecs;
 
 import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
 import java.nio.ByteBuffer;
 import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
 import java.nio.channels.WritableByteChannel;
 
 import junit.framework.Test;
@@ -145,5 +150,110 @@
             // ignore
         }
     }
+    
+    /* ----------------- FileChannel Part testing --------------------------- */
+    public void testCodingBeyondContentLimitFromFile() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
+        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(newChannel(baos), 16);
+               
+        File tmpFile = File.createTempFile("testFile", "txt");
+        FileOutputStream fout = new FileOutputStream(tmpFile);
+        OutputStreamWriter wrtout = new OutputStreamWriter(fout);
+        
+        wrtout.write("stuff;");
+        wrtout.write("more stuff; and a lot more stuff");
+        
+        wrtout.flush();
+        wrtout.close();
+        
+        FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
+        
+        encoder.write(fchannel, 0, 20);
+        
+        String s = baos.toString("US-ASCII");
+        
+        assertTrue(encoder.isCompleted());
+        assertEquals("stuff;more stuff", s);
+        
+        tmpFile.delete();
+    }
+    
+    
+    public void testCodingEmptyFile() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
+        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(newChannel(baos), 16);
+        encoder.write(wrap("stuff;"));
+
+        //Create an empty file
+        File tmpFile = File.createTempFile("testFile", "txt");
+        FileOutputStream fout = new FileOutputStream(tmpFile);
+        OutputStreamWriter wrtout = new OutputStreamWriter(fout);
+        
+        wrtout.flush();
+        wrtout.close();
+        
+        FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
+        
+        encoder.write(fchannel, 0, 20);
+                
+        encoder.write(wrap("more stuff"));
+        
+        String s = baos.toString("US-ASCII");
+        
+        assertTrue(encoder.isCompleted());
+        assertEquals("stuff;more stuff", s);
+        
+        tmpFile.delete();
+    }
+
+    public void testCodingCompletedFromFile() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
+        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(newChannel(baos), 5);
+        encoder.write(wrap("stuff"));
 
+        File tmpFile = File.createTempFile("testFile", "txt");
+        FileOutputStream fout = new FileOutputStream(tmpFile);
+        OutputStreamWriter wrtout = new OutputStreamWriter(fout);
+        
+        wrtout.write("more stuff");
+        
+        wrtout.flush();
+        wrtout.close();
+        
+        try {
+            FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
+            encoder.write(fchannel, 0, 10);
+            fail("IllegalStateException should have been thrown");
+        } catch (IllegalStateException ex) {
+            // ignore
+        } finally {
+            tmpFile.delete();
+        }
+    }
+    
+    public void testCodingFromFileSmaller() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
+        LengthDelimitedEncoder encoder = new LengthDelimitedEncoder(newChannel(baos), 16);
+               
+        File tmpFile = File.createTempFile("testFile", "txt");
+        FileOutputStream fout = new FileOutputStream(tmpFile);
+        OutputStreamWriter wrtout = new OutputStreamWriter(fout);
+        
+        wrtout.write("stuff;");
+        wrtout.write("more stuff;");
+        
+        wrtout.flush();
+        wrtout.close();
+        
+        FileChannel fchannel = new FileInputStream(tmpFile).getChannel();
+        
+        encoder.write(fchannel, 0, 20);
+        
+        String s = baos.toString("US-ASCII");
+        
+        assertTrue(encoder.isCompleted());
+        assertEquals("stuff;more stuff", s);
+        
+        tmpFile.delete();
+    }
 }