Commit b9607321 by Oliver Woodman

Simplify DefaultExtractorInput

parent cf132805
...@@ -51,13 +51,23 @@ public final class DefaultExtractorInput implements ExtractorInput { ...@@ -51,13 +51,23 @@ public final class DefaultExtractorInput implements ExtractorInput {
@Override @Override
public int read(byte[] target, int offset, int length) throws IOException, InterruptedException { public int read(byte[] target, int offset, int length) throws IOException, InterruptedException {
return internalRead(target, offset, length, true, false, false); int bytesRead = readFromPeekBuffer(target, offset, length);
if (bytesRead == 0) {
bytesRead = readFromDataSource(target, offset, length, 0, true);
}
commitBytesRead(bytesRead);
return bytesRead;
} }
@Override @Override
public boolean readFully(byte[] target, int offset, int length, boolean allowEndOfInput) public boolean readFully(byte[] target, int offset, int length, boolean allowEndOfInput)
throws IOException, InterruptedException { throws IOException, InterruptedException {
return internalReadFully(target, offset, length, allowEndOfInput, false); int bytesRead = readFromPeekBuffer(target, offset, length);
while (bytesRead < length && bytesRead != C.RESULT_END_OF_INPUT) {
bytesRead = readFromDataSource(target, offset, length, bytesRead, allowEndOfInput);
}
commitBytesRead(bytesRead);
return bytesRead != C.RESULT_END_OF_INPUT;
} }
@Override @Override
...@@ -68,14 +78,24 @@ public final class DefaultExtractorInput implements ExtractorInput { ...@@ -68,14 +78,24 @@ public final class DefaultExtractorInput implements ExtractorInput {
@Override @Override
public int skip(int length) throws IOException, InterruptedException { public int skip(int length) throws IOException, InterruptedException {
return internalRead(null, 0, Math.min(SCRATCH_SPACE.length + peekBufferLength, length), true, int bytesSkipped = skipFromPeekBuffer(length);
true, false); if (bytesSkipped == 0) {
bytesSkipped = readFromDataSource(SCRATCH_SPACE, 0, length, 0, true);
}
commitBytesRead(bytesSkipped);
return bytesSkipped;
} }
@Override @Override
public boolean skipFully(final int length, boolean allowEndOfInput) public boolean skipFully(int length, boolean allowEndOfInput)
throws IOException, InterruptedException { throws IOException, InterruptedException {
return internalReadFully(null, 0, length, allowEndOfInput, true); int bytesSkipped = skipFromPeekBuffer(length);
while (bytesSkipped < length && bytesSkipped != C.RESULT_END_OF_INPUT) {
bytesSkipped = readFromDataSource(SCRATCH_SPACE, -bytesSkipped,
Math.min(length, bytesSkipped + SCRATCH_SPACE.length), bytesSkipped, allowEndOfInput);
}
commitBytesRead(bytesSkipped);
return bytesSkipped != C.RESULT_END_OF_INPUT;
} }
@Override @Override
...@@ -94,10 +114,9 @@ public final class DefaultExtractorInput implements ExtractorInput { ...@@ -94,10 +114,9 @@ public final class DefaultExtractorInput implements ExtractorInput {
public void advancePeekPosition(int length) throws IOException, InterruptedException { public void advancePeekPosition(int length) throws IOException, InterruptedException {
ensureSpaceForPeek(length); ensureSpaceForPeek(length);
peekBufferPosition += length; peekBufferPosition += length;
if (peekBufferPosition > peekBufferLength) { while (peekBufferPosition > peekBufferLength) {
readFromDataSource(peekBuffer, peekBufferLength, peekBufferPosition - peekBufferLength, peekBufferLength = readFromDataSource(peekBuffer, 0, peekBufferPosition, peekBufferLength,
false, false, 0, true); false);
peekBufferLength = peekBufferPosition;
} }
} }
...@@ -128,42 +147,15 @@ public final class DefaultExtractorInput implements ExtractorInput { ...@@ -128,42 +147,15 @@ public final class DefaultExtractorInput implements ExtractorInput {
} }
/** /**
* Updates the peek buffer's length, position and contents after consuming data. * Skips from the peek buffer.
*
* @param bytesConsumed The number of bytes consumed from the peek buffer.
*/
private void updatePeekBuffer(int bytesConsumed) {
peekBufferLength -= bytesConsumed;
peekBufferPosition = 0;
System.arraycopy(peekBuffer, bytesConsumed, peekBuffer, 0, peekBufferLength);
}
/**
* Internal read method.
* *
* @see #internalRead(byte[], int, int, boolean, boolean, boolean) * @param length The maximum number of bytes to skip from the peek buffer.
* @return The number of bytes skipped.
*/ */
private boolean internalReadFully(byte[] target, int offset, int length, boolean allowEndOfInput, private int skipFromPeekBuffer(int length) {
boolean skip) throws InterruptedException, IOException { int bytesSkipped = Math.min(peekBufferLength, length);
return internalRead(target, offset, length, allowEndOfInput, skip, true) updatePeekBuffer(bytesSkipped);
!= C.RESULT_END_OF_INPUT; return bytesSkipped;
}
/**
* Internal read method.
*
* @see #readFromPeekBuffer(byte[], int, int, boolean)
* @see #readFromDataSource(byte[], int, int, boolean, boolean, int, boolean)
*/
private int internalRead(byte[] target, int offset, int length, boolean allowEndOfInput,
boolean skip, boolean readFully) throws InterruptedException, IOException {
int totalBytesRead = readFromPeekBuffer(target, offset, length, skip);
totalBytesRead = readFromDataSource(target, offset, length, allowEndOfInput, skip,
totalBytesRead, readFully);
if (totalBytesRead != C.RESULT_END_OF_INPUT) {
position += totalBytesRead;
}
return totalBytesRead;
} }
/** /**
...@@ -171,68 +163,72 @@ public final class DefaultExtractorInput implements ExtractorInput { ...@@ -171,68 +163,72 @@ public final class DefaultExtractorInput implements ExtractorInput {
* *
* @param target A target array into which data should be written. * @param target A target array into which data should be written.
* @param offset The offset into the target array at which to write. * @param offset The offset into the target array at which to write.
* @param length The maximum number of bytes to read from the input. * @param length The maximum number of bytes to read from the peek buffer.
* @param skip If true, instead of reading skip the data * @return The number of bytes read.
* @return The number of bytes read
*/ */
private int readFromPeekBuffer(byte[] target, int offset, int length, boolean skip) { private int readFromPeekBuffer(byte[] target, int offset, int length) {
if (peekBufferLength == 0) { if (peekBufferLength == 0) {
return 0; return 0;
} }
int peekBytes = Math.min(peekBufferLength, length); int peekBytes = Math.min(peekBufferLength, length);
if (!skip) { System.arraycopy(peekBuffer, 0, target, offset, peekBytes);
System.arraycopy(peekBuffer, 0, target, offset, peekBytes);
}
updatePeekBuffer(peekBytes); updatePeekBuffer(peekBytes);
return peekBytes; return peekBytes;
} }
/** /**
* Reads from the data source * Updates the peek buffer's length, position and contents after consuming data.
*
* @param bytesConsumed The number of bytes consumed from the peek buffer.
*/
private void updatePeekBuffer(int bytesConsumed) {
peekBufferLength -= bytesConsumed;
peekBufferPosition = 0;
System.arraycopy(peekBuffer, bytesConsumed, peekBuffer, 0, peekBufferLength);
}
/**
* Starts or continues a read from the data source.
* *
* @param target A target array into which data should be written. * @param target A target array into which data should be written.
* @param offset The offset into the target array at which to write. * @param offset The offset into the target array at which to write.
* @param length The maximum number of bytes to read from the input. * @param length The maximum number of bytes to read from the input.
* @param returnEOIifNoReadBytes If true on encountering the end of the input having read no data * @param bytesAlreadyRead The number of bytes already read from the input.
* should result in {@link C#RESULT_END_OF_INPUT} being returned. * @param allowEndOfInput True if encountering the end of the input having read no data is
* @param skip If true, instead of reading skip the data * allowed, and should result in {@link C#RESULT_END_OF_INPUT} being returned. False if it
* @param totalBytesRead Number of bytes read until now for the external request * should be considered an error, causing an {@link EOFException} to be thrown.
* @param readFully If true reads the requested {@code length} in full. * @return The total number of bytes read so far, or {@link C#RESULT_END_OF_INPUT} if
* @return The number of bytes read, or {@link C#RESULT_END_OF_INPUT} if the input has ended. * {@code allowEndOfInput} is true and the input has ended having read no bytes.
* @throws EOFException If the end of input was encountered. * @throws EOFException If the end of input was encountered having partially satisfied the read
* (i.e. having read at least one byte, but fewer than {@code length}), or if no bytes were
* read and {@code allowEndOfInput} is false.
* @throws IOException If an error occurs reading from the input. * @throws IOException If an error occurs reading from the input.
* @throws InterruptedException If the thread is interrupted. * @throws InterruptedException If the thread is interrupted.
*/ */
private int readFromDataSource(byte[] target, int offset, int length, private int readFromDataSource(byte[] target, int offset, int length, int bytesAlreadyRead,
boolean returnEOIifNoReadBytes, boolean skip, int totalBytesRead, boolean readFully) boolean allowEndOfInput) throws InterruptedException, IOException {
throws InterruptedException, IOException { if (Thread.interrupted()) {
while (totalBytesRead < length) { throw new InterruptedException();
if (Thread.interrupted()) { }
throw new InterruptedException(); int bytesRead = dataSource.read(target, offset + bytesAlreadyRead, length - bytesAlreadyRead);
} if (bytesRead == C.RESULT_END_OF_INPUT) {
if (bytesAlreadyRead == 0 && allowEndOfInput) {
int bytesRead = !skip return C.RESULT_END_OF_INPUT;
? dataSource.read(target, offset + totalBytesRead, length - totalBytesRead)
: dataSource.read(SCRATCH_SPACE, 0,
Math.min(SCRATCH_SPACE.length, length - totalBytesRead));
if (bytesRead == C.RESULT_END_OF_INPUT) {
if (returnEOIifNoReadBytes && totalBytesRead == 0) {
return C.RESULT_END_OF_INPUT;
}
if (readFully) {
throw new EOFException();
}
} else {
totalBytesRead += bytesRead;
} }
throw new EOFException();
}
return bytesAlreadyRead + bytesRead;
}
if (!readFully) { /**
break; * Advances the position by the specified number of bytes read.
} *
* @param bytesRead The number of bytes read.
*/
private void commitBytesRead(int bytesRead) {
if (bytesRead != C.RESULT_END_OF_INPUT) {
position += bytesRead;
} }
return totalBytesRead;
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment