/* ZipOutputStream.java --
   Copyright (C) 2001, 2004  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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.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;
    commentBytes = comment.getBytes();
    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);
  }

  /**
   * 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 = entry.getName().getBytes();
    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 = entry.getName().getBytes();
	if (name.length > 0xffff)
	  throw new ZipException("Name too long.");
	byte[] extra = entry.getExtra();
	if (extra == null)
	  extra = new byte[0];
	String strComment = entry.getComment();
	byte[] comment = strComment != null
	  ? strComment.getBytes() : new byte[0];
	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;
  }
}
