/* ZipEntry.java --
   Copyright (C) 2001, 2002, 2004, 2005 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.util.Calendar;

/**
 * This class represents a member of a zip archive.  ZipFile and
 * ZipInputStream will give you instances of this class as information
 * about the members in an archive.  On the other hand ZipOutputStream
 * needs an instance of this class to create a new member.
 *
 * @author Jochen Hoenicke 
 */
public class ZipEntry implements ZipConstants, Cloneable
{
  private static final int KNOWN_SIZE   = 1;
  private static final int KNOWN_CSIZE  = 2;
  private static final int KNOWN_CRC    = 4;
  private static final int KNOWN_TIME   = 8;
  private static final int KNOWN_EXTRA  = 16;

  private static Calendar cal;

  private String name;
  private int size;
  private long compressedSize = -1;
  private int crc;
  private int dostime;
  private short known = 0;
  private short method = -1;
  private byte[] extra = null;
  private String comment = null;

  int flags;              /* used by ZipOutputStream */
  int offset;             /* used by ZipFile and ZipOutputStream */

  /**
   * 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 zip entry with the given name.
   * @param name the name. May include directory components separated
   * by '/'.
   *
   * @exception NullPointerException when name is null.
   * @exception IllegalArgumentException when name is bigger then 65535 chars.
   */
  public ZipEntry(String name)
  {
    int length = name.length();
    if (length > 65535)
      throw new IllegalArgumentException("name length is " + length);
    this.name = name;
  }

  /**
   * Creates a copy of the given zip entry.
   * @param e the entry to copy.
   */
  public ZipEntry(ZipEntry e)
  {
    this(e, e.name);
  }

  ZipEntry(ZipEntry e, String name)
  {
    this.name = name;
    known = e.known;
    size = e.size;
    compressedSize = e.compressedSize;
    crc = e.crc;
    dostime = e.dostime;
    method = e.method;
    extra = e.extra;
    comment = e.comment;
  }

  final void setDOSTime(int dostime)
  {
    this.dostime = dostime;
    known |= KNOWN_TIME;
  }

  final int getDOSTime()
  {
    if ((known & KNOWN_TIME) == 0)
      return 0;
    else
      return dostime;
  }

  /**
   * Creates a copy of this zip entry.
   */
  /**
   * Clones the entry.
   */
  public Object clone()
  {
    try
      {
	// The JCL says that the `extra' field is also copied.
	ZipEntry clone = (ZipEntry) super.clone();
	if (extra != null)
	  clone.extra = (byte[]) extra.clone();
	return clone;
      }
    catch (CloneNotSupportedException ex)
      {
	throw new InternalError();
      }
  }

  /**
   * Returns the entry name.  The path components in the entry are
   * always separated by slashes ('/').  
   */
  public String getName()
  {
    return name;
  }

  /**
   * Sets the time of last modification of the entry.
   * @time the time of last modification of the entry.
   */
  public void setTime(long time)
  {
    Calendar cal = getCalendar();
    synchronized (cal)
      {
	cal.setTimeInMillis(time);
	dostime = (cal.get(Calendar.YEAR) - 1980 & 0x7f) << 25
	  | (cal.get(Calendar.MONTH) + 1) << 21
	  | (cal.get(Calendar.DAY_OF_MONTH)) << 16
	  | (cal.get(Calendar.HOUR_OF_DAY)) << 11
	  | (cal.get(Calendar.MINUTE)) << 5
	  | (cal.get(Calendar.SECOND)) >> 1;
      }
    this.known |= KNOWN_TIME;
  }

  /**
   * Gets the time of last modification of the entry.
   * @return the time of last modification of the entry, or -1 if unknown.
   */
  public long getTime()
  {
    // The extra bytes might contain the time (posix/unix extension)
    parseExtra();

    if ((known & KNOWN_TIME) == 0)
      return -1;

    int sec = 2 * (dostime & 0x1f);
    int min = (dostime >> 5) & 0x3f;
    int hrs = (dostime >> 11) & 0x1f;
    int day = (dostime >> 16) & 0x1f;
    int mon = ((dostime >> 21) & 0xf) - 1;
    int year = ((dostime >> 25) & 0x7f) + 1980; /* since 1900 */
   
    try
      {
	cal = getCalendar();
	synchronized (cal)
	  {
	    cal.set(year, mon, day, hrs, min, sec);
	    return cal.getTimeInMillis();
	  }
      }
    catch (RuntimeException ex)
      {
	/* Ignore illegal time stamp */
	known &= ~KNOWN_TIME;
	return -1;
      }
  }

  private static synchronized Calendar getCalendar()
  {
    if (cal == null)
      cal = Calendar.getInstance();

    return cal;
  }

  /**
   * Sets the size of the uncompressed data.
   * @exception IllegalArgumentException if size is not in 0..0xffffffffL
   */
  public void setSize(long size)
  {
    if ((size & 0xffffffff00000000L) != 0)
	throw new IllegalArgumentException();
    this.size = (int) size;
    this.known |= KNOWN_SIZE;
  }

  /**
   * Gets the size of the uncompressed data.
   * @return the size or -1 if unknown.
   */
  public long getSize()
  {
    return (known & KNOWN_SIZE) != 0 ? size & 0xffffffffL : -1L;
  }

  /**
   * Sets the size of the compressed data.
   */
  public void setCompressedSize(long csize)
  {
    this.compressedSize = csize;
  }

  /**
   * Gets the size of the compressed data.
   * @return the size or -1 if unknown.
   */
  public long getCompressedSize()
  {
    return compressedSize;
  }

  /**
   * Sets the crc of the uncompressed data.
   * @exception IllegalArgumentException if crc is not in 0..0xffffffffL
   */
  public void setCrc(long crc)
  {
    if ((crc & 0xffffffff00000000L) != 0)
	throw new IllegalArgumentException();
    this.crc = (int) crc;
    this.known |= KNOWN_CRC;
  }

  /**
   * Gets the crc of the uncompressed data.
   * @return the crc or -1 if unknown.
   */
  public long getCrc()
  {
    return (known & KNOWN_CRC) != 0 ? crc & 0xffffffffL : -1L;
  }

  /**
   * Sets the compression method.  Only DEFLATED and STORED are
   * supported.
   * @exception IllegalArgumentException if method is not supported.
   * @see ZipOutputStream#DEFLATED
   * @see ZipOutputStream#STORED 
   */
  public void setMethod(int method)
  {
    if (method != ZipOutputStream.STORED
	&& method != ZipOutputStream.DEFLATED)
	throw new IllegalArgumentException();
    this.method = (short) method;
  }

  /**
   * Gets the compression method.  
   * @return the compression method or -1 if unknown.
   */
  public int getMethod()
  {
    return method;
  }

  /**
   * Sets the extra data.
   * @exception IllegalArgumentException if extra is longer than 0xffff bytes.
   */
  public void setExtra(byte[] extra)
  {
    if (extra == null) 
      {
	this.extra = null;
	return;
      }
    if (extra.length > 0xffff)
      throw new IllegalArgumentException();
    this.extra = extra;
  }

  private void parseExtra()
  {
    // Already parsed?
    if ((known & KNOWN_EXTRA) != 0)
      return;

    if (extra == null)
      {
	known |= KNOWN_EXTRA;
	return;
      }

    try
      {
	int pos = 0;
	while (pos < extra.length) 
	  {
	    int sig = (extra[pos++] & 0xff)
	      | (extra[pos++] & 0xff) << 8;
	    int len = (extra[pos++] & 0xff)
	      | (extra[pos++] & 0xff) << 8;
	    if (sig == 0x5455) 
	      {
		/* extended time stamp */
		int flags = extra[pos];
		if ((flags & 1) != 0)
		  {
		    long time = ((extra[pos+1] & 0xff)
			    | (extra[pos+2] & 0xff) << 8
			    | (extra[pos+3] & 0xff) << 16
			    | (extra[pos+4] & 0xff) << 24);
		    setTime(time);
		  }
	      }
	    pos += len;
	  }
      }
    catch (ArrayIndexOutOfBoundsException ex)
      {
	/* be lenient */
      }

    known |= KNOWN_EXTRA;
    return;
  }

  /**
   * Gets the extra data.
   * @return the extra data or null if not set.
   */
  public byte[] getExtra()
  {
    return extra;
  }

  /**
   * Sets the entry comment.
   * @exception IllegalArgumentException if comment is longer than 0xffff.
   */
  public void setComment(String comment)
  {
    if (comment != null && comment.length() > 0xffff)
      throw new IllegalArgumentException();
    this.comment = comment;
  }

  /**
   * Gets the comment.
   * @return the comment or null if not set.
   */
  public String getComment()
  {
    return comment;
  }

  /**
   * Gets true, if the entry is a directory.  This is solely
   * determined by the name, a trailing slash '/' marks a directory.  
   */
  public boolean isDirectory()
  {
    int nlen = name.length();
    return nlen > 0 && name.charAt(nlen - 1) == '/';
  }

  /**
   * Gets the string representation of this ZipEntry.  This is just
   * the name as returned by getName().
   */
  public String toString()
  {
    return name;
  }

  /**
   * Gets the hashCode of this ZipEntry.  This is just the hashCode
   * of the name.  Note that the equals method isn't changed, though.
   */
  public int hashCode()
  {
    return name.hashCode();
  }
}
