private void setSizesAndOffsetFromZip64Extra(
     final ZipEntry ze, final OffsetEntry offset, final int diskStart) throws IOException {
   final Zip64ExtendedInformationExtraField z64 =
       (Zip64ExtendedInformationExtraField)
           ze.getExtraField(Zip64ExtendedInformationExtraField.HEADER_ID);
   if (z64 != null) {
     final boolean hasUncompressedSize = ze.getSize() == 4294967295L;
     final boolean hasCompressedSize = ze.getCompressedSize() == 4294967295L;
     final boolean hasRelativeHeaderOffset = offset.headerOffset == 4294967295L;
     z64.reparseCentralDirectoryData(
         hasUncompressedSize, hasCompressedSize, hasRelativeHeaderOffset, diskStart == 65535);
     if (hasUncompressedSize) {
       ze.setSize(z64.getSize().getLongValue());
     } else if (hasCompressedSize) {
       z64.setSize(new ZipEightByteInteger(ze.getSize()));
     }
     if (hasCompressedSize) {
       ze.setCompressedSize(z64.getCompressedSize().getLongValue());
     } else if (hasUncompressedSize) {
       z64.setCompressedSize(new ZipEightByteInteger(ze.getCompressedSize()));
     }
     if (hasRelativeHeaderOffset) {
       offset.headerOffset = z64.getRelativeHeaderOffset().getLongValue();
     }
   }
 }
 private void readCentralDirectoryEntry(final Map<ZipEntry, NameAndComment> noUTF8Flag)
     throws IOException {
   this.archive.readFully(this.CFH_BUF);
   int off = 0;
   final OffsetEntry offset = new OffsetEntry();
   final Entry ze = new Entry(offset);
   final int versionMadeBy = ZipShort.getValue(this.CFH_BUF, off);
   off += 2;
   ze.setPlatform(versionMadeBy >> 8 & 0xF);
   off += 2;
   final GeneralPurposeBit gpFlag = GeneralPurposeBit.parse(this.CFH_BUF, off);
   final boolean hasUTF8Flag = gpFlag.usesUTF8ForNames();
   final ZipEncoding entryEncoding =
       hasUTF8Flag ? ZipEncodingHelper.UTF8_ZIP_ENCODING : this.zipEncoding;
   ze.setGeneralPurposeBit(gpFlag);
   off += 2;
   ze.setMethod(ZipShort.getValue(this.CFH_BUF, off));
   off += 2;
   final long time = ZipUtil.dosToJavaTime(ZipLong.getValue(this.CFH_BUF, off));
   ze.setTime(time);
   off += 4;
   ze.setCrc(ZipLong.getValue(this.CFH_BUF, off));
   off += 4;
   ze.setCompressedSize(ZipLong.getValue(this.CFH_BUF, off));
   off += 4;
   ze.setSize(ZipLong.getValue(this.CFH_BUF, off));
   off += 4;
   final int fileNameLen = ZipShort.getValue(this.CFH_BUF, off);
   off += 2;
   final int extraLen = ZipShort.getValue(this.CFH_BUF, off);
   off += 2;
   final int commentLen = ZipShort.getValue(this.CFH_BUF, off);
   off += 2;
   final int diskStart = ZipShort.getValue(this.CFH_BUF, off);
   off += 2;
   ze.setInternalAttributes(ZipShort.getValue(this.CFH_BUF, off));
   off += 2;
   ze.setExternalAttributes(ZipLong.getValue(this.CFH_BUF, off));
   off += 4;
   final byte[] fileName = new byte[fileNameLen];
   this.archive.readFully(fileName);
   ze.setName(entryEncoding.decode(fileName), fileName);
   offset.headerOffset = ZipLong.getValue(this.CFH_BUF, off);
   this.entries.add(ze);
   final byte[] cdExtraData = new byte[extraLen];
   this.archive.readFully(cdExtraData);
   ze.setCentralDirectoryExtra(cdExtraData);
   this.setSizesAndOffsetFromZip64Extra(ze, offset, diskStart);
   final byte[] comment = new byte[commentLen];
   this.archive.readFully(comment);
   ze.setComment(entryEncoding.decode(comment));
   if (!hasUTF8Flag && this.useUnicodeExtraFields) {
     noUTF8Flag.put(ze, new NameAndComment(fileName, comment));
   }
 }