Author: jochen Date: Sun Jun 18 12:19:46 2006 New Revision: 415180 URL: http://svn.apache.org/viewvc?rev=415180&view=rev Log: Added the ItemInputStream.
Added: jakarta/commons/proper/fileupload/trunk/.classpath jakarta/commons/proper/fileupload/trunk/.project jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/SizesTest.java Modified: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/MultipartStream.java Added: jakarta/commons/proper/fileupload/trunk/.classpath URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/.classpath?rev=415180&view=auto ============================================================================== --- jakarta/commons/proper/fileupload/trunk/.classpath (added) +++ jakarta/commons/proper/fileupload/trunk/.classpath Sun Jun 18 12:19:46 2006 @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<classpath> + <classpathentry excluding="" kind="src" path="src/java"> + </classpathentry> + <classpathentry output="target/test-classes" kind="src" path="src/test"> + </classpathentry> + <classpathentry kind="var" path="MAVEN_REPO/junit/jars/junit-3.8.1.jar"> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"> + </classpathentry> + <classpathentry kind="var" path="MAVEN_REPO/commons-io/jars/commons-io-1.1.jar"> + </classpathentry> + <classpathentry kind="var" path="MAVEN_REPO/javax.servlet/jars/servlet-api-2.3.jar"> + </classpathentry> + <classpathentry kind="var" path="MAVEN_REPO/javax.portlet/jars/portlet-api-1.0.jar"> + </classpathentry> + <classpathentry kind="output" path="target/classes"> + </classpathentry> +</classpath> \ No newline at end of file Added: jakarta/commons/proper/fileupload/trunk/.project URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/.project?rev=415180&view=auto ============================================================================== --- jakarta/commons/proper/fileupload/trunk/.project (added) +++ jakarta/commons/proper/fileupload/trunk/.project Sun Jun 18 12:19:46 2006 @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<projectDescription> + <name>commons-fileupload</name> + <comment>The FileUpload component provides a simple yet flexible means of adding support for multipart file upload functionality to servlets and web applications.</comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> \ No newline at end of file Modified: jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/MultipartStream.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/MultipartStream.java?rev=415180&r1=415179&r2=415180&view=diff ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/MultipartStream.java (original) +++ jakarta/commons/proper/fileupload/trunk/src/java/org/apache/commons/fileupload/MultipartStream.java Sun Jun 18 12:19:46 2006 @@ -496,64 +496,22 @@ public int readBodyData(OutputStream output) throws MalformedStreamException, IOException { - boolean done = false; - int pad; - int pos; - int bytesRead; - int total = 0; - while (!done) { - // Is boundary token present somewere in the buffer? - pos = findSeparator(); - if (pos != -1) { - // Write the rest of the data before the boundary. + final ItemInputStream istream = new ItemInputStream(); + final byte[] bytes = new byte[8192]; + for (;;) { + int res = istream.read(bytes); + if (res == -1) { if (output != null) { - output.write(buffer, head, pos - head); - } - total += pos - head; - head = pos; - done = true; - } else { - // Determine how much data should be kept in the - // buffer. - if (tail - head > keepRegion) { - pad = keepRegion; - } else { - pad = tail - head; + output.flush(); } - // Write out the data belonging to the body-data. + return (int) istream.getBytesRead(); + } + if (res > 0 && output != null) { if (output != null) { - output.write(buffer, head, tail - head - pad); - } - - // Move the data to the beginning of the buffer. - total += tail - head - pad; - System.arraycopy(buffer, tail - pad, buffer, 0, pad); - - // Refill buffer with new data. - head = 0; - bytesRead = input.read(buffer, pad, bufSize - pad); - - // [pprrrrrrr] - if (bytesRead != -1) { - tail = pad + bytesRead; - } else { - // The last pad amount is left in the buffer. - // Boundary can't be in there so write out the - // data you have and signal an error condition. - if (output != null) { - output.write(buffer, 0, pad); - output.flush(); - } - total += pad; - throw new MalformedStreamException( - "Stream ended unexpectedly"); + output.write(bytes, 0, res); } } } - if (output != null) { - output.flush(); - } - return total; } @@ -748,6 +706,122 @@ } } + /** + * An [EMAIL PROTECTED] InputStream} for reading an items contents. + */ + public class ItemInputStream extends InputStream { + private long total; + private int pad, pos; + + ItemInputStream() { + findSeparator(); + } + + private void findSeparator() { + pos = MultipartStream.this.findSeparator(); + if (pos == -1) { + if (tail - head > keepRegion) { + pad = keepRegion; + } else { + pad = tail - head; + } + } + } + + /** Returns the number of bytes, which have been read + * by the stream. + */ + public long getBytesRead() { + return total; + } + + public int available() throws IOException { + if (pos == -1) { + return tail - head - pad; + } else { + return pos - head; + } + } + + public int read() throws IOException { + if (available() == 0) { + if (makeAvailable() == 0) { + return -1; + } + } + ++total; + int b = buffer[head++]; + return b >= 0 ? b : b + 256; + } + + public int read(byte[] b, int off, int len) throws IOException { + if (len == 0) { + return 0; + } + int res = available(); + if (res == 0) { + res = makeAvailable(); + if (res == 0) { + return -1; + } + } + res = Math.min(res, len); + System.arraycopy(buffer, head, b, off, res); + head += res; + total += res; + return res; + } + + public void close() throws IOException { + for (;;) { + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + break; + } + } + skip(av); + } + } + + public long skip(long bytes) throws IOException { + int av = available(); + if (av == 0) { + av = makeAvailable(); + if (av == 0) { + return 0; + } + } + long res = Math.min(av, bytes); + head += res; + return res; + } + + private int makeAvailable() throws IOException { + if (pos != -1) { + return 0; + } + + // Move the data to the beginning of the buffer. + total += tail - head - pad; + System.arraycopy(buffer, tail - pad, buffer, 0, pad); + + // Refill buffer with new data. + head = 0; + int bytesRead = input.read(buffer, pad, bufSize - pad); + if (bytesRead == -1) { + // The last pad amount is left in the buffer. + // Boundary can't be in there so signal an error + // condition. + throw new MalformedStreamException( + "Stream ended unexpectedly"); + } + tail = pad + bytesRead; + findSeparator(); + return available(); + } + } // ------------------------------------------------------ Debugging methods Added: jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/SizesTest.java URL: http://svn.apache.org/viewvc/jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/SizesTest.java?rev=415180&view=auto ============================================================================== --- jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/SizesTest.java (added) +++ jakarta/commons/proper/fileupload/trunk/src/test/org/apache/commons/fileupload/SizesTest.java Sun Jun 18 12:19:46 2006 @@ -0,0 +1,81 @@ +/* + * Copyright 2001-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.commons.fileupload; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import javax.servlet.http.HttpServletRequest; +import junit.framework.TestCase; + + +/** + * Unit test for items with varying sizes. + */ +public class SizesTest extends TestCase +{ + public void testFileUpload() + throws IOException, FileUploadException + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int add = 16; + int num = 0; + for (int i = 0; i < 16384; i += add) { + if (++add == 32) { + add = 16; + } + String header = "-----1234\r\n" + + "Content-Disposition: form-data; name=\"field" + (num++) + "\"\r\n" + + "\r\n"; + baos.write(header.getBytes("US-ASCII")); + for (int j = 0; j < i; j++) { + baos.write((byte) j); + } + baos.write("\r\n".getBytes("US-ASCII")); + } + baos.write("-----1234--\r\n".getBytes("US-ASCII")); + + List fileItems = parseUpload(baos.toByteArray()); + Iterator fileIter = fileItems.iterator(); + add = 16; + num = 0; + for (int i = 0; i < 16384; i += add) { + if (++add == 32) { + add = 16; + } + FileItem item = (FileItem) fileIter.next(); + assertEquals("field" + (num++), item.getFieldName()); + byte[] bytes = item.get(); + assertEquals(i, bytes.length); + for (int j = 0; j < i; j++) { + assertEquals((byte) j, bytes[j]); + } + } + assertTrue(!fileIter.hasNext()); + } + + private List parseUpload(byte[] bytes) throws FileUploadException { + String contentType = "multipart/form-data; boundary=---1234"; + + FileUploadBase upload = new DiskFileUpload(); + HttpServletRequest request = new MockHttpServletRequest(bytes, contentType); + + List fileItems = upload.parseRequest(request); + return fileItems; + } + +} --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]