21 package com.google.appinventor.components.runtime.multidex;
24 import java.io.IOException;
25 import java.io.RandomAccessFile;
26 import java.util.zip.CRC32;
27 import java.util.zip.ZipException;
33 static class CentralDirectory {
40 private static final int ENDHDR = 22;
41 private static final int ENDSIG = 0x6054b50;
46 private static final int BUFFER_SIZE = 0x4000;
54 static long getZipCrc(File apk)
throws IOException {
55 RandomAccessFile raf =
new RandomAccessFile(apk,
"r");
57 CentralDirectory dir = findCentralDirectory(raf);
59 return computeCrcOfCentralDir(raf, dir);
66 static CentralDirectory findCentralDirectory(RandomAccessFile raf)
throws IOException,
68 long scanOffset = raf.length() - ENDHDR;
70 throw new ZipException(
"File too short to be a zip file: " + raf.length());
73 long stopOffset = scanOffset - 0x10000 ;
78 int endSig = Integer.reverseBytes(ENDSIG);
81 if (raf.readInt() == endSig) {
86 if (scanOffset < stopOffset) {
87 throw new ZipException(
"End Of Central Directory signature not found");
99 CentralDirectory dir =
new CentralDirectory();
100 dir.size = Integer.reverseBytes(raf.readInt()) & 0xFFFFFFFFL;
101 dir.offset = Integer.reverseBytes(raf.readInt()) & 0xFFFFFFFFL;
106 static long computeCrcOfCentralDir(RandomAccessFile raf, CentralDirectory dir)
108 CRC32 crc =
new CRC32();
109 long stillToRead = dir.size;
110 raf.seek(dir.offset);
111 int length = (int) Math.min(BUFFER_SIZE, stillToRead);
112 byte[] buffer =
new byte[BUFFER_SIZE];
113 length = raf.read(buffer, 0, length);
114 while (length != -1) {
115 crc.update(buffer, 0, length);
116 stillToRead -= length;
117 if (stillToRead == 0) {
120 length = (int) Math.min(BUFFER_SIZE, stillToRead);
121 length = raf.read(buffer, 0, length);
123 return crc.getValue();