*** empty log message ***
From-SVN: r26796
This commit is contained in:
parent
0ec3c5478a
commit
bb27e3881a
1 changed files with 190 additions and 0 deletions
190
libjava/java/util/zip/ZipInputStream.java
Normal file
190
libjava/java/util/zip/ZipInputStream.java
Normal file
|
@ -0,0 +1,190 @@
|
|||
/* Copyright (C) 1999 Cygnus Solutions
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
This software is copyrighted work licensed under the terms of the
|
||||
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
|
||||
details. */
|
||||
|
||||
package java.util.zip;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* @author Per Bothner
|
||||
* @date May 1999.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Written using on-line Java Platform 1.2 API Specification, as well
|
||||
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
|
||||
* Status: Quite incomplete, but can read uncompressed .zip archives.
|
||||
*/
|
||||
|
||||
// JDK1.2 has "protected ZipEntry createZipEntry(String)" but is very
|
||||
// vague about what the method does. FIXME.
|
||||
// We do not calculate the CRC and compare it with the specified value;
|
||||
// we probably should. FIXME.
|
||||
|
||||
|
||||
public class ZipInputStream extends InflaterInputStream
|
||||
{
|
||||
ZipEntry current;
|
||||
int current_flags;
|
||||
int avail;
|
||||
|
||||
public ZipInputStream (InputStream in)
|
||||
{
|
||||
super(in);
|
||||
}
|
||||
|
||||
public ZipEntry getNextEntry () throws IOException
|
||||
{
|
||||
if (current != null)
|
||||
closeZipEntry();
|
||||
if (in.read() != 'P'
|
||||
|| in.read() != 'K')
|
||||
return null;
|
||||
int code = in.read();
|
||||
while (code == '\001')
|
||||
{
|
||||
code = in.read();
|
||||
if (code != '\002')
|
||||
return null;
|
||||
in.skip(16);
|
||||
int size = read4();
|
||||
in.skip(4);
|
||||
int fname_length = readu2();
|
||||
int extra_length = readu2();
|
||||
int fcomment_length = readu2();
|
||||
in.skip(12+fname_length+extra_length+fcomment_length+size);
|
||||
if (in.read() != 'P' || in.read() != 'K')
|
||||
return null;
|
||||
code = in.read();
|
||||
}
|
||||
if (code == '\005')
|
||||
{
|
||||
if (in.read() != '\006')
|
||||
return null;
|
||||
in.skip(16);
|
||||
int comment_size = readu2();
|
||||
in.skip(comment_size);
|
||||
if (in.read() != 'P' || in.read() != 'K')
|
||||
return null;
|
||||
code = in.read();
|
||||
}
|
||||
if (code != '\003'
|
||||
|| in.read() != '\004')
|
||||
return null;
|
||||
int ex_version = readu2();
|
||||
current_flags = readu2();
|
||||
int method = readu2();
|
||||
int modtime = readu2();
|
||||
int moddate = readu2();
|
||||
int crc = read4();
|
||||
int compressedSize = read4();
|
||||
int uncompressedSize = read4();
|
||||
int filenameLength = readu2();
|
||||
int extraLength = readu2();
|
||||
byte[] bname = new byte[filenameLength];
|
||||
readFully(bname);
|
||||
ZipEntry entry = new ZipEntry(new String(bname, "8859_1"));
|
||||
if (extraLength > 0)
|
||||
{
|
||||
byte[] bextra = new byte[extraLength];
|
||||
readFully(bextra);
|
||||
entry.extra = bextra;
|
||||
}
|
||||
entry.compressedSize = compressedSize;
|
||||
entry.size = uncompressedSize;
|
||||
entry.crc = (long) crc & 0xffffffffL;
|
||||
entry.method = method;
|
||||
entry.time = ZipEntry.timeFromDOS(moddate, modtime);
|
||||
current = entry;
|
||||
avail = uncompressedSize;
|
||||
return entry;
|
||||
}
|
||||
|
||||
public int read (byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
if (len > avail)
|
||||
len = avail;
|
||||
int count = super.read(b, off, len);
|
||||
if (count > 0)
|
||||
avail -= count;
|
||||
return count;
|
||||
}
|
||||
|
||||
public long skip (long n) throws IOException
|
||||
{
|
||||
if (n > avail)
|
||||
n = avail;
|
||||
long count = super.skip(n);
|
||||
avail = avail - (int) count;
|
||||
return count;
|
||||
}
|
||||
|
||||
private void readFully (byte[] b) throws IOException
|
||||
{
|
||||
int off = 0;
|
||||
int len = b.length;
|
||||
while (len > 0)
|
||||
{
|
||||
int count = in.read(b, off, len);
|
||||
if (count <= 0)
|
||||
throw new EOFException(".zip archive ended prematurely");
|
||||
off += count;
|
||||
len -= count;
|
||||
}
|
||||
}
|
||||
|
||||
private int readu2 () throws IOException
|
||||
{
|
||||
int byte0 = in.read();
|
||||
int byte1 = in.read();
|
||||
if (byte0 < 0 || byte1 < 0)
|
||||
throw new EOFException(".zip archive ended prematurely");
|
||||
return ((byte1 & 0xFF) << 8) | (byte0 & 0xFF);
|
||||
}
|
||||
|
||||
private int read4 () throws IOException
|
||||
{
|
||||
int byte0 = in.read();
|
||||
int byte1 = in.read();
|
||||
int byte2 = in.read();
|
||||
int byte3 = in.read();
|
||||
if (byte3 < 0)
|
||||
throw new EOFException(".zip archive ended prematurely");
|
||||
return ((byte3 & 0xFF) << 24) + ((byte2 & 0xFF) << 16)
|
||||
+ ((byte1 & 0xFF) << 8) + (byte0 & 0xFF);
|
||||
}
|
||||
|
||||
public void closeZipEntry () throws IOException
|
||||
{
|
||||
if (current != null)
|
||||
{
|
||||
if (avail > 0)
|
||||
skip (avail);
|
||||
if ((current_flags & 8) != 0)
|
||||
{
|
||||
int sig = read4();
|
||||
if (sig != 0x04034b50)
|
||||
throw new IOException("bad/missing magic number at end of .zip entry");
|
||||
int crc = read4();
|
||||
int compressedSize = read4();
|
||||
int uncompressedSize = read4();
|
||||
if (current.compressedSize != compressedSize
|
||||
|| current.size != uncompressedSize
|
||||
|| current.crc != crc)
|
||||
throw new IOException("bad data descriptor at end of .zip entry");
|
||||
}
|
||||
current = null;
|
||||
avail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void close () throws IOException
|
||||
{
|
||||
current = null;
|
||||
super.close();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue