Merge change Ide90d0cc into eclair
* changes: Unify Java NIO to read/write MiniThumbFile.
This commit is contained in:
@@ -25,6 +25,7 @@ import android.util.Log;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.util.Hashtable;
|
||||
@@ -44,12 +45,6 @@ import java.util.Hashtable;
|
||||
* only.
|
||||
*/
|
||||
public class MiniThumbFile {
|
||||
public static final int THUMBNAIL_TARGET_SIZE = 320;
|
||||
public static final int MINI_THUMB_TARGET_SIZE = 96;
|
||||
public static final int THUMBNAIL_MAX_NUM_PIXELS = 512 * 384;
|
||||
public static final int MINI_THUMB_MAX_NUM_PIXELS = 128 * 128;
|
||||
public static final int UNCONSTRAINED = -1;
|
||||
|
||||
private static final String TAG = "MiniThumbFile";
|
||||
private static final int MINI_THUMB_DATA_FILE_VERSION = 3;
|
||||
public static final int BYTES_PER_MINTHUMB = 10000;
|
||||
@@ -57,6 +52,7 @@ public class MiniThumbFile {
|
||||
private Uri mUri;
|
||||
private RandomAccessFile mMiniThumbFile;
|
||||
private FileChannel mChannel;
|
||||
private ByteBuffer mBuffer;
|
||||
private static Hashtable<String, MiniThumbFile> sThumbFiles =
|
||||
new Hashtable<String, MiniThumbFile>();
|
||||
|
||||
@@ -130,6 +126,7 @@ public class MiniThumbFile {
|
||||
|
||||
public MiniThumbFile(Uri uri) {
|
||||
mUri = uri;
|
||||
mBuffer = ByteBuffer.allocateDirect(BYTES_PER_MINTHUMB);
|
||||
}
|
||||
|
||||
public synchronized void deactivate() {
|
||||
@@ -154,14 +151,16 @@ public class MiniThumbFile {
|
||||
long pos = id * BYTES_PER_MINTHUMB;
|
||||
FileLock lock = null;
|
||||
try {
|
||||
lock = mChannel.lock();
|
||||
mBuffer.clear();
|
||||
mBuffer.limit(1 + 8);
|
||||
|
||||
lock = mChannel.lock(pos, 1 + 8, true);
|
||||
// check that we can read the following 9 bytes
|
||||
// (1 for the "status" and 8 for the long)
|
||||
if (r.length() >= pos + 1 + 8) {
|
||||
r.seek(pos);
|
||||
if (r.readByte() == 1) {
|
||||
long fileMagic = r.readLong();
|
||||
return fileMagic;
|
||||
if (mChannel.read(mBuffer, pos) == 9) {
|
||||
mBuffer.position(0);
|
||||
if (mBuffer.get() == 1) {
|
||||
return mBuffer.getLong();
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
@@ -196,25 +195,20 @@ public class MiniThumbFile {
|
||||
long pos = id * BYTES_PER_MINTHUMB;
|
||||
FileLock lock = null;
|
||||
try {
|
||||
lock = mChannel.lock();
|
||||
if (data != null) {
|
||||
if (data.length > BYTES_PER_MINTHUMB - HEADER_SIZE) {
|
||||
// not enough space to store it.
|
||||
return;
|
||||
}
|
||||
r.seek(pos);
|
||||
r.writeByte(0); // we have no data in this slot
|
||||
mBuffer.clear();
|
||||
mBuffer.put((byte) 1);
|
||||
mBuffer.putLong(magic);
|
||||
mBuffer.putInt(data.length);
|
||||
mBuffer.put(data);
|
||||
mBuffer.flip();
|
||||
|
||||
// if magic is 0 then leave it alone
|
||||
if (magic == 0) {
|
||||
r.skipBytes(8);
|
||||
} else {
|
||||
r.writeLong(magic);
|
||||
}
|
||||
r.writeInt(data.length);
|
||||
r.write(data);
|
||||
r.seek(pos);
|
||||
r.writeByte(1); // we have data in this slot
|
||||
lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, false);
|
||||
mChannel.write(mBuffer, pos);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, "couldn't save mini thumbnail data for "
|
||||
@@ -248,20 +242,22 @@ public class MiniThumbFile {
|
||||
long pos = id * BYTES_PER_MINTHUMB;
|
||||
FileLock lock = null;
|
||||
try {
|
||||
lock = mChannel.lock();
|
||||
r.seek(pos);
|
||||
if (r.readByte() == 1) {
|
||||
long magic = r.readLong();
|
||||
int length = r.readInt();
|
||||
int got = r.read(data, 0, length);
|
||||
if (got != length) return null;
|
||||
return data;
|
||||
} else {
|
||||
return null;
|
||||
mBuffer.clear();
|
||||
lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, true);
|
||||
int size = mChannel.read(mBuffer, pos);
|
||||
if (size > 1 + 8 + 4) { // flag, magic, length
|
||||
mBuffer.position(0);
|
||||
byte flag = mBuffer.get();
|
||||
long magic = mBuffer.getLong();
|
||||
int length = mBuffer.getInt();
|
||||
|
||||
if (size >= 1 + 8 + 4 + length && data.length >= length) {
|
||||
mBuffer.get(data, 0, length);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Log.w(TAG, "got exception when reading thumbnail: " + ex);
|
||||
return null;
|
||||
Log.w(TAG, "got exception when reading thumbnail id=" + id + ", exception: " + ex);
|
||||
} catch (RuntimeException ex) {
|
||||
// Other NIO related exception like disk full, read only channel..etc
|
||||
Log.e(TAG, "Got exception when reading thumbnail, id = " + id +
|
||||
|
||||
Reference in New Issue
Block a user