Content/Asset data sources - Handle >2^31 byte files correctly.
Issue #641
This commit is contained in:
parent
b57b80f723
commit
7ea199638e
@ -16,7 +16,6 @@
|
|||||||
package com.google.android.exoplayer.upstream;
|
package com.google.android.exoplayer.upstream;
|
||||||
|
|
||||||
import com.google.android.exoplayer.C;
|
import com.google.android.exoplayer.C;
|
||||||
import com.google.android.exoplayer.util.Assertions;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
@ -79,12 +78,22 @@ public final class AssetDataSource implements UriDataSource {
|
|||||||
uriString = dataSpec.uri.toString();
|
uriString = dataSpec.uri.toString();
|
||||||
inputStream = assetManager.open(path, AssetManager.ACCESS_RANDOM);
|
inputStream = assetManager.open(path, AssetManager.ACCESS_RANDOM);
|
||||||
long skipped = inputStream.skip(dataSpec.position);
|
long skipped = inputStream.skip(dataSpec.position);
|
||||||
Assertions.checkState(skipped == dataSpec.position);
|
if (skipped < dataSpec.position) {
|
||||||
bytesRemaining = dataSpec.length == C.LENGTH_UNBOUNDED ? inputStream.available()
|
// assetManager.open() returns an AssetInputStream, whose skip() implementation only skips
|
||||||
: dataSpec.length;
|
// fewer bytes than requested if the skip is beyond the end of the asset's data.
|
||||||
if (bytesRemaining < 0) {
|
|
||||||
throw new EOFException();
|
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) {
|
} catch (IOException e) {
|
||||||
throw new AssetDataSourceException(e);
|
throw new AssetDataSourceException(e);
|
||||||
}
|
}
|
||||||
@ -103,13 +112,17 @@ public final class AssetDataSource implements UriDataSource {
|
|||||||
} else {
|
} else {
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
try {
|
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) {
|
} catch (IOException e) {
|
||||||
throw new AssetDataSourceException(e);
|
throw new AssetDataSourceException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytesRead > 0) {
|
if (bytesRead > 0) {
|
||||||
bytesRemaining -= bytesRead;
|
if (bytesRemaining != C.LENGTH_UNBOUNDED) {
|
||||||
|
bytesRemaining -= bytesRead;
|
||||||
|
}
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onBytesTransferred(bytesRead);
|
listener.onBytesTransferred(bytesRead);
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
package com.google.android.exoplayer.upstream;
|
package com.google.android.exoplayer.upstream;
|
||||||
|
|
||||||
import com.google.android.exoplayer.C;
|
import com.google.android.exoplayer.C;
|
||||||
import com.google.android.exoplayer.util.Assertions;
|
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -75,12 +74,22 @@ public final class ContentDataSource implements UriDataSource {
|
|||||||
AssetFileDescriptor assetFd = resolver.openAssetFileDescriptor(dataSpec.uri, "r");
|
AssetFileDescriptor assetFd = resolver.openAssetFileDescriptor(dataSpec.uri, "r");
|
||||||
inputStream = new FileInputStream(assetFd.getFileDescriptor());
|
inputStream = new FileInputStream(assetFd.getFileDescriptor());
|
||||||
long skipped = inputStream.skip(dataSpec.position);
|
long skipped = inputStream.skip(dataSpec.position);
|
||||||
Assertions.checkState(skipped == dataSpec.position);
|
if (skipped < dataSpec.position) {
|
||||||
bytesRemaining = dataSpec.length == C.LENGTH_UNBOUNDED ? inputStream.available()
|
// We expect the skip to be satisfied in full. If it isn't then we're probably trying to
|
||||||
: dataSpec.length;
|
// skip beyond the end of the data.
|
||||||
if (bytesRemaining < 0) {
|
|
||||||
throw new EOFException();
|
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) {
|
} catch (IOException e) {
|
||||||
throw new ContentDataSourceException(e);
|
throw new ContentDataSourceException(e);
|
||||||
}
|
}
|
||||||
@ -100,13 +109,17 @@ public final class ContentDataSource implements UriDataSource {
|
|||||||
} else {
|
} else {
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
try {
|
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) {
|
} catch (IOException e) {
|
||||||
throw new ContentDataSourceException(e);
|
throw new ContentDataSourceException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytesRead > 0) {
|
if (bytesRead > 0) {
|
||||||
bytesRemaining -= bytesRead;
|
if (bytesRemaining != C.LENGTH_UNBOUNDED) {
|
||||||
|
bytesRemaining -= bytesRead;
|
||||||
|
}
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
listener.onBytesTransferred(bytesRead);
|
listener.onBytesTransferred(bytesRead);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user