Imported GNU Classpath 0.90
Imported GNU Classpath 0.90 * scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore. * gnu/classpath/jdwp/VMFrame.java (SIZE): New constant. * java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5. * java/lang/Math.java: New override file. * java/lang/Character.java: Merged from Classpath. (start, end): Now 'int's. (canonicalName): New field. (CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants. (UnicodeBlock): Added argument. (of): New overload. (forName): New method. Updated unicode blocks. (sets): Updated. * sources.am: Regenerated. * Makefile.in: Likewise. From-SVN: r111942
This commit is contained in:
parent
27079765d0
commit
8aa540d2f7
1367 changed files with 188789 additions and 22762 deletions
|
@ -1,5 +1,5 @@
|
|||
/* ZipFile.java --
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
@ -41,8 +41,6 @@ package java.util.zip;
|
|||
|
||||
import gnu.java.util.EmptyEnumeration;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -141,23 +139,33 @@ public class ZipFile implements ZipConstants
|
|||
checkZipFile();
|
||||
}
|
||||
|
||||
private void checkZipFile() throws IOException, ZipException
|
||||
private void checkZipFile() throws ZipException
|
||||
{
|
||||
byte[] magicBuf = new byte[4];
|
||||
boolean validRead = true;
|
||||
boolean valid = false;
|
||||
|
||||
try
|
||||
{
|
||||
raf.readFully(magicBuf);
|
||||
}
|
||||
catch (EOFException eof)
|
||||
byte[] buf = new byte[4];
|
||||
raf.readFully(buf);
|
||||
int sig = buf[0] & 0xFF
|
||||
| ((buf[1] & 0xFF) << 8)
|
||||
| ((buf[2] & 0xFF) << 16)
|
||||
| ((buf[3] & 0xFF) << 24);
|
||||
valid = sig == LOCSIG;
|
||||
}
|
||||
catch (IOException _)
|
||||
{
|
||||
validRead = false;
|
||||
}
|
||||
|
||||
if (validRead == false || readLeInt(magicBuf, 0) != LOCSIG)
|
||||
if (!valid)
|
||||
{
|
||||
raf.close();
|
||||
try
|
||||
{
|
||||
raf.close();
|
||||
}
|
||||
catch (IOException _)
|
||||
{
|
||||
}
|
||||
throw new ZipException("Not a valid zip file");
|
||||
}
|
||||
}
|
||||
|
@ -171,69 +179,6 @@ public class ZipFile implements ZipConstants
|
|||
throw new IllegalStateException("ZipFile has closed: " + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an unsigned short in little endian byte order from the given
|
||||
* DataInput stream using the given byte buffer.
|
||||
*
|
||||
* @param di DataInput stream to read from.
|
||||
* @param b the byte buffer to read in (must be at least 2 bytes long).
|
||||
* @return The value read.
|
||||
*
|
||||
* @exception IOException if a i/o error occured.
|
||||
* @exception EOFException if the file ends prematurely
|
||||
*/
|
||||
private int readLeShort(DataInput di, byte[] b) throws IOException
|
||||
{
|
||||
di.readFully(b, 0, 2);
|
||||
return (b[0] & 0xff) | (b[1] & 0xff) << 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an int in little endian byte order from the given
|
||||
* DataInput stream using the given byte buffer.
|
||||
*
|
||||
* @param di DataInput stream to read from.
|
||||
* @param b the byte buffer to read in (must be at least 4 bytes long).
|
||||
* @return The value read.
|
||||
*
|
||||
* @exception IOException if a i/o error occured.
|
||||
* @exception EOFException if the file ends prematurely
|
||||
*/
|
||||
private int readLeInt(DataInput di, byte[] b) throws IOException
|
||||
{
|
||||
di.readFully(b, 0, 4);
|
||||
return ((b[0] & 0xff) | (b[1] & 0xff) << 8)
|
||||
| ((b[2] & 0xff) | (b[3] & 0xff) << 8) << 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an unsigned short in little endian byte order from the given
|
||||
* byte buffer at the given offset.
|
||||
*
|
||||
* @param b the byte array to read from.
|
||||
* @param off the offset to read from.
|
||||
* @return The value read.
|
||||
*/
|
||||
private int readLeShort(byte[] b, int off)
|
||||
{
|
||||
return (b[off] & 0xff) | (b[off+1] & 0xff) << 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an int in little endian byte order from the given
|
||||
* byte buffer at the given offset.
|
||||
*
|
||||
* @param b the byte array to read from.
|
||||
* @param off the offset to read from.
|
||||
* @return The value read.
|
||||
*/
|
||||
private int readLeInt(byte[] b, int off)
|
||||
{
|
||||
return ((b[off] & 0xff) | (b[off+1] & 0xff) << 8)
|
||||
| ((b[off+2] & 0xff) | (b[off+3] & 0xff) << 8) << 16;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read the central directory of a zip file and fill the entries
|
||||
* array. This is called exactly once when first needed. It is called
|
||||
|
@ -246,63 +191,48 @@ public class ZipFile implements ZipConstants
|
|||
{
|
||||
/* Search for the End Of Central Directory. When a zip comment is
|
||||
* present the directory may start earlier.
|
||||
* FIXME: This searches the whole file in a very slow manner if the
|
||||
* file isn't a zip file.
|
||||
* Note that a comment has a maximum length of 64K, so that is the
|
||||
* maximum we search backwards.
|
||||
*/
|
||||
PartialInputStream inp = new PartialInputStream(raf, 4096);
|
||||
long pos = raf.length() - ENDHDR;
|
||||
byte[] ebs = new byte[CENHDR];
|
||||
|
||||
long top = Math.max(0, pos - 65536);
|
||||
do
|
||||
{
|
||||
if (pos < 0)
|
||||
if (pos < top)
|
||||
throw new ZipException
|
||||
("central directory not found, probably not a zip file: " + name);
|
||||
raf.seek(pos--);
|
||||
inp.seek(pos--);
|
||||
}
|
||||
while (readLeInt(raf, ebs) != ENDSIG);
|
||||
while (inp.readLeInt() != ENDSIG);
|
||||
|
||||
if (raf.skipBytes(ENDTOT - ENDNRD) != ENDTOT - ENDNRD)
|
||||
if (inp.skip(ENDTOT - ENDNRD) != ENDTOT - ENDNRD)
|
||||
throw new EOFException(name);
|
||||
int count = readLeShort(raf, ebs);
|
||||
if (raf.skipBytes(ENDOFF - ENDSIZ) != ENDOFF - ENDSIZ)
|
||||
int count = inp.readLeShort();
|
||||
if (inp.skip(ENDOFF - ENDSIZ) != ENDOFF - ENDSIZ)
|
||||
throw new EOFException(name);
|
||||
int centralOffset = readLeInt(raf, ebs);
|
||||
int centralOffset = inp.readLeInt();
|
||||
|
||||
entries = new HashMap(count+count/2);
|
||||
raf.seek(centralOffset);
|
||||
inp.seek(centralOffset);
|
||||
|
||||
byte[] buffer = new byte[16];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
raf.readFully(ebs);
|
||||
if (readLeInt(ebs, 0) != CENSIG)
|
||||
if (inp.readLeInt() != CENSIG)
|
||||
throw new ZipException("Wrong Central Directory signature: " + name);
|
||||
|
||||
int method = readLeShort(ebs, CENHOW);
|
||||
int dostime = readLeInt(ebs, CENTIM);
|
||||
int crc = readLeInt(ebs, CENCRC);
|
||||
int csize = readLeInt(ebs, CENSIZ);
|
||||
int size = readLeInt(ebs, CENLEN);
|
||||
int nameLen = readLeShort(ebs, CENNAM);
|
||||
int extraLen = readLeShort(ebs, CENEXT);
|
||||
int commentLen = readLeShort(ebs, CENCOM);
|
||||
|
||||
int offset = readLeInt(ebs, CENOFF);
|
||||
|
||||
int needBuffer = Math.max(nameLen, commentLen);
|
||||
if (buffer.length < needBuffer)
|
||||
buffer = new byte[needBuffer];
|
||||
|
||||
raf.readFully(buffer, 0, nameLen);
|
||||
String name;
|
||||
try
|
||||
{
|
||||
name = new String(buffer, 0, nameLen, "UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException uee)
|
||||
{
|
||||
throw new AssertionError(uee);
|
||||
}
|
||||
inp.skip(6);
|
||||
int method = inp.readLeShort();
|
||||
int dostime = inp.readLeInt();
|
||||
int crc = inp.readLeInt();
|
||||
int csize = inp.readLeInt();
|
||||
int size = inp.readLeInt();
|
||||
int nameLen = inp.readLeShort();
|
||||
int extraLen = inp.readLeShort();
|
||||
int commentLen = inp.readLeShort();
|
||||
inp.skip(8);
|
||||
int offset = inp.readLeInt();
|
||||
String name = inp.readString(nameLen);
|
||||
|
||||
ZipEntry entry = new ZipEntry(name);
|
||||
entry.setMethod(method);
|
||||
|
@ -313,20 +243,12 @@ public class ZipFile implements ZipConstants
|
|||
if (extraLen > 0)
|
||||
{
|
||||
byte[] extra = new byte[extraLen];
|
||||
raf.readFully(extra);
|
||||
inp.readFully(extra);
|
||||
entry.setExtra(extra);
|
||||
}
|
||||
if (commentLen > 0)
|
||||
{
|
||||
raf.readFully(buffer, 0, commentLen);
|
||||
try
|
||||
{
|
||||
entry.setComment(new String(buffer, 0, commentLen, "UTF-8"));
|
||||
}
|
||||
catch (UnsupportedEncodingException uee)
|
||||
{
|
||||
throw new AssertionError(uee);
|
||||
}
|
||||
entry.setComment(inp.readString(commentLen));
|
||||
}
|
||||
entry.offset = offset;
|
||||
entries.put(name, entry);
|
||||
|
@ -429,42 +351,6 @@ public class ZipFile implements ZipConstants
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//access should be protected by synchronized(raf)
|
||||
private byte[] locBuf = new byte[LOCHDR];
|
||||
|
||||
/**
|
||||
* Checks, if the local header of the entry at index i matches the
|
||||
* central directory, and returns the offset to the data.
|
||||
*
|
||||
* @param entry to check.
|
||||
* @return the start offset of the (compressed) data.
|
||||
*
|
||||
* @exception IOException if a i/o error occured.
|
||||
* @exception ZipException if the local header doesn't match the
|
||||
* central directory header
|
||||
*/
|
||||
private long checkLocalHeader(ZipEntry entry) throws IOException
|
||||
{
|
||||
synchronized (raf)
|
||||
{
|
||||
raf.seek(entry.offset);
|
||||
raf.readFully(locBuf);
|
||||
|
||||
if (readLeInt(locBuf, 0) != LOCSIG)
|
||||
throw new ZipException("Wrong Local header signature: " + name);
|
||||
|
||||
if (entry.getMethod() != readLeShort(locBuf, LOCHOW))
|
||||
throw new ZipException("Compression method mismatch: " + name);
|
||||
|
||||
if (entry.getName().length() != readLeShort(locBuf, LOCNAM))
|
||||
throw new ZipException("file name length mismatch: " + name);
|
||||
|
||||
int extraLen = entry.getName().length() + readLeShort(locBuf, LOCEXT);
|
||||
return entry.offset + LOCHDR + extraLen;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an input stream reading the given zip entry as
|
||||
* uncompressed data. Normally zip entry should be an entry
|
||||
|
@ -497,16 +383,32 @@ public class ZipFile implements ZipConstants
|
|||
if (zipEntry == null)
|
||||
return null;
|
||||
|
||||
long start = checkLocalHeader(zipEntry);
|
||||
PartialInputStream inp = new PartialInputStream(raf, 1024);
|
||||
inp.seek(zipEntry.offset);
|
||||
|
||||
if (inp.readLeInt() != LOCSIG)
|
||||
throw new ZipException("Wrong Local header signature: " + name);
|
||||
|
||||
inp.skip(4);
|
||||
|
||||
if (zipEntry.getMethod() != inp.readLeShort())
|
||||
throw new ZipException("Compression method mismatch: " + name);
|
||||
|
||||
inp.skip(16);
|
||||
|
||||
int nameLen = inp.readLeShort();
|
||||
int extraLen = inp.readLeShort();
|
||||
inp.skip(nameLen + extraLen);
|
||||
|
||||
inp.setLength(zipEntry.getCompressedSize());
|
||||
|
||||
int method = zipEntry.getMethod();
|
||||
InputStream is = new BufferedInputStream(new PartialInputStream
|
||||
(raf, start, zipEntry.getCompressedSize()));
|
||||
switch (method)
|
||||
{
|
||||
case ZipOutputStream.STORED:
|
||||
return is;
|
||||
return inp;
|
||||
case ZipOutputStream.DEFLATED:
|
||||
return new InflaterInputStream(is, new Inflater(true));
|
||||
return new InflaterInputStream(inp, new Inflater(true));
|
||||
default:
|
||||
throw new ZipException("Unknown compression method " + method);
|
||||
}
|
||||
|
@ -562,21 +464,41 @@ public class ZipFile implements ZipConstants
|
|||
}
|
||||
}
|
||||
|
||||
private static class PartialInputStream extends InputStream
|
||||
private static final class PartialInputStream extends InputStream
|
||||
{
|
||||
private final RandomAccessFile raf;
|
||||
long filepos, end;
|
||||
private final byte[] buffer;
|
||||
private long bufferOffset;
|
||||
private int pos;
|
||||
private long end;
|
||||
|
||||
public PartialInputStream(RandomAccessFile raf, long start, long len)
|
||||
public PartialInputStream(RandomAccessFile raf, int bufferSize)
|
||||
throws IOException
|
||||
{
|
||||
this.raf = raf;
|
||||
filepos = start;
|
||||
end = start + len;
|
||||
buffer = new byte[bufferSize];
|
||||
bufferOffset = -buffer.length;
|
||||
pos = buffer.length;
|
||||
end = raf.length();
|
||||
}
|
||||
|
||||
void setLength(long length)
|
||||
{
|
||||
end = bufferOffset + pos + length;
|
||||
}
|
||||
|
||||
private void fillBuffer() throws IOException
|
||||
{
|
||||
synchronized (raf)
|
||||
{
|
||||
raf.seek(bufferOffset);
|
||||
raf.readFully(buffer, 0, (int) Math.min(buffer.length, end - bufferOffset));
|
||||
}
|
||||
}
|
||||
|
||||
public int available()
|
||||
{
|
||||
long amount = end - filepos;
|
||||
long amount = end - (bufferOffset + pos);
|
||||
if (amount > Integer.MAX_VALUE)
|
||||
return Integer.MAX_VALUE;
|
||||
return (int) amount;
|
||||
|
@ -584,41 +506,130 @@ public class ZipFile implements ZipConstants
|
|||
|
||||
public int read() throws IOException
|
||||
{
|
||||
if (filepos == end)
|
||||
if (bufferOffset + pos >= end)
|
||||
return -1;
|
||||
synchronized (raf)
|
||||
{
|
||||
raf.seek(filepos++);
|
||||
return raf.read();
|
||||
}
|
||||
if (pos == buffer.length)
|
||||
{
|
||||
bufferOffset += buffer.length;
|
||||
pos = 0;
|
||||
fillBuffer();
|
||||
}
|
||||
return buffer[pos++] & 0xFF;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
if (len > end - filepos)
|
||||
if (len > end - (bufferOffset + pos))
|
||||
{
|
||||
len = (int) (end - filepos);
|
||||
len = (int) (end - (bufferOffset + pos));
|
||||
if (len == 0)
|
||||
return -1;
|
||||
}
|
||||
synchronized (raf)
|
||||
{
|
||||
raf.seek(filepos);
|
||||
int count = raf.read(b, off, len);
|
||||
if (count > 0)
|
||||
filepos += len;
|
||||
return count;
|
||||
}
|
||||
|
||||
int totalBytesRead = Math.min(buffer.length - pos, len);
|
||||
System.arraycopy(buffer, pos, b, off, totalBytesRead);
|
||||
pos += totalBytesRead;
|
||||
off += totalBytesRead;
|
||||
len -= totalBytesRead;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
bufferOffset += buffer.length;
|
||||
pos = 0;
|
||||
fillBuffer();
|
||||
int remain = Math.min(buffer.length, len);
|
||||
System.arraycopy(buffer, pos, b, off, remain);
|
||||
pos += remain;
|
||||
off += remain;
|
||||
len -= remain;
|
||||
totalBytesRead += remain;
|
||||
}
|
||||
|
||||
return totalBytesRead;
|
||||
}
|
||||
|
||||
public long skip(long amount)
|
||||
public long skip(long amount) throws IOException
|
||||
{
|
||||
if (amount < 0)
|
||||
throw new IllegalArgumentException();
|
||||
if (amount > end - filepos)
|
||||
amount = end - filepos;
|
||||
filepos += amount;
|
||||
return 0;
|
||||
if (amount > end - (bufferOffset + pos))
|
||||
amount = end - (bufferOffset + pos);
|
||||
seek(bufferOffset + pos + amount);
|
||||
return amount;
|
||||
}
|
||||
|
||||
void seek(long newpos) throws IOException
|
||||
{
|
||||
long offset = newpos - bufferOffset;
|
||||
if (offset >= 0 && offset <= buffer.length)
|
||||
{
|
||||
pos = (int) offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferOffset = newpos;
|
||||
pos = 0;
|
||||
fillBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
void readFully(byte[] buf) throws IOException
|
||||
{
|
||||
if (read(buf, 0, buf.length) != buf.length)
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
void readFully(byte[] buf, int off, int len) throws IOException
|
||||
{
|
||||
if (read(buf, off, len) != len)
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
int readLeShort() throws IOException
|
||||
{
|
||||
int b0 = read();
|
||||
int b1 = read();
|
||||
if (b1 == -1)
|
||||
throw new EOFException();
|
||||
return (b0 & 0xff) | (b1 & 0xff) << 8;
|
||||
}
|
||||
|
||||
int readLeInt() throws IOException
|
||||
{
|
||||
int b0 = read();
|
||||
int b1 = read();
|
||||
int b2 = read();
|
||||
int b3 = read();
|
||||
if (b3 == -1)
|
||||
throw new EOFException();
|
||||
return ((b0 & 0xff) | (b1 & 0xff) << 8)
|
||||
| ((b2 & 0xff) | (b3 & 0xff) << 8) << 16;
|
||||
}
|
||||
|
||||
String readString(int length) throws IOException
|
||||
{
|
||||
if (length > end - (bufferOffset + pos))
|
||||
throw new EOFException();
|
||||
|
||||
try
|
||||
{
|
||||
if (buffer.length - pos >= length)
|
||||
{
|
||||
String s = new String(buffer, pos, length, "UTF-8");
|
||||
pos += length;
|
||||
return s;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] b = new byte[length];
|
||||
readFully(b);
|
||||
return new String(b, 0, length, "UTF-8");
|
||||
}
|
||||
}
|
||||
catch (UnsupportedEncodingException uee)
|
||||
{
|
||||
throw new AssertionError(uee);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue