am 43d0e675: am 7e168ad0: am 6cbef4bd: am 03af0c42: Merge "Ensure that RandomAccessFile is not leaked." into lmp-dev
* commit '43d0e67573e8122d9e75accb00eaa453e2755713': Ensure that RandomAccessFile is not leaked.
This commit is contained in:
@@ -16,74 +16,61 @@
|
||||
|
||||
package com.android.layoutlib.bridge.libcore.io;
|
||||
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import libcore.io.BufferIterator;
|
||||
|
||||
/**
|
||||
* Provides an implementation of {@link BufferIterator} over a {@link MappedByteBuffer}.
|
||||
* Provides an implementation of {@link BufferIterator} over a {@link ByteBuffer}.
|
||||
*/
|
||||
public class BridgeBufferIterator extends BufferIterator {
|
||||
|
||||
private int mPosition;
|
||||
private final long mSize;
|
||||
private final MappedByteBuffer mMappedByteBuffer;
|
||||
private final ByteBuffer mByteBuffer;
|
||||
|
||||
public BridgeBufferIterator(long size, MappedByteBuffer buffer) {
|
||||
public BridgeBufferIterator(long size, ByteBuffer buffer) {
|
||||
mSize = size;
|
||||
mMappedByteBuffer = buffer;
|
||||
mByteBuffer = buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(int offset) {
|
||||
assert offset < mSize;
|
||||
mPosition = offset;
|
||||
assert offset <= mSize;
|
||||
mByteBuffer.position(offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skip(int byteCount) {
|
||||
assert mPosition + byteCount <= mSize;
|
||||
mPosition += byteCount;
|
||||
int newPosition = mByteBuffer.position() + byteCount;
|
||||
assert newPosition <= mSize;
|
||||
mByteBuffer.position(newPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readByteArray(byte[] dst, int dstOffset, int byteCount) {
|
||||
assert dst.length >= dstOffset + byteCount;
|
||||
mMappedByteBuffer.position(mPosition);
|
||||
mMappedByteBuffer.get(dst, dstOffset, byteCount);
|
||||
mPosition = mMappedByteBuffer.position();
|
||||
mByteBuffer.get(dst, dstOffset, byteCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte() {
|
||||
mMappedByteBuffer.position(mPosition);
|
||||
byte b = mMappedByteBuffer.get();
|
||||
mPosition = mMappedByteBuffer.position();
|
||||
return b;
|
||||
return mByteBuffer.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt() {
|
||||
mMappedByteBuffer.position(mPosition);
|
||||
int i = mMappedByteBuffer.getInt();
|
||||
mPosition = mMappedByteBuffer.position();
|
||||
return i;
|
||||
return mByteBuffer.getInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readIntArray(int[] dst, int dstOffset, int intCount) {
|
||||
mMappedByteBuffer.position(mPosition);
|
||||
while (--intCount >= 0) {
|
||||
dst[dstOffset++] = mMappedByteBuffer.getInt();
|
||||
dst[dstOffset++] = mByteBuffer.getInt();
|
||||
}
|
||||
mPosition = mMappedByteBuffer.position();
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort() {
|
||||
mMappedByteBuffer.position(mPosition);
|
||||
short s = mMappedByteBuffer.getShort();
|
||||
mPosition = mMappedByteBuffer.position();
|
||||
return s;
|
||||
return mByteBuffer.getShort();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.system.ErrnoException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.util.HashMap;
|
||||
@@ -59,15 +60,22 @@ public class MemoryMappedFile_Delegate {
|
||||
}
|
||||
path = path.substring(TARGET_PATH.length());
|
||||
try {
|
||||
RandomAccessFile file = new RandomAccessFile(new File(sRootPath, path), "r");
|
||||
long size = file.length();
|
||||
MemoryMappedFile_Delegate newDelegate = new MemoryMappedFile_Delegate(file);
|
||||
long filePointer = file.getFilePointer();
|
||||
MemoryMappedFile mmFile = new MemoryMappedFile(filePointer, size);
|
||||
long delegateIndex = sManager.addNewDelegate(newDelegate);
|
||||
sMemoryMappedFileMap.put(mmFile, delegateIndex);
|
||||
file.close(); // Also closes the channel opened by the delegate constructor.
|
||||
return mmFile;
|
||||
File f = new File(sRootPath, path);
|
||||
if (!f.exists()) {
|
||||
throw new ErrnoException("File not found: " + f.getPath(), 1);
|
||||
}
|
||||
RandomAccessFile file = new RandomAccessFile(f, "r");
|
||||
try {
|
||||
long size = file.length();
|
||||
MemoryMappedFile_Delegate newDelegate = new MemoryMappedFile_Delegate(file);
|
||||
long filePointer = file.getFilePointer();
|
||||
MemoryMappedFile mmFile = new MemoryMappedFile(filePointer, size);
|
||||
long delegateIndex = sManager.addNewDelegate(newDelegate);
|
||||
sMemoryMappedFileMap.put(mmFile, delegateIndex);
|
||||
return mmFile;
|
||||
} finally {
|
||||
file.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ErrnoException("mmapRO", 1, e);
|
||||
}
|
||||
@@ -85,7 +93,7 @@ public class MemoryMappedFile_Delegate {
|
||||
@LayoutlibDelegate
|
||||
static BufferIterator bigEndianIterator(MemoryMappedFile file) {
|
||||
MemoryMappedFile_Delegate delegate = getDelegate(file);
|
||||
return new BridgeBufferIterator(delegate.mSize, delegate.mMappedByteBuffer);
|
||||
return new BridgeBufferIterator(delegate.mSize, delegate.mMappedByteBuffer.duplicate());
|
||||
}
|
||||
|
||||
// TODO: implement littleEndianIterator()
|
||||
@@ -95,6 +103,7 @@ public class MemoryMappedFile_Delegate {
|
||||
// It's weird that map() takes size as long, but returns MappedByteBuffer which uses an int
|
||||
// to store the marker to the position.
|
||||
mMappedByteBuffer = file.getChannel().map(MapMode.READ_ONLY, 0, mSize);
|
||||
assert mMappedByteBuffer.order() == ByteOrder.BIG_ENDIAN;
|
||||
}
|
||||
|
||||
public static void setDataDir(File path) {
|
||||
|
||||
Reference in New Issue
Block a user