Commit 41026495 by olly Committed by Oliver Woodman

Don't open DataSink if resolved length is 0

- It's wasted effort
- DataSpec reconstruction fails because creating a DataSpec with 0
  length isn't allowed.
- Also better document DataSink open/close, to be like DataSource.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=194778132
parent d1fdc518
......@@ -37,6 +37,9 @@ public interface DataSink {
/**
* Opens the sink to consume the specified data.
*
* <p>Note: If an {@link IOException} is thrown, callers must still call {@link #close()} to
* ensure that any partial effects of the invocation are cleaned up.
*
* @param dataSpec Defines the data to be consumed.
* @throws IOException If an error occurs opening the sink.
*/
......@@ -55,8 +58,10 @@ public interface DataSink {
/**
* Closes the sink.
*
* <p>Note: This method must be called even if the corresponding call to {@link #open(DataSpec)}
* threw an {@link IOException}. See {@link #open(DataSpec)} for more details.
*
* @throws IOException If an error occurs closing the sink.
*/
void close() throws IOException;
}
......@@ -28,6 +28,9 @@ public final class TeeDataSource implements DataSource {
private final DataSource upstream;
private final DataSink dataSink;
private boolean dataSinkNeedsClosing;
private long bytesRemaining;
/**
* @param upstream The upstream {@link DataSource}.
* @param dataSink The {@link DataSink} into which data is written.
......@@ -39,24 +42,40 @@ public final class TeeDataSource implements DataSource {
@Override
public long open(DataSpec dataSpec) throws IOException {
long dataLength = upstream.open(dataSpec);
if (dataSpec.length == C.LENGTH_UNSET && dataLength != C.LENGTH_UNSET) {
bytesRemaining = upstream.open(dataSpec);
if (bytesRemaining == 0) {
return 0;
}
if (dataSpec.length == C.LENGTH_UNSET && bytesRemaining != C.LENGTH_UNSET) {
// Reconstruct dataSpec in order to provide the resolved length to the sink.
dataSpec = new DataSpec(dataSpec.uri, dataSpec.absoluteStreamPosition, dataSpec.position,
dataLength, dataSpec.key, dataSpec.flags);
dataSpec =
new DataSpec(
dataSpec.uri,
dataSpec.absoluteStreamPosition,
dataSpec.position,
bytesRemaining,
dataSpec.key,
dataSpec.flags);
}
dataSinkNeedsClosing = true;
dataSink.open(dataSpec);
return dataLength;
return bytesRemaining;
}
@Override
public int read(byte[] buffer, int offset, int max) throws IOException {
int num = upstream.read(buffer, offset, max);
if (num > 0) {
// TODO: Consider continuing even if disk writes fail.
dataSink.write(buffer, offset, num);
if (bytesRemaining == 0) {
return C.RESULT_END_OF_INPUT;
}
int bytesRead = upstream.read(buffer, offset, max);
if (bytesRead > 0) {
// TODO: Consider continuing even if writes to the sink fail.
dataSink.write(buffer, offset, bytesRead);
if (bytesRemaining != C.LENGTH_UNSET) {
bytesRemaining -= bytesRead;
}
}
return num;
return bytesRead;
}
@Override
......@@ -69,7 +88,10 @@ public final class TeeDataSource implements DataSource {
try {
upstream.close();
} finally {
dataSink.close();
if (dataSinkNeedsClosing) {
dataSinkNeedsClosing = false;
dataSink.close();
}
}
}
......
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