Fixed DefaultExtractorInput.read(...) to allow to read bytes in the peek buffer

when the dataSource reaches to the end.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=110131793
This commit is contained in:
eguven 2015-12-14 01:10:18 -08:00 committed by Oliver Woodman
parent 80bd91e636
commit a1d5626fe7
2 changed files with 60 additions and 27 deletions

View File

@ -43,8 +43,7 @@ public class DefaultExtractorInputTest extends TestCase {
} }
public void testRead() throws IOException, InterruptedException { public void testRead() throws IOException, InterruptedException {
FakeDataSource testDataSource = buildDataSource(); DefaultExtractorInput input = createDefaultExtractorInput();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
// We expect to perform three reads of three bytes, as setup in buildTestDataSource. // We expect to perform three reads of three bytes, as setup in buildTestDataSource.
int bytesRead = 0; int bytesRead = 0;
@ -61,9 +60,34 @@ public class DefaultExtractorInputTest extends TestCase {
assertEquals(-1, expectedEndOfInput); assertEquals(-1, expectedEndOfInput);
} }
public void testReadPeeked() throws IOException, InterruptedException {
DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length];
input.advancePeekPosition(TEST_DATA.length);
int bytesRead = input.read(target, 0, TEST_DATA.length);
assertEquals(TEST_DATA.length, bytesRead);
// Check the read data is correct.
assertTrue(Arrays.equals(TEST_DATA, target));
}
public void testReadMoreDataPeeked() throws IOException, InterruptedException {
DefaultExtractorInput input = createDefaultExtractorInput();
byte[] target = new byte[TEST_DATA.length];
input.advancePeekPosition(TEST_DATA.length);
int bytesRead = input.read(target, 0, TEST_DATA.length + 1);
assertEquals(TEST_DATA.length, bytesRead);
// Check the read data is correct.
assertTrue(Arrays.equals(TEST_DATA, target));
}
public void testReadFullyOnce() throws IOException, InterruptedException { public void testReadFullyOnce() throws IOException, InterruptedException {
FakeDataSource testDataSource = buildDataSource(); DefaultExtractorInput input = createDefaultExtractorInput();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
byte[] target = new byte[TEST_DATA.length]; byte[] target = new byte[TEST_DATA.length];
input.readFully(target, 0, TEST_DATA.length); input.readFully(target, 0, TEST_DATA.length);
// Check that we read the whole of TEST_DATA. // Check that we read the whole of TEST_DATA.
@ -83,8 +107,7 @@ public class DefaultExtractorInputTest extends TestCase {
public void testReadFullyTwice() throws IOException, InterruptedException { public void testReadFullyTwice() throws IOException, InterruptedException {
// Read TEST_DATA in two parts. // Read TEST_DATA in two parts.
FakeDataSource testDataSource = buildDataSource(); DefaultExtractorInput input = createDefaultExtractorInput();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
byte[] target = new byte[5]; byte[] target = new byte[5];
input.readFully(target, 0, 5); input.readFully(target, 0, 5);
assertTrue(Arrays.equals(Arrays.copyOf(TEST_DATA, 5), target)); assertTrue(Arrays.equals(Arrays.copyOf(TEST_DATA, 5), target));
@ -97,8 +120,7 @@ public class DefaultExtractorInputTest extends TestCase {
public void testReadFullyTooMuch() throws IOException, InterruptedException { public void testReadFullyTooMuch() throws IOException, InterruptedException {
// Read more than TEST_DATA. Should fail with an EOFException. Position should not update. // Read more than TEST_DATA. Should fail with an EOFException. Position should not update.
FakeDataSource testDataSource = buildDataSource(); DefaultExtractorInput input = createDefaultExtractorInput();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
try { try {
byte[] target = new byte[TEST_DATA.length + 1]; byte[] target = new byte[TEST_DATA.length + 1];
input.readFully(target, 0, TEST_DATA.length + 1); input.readFully(target, 0, TEST_DATA.length + 1);
@ -110,8 +132,7 @@ public class DefaultExtractorInputTest extends TestCase {
// Read more than TEST_DATA with allowEndOfInput set. Should fail with an EOFException because // Read more than TEST_DATA with allowEndOfInput set. Should fail with an EOFException because
// the end of input isn't encountered immediately. Position should not update. // the end of input isn't encountered immediately. Position should not update.
testDataSource = buildDataSource(); input = createDefaultExtractorInput();
input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
try { try {
byte[] target = new byte[TEST_DATA.length + 1]; byte[] target = new byte[TEST_DATA.length + 1];
input.readFully(target, 0, TEST_DATA.length + 1, true); input.readFully(target, 0, TEST_DATA.length + 1, true);
@ -138,8 +159,7 @@ public class DefaultExtractorInputTest extends TestCase {
public void testSkipFullyOnce() throws IOException, InterruptedException { public void testSkipFullyOnce() throws IOException, InterruptedException {
// Skip TEST_DATA. // Skip TEST_DATA.
FakeDataSource testDataSource = buildDataSource(); DefaultExtractorInput input = createDefaultExtractorInput();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
input.skipFully(TEST_DATA.length); input.skipFully(TEST_DATA.length);
assertEquals(TEST_DATA.length, input.getPosition()); assertEquals(TEST_DATA.length, input.getPosition());
// Check that we fail with EOFException we skip again. // Check that we fail with EOFException we skip again.
@ -153,8 +173,7 @@ public class DefaultExtractorInputTest extends TestCase {
public void testSkipFullyTwice() throws IOException, InterruptedException { public void testSkipFullyTwice() throws IOException, InterruptedException {
// Skip TEST_DATA in two parts. // Skip TEST_DATA in two parts.
FakeDataSource testDataSource = buildDataSource(); DefaultExtractorInput input = createDefaultExtractorInput();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
input.skipFully(5); input.skipFully(5);
assertEquals(5, input.getPosition()); assertEquals(5, input.getPosition());
input.skipFully(4); input.skipFully(4);
@ -163,8 +182,7 @@ public class DefaultExtractorInputTest extends TestCase {
public void testSkipFullyTooMuch() throws IOException, InterruptedException { public void testSkipFullyTooMuch() throws IOException, InterruptedException {
// Skip more than TEST_DATA. Should fail with an EOFException. Position should not update. // Skip more than TEST_DATA. Should fail with an EOFException. Position should not update.
FakeDataSource testDataSource = buildDataSource(); DefaultExtractorInput input = createDefaultExtractorInput();
DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
try { try {
input.skipFully(TEST_DATA.length + 1); input.skipFully(TEST_DATA.length + 1);
fail(); fail();
@ -227,4 +245,8 @@ public class DefaultExtractorInputTest extends TestCase {
return testDataSource; return testDataSource;
} }
private static DefaultExtractorInput createDefaultExtractorInput() throws IOException {
FakeDataSource testDataSource = buildDataSource();
return new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNBOUNDED);
}
} }

View File

@ -54,18 +54,29 @@ public final class DefaultExtractorInput implements ExtractorInput {
if (Thread.interrupted()) { if (Thread.interrupted()) {
throw new InterruptedException(); throw new InterruptedException();
} }
int totalBytesRead = 0;
if (peekBufferLength > 0) {
int peekBytes = Math.min(peekBufferLength, length); int peekBytes = Math.min(peekBufferLength, length);
System.arraycopy(peekBuffer, 0, target, offset, peekBytes); System.arraycopy(peekBuffer, 0, target, offset, peekBytes);
offset += peekBytes; updatePeekBuffer(peekBytes);
length -= peekBytes; totalBytesRead += peekBytes;
int bytesRead = length != 0 ? dataSource.read(target, offset, length) : 0; }
if (bytesRead == C.RESULT_END_OF_INPUT) {
if (totalBytesRead != length) {
int readBytes = dataSource.read(target, offset + totalBytesRead, length - totalBytesRead);
if (readBytes == C.RESULT_END_OF_INPUT) {
if (totalBytesRead == 0) {
return C.RESULT_END_OF_INPUT; return C.RESULT_END_OF_INPUT;
} }
updatePeekBuffer(peekBytes); } else {
bytesRead += peekBytes; totalBytesRead += readBytes;
position += bytesRead; }
return bytesRead; }
position += totalBytesRead;
return totalBytesRead;
} }
@Override @Override