Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / java / util / zip / ZipInputStream.java
blob4539828c2b0cc99593f77f9702508eb5d293fa6f
1 /* ZipInputStream.java --
2 Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.util.zip;
41 import java.io.EOFException;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.io.UnsupportedEncodingException;
46 /**
47 * This is a FilterInputStream that reads the files in an zip archive
48 * one after another. It has a special method to get the zip entry of
49 * the next file. The zip entry contains information about the file name
50 * size, compressed size, CRC, etc.
52 * It includes support for STORED and DEFLATED entries.
54 * @author Jochen Hoenicke
56 public class ZipInputStream extends InflaterInputStream implements ZipConstants
58 private CRC32 crc = new CRC32();
59 private ZipEntry entry = null;
61 private int csize;
62 private int size;
63 private int method;
64 private int flags;
65 private int avail;
66 private boolean entryAtEOF;
68 /**
69 * Creates a new Zip input stream, reading a zip archive.
71 public ZipInputStream(InputStream in)
73 super(in, new Inflater(true));
76 private void fillBuf() throws IOException
78 avail = len = in.read(buf, 0, buf.length);
81 private int readBuf(byte[] out, int offset, int length) throws IOException
83 if (avail <= 0)
85 fillBuf();
86 if (avail <= 0)
87 return -1;
89 if (length > avail)
90 length = avail;
91 System.arraycopy(buf, len - avail, out, offset, length);
92 avail -= length;
93 return length;
96 private void readFully(byte[] out) throws IOException
98 int off = 0;
99 int len = out.length;
100 while (len > 0)
102 int count = readBuf(out, off, len);
103 if (count == -1)
104 throw new EOFException();
105 off += count;
106 len -= count;
110 private int readLeByte() throws IOException
112 if (avail <= 0)
114 fillBuf();
115 if (avail <= 0)
116 throw new ZipException("EOF in header");
118 return buf[len - avail--] & 0xff;
122 * Read an unsigned short in little endian byte order.
124 private int readLeShort() throws IOException
126 return readLeByte() | (readLeByte() << 8);
130 * Read an int in little endian byte order.
132 private int readLeInt() throws IOException
134 return readLeShort() | (readLeShort() << 16);
138 * Open the next entry from the zip archive, and return its description.
139 * If the previous entry wasn't closed, this method will close it.
141 public ZipEntry getNextEntry() throws IOException
143 if (crc == null)
144 throw new IOException("Stream closed.");
145 if (entry != null)
146 closeEntry();
148 int header = readLeInt();
149 if (header == CENSIG)
151 /* Central Header reached. */
152 close();
153 return null;
155 if (header != LOCSIG)
156 throw new ZipException("Wrong Local header signature: "
157 + Integer.toHexString(header));
158 /* skip version */
159 readLeShort();
160 flags = readLeShort();
161 method = readLeShort();
162 int dostime = readLeInt();
163 int crc = readLeInt();
164 csize = readLeInt();
165 size = readLeInt();
166 int nameLen = readLeShort();
167 int extraLen = readLeShort();
169 if (method == ZipOutputStream.STORED && csize != size)
170 throw new ZipException("Stored, but compressed != uncompressed");
173 byte[] buffer = new byte[nameLen];
174 readFully(buffer);
175 String name;
178 name = new String(buffer, "UTF-8");
180 catch (UnsupportedEncodingException uee)
182 throw new AssertionError(uee);
185 entry = createZipEntry(name);
186 entryAtEOF = false;
187 entry.setMethod(method);
188 if ((flags & 8) == 0)
190 entry.setCrc(crc & 0xffffffffL);
191 entry.setSize(size & 0xffffffffL);
192 entry.setCompressedSize(csize & 0xffffffffL);
194 entry.setDOSTime(dostime);
195 if (extraLen > 0)
197 byte[] extra = new byte[extraLen];
198 readFully(extra);
199 entry.setExtra(extra);
202 if (method == ZipOutputStream.DEFLATED && avail > 0)
204 System.arraycopy(buf, len - avail, buf, 0, avail);
205 len = avail;
206 avail = 0;
207 inf.setInput(buf, 0, len);
209 return entry;
212 private void readDataDescr() throws IOException
214 if (readLeInt() != EXTSIG)
215 throw new ZipException("Data descriptor signature not found");
216 entry.setCrc(readLeInt() & 0xffffffffL);
217 csize = readLeInt();
218 size = readLeInt();
219 entry.setSize(size & 0xffffffffL);
220 entry.setCompressedSize(csize & 0xffffffffL);
224 * Closes the current zip entry and moves to the next one.
226 public void closeEntry() throws IOException
228 if (crc == null)
229 throw new IOException("Stream closed.");
230 if (entry == null)
231 return;
233 if (method == ZipOutputStream.DEFLATED)
235 if ((flags & 8) != 0)
237 /* We don't know how much we must skip, read until end. */
238 byte[] tmp = new byte[2048];
239 while (read(tmp) > 0)
241 /* read will close this entry */
242 return;
244 csize -= inf.getTotalIn();
245 avail = inf.getRemaining();
248 if (avail > csize && csize >= 0)
249 avail -= csize;
250 else
252 csize -= avail;
253 avail = 0;
254 while (csize != 0)
256 long skipped = in.skip(csize & 0xffffffffL);
257 if (skipped <= 0)
258 throw new ZipException("zip archive ends early.");
259 csize -= skipped;
263 size = 0;
264 crc.reset();
265 if (method == ZipOutputStream.DEFLATED)
266 inf.reset();
267 entry = null;
268 entryAtEOF = true;
271 public int available() throws IOException
273 return entryAtEOF ? 0 : 1;
277 * Reads a byte from the current zip entry.
278 * @return the byte or -1 on EOF.
279 * @exception IOException if a i/o error occured.
280 * @exception ZipException if the deflated stream is corrupted.
282 public int read() throws IOException
284 byte[] b = new byte[1];
285 if (read(b, 0, 1) <= 0)
286 return -1;
287 return b[0] & 0xff;
291 * Reads a block of bytes from the current zip entry.
292 * @return the number of bytes read (may be smaller, even before
293 * EOF), or -1 on EOF.
294 * @exception IOException if a i/o error occured.
295 * @exception ZipException if the deflated stream is corrupted.
297 public int read(byte[] b, int off, int len) throws IOException
299 if (len == 0)
300 return 0;
301 if (crc == null)
302 throw new IOException("Stream closed.");
303 if (entry == null)
304 return -1;
305 boolean finished = false;
306 switch (method)
308 case ZipOutputStream.DEFLATED:
309 len = super.read(b, off, len);
310 if (len < 0)
312 if (!inf.finished())
313 throw new ZipException("Inflater not finished!?");
314 avail = inf.getRemaining();
315 if ((flags & 8) != 0)
316 readDataDescr();
318 if (inf.getTotalIn() != csize
319 || inf.getTotalOut() != size)
320 throw new ZipException("size mismatch: "+csize+";"+size+" <-> "+inf.getTotalIn()+";"+inf.getTotalOut());
321 inf.reset();
322 finished = true;
324 break;
326 case ZipOutputStream.STORED:
328 if (len > csize && csize >= 0)
329 len = csize;
331 len = readBuf(b, off, len);
332 if (len > 0)
334 csize -= len;
335 size -= len;
338 if (csize == 0)
339 finished = true;
340 else if (len < 0)
341 throw new ZipException("EOF in stored block");
342 break;
345 if (len > 0)
346 crc.update(b, off, len);
348 if (finished)
350 if ((crc.getValue() & 0xffffffffL) != entry.getCrc())
351 throw new ZipException("CRC mismatch");
352 crc.reset();
353 entry = null;
354 entryAtEOF = true;
356 return len;
360 * Closes the zip file.
361 * @exception IOException if a i/o error occured.
363 public void close() throws IOException
365 super.close();
366 crc = null;
367 entry = null;
368 entryAtEOF = true;
372 * Creates a new zip entry for the given name. This is equivalent
373 * to new ZipEntry(name).
374 * @param name the name of the zip entry.
376 protected ZipEntry createZipEntry(String name)
378 return new ZipEntry(name);