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();