21 package com.google.appinventor.components.runtime.multidex;
23 import java.io.IOException;
24 import java.nio.ByteBuffer;
25 import java.nio.charset.Charset;
26 import java.util.Calendar;
27 import java.util.GregorianCalendar;
28 import java.util.zip.ZipEntry;
29 import java.util.zip.ZipException;
31 class ZipEntryReader {
32 static final Charset UTF_8 = Charset.forName(
"UTF-8");
37 private static final int GPBF_ENCRYPTED_FLAG = 1 << 0;
47 private static final int GPBF_UNSUPPORTED_MASK = GPBF_ENCRYPTED_FLAG;
48 private static final long CENSIG = 0x2014b50;
50 static ZipEntry readEntry(ByteBuffer in)
throws IOException {
52 int sig = in.getInt();
54 throw new ZipException(
"Central Directory Entry not found");
58 int gpbf = in.getShort() & 0xffff;
60 if ((gpbf & GPBF_UNSUPPORTED_MASK) != 0) {
61 throw new ZipException(
"Invalid General Purpose Bit Flag: " + gpbf);
64 int compressionMethod = in.getShort() & 0xffff;
65 int time = in.getShort() & 0xffff;
66 int modDate = in.getShort() & 0xffff;
69 long crc = ((long) in.getInt()) & 0xffffffffL;
70 long compressedSize = ((long) in.getInt()) & 0xffffffffL;
71 long size = ((long) in.getInt()) & 0xffffffffL;
73 int nameLength = in.getShort() & 0xffff;
74 int extraLength = in.getShort() & 0xffff;
75 int commentByteCount = in.getShort() & 0xffff;
79 long localHeaderRelOffset = ((long) in.getInt()) & 0xffffffffL;
81 byte[] nameBytes =
new byte[nameLength];
82 in.get(nameBytes, 0, nameBytes.length);
83 String name =
new String(nameBytes, 0, nameBytes.length, UTF_8);
85 ZipEntry entry =
new ZipEntry(name);
86 entry.setMethod(compressionMethod);
87 entry.setTime(getTime(time, modDate));
90 entry.setCompressedSize(compressedSize);
95 if (commentByteCount > 0) {
96 byte[] commentBytes =
new byte[commentByteCount];
97 in.get(commentBytes, 0, commentByteCount);
98 entry.setComment(
new String(commentBytes, 0, commentBytes.length, UTF_8));
101 if (extraLength > 0) {
102 byte[] extra =
new byte[extraLength];
103 in.get(extra, 0, extraLength);
104 entry.setExtra(extra);
111 private static long getTime(
int time,
int modDate) {
112 GregorianCalendar cal =
new GregorianCalendar();
113 cal.set(Calendar.MILLISECOND, 0);
114 cal.set(1980 + ((modDate >> 9) & 0x7f), ((modDate >> 5) & 0xf) - 1,
115 modDate & 0x1f, (time >> 11) & 0x1f, (time >> 5) & 0x3f,
117 return cal.getTime().getTime();