1.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/FastJar.java Sun Feb 10 09:51:22 2013 +0100
1.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/FastJar.java Sun Feb 10 12:14:40 2013 +0100
1.3 @@ -28,17 +28,12 @@
1.4 *
1.5 * Portions Copyrighted 2007 Sun Microsystems, Inc.
1.6 */
1.7 -package org.netbeans.modules.java.source.parsing;
1.8 +package org.apidesign.bck2brwsr.emul.zip;
1.9
1.10 -import java.io.File;
1.11 +import java.io.ByteArrayInputStream;
1.12 import java.io.IOException;
1.13 import java.io.InputStream;
1.14 -import java.io.RandomAccessFile;
1.15 -import java.util.Date;
1.16 -import java.util.LinkedList;
1.17 -import java.util.List;
1.18 import java.util.zip.ZipEntry;
1.19 -import java.util.zip.ZipFile;
1.20 import java.util.zip.ZipInputStream;
1.21
1.22 /**
1.23 @@ -46,78 +41,28 @@
1.24 * @author Tomas Zezula
1.25 */
1.26 public final class FastJar {
1.27 + private final byte[] arr;
1.28
1.29 - private FastJar() {
1.30 + public FastJar(byte[] arr) {
1.31 + this.arr = arr;
1.32 }
1.33
1.34
1.35 private static final int GIVE_UP = 1<<16;
1.36 -
1.37 -
1.38 - private static class RandomAccessFileInputStream extends InputStream {
1.39 -
1.40 - private final RandomAccessFile b;
1.41 - private final long len;
1.42 -
1.43 - public RandomAccessFileInputStream (RandomAccessFile b) throws IOException {
1.44 - assert b != null;
1.45 - this.b = b;
1.46 - this.len = b.length();
1.47 - }
1.48 -
1.49 - public RandomAccessFileInputStream (RandomAccessFile b, long len) throws IOException {
1.50 - assert b != null;
1.51 - assert len >=0;
1.52 - this.b = b;
1.53 - this.len = b.getFilePointer()+len;
1.54 - }
1.55 -
1.56 - public int read (byte[] data, int offset, int size) throws IOException {
1.57 - int rem = available();
1.58 - if (rem == 0) {
1.59 - return -1;
1.60 - }
1.61 - int rlen;
1.62 - if (size<rem) {
1.63 - rlen = size;
1.64 - }
1.65 - else {
1.66 - rlen = rem;
1.67 - }
1.68 - return this.b.read(data, offset, rlen);
1.69 - }
1.70
1.71 - public int read() throws java.io.IOException {
1.72 - if (available()==0) {
1.73 - return -1;
1.74 - }
1.75 - else {
1.76 - return b.readByte();
1.77 - }
1.78 - }
1.79 -
1.80 - public int available () throws IOException {
1.81 - return (int) (len - this.b.getFilePointer());
1.82 - }
1.83 -
1.84 - public void close () throws IOException {
1.85 - b.close ();
1.86 - }
1.87 - }
1.88 -
1.89 public static final class Entry {
1.90
1.91 public final String name;
1.92 final long offset;
1.93 private final long dosTime;
1.94
1.95 - public Entry (String name, long offset, long time) {
1.96 + Entry (String name, long offset, long time) {
1.97 assert name != null;
1.98 this.name = name;
1.99 this.offset = offset;
1.100 this.dosTime = time;
1.101 }
1.102 -
1.103 +/*
1.104 public long getTime () {
1.105 Date d = new Date((int)(((dosTime >> 25) & 0x7f) + 80),
1.106 (int)(((dosTime >> 21) & 0x0f) - 1),
1.107 @@ -127,120 +72,94 @@
1.108 (int)((dosTime << 1) & 0x3e));
1.109 return d.getTime();
1.110 }
1.111 + */
1.112 }
1.113
1.114 - public static InputStream getInputStream (final File file, final Entry e) throws IOException {
1.115 - return getInputStream(file, e.offset);
1.116 + public InputStream getInputStream (final Entry e) throws IOException {
1.117 + return getInputStream(arr, e.offset);
1.118 }
1.119
1.120 - static InputStream getInputStream (final File file, final long offset) throws IOException {
1.121 - RandomAccessFile f = new RandomAccessFile (file, "r"); //NOI18N
1.122 - f.seek (offset);
1.123 - ZipInputStream in = new ZipInputStream (new RandomAccessFileInputStream (f));
1.124 + private static InputStream getInputStream (byte[] arr, final long offset) throws IOException {
1.125 + ByteArrayInputStream is = new ByteArrayInputStream(arr);
1.126 + is.skip(offset);
1.127 + ZipInputStream in = new ZipInputStream (is);
1.128 ZipEntry e = in.getNextEntry();
1.129 if (e != null && e.getCrc() == 0L && e.getMethod() == ZipEntry.STORED) {
1.130 - long cp = f.getFilePointer();
1.131 - in.close();
1.132 - f = new RandomAccessFile (file, "r"); //NOI18N
1.133 - f.seek (cp);
1.134 - return new RandomAccessFileInputStream (f, e.getSize());
1.135 + int cp = arr.length - is.available();
1.136 + return new ByteArrayInputStream(arr, cp, (int)e.getSize());
1.137 }
1.138 return in;
1.139 }
1.140
1.141 - static ZipEntry getZipEntry (final File file, final long offset) throws IOException {
1.142 - RandomAccessFile f = new RandomAccessFile (file, "r"); //NOI18N
1.143 - try {
1.144 - f.seek (offset);
1.145 - ZipInputStream in = new ZipInputStream (new RandomAccessFileInputStream (f));
1.146 - try {
1.147 - return in.getNextEntry();
1.148 - } finally {
1.149 - in.close();
1.150 + public Entry[] list() throws IOException {
1.151 + final int size = arr.length;
1.152 +
1.153 + int at = size - ZipInputStream.ENDHDR;
1.154 +
1.155 + byte[] data = new byte[ZipInputStream.ENDHDR];
1.156 + int giveup = 0;
1.157 +
1.158 + do {
1.159 + org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, at, data, 0, data.length);
1.160 + at--;
1.161 + giveup++;
1.162 + if (giveup > GIVE_UP) {
1.163 + throw new IOException ();
1.164 }
1.165 - } finally {
1.166 - f.close ();
1.167 + } while (getsig(data) != ZipInputStream.ENDSIG);
1.168 +
1.169 +
1.170 + final long censize = endsiz(data);
1.171 + final long cenoff = endoff(data);
1.172 + at = (int) cenoff;
1.173 +
1.174 + Entry[] result = new Entry[0];
1.175 + int cenread = 0;
1.176 + data = new byte[ZipInputStream.CENHDR];
1.177 + while (cenread < censize) {
1.178 + org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, at, data, 0, data.length);
1.179 + at += data.length;
1.180 + if (getsig(data) != ZipInputStream.CENSIG) {
1.181 + throw new IOException("No central table"); //NOI18N
1.182 + }
1.183 + int cennam = cennam(data);
1.184 + int cenext = cenext(data);
1.185 + int cencom = cencom(data);
1.186 + long lhoff = cenoff(data);
1.187 + long centim = centim(data);
1.188 + String name = new String(arr, at, cennam, "UTF-8");
1.189 + at += cennam;
1.190 + int seekby = cenext+cencom;
1.191 + int cendatalen = ZipInputStream.CENHDR + cennam + seekby;
1.192 + cenread+=cendatalen;
1.193 + result = addEntry(result, new Entry(name,lhoff, centim));
1.194 + at += seekby;
1.195 }
1.196 + return result;
1.197 }
1.198
1.199 - public static Iterable<? extends Entry> list(File f) throws IOException {
1.200 - RandomAccessFile b = new RandomAccessFile (f,"r"); //NOI18N
1.201 - try {
1.202 - final long size = (int) b.length();
1.203 - b.seek (size-ZipFile.ENDHDR);
1.204 -
1.205 - byte[] data = new byte[ZipFile.ENDHDR];
1.206 - int giveup = 0;
1.207 -
1.208 - do {
1.209 - if (b.read(data, 0, ZipFile.ENDHDR)!=ZipFile.ENDHDR) {
1.210 - throw new IOException ();
1.211 - }
1.212 - b.seek(b.getFilePointer()-(ZipFile.ENDHDR+1));
1.213 - giveup++;
1.214 - if (giveup > GIVE_UP) {
1.215 - throw new IOException ();
1.216 - }
1.217 - } while (getsig(data) != ZipFile.ENDSIG);
1.218 -
1.219 -
1.220 - final long censize = endsiz(data);
1.221 - final long cenoff = endoff(data);
1.222 - b.seek (cenoff);
1.223 -
1.224 - List<Entry> result = new LinkedList<Entry>();
1.225 - int cenread = 0;
1.226 - data = new byte[ZipFile.CENHDR];
1.227 - while (cenread < censize) {
1.228 - if (b.read(data, 0, ZipFile.CENHDR)!=ZipFile.CENHDR) {
1.229 - throw new IOException ("No central table"); //NOI18N
1.230 - }
1.231 - if (getsig(data) != ZipFile.CENSIG) {
1.232 - throw new IOException("No central table"); //NOI18N
1.233 - }
1.234 - int cennam = cennam(data);
1.235 - int cenext = cenext(data);
1.236 - int cencom = cencom(data);
1.237 - long lhoff = cenoff(data);
1.238 - long centim = centim(data);
1.239 - String name = name(b, cennam);
1.240 - int seekby = cenext+cencom;
1.241 - int cendatalen = ZipFile.CENHDR + cennam + seekby;
1.242 - cenread+=cendatalen;
1.243 - result.add(new Entry(name,lhoff, centim));
1.244 - seekBy(b,seekby);
1.245 - }
1.246 - return result;
1.247 - } finally {
1.248 - b.close();
1.249 - }
1.250 - }
1.251 -
1.252 - private static final String name(final RandomAccessFile b, final int cennam) throws IOException {
1.253 - byte[] name = new byte[cennam];
1.254 - b.read(name, 0, cennam);
1.255 - return new String(name, "UTF-8"); //NOI18N
1.256 + private Entry[] addEntry(Entry[] result, Entry entry) {
1.257 + Entry[] e = new Entry[result.length + 1];
1.258 + e[result.length] = entry;
1.259 + org.apidesign.bck2brwsr.emul.lang.System.arraycopy(result, 0, e, 0, result.length);
1.260 + return e;
1.261 }
1.262
1.263 private static final long getsig(final byte[] b) throws IOException {return get32(b,0);}
1.264 - private static final long endsiz(final byte[] b) throws IOException {return get32(b,ZipFile.ENDSIZ);}
1.265 - private static final long endoff(final byte[] b) throws IOException {return get32(b,ZipFile.ENDOFF);}
1.266 - private static final long cenlen(final byte[] b) throws IOException {return get32(b,ZipFile.CENLEN);}
1.267 - private static final long censiz(final byte[] b) throws IOException {return get32(b,ZipFile.CENSIZ);}
1.268 - private static final long centim(final byte[] b) throws IOException {return get32(b,ZipFile.CENTIM);}
1.269 - private static final int cennam(final byte[] b) throws IOException {return get16(b,ZipFile.CENNAM);}
1.270 - private static final int cenext(final byte[] b) throws IOException {return get16(b,ZipFile.CENEXT);}
1.271 - private static final int cencom(final byte[] b) throws IOException {return get16(b,ZipFile.CENCOM);}
1.272 - private static final long cenoff (final byte[] b) throws IOException {return get32(b,ZipFile.CENOFF);}
1.273 - private static final int lochow(final byte[] b) throws IOException {return get16(b,ZipFile.LOCHOW);}
1.274 - private static final int locname(final byte[] b) throws IOException {return get16(b,ZipFile.LOCNAM);}
1.275 - private static final int locext(final byte[] b) throws IOException {return get16(b,ZipFile.LOCEXT);}
1.276 - private static final long locsiz(final byte[] b) throws IOException {return get32(b,ZipFile.LOCSIZ);}
1.277 + private static final long endsiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.ENDSIZ);}
1.278 + private static final long endoff(final byte[] b) throws IOException {return get32(b,ZipInputStream.ENDOFF);}
1.279 + private static final long cenlen(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENLEN);}
1.280 + private static final long censiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENSIZ);}
1.281 + private static final long centim(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENTIM);}
1.282 + private static final int cennam(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENNAM);}
1.283 + private static final int cenext(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENEXT);}
1.284 + private static final int cencom(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENCOM);}
1.285 + private static final long cenoff (final byte[] b) throws IOException {return get32(b,ZipInputStream.CENOFF);}
1.286 + private static final int lochow(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCHOW);}
1.287 + private static final int locname(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCNAM);}
1.288 + private static final int locext(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCEXT);}
1.289 + private static final long locsiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.LOCSIZ);}
1.290
1.291 - private static final void seekBy(final RandomAccessFile b, int offset) throws IOException {
1.292 - b.seek(b.getFilePointer() + offset);
1.293 - }
1.294 -
1.295 private static final int get16(final byte[] b, int off) throws IOException {
1.296 final int b1 = b[off];
1.297 final int b2 = b[off+1];