/* ZipOutputStream.java --
   Copyright (C) 2001, 2004, 2005, 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.util.zip;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Vector;

/**
 * This is a FilterOutputStream that writes the files into a zip
 * archive one after another.  It has a special method to start a new
 * zip entry.  The zip entries contains information about the file name
 * size, compressed size, CRC, etc.
 *
 * It includes support for STORED and DEFLATED entries.
 *
 * This class is not thread safe.
 *
 * @author Jochen Hoenicke
 */
public class ZipOutputStream extends DeflaterOutputStream implements ZipConstants
{
  private Vector entries = new Vector();
  private CRC32 crc = new CRC32();
  private ZipEntry curEntry = null;

  private int curMethod;
  private int size;
  private int offset = 0;

  private byte[] zipComment = new byte[0];
  private int defaultMethod = DEFLATED;

  /**
   * Our Zip version is hard coded to 1.0 resp. 2.0
   */
  private static final int ZIP_STORED_VERSION = 10;
  private static final int ZIP_DEFLATED_VERSION = 20;

  /**
   * Compression method.  This method doesn't compress at all.
   */
  public static final int STORED = 0;

  /**
   * Compression method.  This method uses the Deflater.
   */
  public static final int DEFLATED = 8;

  /**
   * Creates a new Zip output stream, writing a zip archive.
   * @param out the output stream to which the zip archive is written.
   */
  public ZipOutputStream(OutputStream out)
  {
    super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
  }

  /**
   * Set the zip file comment.
   * @param comment the comment.
   * @exception IllegalArgumentException if encoding of comment is
   * longer than 0xffff bytes.
   */
  public void setComment(String comment)
  {
    byte[] commentBytes;
    try
      {
        commentBytes = comment.getBytes("UTF-8");
      }
    catch (UnsupportedEncodingException uee)
      {
        throw new AssertionError(uee);
      }
    if (commentBytes.length > 0xffff)
      throw new IllegalArgumentException("Comment too long.");
    zipComment = commentBytes;
  }

  /**
   * Sets default compression method.  If the Zip entry specifies
   * another method its method takes precedence.
   * @param method the method.
   * @exception IllegalArgumentException if method is not supported.
   * @see #STORED
   * @see #DEFLATED
   */
  public void setMethod(int method)
  {
    if (method != STORED && method != DEFLATED)
      throw new IllegalArgumentException("Method not supported.");
    defaultMethod = method;
  }

  /**
   * Sets default compression level.  The new level will be activated
   * immediately.
   * @exception IllegalArgumentException if level is not supported.
   * @see Deflater
   */
  public void setLevel(int level)
  {
    def.setLevel(level);
  }

  /**
   * Write an unsigned short in little endian byte order.
   */
  private void writeLeShort(int value) throws IOException
  {
    out.write(value & 0xff);
    out.write((value >> 8) & 0xff);
  }

  /**
   * Write an int in little endian byte order.
   */
  private void writeLeInt(int value) throws IOException
  {
    writeLeShort(value);
    writeLeShort(value >> 16);
  }

  /**
   * Write a long value as an int.  Some of the zip constants
   * are declared as longs even though they fit perfectly well
   * into integers.
   */
  private void writeLeInt(long value) throws IOException
  {
    writeLeInt((int) value);
  }

  /**
   * Starts a new Zip entry. It automatically closes the previous
   * entry if present.  If the compression method is stored, the entry
   * must have a valid size and crc, otherwise all elements (except
   * name) are optional, but must be correct if present.  If the time
   * is not set in the entry, the current time is used.
   * @param entry the entry.
   * @exception IOException if an I/O error occured.
   * @exception ZipException if stream was finished.
   */
  public void putNextEntry(ZipEntry entry) throws IOException
  {
    if (entries == null)
      throw new ZipException("ZipOutputStream was finished");

    int method = entry.getMethod();
    int flags = 0;
    if (method == -1)
      method = defaultMethod;

    if (method == STORED)
      {
        if (entry.getCompressedSize() >= 0)
          {
            if (entry.getSize() < 0)
              entry.setSize(entry.getCompressedSize());
            else if (entry.getSize() != entry.getCompressedSize())
              throw new ZipException
                ("Method STORED, but compressed size != size");
          }
        else
          entry.setCompressedSize(entry.getSize());

        if (entry.getSize() < 0)
          throw new ZipException("Method STORED, but size not set");
        if (entry.getCrc() < 0)
          throw new ZipException("Method STORED, but crc not set");
      }
    else if (method == DEFLATED)
      {
        if (entry.getCompressedSize() < 0
            || entry.getSize() < 0 || entry.getCrc() < 0)
          flags |= 8;
      }

    if (curEntry != null)
      closeEntry();

    if (entry.getTime() < 0)
      entry.setTime(System.currentTimeMillis());

    entry.flags = flags;
    entry.offset = offset;
    entry.setMethod(method);
    curMethod = method;
    /* Write the local file header */
    writeLeInt(LOCSIG);
    writeLeShort(method == STORED
                 ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
    writeLeShort(flags);
    writeLeShort(method);
    writeLeInt(entry.getDOSTime());
    if ((flags & 8) == 0)
      {
        writeLeInt((int)entry.getCrc());
        writeLeInt((int)entry.getCompressedSize());
        writeLeInt((int)entry.getSize());
      }
    else
      {
        writeLeInt(0);
        writeLeInt(0);
        writeLeInt(0);
      }
    byte[] name;
    try
      {
        name = entry.getName().getBytes("UTF-8");
      }
    catch (UnsupportedEncodingException uee)
      {
        throw new AssertionError(uee);
      }
    if (name.length > 0xffff)
      throw new ZipException("Name too long.");
    byte[] extra = entry.getExtra();
    if (extra == null)
      extra = new byte[0];
    writeLeShort(name.length);
    writeLeShort(extra.length);
    out.write(name);
    out.write(extra);

    offset += LOCHDR + name.length + extra.length;

    /* Activate the entry. */

    curEntry = entry;
    crc.reset();
    if (method == DEFLATED)
      def.reset();
    size = 0;
  }

  /**
   * Closes the current entry.
   * @exception IOException if an I/O error occured.
   * @exception ZipException if no entry is active.
   */
  public void closeEntry() throws IOException
  {
    if (curEntry == null)
      throw new ZipException("No open entry");

    /* First finish the deflater, if appropriate */
    if (curMethod == DEFLATED)
      super.finish();

    int csize = curMethod == DEFLATED ? def.getTotalOut() : size;

    if (curEntry.getSize() < 0)
      curEntry.setSize(size);
    else if (curEntry.getSize() != size)
      throw new ZipException("size was "+size
                             +", but I expected "+curEntry.getSize());

    if (curEntry.getCompressedSize() < 0)
      curEntry.setCompressedSize(csize);
    else if (curEntry.getCompressedSize() != csize)
      throw new ZipException("compressed size was "+csize
                             +", but I expected "+curEntry.getSize());

    if (curEntry.getCrc() < 0)
      curEntry.setCrc(crc.getValue());
    else if (curEntry.getCrc() != crc.getValue())
      throw new ZipException("crc was " + Long.toHexString(crc.getValue())
                             + ", but I expected "
                             + Long.toHexString(curEntry.getCrc()));

    offset += csize;

    /* Now write the data descriptor entry if needed. */
    if (curMethod == DEFLATED && (curEntry.flags & 8) != 0)
      {
        writeLeInt(EXTSIG);
        writeLeInt((int)curEntry.getCrc());
        writeLeInt((int)curEntry.getCompressedSize());
        writeLeInt((int)curEntry.getSize());
        offset += EXTHDR;
      }

    entries.addElement(curEntry);
    curEntry = null;
  }

  /**
   * Writes the given buffer to the current entry.
   * @exception IOException if an I/O error occured.
   * @exception ZipException if no entry is active.
   */
  public void write(byte[] b, int off, int len) throws IOException
  {
    if (curEntry == null)
      throw new ZipException("No open entry.");

    switch (curMethod)
      {
      case DEFLATED:
        super.write(b, off, len);
        break;

      case STORED:
        out.write(b, off, len);
        break;
      }

    crc.update(b, off, len);
    size += len;
  }

  /**
   * Finishes the stream.  This will write the central directory at the
   * end of the zip file and flush the stream.
   * @exception IOException if an I/O error occured.
   */
  public void finish() throws IOException
  {
    if (entries == null)
      return;
    if (curEntry != null)
      closeEntry();

    int numEntries = 0;
    int sizeEntries = 0;

    Enumeration e = entries.elements();
    while (e.hasMoreElements())
      {
        ZipEntry entry = (ZipEntry) e.nextElement();

        int method = entry.getMethod();
        writeLeInt(CENSIG);
        writeLeShort(method == STORED
                     ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
        writeLeShort(method == STORED
                     ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
        writeLeShort(entry.flags);
        writeLeShort(method);
        writeLeInt(entry.getDOSTime());
        writeLeInt((int)entry.getCrc());
        writeLeInt((int)entry.getCompressedSize());
        writeLeInt((int)entry.getSize());

        byte[] name;
        try
          {
            name = entry.getName().getBytes("UTF-8");
          }
        catch (UnsupportedEncodingException uee)
          {
            throw new AssertionError(uee);
          }
        if (name.length > 0xffff)
          throw new ZipException("Name too long.");
        byte[] extra = entry.getExtra();
        if (extra == null)
          extra = new byte[0];
        String str = entry.getComment();
        byte[] comment;
        try
          {
            comment = str != null ? str.getBytes("UTF-8") : new byte[0];
          }
        catch (UnsupportedEncodingException uee)
          {
            throw new AssertionError(uee);
          }
        if (comment.length > 0xffff)
          throw new ZipException("Comment too long.");

        writeLeShort(name.length);
        writeLeShort(extra.length);
        writeLeShort(comment.length);
        writeLeShort(0); /* disk number */
        writeLeShort(0); /* internal file attr */
        writeLeInt(0);   /* external file attr */
        writeLeInt(entry.offset);

        out.write(name);
        out.write(extra);
        out.write(comment);
        numEntries++;
        sizeEntries += CENHDR + name.length + extra.length + comment.length;
      }

    writeLeInt(ENDSIG);
    writeLeShort(0); /* disk number */
    writeLeShort(0); /* disk with start of central dir */
    writeLeShort(numEntries);
    writeLeShort(numEntries);
    writeLeInt(sizeEntries);
    writeLeInt(offset);
    writeLeShort(zipComment.length);
    out.write(zipComment);
    out.flush();
    entries = null;
  }
}
