OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [util/] [zip/] [ZipInputStream.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* ZipInputStream.java --
2
   Copyright (C) 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
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.
10
 
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.
15
 
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.
20
 
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.
25
 
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. */
37
 
38
 
39
package java.util.zip;
40
 
41
import java.io.EOFException;
42
import java.io.IOException;
43
import java.io.InputStream;
44
import java.io.UnsupportedEncodingException;
45
 
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.
51
 *
52
 * It includes support for STORED and DEFLATED entries.
53
 *
54
 * @author Jochen Hoenicke
55
 */
56
public class ZipInputStream extends InflaterInputStream implements ZipConstants
57
{
58
  private CRC32 crc = new CRC32();
59
  private ZipEntry entry = null;
60
 
61
  private int csize;
62
  private int size;
63
  private int method;
64
  private int flags;
65
  private int avail;
66
  private boolean entryAtEOF;
67
 
68
  /**
69
   * Creates a new Zip input stream, reading a zip archive.
70
   */
71
  public ZipInputStream(InputStream in)
72
  {
73
    super(in, new Inflater(true));
74
  }
75
 
76
  private void fillBuf() throws IOException
77
  {
78
    avail = len = in.read(buf, 0, buf.length);
79
  }
80
 
81
  private int readBuf(byte[] out, int offset, int length) throws IOException
82
  {
83
    if (avail <= 0)
84
      {
85
        fillBuf();
86
        if (avail <= 0)
87
          return -1;
88
      }
89
    if (length > avail)
90
      length = avail;
91
    System.arraycopy(buf, len - avail, out, offset, length);
92
    avail -= length;
93
    return length;
94
  }
95
 
96
  private void readFully(byte[] out) throws IOException
97
  {
98
    int off = 0;
99
    int len = out.length;
100
    while (len > 0)
101
      {
102
        int count = readBuf(out, off, len);
103
        if (count == -1)
104
          throw new EOFException();
105
        off += count;
106
        len -= count;
107
      }
108
  }
109
 
110
  private int readLeByte() throws IOException
111
  {
112
    if (avail <= 0)
113
      {
114
        fillBuf();
115
        if (avail <= 0)
116
          throw new ZipException("EOF in header");
117
      }
118
    return buf[len - avail--] & 0xff;
119
  }
120
 
121
  /**
122
   * Read an unsigned short in little endian byte order.
123
   */
124
  private int readLeShort() throws IOException
125
  {
126
    return readLeByte() | (readLeByte() << 8);
127
  }
128
 
129
  /**
130
   * Read an int in little endian byte order.
131
   */
132
  private int readLeInt() throws IOException
133
  {
134
    return readLeShort() | (readLeShort() << 16);
135
  }
136
 
137
  /**
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.
140
   */
141
  public ZipEntry getNextEntry() throws IOException
142
  {
143
    if (crc == null)
144
      throw new IOException("Stream closed.");
145
    if (entry != null)
146
      closeEntry();
147
 
148
    int header = readLeInt();
149
    if (header == CENSIG)
150
      {
151
        /* Central Header reached. */
152
        close();
153
        return null;
154
      }
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();
168
 
169
    if (method == ZipOutputStream.STORED && csize != size)
170
      throw new ZipException("Stored, but compressed != uncompressed");
171
 
172
 
173
    byte[] buffer = new byte[nameLen];
174
    readFully(buffer);
175
    String name;
176
    try
177
      {
178
        name = new String(buffer, "UTF-8");
179
      }
180
    catch (UnsupportedEncodingException uee)
181
      {
182
        throw new AssertionError(uee);
183
      }
184
 
185
    entry = createZipEntry(name);
186
    entryAtEOF = false;
187
    entry.setMethod(method);
188
    if ((flags & 8) == 0)
189
      {
190
        entry.setCrc(crc & 0xffffffffL);
191
        entry.setSize(size & 0xffffffffL);
192
        entry.setCompressedSize(csize & 0xffffffffL);
193
      }
194
    entry.setDOSTime(dostime);
195
    if (extraLen > 0)
196
      {
197
        byte[] extra = new byte[extraLen];
198
        readFully(extra);
199
        entry.setExtra(extra);
200
      }
201
 
202
    if (method == ZipOutputStream.DEFLATED && avail > 0)
203
      {
204
        System.arraycopy(buf, len - avail, buf, 0, avail);
205
        len = avail;
206
        avail = 0;
207
        inf.setInput(buf, 0, len);
208
      }
209
    return entry;
210
  }
211
 
212
  private void readDataDescr() throws IOException
213
  {
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);
221
  }
222
 
223
  /**
224
   * Closes the current zip entry and moves to the next one.
225
   */
226
  public void closeEntry() throws IOException
227
  {
228
    if (crc == null)
229
      throw new IOException("Stream closed.");
230
    if (entry == null)
231
      return;
232
 
233
    if (method == ZipOutputStream.DEFLATED)
234
      {
235
        if ((flags & 8) != 0)
236
          {
237
            /* We don't know how much we must skip, read until end. */
238
            byte[] tmp = new byte[2048];
239
            while (read(tmp) > 0)
240
              ;
241
            /* read will close this entry */
242
            return;
243
          }
244
        csize -= inf.getTotalIn();
245
        avail = inf.getRemaining();
246
      }
247
 
248
    if (avail > csize && csize >= 0)
249
      avail -= csize;
250
    else
251
      {
252
        csize -= avail;
253
        avail = 0;
254
        while (csize != 0)
255
          {
256
            long skipped = in.skip(csize & 0xffffffffL);
257
            if (skipped <= 0)
258
              throw new ZipException("zip archive ends early.");
259
            csize -= skipped;
260
          }
261
      }
262
 
263
    size = 0;
264
    crc.reset();
265
    if (method == ZipOutputStream.DEFLATED)
266
      inf.reset();
267
    entry = null;
268
    entryAtEOF = true;
269
  }
270
 
271
  public int available() throws IOException
272
  {
273
    return entryAtEOF ? 0 : 1;
274
  }
275
 
276
  /**
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.
281
   */
282
  public int read() throws IOException
283
  {
284
    byte[] b = new byte[1];
285
    if (read(b, 0, 1) <= 0)
286
      return -1;
287
    return b[0] & 0xff;
288
  }
289
 
290
  /**
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.
296
   */
297
  public int read(byte[] b, int off, int len) throws IOException
298
  {
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)
307
      {
308
      case ZipOutputStream.DEFLATED:
309
        len = super.read(b, off, len);
310
        if (len < 0)
311
          {
312
            if (!inf.finished())
313
              throw new ZipException("Inflater not finished!?");
314
            avail = inf.getRemaining();
315
            if ((flags & 8) != 0)
316
              readDataDescr();
317
 
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;
323
          }
324
        break;
325
 
326
      case ZipOutputStream.STORED:
327
 
328
        if (len > csize && csize >= 0)
329
          len = csize;
330
 
331
        len = readBuf(b, off, len);
332
        if (len > 0)
333
          {
334
            csize -= len;
335
            size -= len;
336
          }
337
 
338
        if (csize == 0)
339
          finished = true;
340
        else if (len < 0)
341
          throw new ZipException("EOF in stored block");
342
        break;
343
      }
344
 
345
    if (len > 0)
346
      crc.update(b, off, len);
347
 
348
    if (finished)
349
      {
350
        if ((crc.getValue() & 0xffffffffL) != entry.getCrc())
351
          throw new ZipException("CRC mismatch");
352
        crc.reset();
353
        entry = null;
354
        entryAtEOF = true;
355
      }
356
    return len;
357
  }
358
 
359
  /**
360
   * Closes the zip file.
361
   * @exception IOException if a i/o error occured.
362
   */
363
  public void close() throws IOException
364
  {
365
    super.close();
366
    crc = null;
367
    entry = null;
368
    entryAtEOF = true;
369
  }
370
 
371
  /**
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.
375
   */
376
  protected ZipEntry createZipEntry(String name)
377
  {
378
    return new ZipEntry(name);
379
  }
380
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.