Merge "Have AssetFileDescriptor.AutoCloseInputStream use pread"

This commit is contained in:
Jeremy Meyer
2021-10-15 18:07:39 +00:00
committed by Android (Google) Code Review

View File

@@ -21,6 +21,8 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.system.ErrnoException;
import android.system.Os;
import java.io.Closeable;
import java.io.FileDescriptor;
@@ -203,19 +205,22 @@ public class AssetFileDescriptor implements Parcelable, Closeable {
*/
public static class AutoCloseInputStream
extends ParcelFileDescriptor.AutoCloseInputStream {
private long mRemaining;
private long mTotalSize;
private final long mFileOffset;
private long mOffset;
public AutoCloseInputStream(AssetFileDescriptor fd) throws IOException {
super(fd.getParcelFileDescriptor());
super.skip(fd.getStartOffset());
mRemaining = (int)fd.getLength();
mTotalSize = fd.getLength();
mFileOffset = fd.getStartOffset();
}
@Override
public int available() throws IOException {
return mRemaining >= 0
? (mRemaining < 0x7fffffff ? (int)mRemaining : 0x7fffffff)
: super.available();
long available = mTotalSize - mOffset;
return available >= 0
? (available < 0x7fffffff ? (int) available : 0x7fffffff)
: 0;
}
@Override
@@ -227,15 +232,21 @@ public class AssetFileDescriptor implements Parcelable, Closeable {
@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
if (mRemaining >= 0) {
if (mRemaining == 0) return -1;
if (count > mRemaining) count = (int)mRemaining;
int res = super.read(buffer, offset, count);
if (res >= 0) mRemaining -= res;
return res;
int available = available();
if (available <= 0) {
return -1;
}
if (count > available) count = available;
try {
int res = Os.pread(getFD(), buffer, offset, count, mFileOffset + mOffset);
// pread returns 0 at end of file, while java's InputStream interface requires -1
if (res == 0) res = -1;
if (res >= 0) mOffset += res;
return res;
} catch (ErrnoException e) {
throw new IOException(e);
}
return super.read(buffer, offset, count);
}
@Override
@@ -245,41 +256,31 @@ public class AssetFileDescriptor implements Parcelable, Closeable {
@Override
public long skip(long count) throws IOException {
if (mRemaining >= 0) {
if (mRemaining == 0) return -1;
if (count > mRemaining) count = mRemaining;
long res = super.skip(count);
if (res >= 0) mRemaining -= res;
return res;
int available = available();
if (available <= 0) {
return -1;
}
return super.skip(count);
if (count > available) count = available;
mOffset += count;
return count;
}
@Override
public void mark(int readlimit) {
if (mRemaining >= 0) {
// Not supported.
return;
}
super.mark(readlimit);
// Not supported.
return;
}
@Override
public boolean markSupported() {
if (mRemaining >= 0) {
return false;
}
return super.markSupported();
return false;
}
@Override
public synchronized void reset() throws IOException {
if (mRemaining >= 0) {
// Not supported.
return;
}
super.reset();
// Not supported.
return;
}
}