Ignore:
Timestamp:
Apr 27, 2004, 8:39:34 PM (22 years ago)
Author:
bird
Message:

GCC v3.3.3 sources.

Location:
branches/GNU/src/gcc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/GNU/src/gcc

    • Property svn:ignore
      •  

        old new  
        2626configure.vr
        2727configure.vrs
         28
        2829Makefile
        29 dir.info
        3030lost+found
        3131update.out
  • branches/GNU/src/gcc/libjava/java/util/zip/ZipOutputStream.java

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.1.1.2
    r1390 r1391  
    1 /* ZipOutputStream.java - Create a file in zip format
    2    Copyright (C) 1999, 2000 Free Software Foundation, Inc.
     1/*
     2   Copyright (C) Free Software Foundation, Inc.
    33
    44This file is part of GNU Classpath.
     
    88the Free Software Foundation; either version 2, or (at your option)
    99any later version.
    10  
     10
    1111GNU Classpath is distributed in the hope that it will be useful, but
    1212WITHOUT ANY WARRANTY; without even the implied warranty of
     
    3737
    3838package java.util.zip;
    39 
    40 import java.io.*;
    41 
    42 /* Written using on-line Java Platform 1.2 API Specification
    43  * and JCL book.
    44  * Believed complete and correct.
     39import java.io.OutputStream;
     40import java.io.IOException;
     41import java.io.UnsupportedEncodingException;
     42import java.util.Vector;
     43import java.util.Enumeration;
     44
     45/**
     46 * This is a FilterOutputStream that writes the files into a zip
     47 * archive one after another.  It has a special method to start a new
     48 * zip entry.  The zip entries contains information about the file name
     49 * size, compressed size, CRC, etc.
     50 *
     51 * It includes support for STORED and DEFLATED entries.
     52 *
     53 * This class is not thread safe.
     54 *
     55 * @author Jochen Hoenicke
    4556 */
    46 
    47 public class ZipOutputStream extends DeflaterOutputStream
    48   implements ZipConstants
     57public class ZipOutputStream extends DeflaterOutputStream implements ZipConstants
    4958{
    50   public static final int STORED = 0;
    51   public static final int DEFLATED = 8;
    52 
    53   public void close () throws IOException
    54   {
    55     finish ();
    56     out.close();
    57   }
    58 
    59   public void closeEntry ()  throws IOException
    60   {
    61     int compressed_size;
    62     if (current.method == STORED)
    63       {
    64         compressed_size = uncompressed_size;
     59  private Vector entries = new Vector();
     60  private CRC32 crc = new CRC32();
     61  private ZipEntry curEntry = null;
     62
     63  private int curMethod;
     64  private int size;
     65  private int offset = 0;
     66
     67  private byte[] zipComment = new byte[0];
     68  private int defaultMethod = DEFLATED;
     69
     70  /**
     71   * Our Zip version is hard coded to 1.0 resp. 2.0
     72   */
     73  private final static int ZIP_STORED_VERSION   = 10;
     74  private final static int ZIP_DEFLATED_VERSION = 20;
     75
     76  /**
     77   * Compression method.  This method doesn't compress at all.
     78   */
     79  public final static int STORED      =  0;
     80  /**
     81   * Compression method.  This method uses the Deflater.
     82   */
     83  public final static int DEFLATED    =  8;
     84
     85  /**
     86   * Creates a new Zip output stream, writing a zip archive.
     87   * @param out the output stream to which the zip archive is written.
     88   */
     89  public ZipOutputStream(OutputStream out)
     90  {
     91    super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
     92  }
     93
     94  /**
     95   * Set the zip file comment.
     96   * @param comment the comment.
     97   * @exception IllegalArgumentException if encoding of comment is
     98   * longer than 0xffff bytes.
     99   */
     100  public void setComment(String comment)
     101  {
     102    byte[] commentBytes;
     103    commentBytes = comment.getBytes();
     104    if (commentBytes.length > 0xffff)
     105      throw new IllegalArgumentException("Comment too long.");
     106    zipComment = commentBytes;
     107  }
     108 
     109  /**
     110   * Sets default compression method.  If the Zip entry specifies
     111   * another method its method takes precedence.
     112   * @param method the method.
     113   * @exception IllegalArgumentException if method is not supported.
     114   * @see #STORED
     115   * @see #DEFLATED
     116   */
     117  public void setMethod(int method)
     118  {
     119    if (method != STORED && method != DEFLATED)
     120      throw new IllegalArgumentException("Method not supported.");
     121    defaultMethod = method;
     122  }
     123
     124  /**
     125   * Sets default compression level.  The new level will be activated
     126   * immediately. 
     127   * @exception IllegalArgumentException if level is not supported.
     128   * @see Deflater
     129   */
     130  public void setLevel(int level)
     131  {
     132    def.setLevel(level);
     133  }
     134 
     135  /**
     136   * Write an unsigned short in little endian byte order.
     137   */
     138  private final void writeLeShort(int value) throws IOException
     139  {
     140    out.write(value & 0xff);
     141    out.write((value >> 8) & 0xff);
     142  }
     143
     144  /**
     145   * Write an int in little endian byte order.
     146   */
     147  private final void writeLeInt(int value) throws IOException
     148  {
     149    writeLeShort(value);
     150    writeLeShort(value >> 16);
     151  }
     152
     153  /**
     154   * Starts a new Zip entry. It automatically closes the previous
     155   * entry if present.  If the compression method is stored, the entry
     156   * must have a valid size and crc, otherwise all elements (except
     157   * name) are optional, but must be correct if present.  If the time
     158   * is not set in the entry, the current time is used.
     159   * @param entry the entry.
     160   * @exception IOException if an I/O error occured.
     161   * @exception ZipException if stream was finished.
     162   */
     163  public void putNextEntry(ZipEntry entry) throws IOException
     164  {
     165    if (entries == null)
     166      throw new ZipException("ZipOutputStream was finished");
     167
     168    int method = entry.getMethod();
     169    int flags = 0;
     170    if (method == -1)
     171      method = defaultMethod;
     172
     173    if (method == STORED)
     174      {
     175        if (entry.getCompressedSize() >= 0)
     176          {
     177            if (entry.getSize() < 0)
     178              entry.setSize(entry.getCompressedSize());
     179            else if (entry.getSize() != entry.getCompressedSize())
     180              throw new ZipException
     181                ("Method STORED, but compressed size != size");
     182          }
     183        else
     184          entry.setCompressedSize(entry.getSize());
     185
     186        if (entry.getSize() < 0)
     187          throw new ZipException("Method STORED, but size not set");
     188        if (entry.getCrc() < 0)
     189          throw new ZipException("Method STORED, but crc not set");
     190      }
     191    else if (method == DEFLATED)
     192      {
     193        if (entry.getCompressedSize() < 0
     194            || entry.getSize() < 0 || entry.getCrc() < 0)
     195          flags |= 8;
     196      }
     197
     198    if (curEntry != null)
     199      closeEntry();
     200
     201    if (entry.getTime() < 0)
     202      entry.setTime(System.currentTimeMillis());
     203
     204    entry.flags = flags;
     205    entry.offset = offset;
     206    entry.setMethod(method);
     207    curMethod = method;
     208    /* Write the local file header */
     209    writeLeInt(LOCSIG);
     210    writeLeShort(method == STORED
     211                 ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
     212    writeLeShort(flags);
     213    writeLeShort(method);
     214    writeLeInt(entry.getDOSTime());
     215    if ((flags & 8) == 0)
     216      {
     217        writeLeInt((int)entry.getCrc());
     218        writeLeInt((int)entry.getCompressedSize());
     219        writeLeInt((int)entry.getSize());
    65220      }
    66221    else
    67222      {
    68         super.finish();
    69         compressed_size = def.getTotalOut();
    70       }
    71     long crc = sum.getValue();
    72 
    73     bytes_written += compressed_size;
    74 
    75     if (current.getCrc() == -1 || current.getCompressedSize() == -1
    76         || current.getSize() == -1)
    77       {
    78         current.setCrc(crc);
    79         current.compressedSize = compressed_size;
    80         current.setSize(uncompressed_size);
    81         put4 (0x08074b50);
    82         put4 ((int) (current.getCrc()));
    83         put4 ((int) (current.getCompressedSize()));
    84         put4 ((int) (current.getSize()));
    85         bytes_written += 16;
    86       }
    87     else if (current.getCrc() != crc
    88              || current.getCompressedSize() != compressed_size
    89              || current.getSize() != uncompressed_size)
    90       throw new ZipException ("zip entry field incorrect");
    91 
    92     current.next = chain;
    93     chain = current;
    94     current = null;
    95   }
    96 
    97   public void write (int bval) throws IOException
    98   {
    99     if (current.method == STORED)
    100       {
    101         out.write(bval);
    102       }
    103     else
    104       super.write(bval);
    105     sum.update(bval);
    106     uncompressed_size += 1;
    107   }
    108 
    109   public void write (byte[] buf, int off, int len) throws IOException
    110   {
    111     if (current.method == STORED)
    112       out.write(buf, off, len);
    113     else
    114       super.write(buf, off, len);
    115     sum.update(buf, off, len);
    116     uncompressed_size += len;
    117   }
    118 
    119   public void finish () throws IOException
    120   {
    121     if (current != null)
    122       closeEntry ();
    123 
    124     // Write the central directory.
    125     long offset = bytes_written;
    126     int count = 0;
    127     int bytes = 0;
    128     while (chain != null)
    129       {
    130         bytes += write_entry (chain, false);
    131         ++count;
    132         chain = chain.next;
    133       }
    134 
    135     // Write the end of the central directory record.
    136     put4 (0x06054b50);
    137     // Disk number.
    138     put2 (0);
    139     // Another disk number.
    140     put2 (0);
    141     put2 (count);
    142     put2 (count);
    143     put4 (bytes);
    144     put4 ((int) offset);
    145 
    146     byte[] c = comment.getBytes("8859_1");
    147     put2 (c.length);
    148     out.write(c);
    149   }
    150 
    151   // Helper for finish and putNextEntry.
    152   private int write_entry (ZipEntry entry, boolean is_local)
    153     throws IOException
    154   {
    155     int bytes = put4 (is_local ? 0x04034b50 : 0x02014b50);
    156     if (! is_local)
    157       bytes += put_version ();
    158     bytes += put_version ();
    159 
    160     boolean crc_after = false;
    161     if (is_local
    162         && (entry.getCrc() == -1 || entry.getCompressedSize() == -1
    163             || entry.getSize() == -1))
    164       crc_after = true;
    165     // For the bits field we always indicate `normal' compression,
    166     // even if that isn't true.
    167     bytes += put2 (crc_after ? (1 << 3) : 0);
    168     bytes += put2 (entry.method);
    169 
    170     bytes += put2(0);  // time - FIXME
    171     bytes += put2(0);  // date - FIXME
    172 
    173     if (crc_after)
    174       {
    175         // CRC, compressedSize, and Size are always 0 in this header.
    176         // The actual values are given after the entry.
    177         bytes += put4 (0);
    178         bytes += put4 (0);
    179         bytes += put4 (0);
    180       }
    181     else
    182       {
    183         bytes += put4 ((int) (entry.getCrc()));
    184         bytes += put4 ((int) (entry.getCompressedSize()));
    185         bytes += put4 ((int) (entry.getSize()));
    186       }
    187 
    188     byte[] name = entry.name.getBytes("8859_1");
    189     bytes += put2 (name.length);
    190     bytes += put2 (entry.extra == null ? 0 : entry.extra.length);
    191 
    192     byte[] comment = null;
    193     if (! is_local)
    194       {
    195         if (entry.getComment() == null)
    196           bytes += put2 (0);
    197         else
    198           {
    199             comment = entry.getComment().getBytes("8859_1");
    200             bytes += put2 (comment.length);
    201           }
    202 
    203         // Disk number start.
    204         bytes += put2 (0);
    205         // Internal file attributes.
    206         bytes += put2 (0);
    207         // External file attributes.
    208         bytes += put4 (0);
    209         // Relative offset of local header.
    210         bytes += put4 ((int) entry.relativeOffset);
    211       }
    212 
    213     out.write (name);
    214     bytes += name.length;
    215     if (entry.extra != null)
    216       {
    217         out.write(entry.extra);
    218         bytes += entry.extra.length;
    219       }
    220     if (comment != null)
    221       {
     223        writeLeInt(0);
     224        writeLeInt(0);
     225        writeLeInt(0);
     226      }
     227    byte[] name = entry.getName().getBytes();
     228    if (name.length > 0xffff)
     229      throw new ZipException("Name too long.");
     230    byte[] extra = entry.getExtra();
     231    if (extra == null)
     232      extra = new byte[0];
     233    writeLeShort(name.length);
     234    writeLeShort(extra.length);
     235    out.write(name);
     236    out.write(extra);
     237
     238    offset += LOCHDR + name.length + extra.length;
     239
     240    /* Activate the entry. */
     241
     242    curEntry = entry;
     243    crc.reset();
     244    if (method == DEFLATED)
     245      def.reset();
     246    size = 0;
     247  }
     248
     249  /**
     250   * Closes the current entry.
     251   * @exception IOException if an I/O error occured.
     252   * @exception ZipException if no entry is active.
     253   */
     254  public void closeEntry() throws IOException
     255  {
     256    if (curEntry == null)
     257      throw new ZipException("No open entry");
     258
     259    /* First finish the deflater, if appropriate */
     260    if (curMethod == DEFLATED)
     261      super.finish();
     262
     263    int csize = curMethod == DEFLATED ? def.getTotalOut() : size;
     264
     265    if (curEntry.getSize() < 0)
     266      curEntry.setSize(size);
     267    else if (curEntry.getSize() != size)
     268      throw new ZipException("size was "+size
     269                             +", but I expected "+curEntry.getSize());
     270
     271    if (curEntry.getCompressedSize() < 0)
     272      curEntry.setCompressedSize(csize);
     273    else if (curEntry.getCompressedSize() != csize)
     274      throw new ZipException("compressed size was "+csize
     275                             +", but I expected "+curEntry.getSize());
     276
     277    if (curEntry.getCrc() < 0)
     278      curEntry.setCrc(crc.getValue());
     279    else if (curEntry.getCrc() != crc.getValue())
     280      throw new ZipException("crc was " + Long.toHexString(crc.getValue())
     281                             + ", but I expected "
     282                             + Long.toHexString(curEntry.getCrc()));
     283
     284    offset += csize;
     285
     286    /* Now write the data descriptor entry if needed. */
     287    if (curMethod == DEFLATED && (curEntry.flags & 8) != 0)
     288      {
     289        writeLeInt(EXTSIG);
     290        writeLeInt((int)curEntry.getCrc());
     291        writeLeInt((int)curEntry.getCompressedSize());
     292        writeLeInt((int)curEntry.getSize());
     293        offset += EXTHDR;
     294      }
     295
     296    entries.addElement(curEntry);
     297    curEntry = null;
     298  }
     299
     300  /**
     301   * Writes the given buffer to the current entry.
     302   * @exception IOException if an I/O error occured.
     303   * @exception ZipException if no entry is active.
     304   */
     305  public void write(byte[] b, int off, int len) throws IOException
     306  {
     307    if (curEntry == null)
     308      throw new ZipException("No open entry.");
     309
     310    switch (curMethod)
     311      {
     312      case DEFLATED:
     313        super.write(b, off, len);
     314        break;
     315       
     316      case STORED:
     317        out.write(b, off, len);
     318        break;
     319      }
     320
     321    crc.update(b, off, len);
     322    size += len;
     323  }
     324
     325  /**
     326   * Finishes the stream.  This will write the central directory at the
     327   * end of the zip file and flush the stream.
     328   * @exception IOException if an I/O error occured.
     329   */
     330  public void finish() throws IOException
     331  {
     332    if (entries == null)
     333      return;
     334    if (curEntry != null)
     335      closeEntry();
     336
     337    int numEntries = 0;
     338    int sizeEntries = 0;
     339   
     340    Enumeration enum = entries.elements();
     341    while (enum.hasMoreElements())
     342      {
     343        ZipEntry entry = (ZipEntry) enum.nextElement();
     344       
     345        int method = entry.getMethod();
     346        writeLeInt(CENSIG);
     347        writeLeShort(method == STORED
     348                     ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
     349        writeLeShort(method == STORED
     350                     ? ZIP_STORED_VERSION : ZIP_DEFLATED_VERSION);
     351        writeLeShort(entry.flags);
     352        writeLeShort(method);
     353        writeLeInt(entry.getDOSTime());
     354        writeLeInt((int)entry.getCrc());
     355        writeLeInt((int)entry.getCompressedSize());
     356        writeLeInt((int)entry.getSize());
     357
     358        byte[] name = entry.getName().getBytes();
     359        if (name.length > 0xffff)
     360          throw new ZipException("Name too long.");
     361        byte[] extra = entry.getExtra();
     362        if (extra == null)
     363          extra = new byte[0];
     364        String strComment = entry.getComment();
     365        byte[] comment = strComment != null
     366          ? strComment.getBytes() : new byte[0];
     367        if (comment.length > 0xffff)
     368          throw new ZipException("Comment too long.");
     369
     370        writeLeShort(name.length);
     371        writeLeShort(extra.length);
     372        writeLeShort(comment.length);
     373        writeLeShort(0); /* disk number */
     374        writeLeShort(0); /* internal file attr */
     375        writeLeInt(0);   /* external file attr */
     376        writeLeInt(entry.offset);
     377
     378        out.write(name);
     379        out.write(extra);
    222380        out.write(comment);
    223         bytes += comment.length;
    224       }
    225 
    226     bytes_written += bytes;
    227     return bytes;
    228   }
    229 
    230   public void putNextEntry (ZipEntry entry) throws IOException
    231   {
    232     if (current != null)
    233       closeEntry ();
    234 
    235     if (entry.method < 0 )
    236       entry.method = method;
    237     if (entry.method == STORED)
    238       {
    239         if (entry.getSize() == -1 || entry.getCrc() == -1)
    240           throw new ZipException ("required entry not set");
    241         // Just in case.
    242         entry.compressedSize = entry.getSize();
    243       }
    244     entry.relativeOffset = bytes_written;
    245     write_entry (entry, true);
    246     current = entry;
    247     int compr = (method == STORED) ? Deflater.NO_COMPRESSION : level;
    248     def.reset();
    249     def.setLevel(compr);
    250     sum.reset();
    251     uncompressed_size = 0;
    252   }
    253 
    254   public void setLevel (int level)
    255   {
    256     if (level != Deflater.DEFAULT_COMPRESSION
    257         && (level < Deflater.NO_COMPRESSION
    258             || level > Deflater.BEST_COMPRESSION))
    259       throw new IllegalArgumentException ();
    260     this.level = level;
    261   }
    262 
    263   public void setMethod (int method)
    264   {
    265     if (method != DEFLATED && method != STORED)
    266       throw new IllegalArgumentException ();
    267     this.method = method;
    268   }
    269 
    270   public void setComment (String comment)
    271   {
    272     if (comment.length() > 65535)
    273       throw new IllegalArgumentException ();
    274     this.comment = comment;
    275   }
    276 
    277   public ZipOutputStream (OutputStream out)
    278   {
    279     super (out, new Deflater (Deflater.DEFAULT_COMPRESSION, true), 8192);
    280     sum = new CRC32 ();
    281   }
    282 
    283   private int put2 (int i) throws IOException
    284   {
    285     out.write (i);
    286     out.write (i >> 8);
    287     return 2;
    288   }
    289 
    290   private int put4 (int i) throws IOException
    291   {
    292     out.write (i);
    293     out.write (i >> 8);
    294     out.write (i >> 16);
    295     out.write (i >> 24);
    296     return 4;
    297   }
    298 
    299   private int put_version () throws IOException
    300   {
    301     // FIXME: for now we assume Unix, and we ignore the version
    302     // number.
    303     return put2 (3 << 8);
    304   }
    305 
    306   // The entry we are currently writing, or null if we've called
    307   // closeEntry.
    308   private ZipEntry current;
    309   // The chain of entries which have been written to this file.
    310   private ZipEntry chain;
    311 
    312   private int method = DEFLATED;
    313   private int level = Deflater.DEFAULT_COMPRESSION;
    314   private String comment = "";
    315   private long bytes_written;
    316 
    317   private int uncompressed_size;
    318 
    319   /** The checksum object. */
    320   private Checksum sum;
     381        numEntries++;
     382        sizeEntries += CENHDR + name.length + extra.length + comment.length;
     383      }
     384
     385    writeLeInt(ENDSIG);
     386    writeLeShort(0); /* disk number */
     387    writeLeShort(0); /* disk with start of central dir */
     388    writeLeShort(numEntries);
     389    writeLeShort(numEntries);
     390    writeLeInt(sizeEntries);
     391    writeLeInt(offset);
     392    writeLeShort(zipComment.length);
     393    out.write(zipComment);
     394    out.flush();
     395    entries = null;
     396  }
    321397}
Note: See TracChangeset for help on using the changeset viewer.