diff --git a/src/zutil/io/BufferedBoundaryInputStream.java b/src/zutil/io/BufferedBoundaryInputStream.java index 26c33de..bc9b042 100755 --- a/src/zutil/io/BufferedBoundaryInputStream.java +++ b/src/zutil/io/BufferedBoundaryInputStream.java @@ -29,25 +29,28 @@ import java.io.IOException; import java.io.InputStream; /** - * TODO: boundry + * A stream that is handled as a iterator. The stream will read + * until it gets to a boundary and will return -1 (end of stream). + * The stream will not return any data until the {@link #next()} + * method is called. * * @author Ziver * */ public class BufferedBoundaryInputStream extends FilterInputStream{ /** The size of the buffer in bytes */ - public static final int DEFAULT_BUF_SIZE = 8192; + private static final int DEFAULT_BUF_SIZE = 8192; /** The raw buffer */ - protected byte buffer[]; + private byte buffer[]; + /** The current position in the buffer */ + private int buf_pos = 0; /** The end position of the buffer */ - protected int buf_end = 0; - /** The current position in the buffer */ - protected int buf_pos = 0; + private int buf_end = 0; + /** Boundary position, 0< means no boundary found */ + private int buf_bound_pos; /** The boundary (the delimiter) */ - protected byte[] boundary; - /** Boundary position, 0< means no boundary found */ - protected int bound_pos; + private byte[] boundary; /** @@ -67,10 +70,10 @@ public class BufferedBoundaryInputStream extends FilterInputStream{ */ public BufferedBoundaryInputStream(InputStream in, int buf_size){ super(in); + buf_pos = 0; buf_end = 0; - buf_pos = 0; + buf_bound_pos = -1; buffer = new byte[buf_size]; - bound_pos = -1; } /** @@ -109,7 +112,7 @@ public class BufferedBoundaryInputStream extends FilterInputStream{ return -1; // EOF } - if(bound_pos == buf_pos) + if(buf_bound_pos == buf_pos) return -1; // boundary return buffer[buf_pos++]; } @@ -137,7 +140,7 @@ public class BufferedBoundaryInputStream extends FilterInputStream{ if(fillBuffer() <= 0) return -1; // EOF } - if(bound_pos == buf_pos) + if(buf_bound_pos == buf_pos) return -1; // boundary // The request is larger then the buffer size @@ -146,8 +149,8 @@ public class BufferedBoundaryInputStream extends FilterInputStream{ len = leftover; } // the boundary is in the read range - if(buf_pos < bound_pos && bound_pos < buf_pos+len){ - len = buf_pos - bound_pos; + if(buf_pos < buf_bound_pos && buf_bound_pos < buf_pos+len){ + len = buf_bound_pos - buf_pos; } System.arraycopy(buffer, buf_pos, b, off, len); @@ -155,11 +158,19 @@ public class BufferedBoundaryInputStream extends FilterInputStream{ return len; } - /** + + /** + * @return if there is more data to read + */ + public boolean isOnBoundary(){ + return buf_bound_pos == buf_pos; + } + + /** * Skips over the boundary at the current position in the buffer */ public boolean next(){ - if(bound_pos == buf_pos){ + if(buf_bound_pos == buf_pos){ buf_pos += boundary.length; searchNextBoundary(); return buf_end >= buf_pos; @@ -173,15 +184,15 @@ public class BufferedBoundaryInputStream extends FilterInputStream{ protected void searchNextBoundary(){ for(int i=buf_pos; i{ public boolean hasNext() { try { IOUtil.copyStream(buffIn, new NullWriter()); - return boundaryIn.next(); + return boundaryIn.isOnBoundary(); } catch (IOException e){ logger.log(Level.SEVERE, null, e); } @@ -130,14 +130,13 @@ public class MultipartParser implements Iterable{ @Override public MultipartField next() { - if (!hasNext()) - return null; try { - HttpHeader header = parser.read(); + boundaryIn.next(); String tmp = buffIn.readLine(); // read the new line after the delimiter - if (tmp == null && tmp.equals("--")) + if (tmp == null || tmp.equals("--")) return null; + HttpHeader header = parser.read(); String disposition = header.getHeader(HEADER_CONTENT_DISPOSITION); if (disposition != null){ HashMap map = new HashMap<>(); diff --git a/src/zutil/net/http/multipart/MultipartStringField.java b/src/zutil/net/http/multipart/MultipartStringField.java index 6548a1e..e72aceb 100755 --- a/src/zutil/net/http/multipart/MultipartStringField.java +++ b/src/zutil/net/http/multipart/MultipartStringField.java @@ -17,7 +17,7 @@ public class MultipartStringField implements MultipartField { protected MultipartStringField(Map header, BufferedReader in) throws IOException { this.name = header.get("name"); - value = IOUtil.getContentAsString(in); + value = in.readLine(); } @Override diff --git a/test/zutil/io/BufferedBoundaryInputStreamTest.java b/test/zutil/io/BufferedBoundaryInputStreamTest.java index 7f40a3a..de887ed 100755 --- a/test/zutil/io/BufferedBoundaryInputStreamTest.java +++ b/test/zutil/io/BufferedBoundaryInputStreamTest.java @@ -29,6 +29,7 @@ import org.junit.Test; import java.io.IOException; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -36,51 +37,117 @@ import static org.junit.Assert.assertTrue; public class BufferedBoundaryInputStreamTest { @Test - public void normal() throws IOException { - StringInputStream inin = new StringInputStream("aaa#aaaaaaaaaaaaaaaa#aaaaaaaaaaaaaaa#"); + public void read_normal() throws IOException { + StringInputStream inin = new StringInputStream("aaa#a##aaaaaaa#"); BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin); - in.setBoundary("#"); - - int n = 0; - for(n=0; in.read() != -1; n++); - assertEquals(3, n); - + + assertEquals('a', in.read()); + assertEquals('a', in.read()); + assertEquals('a', in.read()); + assertEquals(-1, in.read()); + assertTrue(in.isOnBoundary()); + in.next(); - n = 0; - for(n=0; in.read() != -1; n++); - assertEquals(16, n); - - in.next(); - n = 0; - for(n=0; in.read() != -1; n++); - assertEquals(15, n); - + assertEquals('a', in.read()); + assertEquals(-1, in.read()); + assertTrue(in.isOnBoundary()); + + in.next(); + assertEquals(-1, in.read()); + assertTrue(in.isOnBoundary()); + + in.next(); + assertEquals('a', in.read()); + assertEquals('a', in.read()); + assertEquals('a', in.read()); + assertEquals('a', in.read()); + assertEquals('a', in.read()); + assertEquals('a', in.read()); + assertEquals('a', in.read()); + assertEquals(-1, in.read()); + assertTrue(in.isOnBoundary()); + in.next(); assertEquals(-1, in.read()); - + assertFalse(in.isOnBoundary()); + } + @Test + public void readArr_normal() throws IOException { + StringInputStream inin = new StringInputStream("aaa#aaaaaaaaaaaaaaaa#aaaaaaaaaaaaaaa#"); + BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin); + in.setBoundary("#"); + + byte[] buff = new byte[100]; + int n = in.read(buff); + assertEquals(3, n); + + in.next(); + n = in.read(buff); + assertEquals(16, n); + + in.next(); + n = in.read(buff); + assertEquals(15, n); + + in.next(); + n = in.read(buff); + assertEquals(-1, n); } + @Test + public void read_multiCharBoundary() throws IOException { + StringInputStream inin = new StringInputStream("aaa1234"); + BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin); + in.setBoundary("1234"); + + byte[] buff = new byte[100]; + assertEquals(3, in.read(buff)); + assertEquals(-1, in.read()); + assertTrue(in.isOnBoundary()); + + in.next(); + assertEquals(-1, in.read(buff)); + assertFalse(in.isOnBoundary()); + } + @Test + public void readArr_multiCharBoundary() throws IOException { + StringInputStream inin = new StringInputStream("aaa1234"); + BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin); + in.setBoundary("1234"); + + assertEquals('a', in.read()); + assertEquals('a', in.read()); + assertEquals('a', in.read()); + assertEquals(-1, in.read()); + assertTrue(in.isOnBoundary()); + + in.next(); + assertEquals(-1, in.read()); + assertFalse(in.isOnBoundary()); + } + @Test - public void startWithBound() throws IOException { + public void read_startWithBound() throws IOException { StringInputStream inin = new StringInputStream("#aaa"); BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin); in.setBoundary("#"); assertEquals(-1, in.read()); - - inin = new StringInputStream("#aaa"); - in = new BufferedBoundaryInputStream(inin); - in.setBoundary("#"); + } + @Test + public void readArr_startWithBound() throws IOException { + StringInputStream inin = new StringInputStream("#aaa"); + BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin); + in.setBoundary("#"); assertEquals(-1, in.read(new byte[10], 0, 10)); } @Test - public void onlyBoundaries() throws IOException { + public void read_onlyBoundaries() throws IOException { StringInputStream inin = new StringInputStream("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin); - in.setBoundary("a"); int n; @@ -93,9 +160,26 @@ public class BufferedBoundaryInputStreamTest { } assertEquals(35, n); } + @Test + public void readArr_onlyBoundaries() throws IOException { + StringInputStream inin = new StringInputStream("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin); + in.setBoundary("a"); + + byte[] buff = new byte[100]; + int n; + for(n=1; true; n++){ + assertEquals(-1, in.read(buff)); + assertEquals(-1, in.read(buff)); + in.next(); + if(!in.isOnBoundary()) + break; + } + assertEquals(35, n); + } @Test - public void noBounds() throws IOException { + public void read_noBounds() throws IOException { String data = "1234567891011121314151617181920"; StringInputStream inin = new StringInputStream(data); BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin); @@ -108,18 +192,15 @@ public class BufferedBoundaryInputStreamTest { } assertEquals(data, output.toString()); } - @Test - public void next() throws IOException { - StringInputStream inin = new StringInputStream("a#a#"); + public void readArr_noBounds() throws IOException { + String data = "1234567891011121314151617181920"; + StringInputStream inin = new StringInputStream(data); BufferedBoundaryInputStream in = new BufferedBoundaryInputStream(inin); in.setBoundary("#"); - assertEquals('a', in.read()); - assertEquals(-1, in.read()); - assertEquals(true, in.next()); - assertEquals('a', in.read()); - assertEquals(-1, in.read()); - assertEquals(false, in.next()); + byte[] buff = new byte[100]; + assertEquals(data.length(), in.read(buff)); + assertEquals(data, new String(buff, 0, data.length())); } }