Commit 7ea19963 by Oliver Woodman

Content/Asset data sources - Handle >2^31 byte files correctly.

Issue #641
parent b57b80f7
......@@ -16,7 +16,6 @@
package com.google.android.exoplayer.upstream;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.util.Assertions;
import android.content.Context;
import android.content.res.AssetManager;
......@@ -79,12 +78,22 @@ public final class AssetDataSource implements UriDataSource {
uriString = dataSpec.uri.toString();
inputStream = assetManager.open(path, AssetManager.ACCESS_RANDOM);
long skipped = inputStream.skip(dataSpec.position);
Assertions.checkState(skipped == dataSpec.position);
bytesRemaining = dataSpec.length == C.LENGTH_UNBOUNDED ? inputStream.available()
: dataSpec.length;
if (bytesRemaining < 0) {
if (skipped < dataSpec.position) {
// assetManager.open() returns an AssetInputStream, whose skip() implementation only skips
// fewer bytes than requested if the skip is beyond the end of the asset's data.
throw new EOFException();
}
if (dataSpec.length != C.LENGTH_UNBOUNDED) {
bytesRemaining = dataSpec.length;
} else {
bytesRemaining = inputStream.available();
if (bytesRemaining == Integer.MAX_VALUE) {
// assetManager.open() returns an AssetInputStream, whose available() implementation
// returns Integer.MAX_VALUE if the remaining length is greater than (or equal to)
// Integer.MAX_VALUE. We don't know the true length in this case, so treat as unbounded.
bytesRemaining = C.LENGTH_UNBOUNDED;
}
}
} catch (IOException e) {
throw new AssetDataSourceException(e);
}
......@@ -103,13 +112,17 @@ public final class AssetDataSource implements UriDataSource {
} else {
int bytesRead = 0;
try {
bytesRead = inputStream.read(buffer, offset, (int) Math.min(bytesRemaining, readLength));
int bytesToRead = bytesRemaining == C.LENGTH_UNBOUNDED ? readLength
: (int) Math.min(bytesRemaining, readLength);
bytesRead = inputStream.read(buffer, offset, bytesToRead);
} catch (IOException e) {
throw new AssetDataSourceException(e);
}
if (bytesRead > 0) {
bytesRemaining -= bytesRead;
if (bytesRemaining != C.LENGTH_UNBOUNDED) {
bytesRemaining -= bytesRead;
}
if (listener != null) {
listener.onBytesTransferred(bytesRead);
}
......
......@@ -16,7 +16,6 @@
package com.google.android.exoplayer.upstream;
import com.google.android.exoplayer.C;
import com.google.android.exoplayer.util.Assertions;
import android.content.ContentResolver;
import android.content.Context;
......@@ -75,12 +74,22 @@ public final class ContentDataSource implements UriDataSource {
AssetFileDescriptor assetFd = resolver.openAssetFileDescriptor(dataSpec.uri, "r");
inputStream = new FileInputStream(assetFd.getFileDescriptor());
long skipped = inputStream.skip(dataSpec.position);
Assertions.checkState(skipped == dataSpec.position);
bytesRemaining = dataSpec.length == C.LENGTH_UNBOUNDED ? inputStream.available()
: dataSpec.length;
if (bytesRemaining < 0) {
if (skipped < dataSpec.position) {
// We expect the skip to be satisfied in full. If it isn't then we're probably trying to
// skip beyond the end of the data.
throw new EOFException();
}
if (dataSpec.length != C.LENGTH_UNBOUNDED) {
bytesRemaining = dataSpec.length;
} else {
bytesRemaining = inputStream.available();
if (bytesRemaining == 0) {
// FileInputStream.available() returns 0 if the remaining length cannot be determined, or
// if it's greater than Integer.MAX_VALUE. We don't know the true length in either case,
// so treat as unbounded.
bytesRemaining = C.LENGTH_UNBOUNDED;
}
}
} catch (IOException e) {
throw new ContentDataSourceException(e);
}
......@@ -100,13 +109,17 @@ public final class ContentDataSource implements UriDataSource {
} else {
int bytesRead = 0;
try {
bytesRead = inputStream.read(buffer, offset, (int) Math.min(bytesRemaining, readLength));
int bytesToRead = bytesRemaining == C.LENGTH_UNBOUNDED ? readLength
: (int) Math.min(bytesRemaining, readLength);
bytesRead = inputStream.read(buffer, offset, bytesToRead);
} catch (IOException e) {
throw new ContentDataSourceException(e);
}
if (bytesRead > 0) {
bytesRemaining -= bytesRead;
if (bytesRemaining != C.LENGTH_UNBOUNDED) {
bytesRemaining -= bytesRead;
}
if (listener != null) {
listener.onBytesTransferred(bytesRead);
}
......
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