/** * 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(); } } }