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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [util/] [zip/] [ZipInputStream.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* 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
 
242
            /* read will close this entry */
243
            return;
244
          }
245
        csize -= inf.getTotalIn();
246
        avail = inf.getRemaining();
247
      }
248
 
249
    if (avail > csize && csize >= 0)
250
      avail -= csize;
251
    else
252
      {
253
        csize -= avail;
254
        avail = 0;
255
        while (csize != 0)
256
          {
257
            long skipped = in.skip(csize & 0xffffffffL);
258
            if (skipped <= 0)
259
              throw new ZipException("zip archive ends early.");
260
            csize -= skipped;
261
          }
262
      }
263
 
264
    size = 0;
265
    crc.reset();
266
    if (method == ZipOutputStream.DEFLATED)
267
      inf.reset();
268
    entry = null;
269
    entryAtEOF = true;
270
  }
271
 
272
  public int available() throws IOException
273
  {
274
    return entryAtEOF ? 0 : 1;
275
  }
276
 
277
  /**
278
   * Reads a byte from the current zip entry.
279
   * @return the byte or -1 on EOF.
280
   * @exception IOException if a i/o error occured.
281
   * @exception ZipException if the deflated stream is corrupted.
282
   */
283
  public int read() throws IOException
284
  {
285
    byte[] b = new byte[1];
286
    if (read(b, 0, 1) <= 0)
287
      return -1;
288
    return b[0] & 0xff;
289
  }
290
 
291
  /**
292
   * Reads a block of bytes from the current zip entry.
293
   * @return the number of bytes read (may be smaller, even before
294
   * EOF), or -1 on EOF.
295
   * @exception IOException if a i/o error occured.
296
   * @exception ZipException if the deflated stream is corrupted.
297
   */
298
  public int read(byte[] b, int off, int len) throws IOException
299
  {
300
    if (len == 0)
301
      return 0;
302
    if (crc == null)
303
      throw new IOException("Stream closed.");
304
    if (entry == null)
305
      return -1;
306
    boolean finished = false;
307
    switch (method)
308
      {
309
      case ZipOutputStream.DEFLATED:
310
        len = super.read(b, off, len);
311
        if (len < 0)
312
          {
313
            if (!inf.finished())
314
              throw new ZipException("Inflater not finished!?");
315
            avail = inf.getRemaining();
316
            if ((flags & 8) != 0)
317
              readDataDescr();
318
 
319
            if (inf.getTotalIn() != csize
320
                || inf.getTotalOut() != size)
321
              throw new ZipException("size mismatch: "+csize+";"+size+" <-> "+inf.getTotalIn()+";"+inf.getTotalOut());
322
            inf.reset();
323
            finished = true;
324
          }
325
        break;
326
 
327
      case ZipOutputStream.STORED:
328
 
329
        if (len > csize && csize >= 0)
330
          len = csize;
331
 
332
        len = readBuf(b, off, len);
333
        if (len > 0)
334
          {
335
            csize -= len;
336
            size -= len;
337
          }
338
 
339
        if (csize == 0)
340
          finished = true;
341
        else if (len < 0)
342
          throw new ZipException("EOF in stored block");
343
        break;
344
      }
345
 
346
    if (len > 0)
347
      crc.update(b, off, len);
348
 
349
    if (finished)
350
      {
351
        if ((crc.getValue() & 0xffffffffL) != entry.getCrc())
352
          throw new ZipException("CRC mismatch");
353
        crc.reset();
354
        entry = null;
355
        entryAtEOF = true;
356
      }
357
    return len;
358
  }
359
 
360
  /**
361
   * Closes the zip file.
362
   * @exception IOException if a i/o error occured.
363
   */
364
  public void close() throws IOException
365
  {
366
    super.close();
367
    crc = null;
368
    entry = null;
369
    entryAtEOF = true;
370
  }
371
 
372
  /**
373
   * Creates a new zip entry for the given name.  This is equivalent
374
   * to new ZipEntry(name).
375
   * @param name the name of the zip entry.
376
   */
377
  protected ZipEntry createZipEntry(String name)
378
  {
379
    return new ZipEntry(name);
380
  }
381
}

powered by: WebSVN 2.1.0

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