mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Refactor CacheDataSource
Simplified and clarified the code. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=180649983
This commit is contained in:
parent
bf3d6028fa
commit
d3ba207a4b
1 changed files with 43 additions and 48 deletions
|
|
@ -97,7 +97,7 @@ public final class CacheDataSource implements DataSource {
|
||||||
private final boolean ignoreCacheForUnsetLengthRequests;
|
private final boolean ignoreCacheForUnsetLengthRequests;
|
||||||
|
|
||||||
private DataSource currentDataSource;
|
private DataSource currentDataSource;
|
||||||
private boolean currentRequestUnbounded;
|
private boolean readingUnknownLengthDataFromUpstream;
|
||||||
private Uri uri;
|
private Uri uri;
|
||||||
private int flags;
|
private int flags;
|
||||||
private String key;
|
private String key;
|
||||||
|
|
@ -202,7 +202,7 @@ public final class CacheDataSource implements DataSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
openNextSource(true);
|
openNextSource();
|
||||||
return bytesRemaining;
|
return bytesRemaining;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
handleBeforeThrow(e);
|
handleBeforeThrow(e);
|
||||||
|
|
@ -229,15 +229,21 @@ public final class CacheDataSource implements DataSource {
|
||||||
bytesRemaining -= bytesRead;
|
bytesRemaining -= bytesRead;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (currentRequestUnbounded) {
|
if (readingUnknownLengthDataFromUpstream) {
|
||||||
// We only do unbounded requests to upstream and only when we don't know the actual stream
|
setCurrentDataSourceBytesRemaining(0);
|
||||||
// length. So we reached the end of stream.
|
|
||||||
setContentLength(readPosition);
|
|
||||||
bytesRemaining = 0;
|
|
||||||
}
|
}
|
||||||
closeCurrentSource();
|
closeCurrentSource();
|
||||||
if (bytesRemaining > 0 || bytesRemaining == C.LENGTH_UNSET) {
|
if (bytesRemaining > 0 || bytesRemaining == C.LENGTH_UNSET) {
|
||||||
if (openNextSource(false)) {
|
try {
|
||||||
|
openNextSource();
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (readingUnknownLengthDataFromUpstream && isCausedByPositionOutOfRange(e)) {
|
||||||
|
setCurrentDataSourceBytesRemaining(0);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bytesRemaining != 0) {
|
||||||
return read(buffer, offset, readLength);
|
return read(buffer, offset, readLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -270,9 +276,8 @@ public final class CacheDataSource implements DataSource {
|
||||||
* Opens the next source. If the cache contains data spanning the current read position then
|
* Opens the next source. If the cache contains data spanning the current read position then
|
||||||
* {@link #cacheReadDataSource} is opened to read from it. Else {@link #upstreamDataSource} is
|
* {@link #cacheReadDataSource} is opened to read from it. Else {@link #upstreamDataSource} is
|
||||||
* opened to read from the upstream source and write into the cache.
|
* opened to read from the upstream source and write into the cache.
|
||||||
* @param initial Whether it is the initial open call.
|
|
||||||
*/
|
*/
|
||||||
private boolean openNextSource(boolean initial) throws IOException {
|
private void openNextSource() throws IOException {
|
||||||
DataSpec dataSpec;
|
DataSpec dataSpec;
|
||||||
CacheSpan span;
|
CacheSpan span;
|
||||||
if (currentRequestIgnoresCache) {
|
if (currentRequestIgnoresCache) {
|
||||||
|
|
@ -323,48 +328,38 @@ public final class CacheDataSource implements DataSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentRequestUnbounded = dataSpec.length == C.LENGTH_UNSET;
|
// If the request is unbounded it must be an upstream request.
|
||||||
boolean successful = false;
|
readingUnknownLengthDataFromUpstream = dataSpec.length == C.LENGTH_UNSET;
|
||||||
long currentBytesRemaining = 0;
|
|
||||||
try {
|
|
||||||
currentBytesRemaining = currentDataSource.open(dataSpec);
|
|
||||||
successful = true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
// if this isn't the initial open call (we had read some bytes) and an unbounded range request
|
|
||||||
// failed because of POSITION_OUT_OF_RANGE then mute the exception. We are trying to find the
|
|
||||||
// end of the stream.
|
|
||||||
if (!initial && currentRequestUnbounded) {
|
|
||||||
Throwable cause = e;
|
|
||||||
while (cause != null) {
|
|
||||||
if (cause instanceof DataSourceException) {
|
|
||||||
int reason = ((DataSourceException) cause).reason;
|
|
||||||
if (reason == DataSourceException.POSITION_OUT_OF_RANGE) {
|
|
||||||
e = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cause = cause.getCause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (e != null) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we did an unbounded request (which means it's to upstream and
|
long resolvedLength = currentDataSource.open(dataSpec);
|
||||||
// bytesRemaining == C.LENGTH_UNSET) and got a resolved length from open() request
|
if (readingUnknownLengthDataFromUpstream && resolvedLength != C.LENGTH_UNSET) {
|
||||||
if (currentRequestUnbounded && currentBytesRemaining != C.LENGTH_UNSET) {
|
setCurrentDataSourceBytesRemaining(resolvedLength);
|
||||||
bytesRemaining = currentBytesRemaining;
|
|
||||||
setContentLength(dataSpec.position + bytesRemaining);
|
|
||||||
}
|
}
|
||||||
return successful;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setContentLength(long length) throws IOException {
|
private static boolean isCausedByPositionOutOfRange(IOException e) {
|
||||||
// If writing into cache
|
Throwable cause = e;
|
||||||
if (currentDataSource == cacheWriteDataSource) {
|
while (cause != null) {
|
||||||
cache.setContentLength(key, length);
|
if (cause instanceof DataSourceException) {
|
||||||
|
int reason = ((DataSourceException) cause).reason;
|
||||||
|
if (reason == DataSourceException.POSITION_OUT_OF_RANGE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cause = cause.getCause();
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCurrentDataSourceBytesRemaining(long bytesRemaining) throws IOException {
|
||||||
|
this.bytesRemaining = bytesRemaining;
|
||||||
|
if (isWritingToCache()) {
|
||||||
|
cache.setContentLength(key, readPosition + bytesRemaining);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWritingToCache() {
|
||||||
|
return currentDataSource == cacheWriteDataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeCurrentSource() throws IOException {
|
private void closeCurrentSource() throws IOException {
|
||||||
|
|
@ -374,7 +369,7 @@ public final class CacheDataSource implements DataSource {
|
||||||
try {
|
try {
|
||||||
currentDataSource.close();
|
currentDataSource.close();
|
||||||
currentDataSource = null;
|
currentDataSource = null;
|
||||||
currentRequestUnbounded = false;
|
readingUnknownLengthDataFromUpstream = false;
|
||||||
} finally {
|
} finally {
|
||||||
if (lockedSpan != null) {
|
if (lockedSpan != null) {
|
||||||
cache.releaseHoleSpan(lockedSpan);
|
cache.releaseHoleSpan(lockedSpan);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue