/**
   * Ensures the current entry's size and CRC information is set to the values just written,
   * verifies it isn't too big in the Zip64Mode.Never case and returns whether the entry would
   * require a Zip64 extra field.
   */
  private boolean handleSizesAndCrc(long bytesWritten, long crc, Zip64Mode effectiveMode)
      throws ZipException {
    if (entry.entry.getMethod() == DEFLATED) {
      /* It turns out def.getBytesRead() returns wrong values if
       * the size exceeds 4 GB on Java < Java7
      entry.entry.setSize(def.getBytesRead());
      */
      entry.entry.setSize(entry.bytesRead);
      entry.entry.setCompressedSize(bytesWritten);
      entry.entry.setCrc(crc);

      def.reset();
    } else if (raf == null) {
      if (entry.entry.getCrc() != crc) {
        throw new ZipException(
            "bad CRC checksum for entry "
                + entry.entry.getName()
                + ": "
                + Long.toHexString(entry.entry.getCrc())
                + " instead of "
                + Long.toHexString(crc));
      }

      if (entry.entry.getSize() != bytesWritten) {
        throw new ZipException(
            "bad size for entry "
                + entry.entry.getName()
                + ": "
                + entry.entry.getSize()
                + " instead of "
                + bytesWritten);
      }
    } else {
        /* method is STORED and we used RandomAccessFile */
      entry.entry.setSize(bytesWritten);
      entry.entry.setCompressedSize(bytesWritten);
      entry.entry.setCrc(crc);
    }

    final boolean actuallyNeedsZip64 =
        effectiveMode == Zip64Mode.Always
            || entry.entry.getSize() >= ZIP64_MAGIC
            || entry.entry.getCompressedSize() >= ZIP64_MAGIC;
    if (actuallyNeedsZip64 && effectiveMode == Zip64Mode.Never) {
      throw new Zip64RequiredException(Zip64RequiredException.getEntryTooBigMessage(entry.entry));
    }
    return actuallyNeedsZip64;
  }
  /**
   * Throws an exception if the size is unknown for a stored entry that is written to a non-seekable
   * output or the entry is too big to be written without Zip64 extra but the mode has been set to
   * Never.
   */
  private void validateSizeInformation(Zip64Mode effectiveMode) throws ZipException {
    // Size/CRC not required if RandomAccessFile is used
    if (entry.entry.getMethod() == STORED && raf == null) {
      if (entry.entry.getSize() == ArchiveEntry.SIZE_UNKNOWN) {
        throw new ZipException(
            "uncompressed size is required for" + " STORED method when not writing to a" + " file");
      }
      if (entry.entry.getCrc() == -1) {
        throw new ZipException(
            "crc checksum is required for STORED" + " method when not writing to a file");
      }
      entry.entry.setCompressedSize(entry.entry.getSize());
    }

    if ((entry.entry.getSize() >= ZIP64_MAGIC || entry.entry.getCompressedSize() >= ZIP64_MAGIC)
        && effectiveMode == Zip64Mode.Never) {
      throw new Zip64RequiredException(Zip64RequiredException.getEntryTooBigMessage(entry.entry));
    }
  }