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]