package org.syzygy.gps.midp;
import org.syzygy.gps.CoordinateMapper;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import java.io.*;
/**
* RmsMapCache is a cache which uses the Record Management System
* to store maps.
* NOTE: this cache has no eviction policy yet, the size of the RMS
* can grow without bound.
* <p/>
* This class was written by Stephen Crane (jscrane@gmail.com)
* and is released under the terms of the GNU GPL
* (http://www.gnu.org/licenses/gpl.html).
*/
class RmsMapCache
extends NoMapCache
{
/**
* @return null if the map doesn't exist in the cache
*/
public byte[] get(CoordinateMapper.Tile tile)
throws IOException
{
String name = tile.toString();
RecordStore rs = null;
try {
rs = RecordStore.openRecordStore(rsName, true);
RecordEnumeration e = rs.enumerateRecords(null, null, false);
while (e.hasNextElement()) {
byte[] rec = e.nextRecord();
ByteArrayInputStream bais = new ByteArrayInputStream(rec);
DataInputStream input = new DataInputStream(bais);
String s = input.readUTF();
if (s.equals(name)) {
int n = input.available(); // FIXME: ???
byte[] map = new byte[n];
input.read(map);
input.close();
bais.close();
System.out.println("found " + name);
return map;
}
input.close();
bais.close();
}
} catch (RecordStoreException e) {
e.printStackTrace();
} finally {
try {
rs.closeRecordStore();
} catch (RecordStoreException e) {
//
}
}
return null;
}
/**
* Fetches a new map for the cache, evicting an existing entry
* if necessary.
*/
public byte[] fetch(CoordinateMapper.Tile tile)
throws IOException
{
byte[] map = super.fetch(tile);
if (map != null) {
String name = tile.toString();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(baos);
output.writeUTF(name);
output.write(map, 0, map.length);
output.close();
byte[] rec = baos.toByteArray();
baos.close();
// FIXME: could maintain a hash of names to RS ids here
RecordStore rs = null;
try {
rs = RecordStore.openRecordStore(rsName, true);
rs.addRecord(rec, 0, rec.length);
System.out.println("added " + name);
} catch (RecordStoreException e) {
e.printStackTrace();
} finally {
try {
rs.closeRecordStore();
} catch (RecordStoreException e) {
//
}
}
}
return map;
}
/**
* Constructs a new cache
*
* @param rsName the name of the Record Store which backs the cache
*/
public RmsMapCache(String rsName)
{
this.rsName = rsName;
}
private final String rsName;
}