brouter/brouter-mapaccess/src/main/java/btools/mapaccess/PhysicalFile.java
2019-05-30 15:11:12 +02:00

148 lines
3.8 KiB
Java

/**
* cache for a single square
*
* @author ab
*/
package btools.mapaccess;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import btools.codec.DataBuffers;
import btools.codec.MicroCache;
import btools.util.ByteDataReader;
import btools.util.Crc32;
final public class PhysicalFile
{
RandomAccessFile ra = null;
long[] fileIndex = new long[25];
int[] fileHeaderCrcs;
private int fileIndexCrc;
public long creationTime;
String fileName;
public int divisor = 80;
public static void main( String[] args )
{
MicroCache.debug = true;
String message = checkFileIntegrity( new File( args[0] ) );
if ( message != null )
{
System.out.println( "************************************" );
System.out.println( message );
System.out.println( "************************************" );
}
}
/**
* Checks the integrity of the file using the build-in checksums
*
* @return the error message if file corrupt, else null
*/
public static String checkFileIntegrity( File f )
{
PhysicalFile pf = null;
try
{
DataBuffers dataBuffers = new DataBuffers();
pf = new PhysicalFile( f, dataBuffers, -1, -1 );
int div = pf.divisor;
for ( int lonDegree = 0; lonDegree < 5; lonDegree++ ) // does'nt really matter..
{
for ( int latDegree = 0; latDegree < 5; latDegree++ ) // ..where on earth we are
{
OsmFile osmf = new OsmFile( pf, lonDegree, latDegree, dataBuffers );
if ( osmf.hasData() )
for ( int lonIdx = 0; lonIdx < div; lonIdx++ )
for ( int latIdx = 0; latIdx < div; latIdx++ )
osmf.createMicroCache( lonDegree * div + lonIdx, latDegree * div + latIdx, dataBuffers, null, null, MicroCache.debug, null );
}
}
}
catch (IllegalArgumentException iae)
{
return iae.getMessage();
}
catch (Exception e)
{
return e.toString();
}
finally
{
if ( pf != null )
try
{
pf.ra.close();
}
catch (Exception ee)
{
}
}
return null;
}
public PhysicalFile( File f, DataBuffers dataBuffers, int lookupVersion, int lookupMinorVersion ) throws Exception
{
fileName = f.getName();
byte[] iobuffer = dataBuffers.iobuffer;
ra = new RandomAccessFile( f, "r" );
ra.readFully( iobuffer, 0, 200 );
fileIndexCrc = Crc32.crc( iobuffer, 0, 200 );
ByteDataReader dis = new ByteDataReader( iobuffer );
for( int i=0; i<25; i++ )
{
long lv = dis.readLong();
short readVersion = (short)(lv >> 48);
if ( i == 0 && lookupVersion != -1 && readVersion != lookupVersion )
{
throw new IllegalArgumentException( "lookup version mismatch (old rd5?) lookups.dat="
+ lookupVersion + " " + f. getAbsolutePath() + "=" + readVersion );
}
fileIndex[i] = lv & 0xffffffffffffL;
}
// read some extra info from the end of the file, if present
long len = ra.length();
long pos = fileIndex[24];
int extraLen = 8 + 26*4;
if ( len == pos ) return; // old format o.k.
if ( len < pos+extraLen ) // > is o.k. for future extensions!
{
throw new IOException( "file of size " + len + " too short, should be " + (pos+extraLen) );
}
ra.seek( pos );
ra.readFully( iobuffer, 0, extraLen );
dis = new ByteDataReader( iobuffer );
creationTime = dis.readLong();
int crcData = dis.readInt();
if ( crcData == fileIndexCrc )
{
divisor = 80; // old format
}
else if ( (crcData ^ 2) == fileIndexCrc )
{
divisor = 32; // new format
}
else
{
throw new IOException( "top index checksum error" );
}
fileHeaderCrcs = new int[25];
for( int i=0; i<25; i++ )
{
fileHeaderCrcs[i] = dis.readInt();
}
}
}