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