Browse Source

FastByteArrayInputStream returns correct count from read(byte[])

Issue: SPR-14209
pull/1045/head
Juergen Hoeller 10 years ago
parent
commit
9bf5a5cbcb
  1. 3
      spring-core/src/main/java/org/springframework/util/FastByteArrayOutputStream.java
  2. 87
      spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java

3
spring-core/src/main/java/org/springframework/util/FastByteArrayOutputStream.java

@ -421,7 +421,8 @@ public class FastByteArrayOutputStream extends OutputStream {
System.arraycopy(this.currentBuffer, this.nextIndexInCurrentBuffer, b, off, bytesToCopy); System.arraycopy(this.currentBuffer, this.nextIndexInCurrentBuffer, b, off, bytesToCopy);
this.totalBytesRead += bytesToCopy; this.totalBytesRead += bytesToCopy;
this.nextIndexInCurrentBuffer += bytesToCopy; this.nextIndexInCurrentBuffer += bytesToCopy;
return (bytesToCopy + read(b, off + bytesToCopy, len - bytesToCopy)); int remaining = read(b, off + bytesToCopy, len - bytesToCopy);
return bytesToCopy + Math.max(remaining, 0);
} }
else { else {
if (this.buffersIterator.hasNext()) { if (this.buffersIterator.hasNext()) {

87
spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2015 the original author or authors. * Copyright 2002-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,8 +16,6 @@
package org.springframework.util; package org.springframework.util;
import static org.junit.Assert.*;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -25,6 +23,8 @@ import java.io.InputStream;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
/** /**
* Test suite for {@link FastByteArrayOutputStream} * Test suite for {@link FastByteArrayOutputStream}
* @author Craig Andrews * @author Craig Andrews
@ -37,21 +37,23 @@ public class FastByteArrayOutputStreamTests {
private byte[] helloBytes; private byte[] helloBytes;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
this.os = new FastByteArrayOutputStream(INITIAL_CAPACITY); this.os = new FastByteArrayOutputStream(INITIAL_CAPACITY);
this.helloBytes = "Hello World".getBytes("UTF-8"); this.helloBytes = "Hello World".getBytes("UTF-8");
} }
@Test @Test
public void size() throws Exception { public void size() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
assertEquals(this.os.size(), helloBytes.length); assertEquals(this.os.size(), this.helloBytes.length);
} }
@Test @Test
public void resize() throws Exception { public void resize() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
int sizeBefore = this.os.size(); int sizeBefore = this.os.size();
this.os.resize(64); this.os.resize(64);
assertByteArrayEqualsString(this.os); assertByteArrayEqualsString(this.os);
@ -70,104 +72,118 @@ public class FastByteArrayOutputStreamTests {
@Test @Test
public void write() throws Exception { public void write() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
assertByteArrayEqualsString(this.os); assertByteArrayEqualsString(this.os);
} }
@Test @Test
public void reset() throws Exception { public void reset() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
assertByteArrayEqualsString(this.os); assertByteArrayEqualsString(this.os);
this.os.reset(); this.os.reset();
assertEquals(0, this.os.size()); assertEquals(0, this.os.size());
this.os.write(helloBytes); this.os.write(this.helloBytes);
assertByteArrayEqualsString(this.os); assertByteArrayEqualsString(this.os);
} }
@Test(expected = IOException.class) @Test(expected = IOException.class)
public void close() throws Exception { public void close() throws Exception {
this.os.close(); this.os.close();
this.os.write(helloBytes); this.os.write(this.helloBytes);
} }
@Test @Test
public void toByteArrayUnsafe() throws Exception { public void toByteArrayUnsafe() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
assertByteArrayEqualsString(this.os); assertByteArrayEqualsString(this.os);
assertSame(this.os.toByteArrayUnsafe(), this.os.toByteArrayUnsafe()); assertSame(this.os.toByteArrayUnsafe(), this.os.toByteArrayUnsafe());
assertArrayEquals(this.os.toByteArray(), helloBytes); assertArrayEquals(this.os.toByteArray(), this.helloBytes);
} }
@Test @Test
public void writeTo() throws Exception { public void writeTo() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
assertByteArrayEqualsString(this.os); assertByteArrayEqualsString(this.os);
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
this.os.writeTo(baos); this.os.writeTo(baos);
assertArrayEquals(baos.toByteArray(), helloBytes); assertArrayEquals(baos.toByteArray(), this.helloBytes);
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void failResize() throws Exception { public void failResize() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
this.os.resize(5); this.os.resize(5);
} }
@Test @Test
public void getInputStream() throws Exception { public void getInputStream() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
assertNotNull(this.os.getInputStream()); assertNotNull(this.os.getInputStream());
} }
@Test @Test
public void getInputStreamAvailable() throws Exception { public void getInputStreamAvailable() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
assertEquals(this.os.getInputStream().available(), helloBytes.length); assertEquals(this.os.getInputStream().available(), this.helloBytes.length);
} }
@Test @Test
public void getInputStreamRead() throws Exception { public void getInputStreamRead() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
InputStream inputStream = this.os.getInputStream(); InputStream inputStream = this.os.getInputStream();
assertEquals(inputStream.read(), helloBytes[0]); assertEquals(inputStream.read(), this.helloBytes[0]);
assertEquals(inputStream.read(), helloBytes[1]); assertEquals(inputStream.read(), this.helloBytes[1]);
assertEquals(inputStream.read(), helloBytes[2]); assertEquals(inputStream.read(), this.helloBytes[2]);
assertEquals(inputStream.read(), helloBytes[3]); assertEquals(inputStream.read(), this.helloBytes[3]);
} }
@Test @Test
public void getInputStreamReadAll() throws Exception { public void getInputStreamReadAll() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
InputStream inputStream = this.os.getInputStream(); InputStream inputStream = this.os.getInputStream();
byte[] actual = new byte[inputStream.available()]; byte[] actual = new byte[inputStream.available()];
int bytesRead = inputStream.read(actual); int bytesRead = inputStream.read(actual);
assertEquals(bytesRead, helloBytes.length); assertEquals(this.helloBytes.length, bytesRead);
assertArrayEquals(actual, helloBytes); assertArrayEquals(this.helloBytes, actual);
assertEquals(0, inputStream.available());
}
@Test
public void getInputStreamReadBeyondEndOfStream() throws Exception {
this.os.write(this.helloBytes);
InputStream inputStream = os.getInputStream();
byte[] actual = new byte[inputStream.available() + 1];
int bytesRead = inputStream.read(actual);
assertEquals(this.helloBytes.length, bytesRead);
for (int i = 0; i < bytesRead; i++) {
assertEquals(this.helloBytes[i], actual[i]);
}
assertEquals(0, actual[this.helloBytes.length]);
assertEquals(0, inputStream.available()); assertEquals(0, inputStream.available());
} }
@Test @Test
public void getInputStreamSkip() throws Exception { public void getInputStreamSkip() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
InputStream inputStream = this.os.getInputStream(); InputStream inputStream = this.os.getInputStream();
assertEquals(inputStream.read(), helloBytes[0]); assertEquals(inputStream.read(), this.helloBytes[0]);
assertEquals(inputStream.skip(1), 1); assertEquals(inputStream.skip(1), 1);
assertEquals(inputStream.read(), helloBytes[2]); assertEquals(inputStream.read(), this.helloBytes[2]);
assertEquals(helloBytes.length - 3, inputStream.available()); assertEquals(this.helloBytes.length - 3, inputStream.available());
} }
@Test @Test
public void getInputStreamSkipAll() throws Exception { public void getInputStreamSkipAll() throws Exception {
this.os.write(helloBytes); this.os.write(this.helloBytes);
InputStream inputStream = this.os.getInputStream(); InputStream inputStream = this.os.getInputStream();
assertEquals(inputStream.skip(1000), helloBytes.length); assertEquals(inputStream.skip(1000), this.helloBytes.length);
assertEquals(0, inputStream.available()); assertEquals(0, inputStream.available());
} }
@Test @Test
public void updateMessageDigest() throws Exception { public void updateMessageDigest() throws Exception {
StringBuilder builder = new StringBuilder("\"0"); StringBuilder builder = new StringBuilder("\"0");
this.os.write(helloBytes); this.os.write(this.helloBytes);
InputStream inputStream = this.os.getInputStream(); InputStream inputStream = this.os.getInputStream();
DigestUtils.appendMd5DigestAsHex(inputStream, builder); DigestUtils.appendMd5DigestAsHex(inputStream, builder);
builder.append("\""); builder.append("\"");
@ -180,7 +196,7 @@ public class FastByteArrayOutputStreamTests {
StringBuilder builder = new StringBuilder("\"0"); StringBuilder builder = new StringBuilder("\"0");
// filling at least one 256 buffer // filling at least one 256 buffer
for ( int i = 0; i < 30; i++) { for ( int i = 0; i < 30; i++) {
this.os.write(helloBytes); this.os.write(this.helloBytes);
} }
InputStream inputStream = this.os.getInputStream(); InputStream inputStream = this.os.getInputStream();
DigestUtils.appendMd5DigestAsHex(inputStream, builder); DigestUtils.appendMd5DigestAsHex(inputStream, builder);
@ -189,8 +205,9 @@ public class FastByteArrayOutputStreamTests {
assertEquals("\"06225ca1e4533354c516e74512065331d\"", actual); assertEquals("\"06225ca1e4533354c516e74512065331d\"", actual);
} }
private void assertByteArrayEqualsString(FastByteArrayOutputStream actual) { private void assertByteArrayEqualsString(FastByteArrayOutputStream actual) {
assertArrayEquals(helloBytes, actual.toByteArray()); assertArrayEquals(this.helloBytes, actual.toByteArray());
} }
} }

Loading…
Cancel
Save