# HG changeset patch # User Jaroslav Tulach # Date 1399809678 -7200 # Node ID bfda398c3a6851e50ef950b16bfb6a4b8a1aec10 # Parent ae8575329e1bbe91853523cf6b93f8c0d0c26165# Parent a936cbe904745496a025d40ae75d2c67381d7a1e Merging separated emulation of ZIP access diff -r ae8575329e1b -r bfda398c3a68 launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java --- a/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java Tue May 06 17:46:47 2014 +0200 +++ b/launcher/http/src/main/java/org/apidesign/bck2brwsr/launcher/CompileCP.java Sun May 11 14:01:18 2014 +0200 @@ -144,9 +144,6 @@ while (en.hasMoreElements()) { JarEntry e = en.nextElement(); final String n = e.getName(); - if (n.contains("package-info")) { - continue; - } if (n.endsWith("/")) { continue; } @@ -192,9 +189,6 @@ private static void listDir(File f, String pref, List classes, List resources) throws IOException { File[] arr = f.listFiles(); if (arr == null) { - if (f.getName().equals("package-info.class")) { - return; - } if (f.getName().endsWith(".class")) { classes.add(pref + f.getName().substring(0, f.getName().length() - 6)); } else { @@ -209,12 +203,19 @@ } static void compileVM(StringBuilder sb, final Res r) throws IOException { - URL u = r.get(InterruptedException.class.getName().replace('.', '/') + ".class", 0); - JarURLConnection juc = (JarURLConnection)u.openConnection(); - List arr = new ArrayList<>(); List classes = new ArrayList<>(); - listJAR(juc.getJarFile(), classes, arr, null, null); + + { + URL u = r.get(InterruptedException.class.getName().replace('.', '/') + ".class", 0); + JarURLConnection juc = (JarURLConnection)u.openConnection(); + listJAR(juc.getJarFile(), classes, arr, null, null); + } + { + URL u = r.get(Bck2Brwsr.class.getName().replace('.', '/') + ".class", 0); + JarURLConnection juc = (JarURLConnection)u.openConnection(); + listJAR(juc.getJarFile(), classes, arr, null, null); + } Bck2Brwsr.newCompiler().addRootClasses(classes.toArray(new String[0])) .resources(new Bck2Brwsr.Resources() { diff -r ae8575329e1b -r bfda398c3a68 pom.xml --- a/pom.xml Tue May 06 17:46:47 2014 +0200 +++ b/pom.xml Sun May 11 14:01:18 2014 +0200 @@ -87,6 +87,7 @@ .*/** rt/emul/mini/src/main/** rt/emul/compact/src/main/** + rt/emul/zip/src/main/** rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeParser.java rt/archetype/src/main/resources/archetype-resources/** rt/emul/*/src/test/resources/** diff -r ae8575329e1b -r bfda398c3a68 rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ZipArchive.java --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ZipArchive.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.bck2brwsr.compact.tck; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; -import java.util.zip.ZipEntry; -import org.apidesign.bck2brwsr.emul.zip.ZipInputStream; - -/** - * - * @author Jaroslav Tulach - */ -final class ZipArchive { - private final Map entries = new LinkedHashMap<>(); - - public static ZipArchive createZip(InputStream is) throws IOException { - ZipArchive a = new ZipArchive(); - readZip(is, a); - return a; - } - - public static ZipArchive createReal(InputStream is) throws IOException { - ZipArchive a = new ZipArchive(); - realZip(is, a); - return a; - } - - /** - * Registers entry name and data - */ - final void register(String entry, InputStream is) throws IOException { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - for (;;) { - int ch = is.read(); - if (ch == -1) { - break; - } - os.write(ch); - } - os.close(); - entries.put(entry, os.toByteArray()); - } - - @Override - public int hashCode() { - return entries.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final ZipArchive other = (ZipArchive) obj; - if (!Objects.deepEquals(this.entries, other.entries)) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (Map.Entry en : entries.entrySet()) { - String string = en.getKey(); - byte[] bs = en.getValue(); - sb.append(string).append(" = ").append(Arrays.toString(bs)).append("\n"); - } - return sb.toString(); - } - - public void assertEquals(ZipArchive zip, String msg) { - boolean ok = true; - StringBuilder sb = new StringBuilder(); - sb.append(msg); - for (Map.Entry en : entries.entrySet()) { - String string = en.getKey(); - byte[] bs = en.getValue(); - byte[] other = zip.entries.get(string); - sb.append("\n"); - if (other == null) { - sb.append("EXTRA ").append(string).append(" = ").append(Arrays.toString(bs)); - ok = false; - continue; - } - if (Arrays.equals(bs, other)) { - sb.append("OK ").append(string); - continue; - } else { - sb.append("DIFF ").append(string).append(" = ").append(Arrays.toString(bs)).append("\n"); - sb.append(" TO").append(string).append(" = ").append(Arrays.toString(other)).append("\n"); - ok = false; - continue; - } - } - for (Map.Entry entry : zip.entries.entrySet()) { - String string = entry.getKey(); - if (entries.get(string) == null) { - sb.append("MISS ").append(string).append(" = ").append(Arrays.toString(entry.getValue())); - ok = false; - } - } - if (!ok) { - assert false : sb.toString(); - } - } - - public static void readZip(InputStream is, ZipArchive data) throws IOException { - ZipInputStream zip = new org.apidesign.bck2brwsr.emul.zip.ZipInputStream(is); - for (;;) { - ZipEntry en = zip.getNextEntry(); - if (en == null) { - return; - } - data.register(en.getName(), zip); - } - } - - public static void realZip(InputStream is, ZipArchive data) throws IOException { - java.util.zip.ZipInputStream zip = new java.util.zip.ZipInputStream(is); - for (;;) { - ZipEntry en = zip.getNextEntry(); - if (en == null) { - return; - } - data.register(en.getName(), zip); - } - } - -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ZipCompatibilityTest.java --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ZipCompatibilityTest.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.bck2brwsr.compact.tck; - -import java.io.IOException; -import java.io.InputStream; -import org.apidesign.bck2brwsr.vmtest.Compare; -import org.apidesign.bck2brwsr.vmtest.VMTest; -import org.testng.annotations.Factory; - -/** - * - * @author Jaroslav Tulach - */ -public class ZipCompatibilityTest { - @Compare - public String testDemoStaticCalculator() throws IOException { - InputStream is = getClass().getResourceAsStream("demo.static.calculator-TEST.jar"); - ZipArchive zip = ZipArchive.createZip(is); - final String ts = zip.toString(); - return ts.substring(0, 4096) + ts.hashCode(); - } - - @Factory - public static Object[] create() { - return VMTest.create(ZipCompatibilityTest.class); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ZipVsJzLibTest.java --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ZipVsJzLibTest.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.bck2brwsr.compact.tck; - -import java.io.IOException; -import java.io.InputStream; -import org.testng.annotations.Test; - -/** - * - * @author Jaroslav Tulach - */ -public class ZipVsJzLibTest { - @Test public void r() throws IOException { - InputStream is = getClass().getResourceAsStream("demo.static.calculator-TEST.jar"); - ZipArchive zip = ZipArchive.createZip(is); - - is = getClass().getResourceAsStream("demo.static.calculator-TEST.jar"); - ZipArchive real = ZipArchive.createReal(is); - - real.assertEquals(zip, "Are they the same?"); - } - -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CRC32Test.java --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CRC32Test.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.bck2brwsr.vmtest.impl; - -import java.io.UnsupportedEncodingException; -import java.util.zip.CRC32; -import org.apidesign.bck2brwsr.vmtest.Compare; -import org.apidesign.bck2brwsr.vmtest.VMTest; -import org.testng.annotations.Factory; - -/** - * - * @author Jaroslav Tulach - */ -public class CRC32Test { - - @Compare public long crc1() throws UnsupportedEncodingException { - CRC32 crc = new CRC32(); - crc.update("Hello World!".getBytes("UTF-8")); - return crc.getValue(); - } - - @Factory public static Object[] create() { - return VMTest.create(CRC32Test.class); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipEntryTest.java --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipEntryTest.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.bck2brwsr.vmtest.impl; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import org.apidesign.bck2brwsr.emul.zip.FastJar; -import org.testng.annotations.Test; -import static org.testng.Assert.*; - -/** - * - * @author Jaroslav Tulach - */ -@GenerateZip(name = "five.zip", contents = { - "1.txt", "one", - "2.txt", "duo", - "3.txt", "three", - "4.txt", "four", - "5.txt", "five" -}) -public class ZipEntryTest { - @Test - public void readEntriesEffectively() throws IOException { - InputStream is = ZipEntryTest.class.getResourceAsStream("five.zip"); - byte[] arr = new byte[is.available()]; - int len = is.read(arr); - assertEquals(len, arr.length, "Read fully"); - - FastJar fj = new FastJar(arr); - FastJar.Entry[] entrs = fj.list(); - - assertEquals(5, entrs.length, "Five entries"); - - for (int i = 1; i <= 5; i++) { - FastJar.Entry en = entrs[i - 1]; - assertEquals(en.name, i + ".txt"); -// assertEquals(cis.cnt, 0, "Content of the file should be skipped, not read"); - } - - assertContent("three", fj.getInputStream(entrs[3 - 1]), "read OK"); - assertContent("five", fj.getInputStream(entrs[5 - 1]), "read OK"); - } - - private static void assertContent(String exp, InputStream is, String msg) throws IOException { - byte[] arr = new byte[512]; - int len = is.read(arr); - String s = new String(arr, 0, len); - assertEquals(exp, s, msg); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.bck2brwsr.vmtest.impl; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Objects; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import org.apidesign.bck2brwsr.core.JavaScriptBody; -import org.apidesign.bck2brwsr.vmtest.BrwsrTest; -import org.apidesign.bck2brwsr.vmtest.Compare; -import org.apidesign.bck2brwsr.vmtest.Http; -import org.apidesign.bck2brwsr.vmtest.VMTest; -import org.testng.annotations.Factory; - -/** - * - * @author Jaroslav Tulach - */ -@GenerateZip(name = "readAnEntry.zip", contents = { - "my/main/file.txt", "Hello World!" -}) -public class ZipFileTest { - - @Compare public String readAnEntry() throws IOException { - InputStream is = ZipFileTest.class.getResourceAsStream("readAnEntry.zip"); - ZipInputStream zip = new ZipInputStream(is); - ZipEntry entry = zip.getNextEntry(); - assertEquals(entry.getName(), "my/main/file.txt", "Correct entry"); - - byte[] arr = new byte[4096]; - int len = zip.read(arr); - - assertEquals(zip.getNextEntry(), null, "No next entry"); - - final String ret = new String(arr, 0, len, "UTF-8"); - return ret; - } - - @JavaScriptBody(args = { "res", "path" }, body = - "var myvm = bck2brwsr.apply(null, path);\n" - + "var cls = myvm.loadClass('java.lang.String');\n" - + "return cls.getClass__Ljava_lang_Class_2().getResourceAsStream__Ljava_io_InputStream_2Ljava_lang_String_2(res);\n" - ) - private static native Object loadVMResource(String res, String...path); - - @Http({ - @Http.Resource(path = "/readAnEntry.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip") - }) - @BrwsrTest public void canVmLoadResourceFromZip() throws IOException { - Object res = loadVMResource("/my/main/file.txt", "/readAnEntry.jar"); - assert res instanceof InputStream : "Got array of bytes: " + res; - InputStream is = (InputStream)res; - - byte[] arr = new byte[4096]; - int len = is.read(arr); - - final String ret = new String(arr, 0, len, "UTF-8"); - - assertEquals(ret, "Hello World!", "Can read the bytes"); - } - - @GenerateZip(name = "cpattr.zip", contents = { - "META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n" - + "Created-By: hand\n" - + "Class-Path: realJar.jar\n\n\n" - }) - @Http({ - @Http.Resource(path = "/readComplexEntry.jar", mimeType = "x-application/zip", content = "", resource="cpattr.zip"), - @Http.Resource(path = "/realJar.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip"), - }) - @BrwsrTest public void understandsClassPathAttr() throws IOException { - Object res = loadVMResource("/my/main/file.txt", "/readComplexEntry.jar"); - assert res instanceof InputStream : "Got array of bytes: " + res; - InputStream is = (InputStream)res; - - byte[] arr = new byte[4096]; - int len = is.read(arr); - - final String ret = new String(arr, 0, len, "UTF-8"); - - assertEquals(ret, "Hello World!", "Can read the bytes from secondary JAR"); - } - - private static void assertEquals(Object real, Object exp, String msg) { - assert Objects.equals(exp, real) : msg + " exp: " + exp + " real: " + real; - } - - @Factory public static Object[] create() { - return VMTest.create(ZipFileTest.class); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/compact/src/test/resources/org/apidesign/bck2brwsr/compact/tck/demo.static.calculator-TEST.jar Binary file rt/emul/compact/src/test/resources/org/apidesign/bck2brwsr/compact/tck/demo.static.calculator-TEST.jar has changed diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/lang/String.java --- a/rt/emul/mini/src/main/java/java/lang/String.java Tue May 06 17:46:47 2014 +0200 +++ b/rt/emul/mini/src/main/java/java/lang/String.java Sun May 11 14:01:18 2014 +0200 @@ -794,9 +794,7 @@ " arr[to++] = s[i];\n" + "}" ) - void getChars(char dst[], int dstBegin) { - System.arraycopy(toCharArray(), offset(), dst, dstBegin, length()); - } + native void getChars(char dst[], int dstBegin); /** * Copies characters from this string into the destination character @@ -834,19 +832,7 @@ " arr[dst++] = s.charCodeAt(beg++);\n" + "}\n" ) - public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { - if (srcBegin < 0) { - throw new StringIndexOutOfBoundsException(srcBegin); - } - if (srcEnd > length()) { - throw new StringIndexOutOfBoundsException(srcEnd); - } - if (srcBegin > srcEnd) { - throw new StringIndexOutOfBoundsException(srcEnd - srcBegin); - } - System.arraycopy(toCharArray(), offset() + srcBegin, dst, dstBegin, - srcEnd - srcBegin); - } + public native void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin); /** * Copies characters from this string into the destination byte array. Each @@ -905,10 +891,9 @@ int j = dstBegin; int n = offset() + srcEnd; int i = offset() + srcBegin; - char[] val = toCharArray(); /* avoid getfield opcode */ while (i < n) { - dst[j++] = (byte)val[i++]; + dst[j++] = (byte)charAt(i++); } } @@ -1016,30 +1001,10 @@ * @see #equalsIgnoreCase(String) */ @JavaScriptBody(args = { "obj" }, body = - "return obj != null && obj['$instOf_java_lang_String'] && " + "return obj !== null && obj['$instOf_java_lang_String'] && " + "this.toString() === obj.toString();" ) - public boolean equals(Object anObject) { - if (this == anObject) { - return true; - } - if (anObject instanceof String) { - String anotherString = (String)anObject; - int n = length(); - if (n == anotherString.length()) { - char v1[] = toCharArray(); - char v2[] = anotherString.toCharArray(); - int i = offset(); - int j = anotherString.offset(); - while (n-- != 0) { - if (v1[i++] != v2[j++]) - return false; - } - return true; - } - } - return false; - } + public native boolean equals(Object anObject); /** * Compares this string to the specified {@code StringBuffer}. The result @@ -1080,13 +1045,12 @@ return false; // Argument is a StringBuffer, StringBuilder if (cs instanceof AbstractStringBuilder) { - char v1[] = toCharArray(); char v2[] = ((AbstractStringBuilder)cs).getValue(); int i = offset(); int j = 0; int n = length(); while (n-- != 0) { - if (v1[i++] != v2[j++]) + if (this.charAt(i++) != v2[j++]) return false; } return true; @@ -1095,12 +1059,11 @@ if (cs.equals(this)) return true; // Argument is a generic CharSequence - char v1[] = toCharArray(); int i = offset(); int j = 0; int n = length(); while (n-- != 0) { - if (v1[i++] != cs.charAt(j++)) + if (this.charAt(i++) != cs.charAt(j++)) return false; } return true; @@ -1185,8 +1148,6 @@ int len1 = length(); int len2 = anotherString.length(); int n = Math.min(len1, len2); - char v1[] = toCharArray(); - char v2[] = anotherString.toCharArray(); int i = offset(); int j = anotherString.offset(); @@ -1194,8 +1155,8 @@ int k = i; int lim = n + i; while (k < lim) { - char c1 = v1[k]; - char c2 = v2[k]; + char c1 = this.charAt(k); + char c2 = anotherString.charAt(k); if (c1 != c2) { return c1 - c2; } @@ -1203,8 +1164,8 @@ } } else { while (n-- != 0) { - char c1 = v1[i++]; - char c2 = v2[j++]; + char c1 = this.charAt(i++); + char c2 = anotherString.charAt(j++); if (c1 != c2) { return c1 - c2; } @@ -1446,23 +1407,7 @@ "find = find.toString();\n" + "return this.toString().substring(from, from + find.length) === find;\n" ) - public boolean startsWith(String prefix, int toffset) { - char ta[] = toCharArray(); - int to = offset() + toffset; - char pa[] = prefix.toCharArray(); - int po = prefix.offset(); - int pc = prefix.length(); - // Note: toffset might be near -1>>>1. - if ((toffset < 0) || (toffset > length() - pc)) { - return false; - } - while (--pc >= 0) { - if (ta[to++] != pa[po++]) { - return false; - } - } - return true; - } + public native boolean startsWith(String prefix, int toffset); /** * Tests if this string starts with the specified prefix. @@ -1596,49 +1541,7 @@ "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" + "return this.toString().indexOf(ch, from);\n" ) - public int indexOf(int ch, int fromIndex) { - if (fromIndex < 0) { - fromIndex = 0; - } else if (fromIndex >= length()) { - // Note: fromIndex might be near -1>>>1. - return -1; - } - - if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { - // handle most cases here (ch is a BMP code point or a - // negative value (invalid code point)) - final char[] value = this.toCharArray(); - final int offset = this.offset(); - final int max = offset + length(); - for (int i = offset + fromIndex; i < max ; i++) { - if (value[i] == ch) { - return i - offset; - } - } - return -1; - } else { - return indexOfSupplementary(ch, fromIndex); - } - } - - /** - * Handles (rare) calls of indexOf with a supplementary character. - */ - private int indexOfSupplementary(int ch, int fromIndex) { - if (Character.isValidCodePoint(ch)) { - final char[] value = this.toCharArray(); - final int offset = this.offset(); - final char hi = Character.highSurrogate(ch); - final char lo = Character.lowSurrogate(ch); - final int max = offset + length() - 1; - for (int i = offset + fromIndex; i < max; i++) { - if (value[i] == hi && value[i+1] == lo) { - return i - offset; - } - } - } - return -1; - } + public native int indexOf(int ch, int fromIndex); /** * Returns the index within this string of the last occurrence of @@ -1705,42 +1608,7 @@ "if (typeof ch === 'number') ch = String.fromCharCode(ch);\n" + "return this.toString().lastIndexOf(ch, from);" ) - public int lastIndexOf(int ch, int fromIndex) { - if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { - // handle most cases here (ch is a BMP code point or a - // negative value (invalid code point)) - final char[] value = this.toCharArray(); - final int offset = this.offset(); - int i = offset + Math.min(fromIndex, length() - 1); - for (; i >= offset ; i--) { - if (value[i] == ch) { - return i - offset; - } - } - return -1; - } else { - return lastIndexOfSupplementary(ch, fromIndex); - } - } - - /** - * Handles (rare) calls of lastIndexOf with a supplementary character. - */ - private int lastIndexOfSupplementary(int ch, int fromIndex) { - if (Character.isValidCodePoint(ch)) { - final char[] value = this.toCharArray(); - final int offset = this.offset(); - char hi = Character.highSurrogate(ch); - char lo = Character.lowSurrogate(ch); - int i = offset + Math.min(fromIndex, length() - 2); - for (; i >= offset; i--) { - if (value[i] == hi && value[i+1] == lo) { - return i - offset; - } - } - } - return -1; - } + public native int lastIndexOf(int ch, int fromIndex); /** * Returns the index within this string of the first occurrence of the @@ -1819,9 +1687,7 @@ @JavaScriptBody(args = { "s", "from" }, body = "return this.toString().lastIndexOf(s.toString(), from);" ) - public int lastIndexOf(String str, int fromIndex) { - return lastIndexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex); - } + public native int lastIndexOf(String str, int fromIndex); /** * Code shared by String and StringBuffer to do searches. The @@ -1928,19 +1794,7 @@ @JavaScriptBody(args = { "beginIndex", "endIndex" }, body = "return this.toString().substring(beginIndex, endIndex);" ) - public String substring(int beginIndex, int endIndex) { - if (beginIndex < 0) { - throw new StringIndexOutOfBoundsException(beginIndex); - } - if (endIndex > length()) { - throw new StringIndexOutOfBoundsException(endIndex); - } - if (beginIndex > endIndex) { - throw new StringIndexOutOfBoundsException(endIndex - beginIndex); - } - return ((beginIndex == 0) && (endIndex == length())) ? this : - new String(toCharArray(), offset() + beginIndex, endIndex - beginIndex); - } + public native String substring(int beginIndex, int endIndex); /** * Returns a new character sequence that is a subsequence of this sequence. @@ -2046,33 +1900,7 @@ " s = ret;\n" + "}" ) - public String replace(char oldChar, char newChar) { - if (oldChar != newChar) { - int len = length(); - int i = -1; - char[] val = toCharArray(); /* avoid getfield opcode */ - int off = offset(); /* avoid getfield opcode */ - - while (++i < len) { - if (val[off + i] == oldChar) { - break; - } - } - if (i < len) { - char buf[] = new char[len]; - for (int j = 0 ; j < i ; j++) { - buf[j] = val[off+j]; - } - while (i < len) { - char c = val[off + i]; - buf[i] = (c == oldChar) ? newChar : c; - i++; - } - return new String(buf, 0, len); - } - } - return this; - } + public native String replace(char oldChar, char newChar); /** * Tells whether or not this string matches the given 0) || (len < length())) ? substring(st, len) : this; diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/lang/reflect/Array.java --- a/rt/emul/mini/src/main/java/java/lang/reflect/Array.java Tue May 06 17:46:47 2014 +0200 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Array.java Sun May 11 14:01:18 2014 +0200 @@ -75,40 +75,10 @@ if (length < 0) { throw new NegativeArraySizeException(); } - String sig = findSignature(componentType); + String sig = Method.findArraySignature(componentType); return newArray(componentType.isPrimitive(), sig, null, length); } - private static String findSignature(Class type) { - if (type == Integer.TYPE) { - return "[I"; - } - if (type == Long.TYPE) { - return "[J"; - } - if (type == Double.TYPE) { - return "[D"; - } - if (type == Float.TYPE) { - return "[F"; - } - if (type == Byte.TYPE) { - return "[B"; - } - if (type == Boolean.TYPE) { - return "[Z"; - } - if (type == Short.TYPE) { - return "[S"; - } - if (type == Character.TYPE) { - return "[C"; - } - if (type.getName().equals("void")) { - throw new IllegalStateException("Can't create array for " + type); - } - return "[L" + type.getName().replace('.', '/') + ";"; - } /** * Creates a new array * with the specified component type and dimensions. @@ -148,7 +118,7 @@ for (int i = 1; i < dimensions.length; i++) { sig.append('['); } - sig.append(findSignature(componentType)); + sig.append(Method.findArraySignature(componentType)); return multiNewArray(sig.toString(), dimensions, 0); } @@ -234,7 +204,7 @@ */ public static byte getByte(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { - if (array.getClass().getComponentType() != Byte.TYPE) { + if (!Method.samePrimitive(array.getClass().getComponentType(), Byte.TYPE)) { throw new IllegalArgumentException(); } byte[] arr = (byte[]) array; @@ -279,7 +249,7 @@ public static short getShort(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { final Class t = array.getClass().getComponentType(); - if (t == Short.TYPE) { + if (Method.samePrimitive(t, Short.TYPE)) { short[] arr = (short[]) array; return arr[index]; } @@ -305,7 +275,7 @@ public static int getInt(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { final Class t = array.getClass().getComponentType(); - if (t == Integer.TYPE) { + if (Method.samePrimitive(t, Integer.TYPE)) { int[] arr = (int[]) array; return arr[index]; } @@ -331,7 +301,7 @@ public static long getLong(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { final Class t = array.getClass().getComponentType(); - if (t == Long.TYPE) { + if (Method.samePrimitive(t, Long.TYPE)) { long[] arr = (long[]) array; return arr[index]; } @@ -357,7 +327,7 @@ public static float getFloat(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { final Class t = array.getClass().getComponentType(); - if (t == Float.TYPE) { + if (Method.samePrimitive(t, Float.TYPE)) { float[] arr = (float[]) array; return arr[index]; } @@ -383,7 +353,7 @@ public static double getDouble(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { final Class t = array.getClass().getComponentType(); - if (t == Double.TYPE) { + if (Method.samePrimitive(t, Double.TYPE)) { double[] arr = (double[]) array; return arr[index]; } @@ -457,7 +427,7 @@ public static void setByte(Object array, int index, byte b) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { Class t = array.getClass().getComponentType(); - if (t == Byte.TYPE) { + if (Method.samePrimitive(t, Byte.TYPE)) { byte[] arr = (byte[]) array; arr[index] = b; } else { @@ -505,7 +475,7 @@ public static void setShort(Object array, int index, short s) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { Class t = array.getClass().getComponentType(); - if (t == Short.TYPE) { + if (Method.samePrimitive(t, Short.TYPE)) { short[] arr = (short[]) array; arr[index] = s; } else { @@ -534,7 +504,7 @@ public static void setInt(Object array, int index, int i) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { Class t = array.getClass().getComponentType(); - if (t == Integer.TYPE) { + if (Method.samePrimitive(t, Integer.TYPE)) { int[] arr = (int[]) array; arr[index] = i; } else { @@ -562,7 +532,7 @@ public static void setLong(Object array, int index, long l) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { Class t = array.getClass().getComponentType(); - if (t == Long.TYPE) { + if (Method.samePrimitive(t, Long.TYPE)) { long[] arr = (long[]) array; arr[index] = l; } else { @@ -590,7 +560,7 @@ public static void setFloat(Object array, int index, float f) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { Class t = array.getClass().getComponentType(); - if (t == Float.TYPE) { + if (Method.samePrimitive(t, Float.TYPE)) { float[] arr = (float[])array; arr[index] = f; } else { @@ -618,7 +588,7 @@ public static void setDouble(Object array, int index, double d) throws IllegalArgumentException, ArrayIndexOutOfBoundsException { Class t = array.getClass().getComponentType(); - if (t == Double.TYPE) { + if (Method.samePrimitive(t, Double.TYPE)) { double[] arr = (double[])array; arr[index] = d; } else { diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/lang/reflect/Method.java --- a/rt/emul/mini/src/main/java/java/lang/reflect/Method.java Tue May 06 17:46:47 2014 +0200 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Method.java Sun May 11 14:01:18 2014 +0200 @@ -552,28 +552,28 @@ } static Object fromPrimitive(Class type, Object o) { - if (type == Integer.TYPE) { + if (samePrimitive(type, Integer.TYPE)) { return fromRaw(Integer.class, "valueOf__Ljava_lang_Integer_2I", o); } - if (type == Long.TYPE) { + if (samePrimitive(type, Long.TYPE)) { return fromRaw(Long.class, "valueOf__Ljava_lang_Long_2J", o); } - if (type == Double.TYPE) { + if (samePrimitive(type, Double.TYPE)) { return fromRaw(Double.class, "valueOf__Ljava_lang_Double_2D", o); } - if (type == Float.TYPE) { + if (samePrimitive(type, Float.TYPE)) { return fromRaw(Float.class, "valueOf__Ljava_lang_Float_2F", o); } - if (type == Byte.TYPE) { + if (samePrimitive(type, Byte.TYPE)) { return fromRaw(Byte.class, "valueOf__Ljava_lang_Byte_2B", o); } - if (type == Boolean.TYPE) { + if (samePrimitive(type, Boolean.TYPE)) { return fromRaw(Boolean.class, "valueOf__Ljava_lang_Boolean_2Z", o); } - if (type == Short.TYPE) { + if (samePrimitive(type, Short.TYPE)) { return fromRaw(Short.class, "valueOf__Ljava_lang_Short_2S", o); } - if (type == Character.TYPE) { + if (samePrimitive(type, Character.TYPE)) { return fromRaw(Character.class, "valueOf__Ljava_lang_Character_2C", o); } if (type.getName().equals("void")) { @@ -581,6 +581,46 @@ } throw new IllegalStateException("Can't convert " + o); } + static boolean samePrimitive(Class c1, Class c2) { + if (c1 == c2) { + return true; + } + if (c1.isPrimitive()) { + return c1.getName().equals(c2.getName()); + } + return false; + } + + static String findArraySignature(Class type) { + if (!type.isPrimitive()) { + return "[L" + type.getName().replace('.', '/') + ";"; + } + if (samePrimitive(type, Integer.TYPE)) { + return "[I"; + } + if (samePrimitive(type, Long.TYPE)) { + return "[J"; + } + if (samePrimitive(type, Double.TYPE)) { + return "[D"; + } + if (samePrimitive(type, Float.TYPE)) { + return "[F"; + } + if (samePrimitive(type, Byte.TYPE)) { + return "[B"; + } + if (samePrimitive(type, Boolean.TYPE)) { + return "[Z"; + } + if (samePrimitive(type, Short.TYPE)) { + return "[S"; + } + if (samePrimitive(type, Character.TYPE)) { + return "[C"; + } + throw new IllegalStateException("Can't create array for " + type); + } @JavaScriptBody(args = { "cls", "m", "o" }, body = "return cls.cnstr(false)[m](o);" diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/Adler32.java --- a/rt/emul/mini/src/main/java/java/util/zip/Adler32.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,205 +0,0 @@ -/* Adler32.java - Computes Adler32 data checksum of a data stream - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.zip; - -/* - * Written using on-line Java Platform 1.2 API Specification, as well - * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). - * The actual Adler32 algorithm is taken from RFC 1950. - * Status: Believed complete and correct. - */ - -/** - * Computes Adler32 checksum for a stream of data. An Adler32 - * checksum is not as reliable as a CRC32 checksum, but a lot faster to - * compute. - *

- * The specification for Adler32 may be found in RFC 1950. - * (ZLIB Compressed Data Format Specification version 3.3) - *

- *

- * From that document: - *

- * "ADLER32 (Adler-32 checksum) - * This contains a checksum value of the uncompressed data - * (excluding any dictionary data) computed according to Adler-32 - * algorithm. This algorithm is a 32-bit extension and improvement - * of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 - * standard. - *

- * Adler-32 is composed of two sums accumulated per byte: s1 is - * the sum of all bytes, s2 is the sum of all s1 values. Both sums - * are done modulo 65521. s1 is initialized to 1, s2 to zero. The - * Adler-32 checksum is stored as s2*65536 + s1 in most- - * significant-byte first (network) order." - *

- * "8.2. The Adler-32 algorithm - *

- * The Adler-32 algorithm is much faster than the CRC32 algorithm yet - * still provides an extremely low probability of undetected errors. - *

- * The modulo on unsigned long accumulators can be delayed for 5552 - * bytes, so the modulo operation time is negligible. If the bytes - * are a, b, c, the second sum is 3a + 2b + c + 3, and so is position - * and order sensitive, unlike the first sum, which is just a - * checksum. That 65521 is prime is important to avoid a possible - * large class of two-byte errors that leave the check unchanged. - * (The Fletcher checksum uses 255, which is not prime and which also - * makes the Fletcher check insensitive to single byte changes 0 <-> - * 255.) - *

- * The sum s1 is initialized to 1 instead of zero to make the length - * of the sequence part of s2, so that the length does not have to be - * checked separately. (Any sequence of zeroes has a Fletcher - * checksum of zero.)" - * - * @author John Leuner, Per Bothner - * @since JDK 1.1 - * - * @see InflaterInputStream - * @see DeflaterOutputStream - */ -public class Adler32 implements Checksum -{ - - /** largest prime smaller than 65536 */ - private static final int BASE = 65521; - - private int checksum; //we do all in int. - - //Note that java doesn't have unsigned integers, - //so we have to be careful with what arithmetic - //we do. We return the checksum as a long to - //avoid sign confusion. - - /** - * Creates a new instance of the Adler32 class. - * The checksum starts off with a value of 1. - */ - public Adler32 () - { - reset(); - } - - /** - * Resets the Adler32 checksum to the initial value. - */ - public void reset () - { - checksum = 1; //Initialize to 1 - } - - /** - * Updates the checksum with the byte b. - * - * @param bval the data value to add. The high byte of the int is ignored. - */ - public void update (int bval) - { - //We could make a length 1 byte array and call update again, but I - //would rather not have that overhead - int s1 = checksum & 0xffff; - int s2 = checksum >>> 16; - - s1 = (s1 + (bval & 0xFF)) % BASE; - s2 = (s1 + s2) % BASE; - - checksum = (s2 << 16) + s1; - } - - /** - * Updates the checksum with the bytes taken from the array. - * - * @param buffer an array of bytes - */ - public void update (byte[] buffer) - { - update(buffer, 0, buffer.length); - } - - /** - * Updates the checksum with the bytes taken from the array. - * - * @param buf an array of bytes - * @param off the start of the data used for this update - * @param len the number of bytes to use for this update - */ - public void update (byte[] buf, int off, int len) - { - //(By Per Bothner) - int s1 = checksum & 0xffff; - int s2 = checksum >>> 16; - - while (len > 0) - { - // We can defer the modulo operation: - // s1 maximally grows from 65521 to 65521 + 255 * 3800 - // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 - int n = 3800; - if (n > len) - n = len; - len -= n; - while (--n >= 0) - { - s1 = s1 + (buf[off++] & 0xFF); - s2 = s2 + s1; - } - s1 %= BASE; - s2 %= BASE; - } - - /*Old implementation, borrowed from somewhere: - int n; - - while (len-- > 0) { - - s1 = (s1 + (bs[offset++] & 0xff)) % BASE; - s2 = (s2 + s1) % BASE; - }*/ - - checksum = (s2 << 16) | s1; - } - - /** - * Returns the Adler32 data checksum computed so far. - */ - public long getValue() - { - return (long) checksum & 0xffffffffL; - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/CRC32.java --- a/rt/emul/mini/src/main/java/java/util/zip/CRC32.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/* CRC32.java - Computes CRC32 data checksum of a data stream - Copyright (C) 1999. 2000, 2001 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package java.util.zip; - -/* - * Written using on-line Java Platform 1.2 API Specification, as well - * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). - * The actual CRC32 algorithm is taken from RFC 1952. - * Status: Believed complete and correct. - */ - -/** - * Computes CRC32 data checksum of a data stream. - * The actual CRC32 algorithm is described in RFC 1952 - * (GZIP file format specification version 4.3). - * Can be used to get the CRC32 over a stream if used with checked input/output - * streams. - * - * @see InflaterInputStream - * @see DeflaterOutputStream - * - * @author Per Bothner - * @date April 1, 1999. - */ -public class CRC32 implements Checksum -{ - /** The crc data checksum so far. */ - private int crc = 0; - - /** The fast CRC table. Computed once when the CRC32 class is loaded. */ - private static int[] crc_table = make_crc_table(); - - /** Make the table for a fast CRC. */ - private static int[] make_crc_table () - { - int[] crc_table = new int[256]; - for (int n = 0; n < 256; n++) - { - int c = n; - for (int k = 8; --k >= 0; ) - { - if ((c & 1) != 0) - c = 0xedb88320 ^ (c >>> 1); - else - c = c >>> 1; - } - crc_table[n] = c; - } - return crc_table; - } - - /** - * Returns the CRC32 data checksum computed so far. - */ - public long getValue () - { - return (long) crc & 0xffffffffL; - } - - /** - * Resets the CRC32 data checksum as if no update was ever called. - */ - public void reset () { crc = 0; } - - /** - * Updates the checksum with the int bval. - * - * @param bval (the byte is taken as the lower 8 bits of bval) - */ - - public void update (int bval) - { - int c = ~crc; - c = crc_table[(c ^ bval) & 0xff] ^ (c >>> 8); - crc = ~c; - } - - /** - * Adds the byte array to the data checksum. - * - * @param buf the buffer which contains the data - * @param off the offset in the buffer where the data starts - * @param len the length of the data - */ - public void update (byte[] buf, int off, int len) - { - int c = ~crc; - while (--len >= 0) - c = crc_table[(c ^ buf[off++]) & 0xff] ^ (c >>> 8); - crc = ~c; - } - - /** - * Adds the complete byte array to the data checksum. - */ - public void update (byte[] buf) { update(buf, 0, buf.length); } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/Checksum.java --- a/rt/emul/mini/src/main/java/java/util/zip/Checksum.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.zip; - -/** - * An interface representing a data checksum. - * - * @author David Connelly - */ -public -interface Checksum { - /** - * Updates the current checksum with the specified byte. - * - * @param b the byte to update the checksum with - */ - public void update(int b); - - /** - * Updates the current checksum with the specified array of bytes. - * @param b the byte array to update the checksum with - * @param off the start offset of the data - * @param len the number of bytes to use for the update - */ - public void update(byte[] b, int off, int len); - - /** - * Returns the current checksum value. - * @return the current checksum value - */ - public long getValue(); - - /** - * Resets the checksum to its initial value. - */ - public void reset(); -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/DataFormatException.java --- a/rt/emul/mini/src/main/java/java/util/zip/DataFormatException.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.zip; - -/** - * Signals that a data format error has occurred. - * - * @author David Connelly - */ -public -class DataFormatException extends Exception { - private static final long serialVersionUID = 2219632870893641452L; - - /** - * Constructs a DataFormatException with no detail message. - */ - public DataFormatException() { - super(); - } - - /** - * Constructs a DataFormatException with the specified detail message. - * A detail message is a String that describes this particular exception. - * @param s the String containing a detail message - */ - public DataFormatException(String s) { - super(s); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/Inflater.java --- a/rt/emul/mini/src/main/java/java/util/zip/Inflater.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,310 +0,0 @@ -/* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.zip; - -/** - * This class provides support for general purpose decompression using the - * popular ZLIB compression library. The ZLIB compression library was - * initially developed as part of the PNG graphics standard and is not - * protected by patents. It is fully described in the specifications at - * the java.util.zip - * package description. - * - *

The following code fragment demonstrates a trivial compression - * and decompression of a string using Deflater and - * Inflater. - * - *

- * try {
- *     // Encode a String into bytes
- *     String inputString = "blahblahblah\u20AC\u20AC";
- *     byte[] input = inputString.getBytes("UTF-8");
- *
- *     // Compress the bytes
- *     byte[] output = new byte[100];
- *     Deflater compresser = new Deflater();
- *     compresser.setInput(input);
- *     compresser.finish();
- *     int compressedDataLength = compresser.deflate(output);
- *
- *     // Decompress the bytes
- *     Inflater decompresser = new Inflater();
- *     decompresser.setInput(output, 0, compressedDataLength);
- *     byte[] result = new byte[100];
- *     int resultLength = decompresser.inflate(result);
- *     decompresser.end();
- *
- *     // Decode the bytes into a String
- *     String outputString = new String(result, 0, resultLength, "UTF-8");
- * } catch(java.io.UnsupportedEncodingException ex) {
- *     // handle
- * } catch (java.util.zip.DataFormatException ex) {
- *     // handle
- * }
- * 
- * - * @see Deflater - * @author David Connelly - * - */ -public -class Inflater { - private final org.apidesign.bck2brwsr.emul.zip.Inflater impl; - - /** - * Creates a new decompressor. If the parameter 'nowrap' is true then - * the ZLIB header and checksum fields will not be used. This provides - * compatibility with the compression format used by both GZIP and PKZIP. - *

- * Note: When using the 'nowrap' option it is also necessary to provide - * an extra "dummy" byte as input. This is required by the ZLIB native - * library in order to support certain optimizations. - * - * @param nowrap if true then support GZIP compatible compression - */ - public Inflater(boolean nowrap) { - if (getClass() == org.apidesign.bck2brwsr.emul.zip.Inflater.class) { - impl = null; - } else { - impl = new org.apidesign.bck2brwsr.emul.zip.Inflater(nowrap); - } - } - - /** - * Creates a new decompressor. - */ - public Inflater() { - this(false); - } - - /** - * Sets input data for decompression. Should be called whenever - * needsInput() returns true indicating that more input data is - * required. - * @param b the input data bytes - * @param off the start offset of the input data - * @param len the length of the input data - * @see Inflater#needsInput - */ - public void setInput(byte[] b, int off, int len) { - impl.setInput(b, off, len); - } - - /** - * Sets input data for decompression. Should be called whenever - * needsInput() returns true indicating that more input data is - * required. - * @param b the input data bytes - * @see Inflater#needsInput - */ - public void setInput(byte[] b) { - impl.setInput(b); - } - - /** - * Sets the preset dictionary to the given array of bytes. Should be - * called when inflate() returns 0 and needsDictionary() returns true - * indicating that a preset dictionary is required. The method getAdler() - * can be used to get the Adler-32 value of the dictionary needed. - * @param b the dictionary data bytes - * @param off the start offset of the data - * @param len the length of the data - * @see Inflater#needsDictionary - * @see Inflater#getAdler - */ - public void setDictionary(byte[] b, int off, int len) { - impl.setDictionary(b, off, len); - } - - /** - * Sets the preset dictionary to the given array of bytes. Should be - * called when inflate() returns 0 and needsDictionary() returns true - * indicating that a preset dictionary is required. The method getAdler() - * can be used to get the Adler-32 value of the dictionary needed. - * @param b the dictionary data bytes - * @see Inflater#needsDictionary - * @see Inflater#getAdler - */ - public void setDictionary(byte[] b) { - impl.setDictionary(b); - } - - /** - * Returns the total number of bytes remaining in the input buffer. - * This can be used to find out what bytes still remain in the input - * buffer after decompression has finished. - * @return the total number of bytes remaining in the input buffer - */ - public int getRemaining() { - return impl.getRemaining(); - } - - /** - * Returns true if no data remains in the input buffer. This can - * be used to determine if #setInput should be called in order - * to provide more input. - * @return true if no data remains in the input buffer - */ - public boolean needsInput() { - return impl.needsInput(); - } - - /** - * Returns true if a preset dictionary is needed for decompression. - * @return true if a preset dictionary is needed for decompression - * @see Inflater#setDictionary - */ - public boolean needsDictionary() { - return impl.needsDictionary(); - } - - /** - * Returns true if the end of the compressed data stream has been - * reached. - * @return true if the end of the compressed data stream has been - * reached - */ - public boolean finished() { - return impl.finished(); - } - - /** - * Uncompresses bytes into specified buffer. Returns actual number - * of bytes uncompressed. A return value of 0 indicates that - * needsInput() or needsDictionary() should be called in order to - * determine if more input data or a preset dictionary is required. - * In the latter case, getAdler() can be used to get the Adler-32 - * value of the dictionary required. - * @param b the buffer for the uncompressed data - * @param off the start offset of the data - * @param len the maximum number of uncompressed bytes - * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid - * @see Inflater#needsInput - * @see Inflater#needsDictionary - */ - public int inflate(byte[] b, int off, int len) - throws DataFormatException - { - return impl.inflate(b, off, len); - } - - /** - * Uncompresses bytes into specified buffer. Returns actual number - * of bytes uncompressed. A return value of 0 indicates that - * needsInput() or needsDictionary() should be called in order to - * determine if more input data or a preset dictionary is required. - * In the latter case, getAdler() can be used to get the Adler-32 - * value of the dictionary required. - * @param b the buffer for the uncompressed data - * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid - * @see Inflater#needsInput - * @see Inflater#needsDictionary - */ - public int inflate(byte[] b) throws DataFormatException { - return impl.inflate(b); - } - - /** - * Returns the ADLER-32 value of the uncompressed data. - * @return the ADLER-32 value of the uncompressed data - */ - public int getAdler() { - return impl.getAdler(); - } - - /** - * Returns the total number of compressed bytes input so far. - * - *

Since the number of bytes may be greater than - * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now - * the preferred means of obtaining this information.

- * - * @return the total number of compressed bytes input so far - */ - public int getTotalIn() { - return impl.getTotalIn(); - } - - /** - * Returns the total number of compressed bytes input so far.

- * - * @return the total (non-negative) number of compressed bytes input so far - * @since 1.5 - */ - public long getBytesRead() { - return impl.getBytesRead(); - } - - /** - * Returns the total number of uncompressed bytes output so far. - * - *

Since the number of bytes may be greater than - * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now - * the preferred means of obtaining this information.

- * - * @return the total number of uncompressed bytes output so far - */ - public int getTotalOut() { - return impl.getTotalOut(); - } - - /** - * Returns the total number of uncompressed bytes output so far.

- * - * @return the total (non-negative) number of uncompressed bytes output so far - * @since 1.5 - */ - public long getBytesWritten() { - return impl.getBytesWritten(); - } - - /** - * Resets inflater so that a new set of input data can be processed. - */ - public void reset() { - impl.reset(); - } - - /** - * Closes the decompressor and discards any unprocessed input. - * This method should be called when the decompressor is no longer - * being used, but will also be called automatically by the finalize() - * method. Once this method is called, the behavior of the Inflater - * object is undefined. - */ - public void end() { - impl.end(); - } - - /** - * Closes the decompressor when garbage is collected. - */ - protected void finalize() { - end(); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/InflaterInputStream.java --- a/rt/emul/mini/src/main/java/java/util/zip/InflaterInputStream.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,288 +0,0 @@ -/* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.zip; - -import java.io.FilterInputStream; -import java.io.InputStream; -import java.io.IOException; -import java.io.EOFException; - -/** - * This class implements a stream filter for uncompressing data in the - * "deflate" compression format. It is also used as the basis for other - * decompression filters, such as GZIPInputStream. - * - * @see Inflater - * @author David Connelly - */ -public -class InflaterInputStream extends FilterInputStream { - /** - * Decompressor for this stream. - */ - protected Inflater inf; - - /** - * Input buffer for decompression. - */ - protected byte[] buf; - - /** - * Length of input buffer. - */ - protected int len; - - private boolean closed = false; - // this flag is set to true after EOF has reached - private boolean reachEOF = false; - - /** - * Check to make sure that this stream has not been closed - */ - private void ensureOpen() throws IOException { - if (closed) { - throw new IOException("Stream closed"); - } - } - - - /** - * Creates a new input stream with the specified decompressor and - * buffer size. - * @param in the input stream - * @param inf the decompressor ("inflater") - * @param size the input buffer size - * @exception IllegalArgumentException if size is <= 0 - */ - public InflaterInputStream(InputStream in, Inflater inf, int size) { - super(in); - if (in == null || inf == null) { - throw new NullPointerException(); - } else if (size <= 0) { - throw new IllegalArgumentException("buffer size <= 0"); - } - this.inf = inf; - buf = new byte[size]; - } - - /** - * Creates a new input stream with the specified decompressor and a - * default buffer size. - * @param in the input stream - * @param inf the decompressor ("inflater") - */ - public InflaterInputStream(InputStream in, Inflater inf) { - this(in, inf, 512); - } - - boolean usesDefaultInflater = false; - - /** - * Creates a new input stream with a default decompressor and buffer size. - * @param in the input stream - */ - public InflaterInputStream(InputStream in) { - this(in, new Inflater()); - usesDefaultInflater = true; - } - - private byte[] singleByteBuf = new byte[1]; - - /** - * Reads a byte of uncompressed data. This method will block until - * enough input is available for decompression. - * @return the byte read, or -1 if end of compressed input is reached - * @exception IOException if an I/O error has occurred - */ - public int read() throws IOException { - ensureOpen(); - return read(singleByteBuf, 0, 1) == -1 ? -1 : singleByteBuf[0] & 0xff; - } - - /** - * Reads uncompressed data into an array of bytes. If len is not - * zero, the method will block until some input can be decompressed; otherwise, - * no bytes are read and 0 is returned. - * @param b the buffer into which the data is read - * @param off the start offset in the destination array b - * @param len the maximum number of bytes read - * @return the actual number of bytes read, or -1 if the end of the - * compressed input is reached or a preset dictionary is needed - * @exception NullPointerException If b is null. - * @exception IndexOutOfBoundsException If off is negative, - * len is negative, or len is greater than - * b.length - off - * @exception ZipException if a ZIP format error has occurred - * @exception IOException if an I/O error has occurred - */ - public int read(byte[] b, int off, int len) throws IOException { - ensureOpen(); - if (b == null) { - throw new NullPointerException(); - } else if (off < 0 || len < 0 || len > b.length - off) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return 0; - } - try { - int n; - while ((n = inf.inflate(b, off, len)) == 0) { - if (inf.finished() || inf.needsDictionary()) { - reachEOF = true; - return -1; - } - if (inf.needsInput()) { - fill(); - } - } - return n; - } catch (DataFormatException e) { - String s = e.getMessage(); - throw new ZipException(s != null ? s : "Invalid ZLIB data format"); - } - } - - /** - * Returns 0 after EOF has been reached, otherwise always return 1. - *

- * Programs should not count on this method to return the actual number - * of bytes that could be read without blocking. - * - * @return 1 before EOF and 0 after EOF. - * @exception IOException if an I/O error occurs. - * - */ - public int available() throws IOException { - ensureOpen(); - if (reachEOF) { - return 0; - } else { - return 1; - } - } - - private byte[] b = new byte[512]; - - /** - * Skips specified number of bytes of uncompressed data. - * @param n the number of bytes to skip - * @return the actual number of bytes skipped. - * @exception IOException if an I/O error has occurred - * @exception IllegalArgumentException if n < 0 - */ - public long skip(long n) throws IOException { - if (n < 0) { - throw new IllegalArgumentException("negative skip length"); - } - ensureOpen(); - int max = (int)Math.min(n, Integer.MAX_VALUE); - int total = 0; - while (total < max) { - int len = max - total; - if (len > b.length) { - len = b.length; - } - len = read(b, 0, len); - if (len == -1) { - reachEOF = true; - break; - } - total += len; - } - return total; - } - - /** - * Closes this input stream and releases any system resources associated - * with the stream. - * @exception IOException if an I/O error has occurred - */ - public void close() throws IOException { - if (!closed) { - if (usesDefaultInflater) - inf.end(); - in.close(); - closed = true; - } - } - - /** - * Fills input buffer with more data to decompress. - * @exception IOException if an I/O error has occurred - */ - protected void fill() throws IOException { - ensureOpen(); - len = in.read(buf, 0, buf.length); - if (len == -1) { - throw new EOFException("Unexpected end of ZLIB input stream"); - } - inf.setInput(buf, 0, len); - } - - /** - * Tests if this input stream supports the mark and - * reset methods. The markSupported - * method of InflaterInputStream returns - * false. - * - * @return a boolean indicating if this stream type supports - * the mark and reset methods. - * @see java.io.InputStream#mark(int) - * @see java.io.InputStream#reset() - */ - public boolean markSupported() { - return false; - } - - /** - * Marks the current position in this input stream. - * - *

The mark method of InflaterInputStream - * does nothing. - * - * @param readlimit the maximum limit of bytes that can be read before - * the mark position becomes invalid. - * @see java.io.InputStream#reset() - */ - public synchronized void mark(int readlimit) { - } - - /** - * Repositions this stream to the position at the time the - * mark method was last called on this input stream. - * - *

The method reset for class - * InflaterInputStream does nothing except throw an - * IOException. - * - * @exception IOException if this method is invoked. - * @see java.io.InputStream#mark(int) - * @see java.io.IOException - */ - public synchronized void reset() throws IOException { - throw new IOException("mark/reset not supported"); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/ZStreamRef.java --- a/rt/emul/mini/src/main/java/java/util/zip/ZStreamRef.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.zip; - -/** - * A reference to the native zlib's z_stream structure. - */ - -class ZStreamRef { - - private long address; - ZStreamRef (long address) { - this.address = address; - } - - long address() { - return address; - } - - void clear() { - address = 0; - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/ZipConstants.java --- a/rt/emul/mini/src/main/java/java/util/zip/ZipConstants.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.zip; - -/* - * This interface defines the constants that are used by the classes - * which manipulate ZIP files. - * - * @author David Connelly - */ -interface ZipConstants { - /* - * Header signatures - */ - static long LOCSIG = 0x04034b50L; // "PK\003\004" - static long EXTSIG = 0x08074b50L; // "PK\007\008" - static long CENSIG = 0x02014b50L; // "PK\001\002" - static long ENDSIG = 0x06054b50L; // "PK\005\006" - - /* - * Header sizes in bytes (including signatures) - */ - static final int LOCHDR = 30; // LOC header size - static final int EXTHDR = 16; // EXT header size - static final int CENHDR = 46; // CEN header size - static final int ENDHDR = 22; // END header size - - /* - * Local file (LOC) header field offsets - */ - static final int LOCVER = 4; // version needed to extract - static final int LOCFLG = 6; // general purpose bit flag - static final int LOCHOW = 8; // compression method - static final int LOCTIM = 10; // modification time - static final int LOCCRC = 14; // uncompressed file crc-32 value - static final int LOCSIZ = 18; // compressed size - static final int LOCLEN = 22; // uncompressed size - static final int LOCNAM = 26; // filename length - static final int LOCEXT = 28; // extra field length - - /* - * Extra local (EXT) header field offsets - */ - static final int EXTCRC = 4; // uncompressed file crc-32 value - static final int EXTSIZ = 8; // compressed size - static final int EXTLEN = 12; // uncompressed size - - /* - * Central directory (CEN) header field offsets - */ - static final int CENVEM = 4; // version made by - static final int CENVER = 6; // version needed to extract - static final int CENFLG = 8; // encrypt, decrypt flags - static final int CENHOW = 10; // compression method - static final int CENTIM = 12; // modification time - static final int CENCRC = 16; // uncompressed file crc-32 value - static final int CENSIZ = 20; // compressed size - static final int CENLEN = 24; // uncompressed size - static final int CENNAM = 28; // filename length - static final int CENEXT = 30; // extra field length - static final int CENCOM = 32; // comment length - static final int CENDSK = 34; // disk number start - static final int CENATT = 36; // internal file attributes - static final int CENATX = 38; // external file attributes - static final int CENOFF = 42; // LOC header offset - - /* - * End of central directory (END) header field offsets - */ - static final int ENDSUB = 8; // number of entries on this disk - static final int ENDTOT = 10; // total number of entries - static final int ENDSIZ = 12; // central directory size in bytes - static final int ENDOFF = 16; // offset of first CEN header - static final int ENDCOM = 20; // zip file comment length -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/ZipEntry.java --- a/rt/emul/mini/src/main/java/java/util/zip/ZipEntry.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,331 +0,0 @@ -/* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.zip; - -/** - * This class is used to represent a ZIP file entry. - * - * @author David Connelly - */ -public -class ZipEntry implements ZipConstants, Cloneable { - String name; // entry name - long time = -1; // modification time (in DOS time) - long crc = -1; // crc-32 of entry data - long size = -1; // uncompressed size of entry data - long csize = -1; // compressed size of entry data - int method = -1; // compression method - int flag = 0; // general purpose flag - byte[] extra; // optional extra field data for entry - String comment; // optional comment string for entry - - /** - * Compression method for uncompressed entries. - */ - public static final int STORED = 0; - - /** - * Compression method for compressed (deflated) entries. - */ - public static final int DEFLATED = 8; - - /** - * Creates a new zip entry with the specified name. - * - * @param name the entry name - * @exception NullPointerException if the entry name is null - * @exception IllegalArgumentException if the entry name is longer than - * 0xFFFF bytes - */ - public ZipEntry(String name) { - if (name == null) { - throw new NullPointerException(); - } - if (name.length() > 0xFFFF) { - throw new IllegalArgumentException("entry name too long"); - } - this.name = name; - } - - /** - * Creates a new zip entry with fields taken from the specified - * zip entry. - * @param e a zip Entry object - */ - public ZipEntry(ZipEntry e) { - name = e.name; - time = e.time; - crc = e.crc; - size = e.size; - csize = e.csize; - method = e.method; - flag = e.flag; - extra = e.extra; - comment = e.comment; - } - - /* - * Creates a new un-initialized zip entry - */ - ZipEntry() {} - - /** - * Returns the name of the entry. - * @return the name of the entry - */ - public String getName() { - return name; - } - - /** - * Sets the modification time of the entry. - * @param time the entry modification time in number of milliseconds - * since the epoch - * @see #getTime() - */ - public void setTime(long time) { - this.time = javaToDosTime(time); - } - - /** - * Returns the modification time of the entry, or -1 if not specified. - * @return the modification time of the entry, or -1 if not specified - * @see #setTime(long) - */ - public long getTime() { - return time != -1 ? dosToJavaTime(time) : -1; - } - - /** - * Sets the uncompressed size of the entry data. - * @param size the uncompressed size in bytes - * @exception IllegalArgumentException if the specified size is less - * than 0, is greater than 0xFFFFFFFF when - * ZIP64 format is not supported, - * or is less than 0 when ZIP64 is supported - * @see #getSize() - */ - public void setSize(long size) { - if (size < 0) { - throw new IllegalArgumentException("invalid entry size"); - } - this.size = size; - } - - /** - * Returns the uncompressed size of the entry data, or -1 if not known. - * @return the uncompressed size of the entry data, or -1 if not known - * @see #setSize(long) - */ - public long getSize() { - return size; - } - - /** - * Returns the size of the compressed entry data, or -1 if not known. - * In the case of a stored entry, the compressed size will be the same - * as the uncompressed size of the entry. - * @return the size of the compressed entry data, or -1 if not known - * @see #setCompressedSize(long) - */ - public long getCompressedSize() { - return csize; - } - - /** - * Sets the size of the compressed entry data. - * @param csize the compressed size to set to - * @see #getCompressedSize() - */ - public void setCompressedSize(long csize) { - this.csize = csize; - } - - /** - * Sets the CRC-32 checksum of the uncompressed entry data. - * @param crc the CRC-32 value - * @exception IllegalArgumentException if the specified CRC-32 value is - * less than 0 or greater than 0xFFFFFFFF - * @see #getCrc() - */ - public void setCrc(long crc) { - if (crc < 0 || crc > 0xFFFFFFFFL) { - throw new IllegalArgumentException("invalid entry crc-32"); - } - this.crc = crc; - } - - /** - * Returns the CRC-32 checksum of the uncompressed entry data, or -1 if - * not known. - * @return the CRC-32 checksum of the uncompressed entry data, or -1 if - * not known - * @see #setCrc(long) - */ - public long getCrc() { - return crc; - } - - /** - * Sets the compression method for the entry. - * @param method the compression method, either STORED or DEFLATED - * @exception IllegalArgumentException if the specified compression - * method is invalid - * @see #getMethod() - */ - public void setMethod(int method) { - if (method != STORED && method != DEFLATED) { - throw new IllegalArgumentException("invalid compression method"); - } - this.method = method; - } - - /** - * Returns the compression method of the entry, or -1 if not specified. - * @return the compression method of the entry, or -1 if not specified - * @see #setMethod(int) - */ - public int getMethod() { - return method; - } - - /** - * Sets the optional extra field data for the entry. - * @param extra the extra field data bytes - * @exception IllegalArgumentException if the length of the specified - * extra field data is greater than 0xFFFF bytes - * @see #getExtra() - */ - public void setExtra(byte[] extra) { - if (extra != null && extra.length > 0xFFFF) { - throw new IllegalArgumentException("invalid extra field length"); - } - this.extra = extra; - } - - /** - * Returns the extra field data for the entry, or null if none. - * @return the extra field data for the entry, or null if none - * @see #setExtra(byte[]) - */ - public byte[] getExtra() { - return extra; - } - - /** - * Sets the optional comment string for the entry. - * - *

ZIP entry comments have maximum length of 0xffff. If the length of the - * specified comment string is greater than 0xFFFF bytes after encoding, only - * the first 0xFFFF bytes are output to the ZIP file entry. - * - * @param comment the comment string - * - * @see #getComment() - */ - public void setComment(String comment) { - this.comment = comment; - } - - /** - * Returns the comment string for the entry, or null if none. - * @return the comment string for the entry, or null if none - * @see #setComment(String) - */ - public String getComment() { - return comment; - } - - /** - * Returns true if this is a directory entry. A directory entry is - * defined to be one whose name ends with a '/'. - * @return true if this is a directory entry - */ - public boolean isDirectory() { - return name.endsWith("/"); - } - - /** - * Returns a string representation of the ZIP entry. - */ - public String toString() { - return getName(); - } - - /* - * Converts DOS time to Java time (number of milliseconds since epoch). - */ - private static long dosToJavaTime(long dtime) { - return dtime; - /* XXX: - Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80), - (int)(((dtime >> 21) & 0x0f) - 1), - (int)((dtime >> 16) & 0x1f), - (int)((dtime >> 11) & 0x1f), - (int)((dtime >> 5) & 0x3f), - (int)((dtime << 1) & 0x3e)); - return d.getTime(); - */ - } - - /* - * Converts Java time to DOS time. - */ - private static long javaToDosTime(long time) { - return time; - /* XXX: - Date d = new Date(time); - int year = d.getYear() + 1900; - if (year < 1980) { - return (1 << 21) | (1 << 16); - } - return (year - 1980) << 25 | (d.getMonth() + 1) << 21 | - d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 | - d.getSeconds() >> 1; - */ - } - - /** - * Returns the hash code value for this entry. - */ - public int hashCode() { - return name.hashCode(); - } - - /** - * Returns a copy of this entry. - */ - public Object clone() { - try { - ZipEntry e = (ZipEntry)super.clone(); - e.extra = (extra == null) ? null : extra.clone(); - return e; - } catch (CloneNotSupportedException e) { - // This should never happen, since we are Cloneable - throw new IllegalStateException(); - } - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/ZipException.java --- a/rt/emul/mini/src/main/java/java/util/zip/ZipException.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.zip; - -import java.io.IOException; - -/** - * Signals that a Zip exception of some sort has occurred. - * - * @author unascribed - * @see java.io.IOException - * @since JDK1.0 - */ - -public -class ZipException extends IOException { - private static final long serialVersionUID = 8000196834066748623L; - - /** - * Constructs a ZipException with null - * as its error detail message. - */ - public ZipException() { - super(); - } - - /** - * Constructs a ZipException with the specified detail - * message. - * - * @param s the detail message. - */ - - public ZipException(String s) { - super(s); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/ZipInputStream.java --- a/rt/emul/mini/src/main/java/java/util/zip/ZipInputStream.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package java.util.zip; - -import java.io.InputStream; -import java.io.IOException; - -/** - * This class implements an input stream filter for reading files in the - * ZIP file format. Includes support for both compressed and uncompressed - * entries. - * - * @author David Connelly - */ -public -class ZipInputStream extends InflaterInputStream implements ZipConstants { - private final org.apidesign.bck2brwsr.emul.zip.ZipInputStream impl; - - /** - * Creates a new ZIP input stream. - * - *

The UTF-8 {@link java.nio.charset.Charset charset} is used to - * decode the entry names. - * - * @param in the actual input stream - */ - public ZipInputStream(InputStream in) { - super(in); - impl = new org.apidesign.bck2brwsr.emul.zip.ZipInputStream(in); - } - - /** - * Creates a new ZIP input stream. - * - * @param in the actual input stream - * - * @param charset - * The {@linkplain java.nio.charset.Charset charset} to be - * used to decode the ZIP entry name (ignored if the - * language - * encoding bit of the ZIP entry's general purpose bit - * flag is set). - * - * @since 1.7 - * - public ZipInputStream(InputStream in, Charset charset) { - super(new PushbackInputStream(in, 512), new Inflater(true), 512); - usesDefaultInflater = true; - if(in == null) { - throw new NullPointerException("in is null"); - } - if (charset == null) - throw new NullPointerException("charset is null"); - this.zc = ZipCoder.get(charset); - } - */ - - /** - * Reads the next ZIP file entry and positions the stream at the - * beginning of the entry data. - * @return the next ZIP file entry, or null if there are no more entries - * @exception ZipException if a ZIP file error has occurred - * @exception IOException if an I/O error has occurred - */ - public ZipEntry getNextEntry() throws IOException { - return impl.getNextEntry(); - } - - /** - * Closes the current ZIP entry and positions the stream for reading the - * next entry. - * @exception ZipException if a ZIP file error has occurred - * @exception IOException if an I/O error has occurred - */ - public void closeEntry() throws IOException { - impl.closeEntry(); - } - - /** - * Returns 0 after EOF has reached for the current entry data, - * otherwise always return 1. - *

- * Programs should not count on this method to return the actual number - * of bytes that could be read without blocking. - * - * @return 1 before EOF and 0 after EOF has reached for current entry. - * @exception IOException if an I/O error occurs. - * - */ - public int available() throws IOException { - return impl.available(); - } - - /** - * Reads from the current ZIP entry into an array of bytes. - * If len is not zero, the method - * blocks until some input is available; otherwise, no - * bytes are read and 0 is returned. - * @param b the buffer into which the data is read - * @param off the start offset in the destination array b - * @param len the maximum number of bytes read - * @return the actual number of bytes read, or -1 if the end of the - * entry is reached - * @exception NullPointerException if b is null. - * @exception IndexOutOfBoundsException if off is negative, - * len is negative, or len is greater than - * b.length - off - * @exception ZipException if a ZIP file error has occurred - * @exception IOException if an I/O error has occurred - */ - public int read(byte[] b, int off, int len) throws IOException { - return impl.read(b, off, len); - } - - /** - * Skips specified number of bytes in the current ZIP entry. - * @param n the number of bytes to skip - * @return the actual number of bytes skipped - * @exception ZipException if a ZIP file error has occurred - * @exception IOException if an I/O error has occurred - * @exception IllegalArgumentException if n < 0 - */ - public long skip(long n) throws IOException { - return impl.skip(n); - } - - /** - * Closes this input stream and releases any system resources associated - * with the stream. - * @exception IOException if an I/O error has occurred - */ - public void close() throws IOException { - impl.close(); - } - - /** - * Creates a new ZipEntry object for the specified - * entry name. - * - * @param name the ZIP file entry name - * @return the ZipEntry just created - */ - protected ZipEntry createZipEntry(String name) { - return new ZipEntry(name); - } - - @Override - public int read() throws IOException { - return impl.read(); - } - - @Override - public boolean markSupported() { - return impl.markSupported(); - } - - @Override - public void mark(int readlimit) { - impl.mark(readlimit); - } - - @Override - public void reset() throws IOException { - impl.reset(); - } - - @Override - public int read(byte[] b) throws IOException { - return impl.read(b); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/package-info.java --- a/rt/emul/mini/src/main/java/java/util/zip/package-info.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -@Exported -package java.util.zip; - -import org.apidesign.bck2brwsr.core.Exported; diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/java/util/zip/package.html --- a/rt/emul/mini/src/main/java/java/util/zip/package.html Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ - - - - - - - - -Provides classes for reading and writing the standard ZIP and GZIP -file formats. Also includes classes for compressing and decompressing -data using the DEFLATE compression algorithm, which is used by the -ZIP and GZIP file formats. Additionally, there are utility classes -for computing the CRC-32 and Adler-32 checksums of arbitrary -input streams. - - -

Package Specification

- - - - - - - -@since JDK1.1 - - - - diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Adler32.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Adler32.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,139 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -final class Adler32 implements Checksum { - - // largest prime smaller than 65536 - static final private int BASE=65521; - // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 - static final private int NMAX=5552; - - private long s1=1L; - private long s2=0L; - - public void reset(long init){ - s1=init&0xffff; - s2=(init>>16)&0xffff; - } - - public void reset(){ - s1=1L; - s2=0L; - } - - public long getValue(){ - return ((s2<<16)|s1); - } - - public void update(byte[] buf, int index, int len){ - - if(len==1){ - s1+=buf[index++]&0xff; s2+=s1; - s1%=BASE; - s2%=BASE; - return; - } - - int len1 = len/NMAX; - int len2 = len%NMAX; - while(len1-->0) { - int k=NMAX; - len-=k; - while(k-->0){ - s1+=buf[index++]&0xff; s2+=s1; - } - s1%=BASE; - s2%=BASE; - } - - int k=len2; - len-=k; - while(k-->0){ - s1+=buf[index++]&0xff; s2+=s1; - } - s1%=BASE; - s2%=BASE; - } - - public Adler32 copy(){ - Adler32 foo = new Adler32(); - foo.s1 = this.s1; - foo.s2 = this.s2; - return foo; - } - - // The following logic has come from zlib.1.2. - static long combine(long adler1, long adler2, long len2){ - long BASEL = (long)BASE; - long sum1; - long sum2; - long rem; // unsigned int - - rem = len2 % BASEL; - sum1 = adler1 & 0xffffL; - sum2 = rem * sum1; - sum2 %= BASEL; // MOD(sum2); - sum1 += (adler2 & 0xffffL) + BASEL - 1; - sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; - if (sum1 >= BASEL) sum1 -= BASEL; - if (sum1 >= BASEL) sum1 -= BASEL; - if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); - if (sum2 >= BASEL) sum2 -= BASEL; - return sum1 | (sum2 << 16); - } - -/* - private java.util.zip.Adler32 adler=new java.util.zip.Adler32(); - public void update(byte[] buf, int index, int len){ - if(buf==null) {adler.reset();} - else{adler.update(buf, index, len);} - } - public void reset(){ - adler.reset(); - } - public void reset(long init){ - if(init==1L){ - adler.reset(); - } - else{ - System.err.println("unsupported operation"); - } - } - public long getValue(){ - return adler.getValue(); - } -*/ -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/CRC32.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/CRC32.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -import org.apidesign.bck2brwsr.emul.lang.System; - -final class CRC32 implements Checksum { - - /* - * The following logic has come from RFC1952. - */ - private int v = 0; - private static int[] crc_table = null; - static { - crc_table = new int[256]; - for (int n = 0; n < 256; n++) { - int c = n; - for (int k = 8; --k >= 0; ) { - if ((c & 1) != 0) - c = 0xedb88320 ^ (c >>> 1); - else - c = c >>> 1; - } - crc_table[n] = c; - } - } - - public void update (byte[] buf, int index, int len) { - int c = ~v; - while (--len >= 0) - c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); - v = ~c; - } - - public void reset(){ - v = 0; - } - - public void reset(long vv){ - v = (int)(vv&0xffffffffL); - } - - public long getValue(){ - return (long)(v&0xffffffffL); - } - - // The following logic has come from zlib.1.2. - private static final int GF2_DIM = 32; - static long combine(long crc1, long crc2, long len2){ - long row; - long[] even = new long[GF2_DIM]; - long[] odd = new long[GF2_DIM]; - - // degenerate case (also disallow negative lengths) - if (len2 <= 0) - return crc1; - - // put operator for one zero bit in odd - odd[0] = 0xedb88320L; // CRC-32 polynomial - row = 1; - for (int n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - // put operator for two zero bits in even - gf2_matrix_square(even, odd); - - // put operator for four zero bits in odd - gf2_matrix_square(odd, even); - - // apply len2 zeros to crc1 (first square will put the operator for one - // zero byte, eight zero bits, in even) - do { - // apply zeros operator for this bit of len2 - gf2_matrix_square(even, odd); - if ((len2 & 1)!=0) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - // if no more bits set, then done - if (len2 == 0) - break; - - // another iteration of the loop with odd and even swapped - gf2_matrix_square(odd, even); - if ((len2 & 1)!=0) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - // if no more bits set, then done - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; - } - - private static long gf2_matrix_times(long[] mat, long vec){ - long sum = 0; - int index = 0; - while (vec!=0) { - if ((vec & 1)!=0) - sum ^= mat[index]; - vec >>= 1; - index++; - } - return sum; - } - - static final void gf2_matrix_square(long[] square, long[] mat) { - for (int n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); - } - - /* - private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32(); - - public void update(byte[] buf, int index, int len){ - if(buf==null) {crc32.reset();} - else{crc32.update(buf, index, len);} - } - public void reset(){ - crc32.reset(); - } - public void reset(long init){ - if(init==0L){ - crc32.reset(); - } - else{ - System.err.println("unsupported operation"); - } - } - public long getValue(){ - return crc32.getValue(); - } -*/ - public CRC32 copy(){ - CRC32 foo = new CRC32(); - foo.v = this.v; - return foo; - } - - public static int[] getCRC32Table(){ - int[] tmp = new int[crc_table.length]; - System.arraycopy(crc_table, 0, tmp, 0, tmp.length); - return tmp; - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Checksum.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Checksum.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -interface Checksum { - void update(byte[] buf, int index, int len); - void reset(); - void reset(long init); - long getValue(); - Checksum copy(); -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/FastJar.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/FastJar.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,175 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * Contributor(s): - * - * Portions Copyrighted 2007 Sun Microsystems, Inc. - */ -package org.apidesign.bck2brwsr.emul.zip; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -/** - * - * @author Tomas Zezula - */ -public final class FastJar { - private final byte[] arr; - - public FastJar(byte[] arr) { - this.arr = arr; - } - - - private static final int GIVE_UP = 1<<16; - - public static final class Entry { - - public final String name; - final long offset; - private final long dosTime; - - Entry (String name, long offset, long time) { - assert name != null; - this.name = name; - this.offset = offset; - this.dosTime = time; - } -/* - public long getTime () { - Date d = new Date((int)(((dosTime >> 25) & 0x7f) + 80), - (int)(((dosTime >> 21) & 0x0f) - 1), - (int)((dosTime >> 16) & 0x1f), - (int)((dosTime >> 11) & 0x1f), - (int)((dosTime >> 5) & 0x3f), - (int)((dosTime << 1) & 0x3e)); - return d.getTime(); - } - */ - } - - public InputStream getInputStream (final Entry e) throws IOException { - return getInputStream(arr, e.offset); - } - - private static InputStream getInputStream (byte[] arr, final long offset) throws IOException { - ByteArrayInputStream is = new ByteArrayInputStream(arr); - is.skip(offset); - ZipInputStream in = new ZipInputStream (is); - ZipEntry e = in.getNextEntry(); - if (e != null && e.getCrc() == 0L && e.getMethod() == ZipEntry.STORED) { - int cp = arr.length - is.available(); - return new ByteArrayInputStream(arr, cp, (int)e.getSize()); - } - return in; - } - - public Entry[] list() throws IOException { - final int size = arr.length; - - int at = size - ZipInputStream.ENDHDR; - - byte[] data = new byte[ZipInputStream.ENDHDR]; - int giveup = 0; - - do { - org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, at, data, 0, data.length); - at--; - giveup++; - if (giveup > GIVE_UP) { - throw new IOException (); - } - } while (getsig(data) != ZipInputStream.ENDSIG); - - - final long censize = endsiz(data); - final long cenoff = endoff(data); - at = (int) cenoff; - - Entry[] result = new Entry[0]; - int cenread = 0; - data = new byte[ZipInputStream.CENHDR]; - while (cenread < censize) { - org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, at, data, 0, data.length); - at += data.length; - if (getsig(data) != ZipInputStream.CENSIG) { - throw new IOException("No central table"); //NOI18N - } - int cennam = cennam(data); - int cenext = cenext(data); - int cencom = cencom(data); - long lhoff = cenoff(data); - long centim = centim(data); - String name = new String(arr, at, cennam, "UTF-8"); - at += cennam; - int seekby = cenext+cencom; - int cendatalen = ZipInputStream.CENHDR + cennam + seekby; - cenread+=cendatalen; - result = addEntry(result, new Entry(name,lhoff, centim)); - at += seekby; - } - return result; - } - - private Entry[] addEntry(Entry[] result, Entry entry) { - Entry[] e = new Entry[result.length + 1]; - e[result.length] = entry; - org.apidesign.bck2brwsr.emul.lang.System.arraycopy(result, 0, e, 0, result.length); - return e; - } - - private static final long getsig(final byte[] b) throws IOException {return get32(b,0);} - private static final long endsiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.ENDSIZ);} - private static final long endoff(final byte[] b) throws IOException {return get32(b,ZipInputStream.ENDOFF);} - private static final long cenlen(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENLEN);} - private static final long censiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENSIZ);} - private static final long centim(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENTIM);} - private static final int cennam(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENNAM);} - private static final int cenext(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENEXT);} - private static final int cencom(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENCOM);} - private static final long cenoff (final byte[] b) throws IOException {return get32(b,ZipInputStream.CENOFF);} - private static final int lochow(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCHOW);} - private static final int locname(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCNAM);} - private static final int locext(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCEXT);} - private static final long locsiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.LOCSIZ);} - - private static final int get16(final byte[] b, int off) throws IOException { - final int b1 = b[off]; - final int b2 = b[off+1]; - return (b1 & 0xff) | ((b2 & 0xff) << 8); - } - - private static final long get32(final byte[] b, int off) throws IOException { - final int s1 = get16(b, off); - final int s2 = get16(b, off+2); - return s1 | ((long)s2 << 16); - } - -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/GZIPHeader.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/GZIPHeader.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,215 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -import org.apidesign.bck2brwsr.emul.lang.System; -import java.io.UnsupportedEncodingException; - -/** - * @see "http://www.ietf.org/rfc/rfc1952.txt" - */ -final class GZIPHeader implements Cloneable { - - public static final byte OS_MSDOS = (byte) 0x00; - public static final byte OS_AMIGA = (byte) 0x01; - public static final byte OS_VMS = (byte) 0x02; - public static final byte OS_UNIX = (byte) 0x03; - public static final byte OS_ATARI = (byte) 0x05; - public static final byte OS_OS2 = (byte) 0x06; - public static final byte OS_MACOS = (byte) 0x07; - public static final byte OS_TOPS20 = (byte) 0x0a; - public static final byte OS_WIN32 = (byte) 0x0b; - public static final byte OS_VMCMS = (byte) 0x04; - public static final byte OS_ZSYSTEM = (byte) 0x08; - public static final byte OS_CPM = (byte) 0x09; - public static final byte OS_QDOS = (byte) 0x0c; - public static final byte OS_RISCOS = (byte) 0x0d; - public static final byte OS_UNKNOWN = (byte) 0xff; - - boolean text = false; - private boolean fhcrc = false; - long time; - int xflags; - int os = 255; - byte[] extra; - byte[] name; - byte[] comment; - int hcrc; - long crc; - boolean done = false; - long mtime = 0; - - public void setModifiedTime(long mtime) { - this.mtime = mtime; - } - - public long getModifiedTime() { - return mtime; - } - - public void setOS(int os) { - if((0<=os && os <=13) || os==255) - this.os=os; - else - throw new IllegalArgumentException("os: "+os); - } - - public int getOS(){ - return os; - } - - public void setName(String name) { - try{ - this.name=name.getBytes("ISO-8859-1"); - } - catch(UnsupportedEncodingException e){ - throw new IllegalArgumentException("name must be in ISO-8859-1 "+name); - } - } - - public String getName(){ - if(name==null) return ""; - try { - return new String(name, "ISO-8859-1"); - } - catch (UnsupportedEncodingException e) { - throw new IllegalArgumentException(e.toString()); - } - } - - public void setComment(String comment) { - try{ - this.comment=comment.getBytes("ISO-8859-1"); - } - catch(UnsupportedEncodingException e){ - throw new IllegalArgumentException("comment must be in ISO-8859-1 "+name); - } - } - - public String getComment(){ - if(comment==null) return ""; - try { - return new String(comment, "ISO-8859-1"); - } - catch (UnsupportedEncodingException e) { - throw new IllegalArgumentException(e.toString()); - } - } - - public void setCRC(long crc){ - this.crc = crc; - } - - public long getCRC(){ - return crc; - } -/* - void put(Deflate d){ - int flag = 0; - if(text){ - flag |= 1; // FTEXT - } - if(fhcrc){ - flag |= 2; // FHCRC - } - if(extra!=null){ - flag |= 4; // FEXTRA - } - if(name!=null){ - flag |= 8; // FNAME - } - if(comment!=null){ - flag |= 16; // FCOMMENT - } - int xfl = 0; - if(d.level == JZlib.Z_BEST_SPEED){ - xfl |= 4; - } - else if (d.level == JZlib.Z_BEST_COMPRESSION){ - xfl |= 2; - } - - d.put_short((short)0x8b1f); // ID1 ID2 - d.put_byte((byte)8); // CM(Compression Method) - d.put_byte((byte)flag); - d.put_byte((byte)mtime); - d.put_byte((byte)(mtime>>8)); - d.put_byte((byte)(mtime>>16)); - d.put_byte((byte)(mtime>>24)); - d.put_byte((byte)xfl); - d.put_byte((byte)os); - - if(extra!=null){ - d.put_byte((byte)extra.length); - d.put_byte((byte)(extra.length>>8)); - d.put_byte(extra, 0, extra.length); - } - - if(name!=null){ - d.put_byte(name, 0, name.length); - d.put_byte((byte)0); - } - - if(comment!=null){ - d.put_byte(comment, 0, comment.length); - d.put_byte((byte)0); - } - } -*/ - @Override - public Object clone() throws CloneNotSupportedException { - GZIPHeader gheader = (GZIPHeader)super.clone(); - byte[] tmp; - if(gheader.extra!=null){ - tmp=new byte[gheader.extra.length]; - System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); - gheader.extra = tmp; - } - - if(gheader.name!=null){ - tmp=new byte[gheader.name.length]; - System.arraycopy(gheader.name, 0, tmp, 0, tmp.length); - gheader.name = tmp; - } - - if(gheader.comment!=null){ - tmp=new byte[gheader.comment.length]; - System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); - gheader.comment = tmp; - } - - return gheader; - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfBlocks.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfBlocks.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,616 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -import org.apidesign.bck2brwsr.emul.lang.System; - -final class InfBlocks{ - static final private int MANY=1440; - - // And'ing with mask[n] masks the lower n bits - static final private int[] inflate_mask = { - 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, - 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, - 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, - 0x00007fff, 0x0000ffff - }; - - // Table for deflate from PKZIP's appnote.txt. - static final int[] border = { // Order of the bit length code lengths - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 - }; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - static final private int TYPE=0; // get type bits (3, including end bit) - static final private int LENS=1; // get lengths for stored - static final private int STORED=2;// processing stored block - static final private int TABLE=3; // get table lengths - static final private int BTREE=4; // get bit lengths tree for a dynamic block - static final private int DTREE=5; // get length, distance trees for a dynamic block - static final private int CODES=6; // processing fixed or dynamic block - static final private int DRY=7; // output remaining window bytes - static final private int DONE=8; // finished last block, done - static final private int BAD=9; // ot a data error--stuck here - - int mode; // current inflate_block mode - - int left; // if STORED, bytes left to copy - - int table; // table lengths (14 bits) - int index; // index into blens (or border) - int[] blens; // bit lengths of codes - int[] bb=new int[1]; // bit length tree depth - int[] tb=new int[1]; // bit length decoding tree - - int[] bl=new int[1]; - int[] bd=new int[1]; - - int[][] tl=new int[1][]; - int[][] td=new int[1][]; - int[] tli=new int[1]; // tl_index - int[] tdi=new int[1]; // td_index - - private final InfCodes codes; // if CODES, current state - - int last; // true if this block is the last block - - // mode independent information - int bitk; // bits in bit buffer - int bitb; // bit buffer - int[] hufts; // single malloc for tree space - byte[] window; // sliding window - int end; // one byte after sliding window - int read; // window read pointer - int write; // window write pointer - private boolean check; - - private final InfTree inftree=new InfTree(); - - private final ZStream z; - - InfBlocks(ZStream z, int w){ - this.z=z; - this.codes=new InfCodes(this.z, this); - hufts=new int[MANY*3]; - window=new byte[w]; - end=w; - this.check = (z.istate.wrap==0) ? false : true; - mode = TYPE; - reset(); - } - - void reset(){ - if(mode==BTREE || mode==DTREE){ - } - if(mode==CODES){ - codes.free(z); - } - mode=TYPE; - bitk=0; - bitb=0; - read=write=0; - if(check){ - z.adler.reset(); - } - } - - int proc(int r){ - int t; // temporary storage - int b; // bit buffer - int k; // bits in bit buffer - int p; // input data pointer - int n; // bytes available there - int q; // output window write pointer - int m; // bytes to end of window or read pointer - - // copy input/output information to locals (UPDATE macro restores) - {p=z.next_in_index;n=z.avail_in;b=bitb;k=bitk;} - {q=write;m=(int)(q>> 1){ - case 0: // stored - {b>>>=(3);k-=(3);} - t = k & 7; // go to byte boundary - - {b>>>=(t);k-=(t);} - mode = LENS; // get length of stored block - break; - case 1: // fixed - InfTree.inflate_trees_fixed(bl, bd, tl, td, z); - codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); - - {b>>>=(3);k-=(3);} - - mode = CODES; - break; - case 2: // dynamic - - {b>>>=(3);k-=(3);} - - mode = TABLE; - break; - case 3: // illegal - - {b>>>=(3);k-=(3);} - mode = BAD; - z.msg = "invalid block type"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - break; - case LENS: - - while(k<(32)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>> 16) & 0xffff) != (b & 0xffff)){ - mode = BAD; - z.msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - left = (b & 0xffff); - b = k = 0; // dump bits - mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); - break; - case STORED: - if (n == 0){ - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - - if(m==0){ - if(q==end&&read!=0){ - q=0; m=(int)(qn) t = n; - if(t>m) t = m; - System.arraycopy(z.next_in, p, window, q, t); - p += t; n -= t; - q += t; m -= t; - if ((left -= t) != 0) - break; - mode = last!=0 ? DRY : TYPE; - break; - case TABLE: - - while(k<(14)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) - { - mode = BAD; - z.msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if(blens==null || blens.length>>=(14);k-=(14);} - - index = 0; - mode = BTREE; - case BTREE: - while (index < 4 + (table >>> 10)){ - while(k<(3)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} - } - - while(index < 19){ - blens[border[index++]] = 0; - } - - bb[0] = 7; - t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); - if (t != Z_OK){ - r = t; - if (r == Z_DATA_ERROR){ - blens=null; - mode = BAD; - } - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - - index = 0; - mode = DTREE; - case DTREE: - while (true){ - t = table; - if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ - break; - } - - int[] h; - int i, j, c; - - t = bb[0]; - - while(k<(t)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); - blens[index++] = c; - } - else { // c == 16..18 - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - - while(k<(t+i)){ - if(n!=0){ - r=Z_OK; - } - else{ - bitb=b; bitk=k; - z.avail_in=n; - z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - }; - n--; - b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); - - j += (b & inflate_mask[i]); - - b>>>=(i);k-=(i); - - i = index; - t = table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)){ - blens=null; - mode = BAD; - z.msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - - c = c == 16 ? blens[i-1] : 0; - do{ - blens[i++] = c; - } - while (--j!=0); - index = i; - } - } - - tb[0]=-1; - { - bl[0] = 9; // must be <= 9 for lookahead assumptions - bd[0] = 6; // must be <= 9 for lookahead assumptions - t = table; - t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), - 1 + ((t >> 5) & 0x1f), - blens, bl, bd, tli, tdi, hufts, z); - - if (t != Z_OK){ - if (t == Z_DATA_ERROR){ - blens=null; - mode = BAD; - } - r = t; - - bitb=b; bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - return inflate_flush(r); - } - codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); - } - mode = CODES; - case CODES: - bitb=b; bitk=k; - z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; - write=q; - - if ((r = codes.proc(r)) != Z_STREAM_END){ - return inflate_flush(r); - } - r = Z_OK; - codes.free(z); - - p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; - q=write;m=(int)(q z.avail_out) n = z.avail_out; - if(n!=0 && r == Z_BUF_ERROR) r = Z_OK; - - // update counters - z.avail_out -= n; - z.total_out += n; - - // update check information - if(check && n>0){ - z.adler.update(window, q, n); - } - - // copy as far as end of window - System.arraycopy(window, q, z.next_out, p, n); - p += n; - q += n; - - // see if more to copy at beginning of window - if (q == end){ - // wrap pointers - q = 0; - if (write == end) - write = 0; - - // compute bytes to copy - n = write - q; - if (n > z.avail_out) n = z.avail_out; - if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; - - // update counters - z.avail_out -= n; - z.total_out += n; - - // update check information - if(check && n>0){ - z.adler.update(window, q, n); - } - - // copy - System.arraycopy(window, q, z.next_out, p, n); - p += n; - q += n; - } - - // update pointers - z.next_out_index = p; - read = q; - - // done - return r; - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfCodes.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfCodes.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,612 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -import org.apidesign.bck2brwsr.emul.lang.System; - -final class InfCodes{ - - static final private int[] inflate_mask = { - 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, - 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, - 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, - 0x00007fff, 0x0000ffff - }; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - // waiting for "i:"=input, - // "o:"=output, - // "x:"=nothing - static final private int START=0; // x: set up for LEN - static final private int LEN=1; // i: get length/literal/eob next - static final private int LENEXT=2; // i: getting length extra (have base) - static final private int DIST=3; // i: get distance next - static final private int DISTEXT=4;// i: getting distance extra - static final private int COPY=5; // o: copying bytes in window, waiting for space - static final private int LIT=6; // o: got literal, waiting for output space - static final private int WASH=7; // o: got eob, possibly still output waiting - static final private int END=8; // x: got eob and all data flushed - static final private int BADCODE=9;// x: got error - - int mode; // current inflate_codes mode - - // mode dependent information - int len; - - int[] tree; // pointer into tree - int tree_index=0; - int need; // bits needed - - int lit; - - // if EXT or COPY, where and how much - int get; // bits to get for extra - int dist; // distance back to copy from - - byte lbits; // ltree bits decoded per branch - byte dbits; // dtree bits decoder per branch - int[] ltree; // literal/length/eob tree - int ltree_index; // literal/length/eob tree - int[] dtree; // distance tree - int dtree_index; // distance tree - - private final ZStream z; - private final InfBlocks s; - InfCodes(ZStream z, InfBlocks s){ - this.z=z; - this.s=s; - } - - void init(int bl, int bd, - int[] tl, int tl_index, - int[] td, int td_index){ - mode=START; - lbits=(byte)bl; - dbits=(byte)bd; - ltree=tl; - ltree_index=tl_index; - dtree = td; - dtree_index=td_index; - tree=null; - } - - int proc(int r){ - int j; // temporary storage - int[] t; // temporary pointer - int tindex; // temporary pointer - int e; // extra bits or operation - int b=0; // bit buffer - int k=0; // bits in bit buffer - int p=0; // input data pointer - int n; // bytes available there - int q; // output window write pointer - int m; // bytes to end of window or read pointer - int f; // pointer to copy strings from - - // copy input/output information to locals (UPDATE macro restores) - p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; - q=s.write;m=q= 258 && n >= 10){ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - r = inflate_fast(lbits, dbits, - ltree, ltree_index, - dtree, dtree_index, - s, z); - - p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; - q=s.write;m=q>>=(tree[tindex+1]); - k-=(tree[tindex+1]); - - e=tree[tindex]; - - if(e == 0){ // literal - lit = tree[tindex+2]; - mode = LIT; - break; - } - if((e & 16)!=0 ){ // length - get = e & 15; - len = tree[tindex+2]; - mode = LENEXT; - break; - } - if ((e & 64) == 0){ // next table - need = e; - tree_index = tindex/3+tree[tindex+2]; - break; - } - if ((e & 32)!=0){ // end of block - mode = WASH; - break; - } - mode = BADCODE; // invalid code - z.msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - - case LENEXT: // i: getting length extra (have base) - j = get; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - } - n--; b|=(z.next_in[p++]&0xff)<>=j; - k-=j; - - need = dbits; - tree = dtree; - tree_index=dtree_index; - mode = DIST; - case DIST: // i: get distance next - j = need; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - } - n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; - k-=tree[tindex+1]; - - e = (tree[tindex]); - if((e & 16)!=0){ // distance - get = e & 15; - dist = tree[tindex+2]; - mode = DISTEXT; - break; - } - if ((e & 64) == 0){ // next table - need = e; - tree_index = tindex/3 + tree[tindex+2]; - break; - } - mode = BADCODE; // invalid code - z.msg = "invalid distance code"; - r = Z_DATA_ERROR; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - - case DISTEXT: // i: getting distance extra - j = get; - - while(k<(j)){ - if(n!=0)r=Z_OK; - else{ - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - return s.inflate_flush(r); - } - n--; b|=(z.next_in[p++]&0xff)<>=j; - k-=j; - - mode = COPY; - case COPY: // o: copying bytes in window, waiting for space - f = q - dist; - while(f < 0){ // modulo window size-"while" instead - f += s.end; // of "if" handles invalid distances - } - while (len!=0){ - - if(m==0){ - if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any - k -= 8; - n++; - p--; // can always return one - } - - s.write=q; r=s.inflate_flush(r); - q=s.write;m=q= 258 && n >= 10 - // get literal/length code - while(k<(20)){ // max bits for literal/length code - n--; - b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - s.window[q++] = (byte)tp[tp_index_t_3+2]; - m--; - continue; - } - do { - - b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - if((e&16)!=0){ - e &= 15; - c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]); - - b>>=e; k-=e; - - // decode distance base of block to copy - while(k<(15)){ // max bits for distance code - n--; - b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - if((e&16)!=0){ - // get extra bits to add to distance base - e &= 15; - while(k<(e)){ // get extra bits (up to 13) - n--; - b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); - - // do the copy - m -= c; - if (q >= d){ // offset before dest - // just copy - r=q-d; - if(q-r>0 && 2>(q-r)){ - s.window[q++]=s.window[r++]; // minimum count is three, - s.window[q++]=s.window[r++]; // so unroll loop a little - c-=2; - } - else{ - System.arraycopy(s.window, r, s.window, q, 2); - q+=2; r+=2; c-=2; - } - } - else{ // else offset after destination - r=q-d; - do{ - r+=s.end; // force pointer in window - }while(r<0); // covers invalid distances - e=s.end-r; - if(c>e){ // if source crosses, - c-=e; // wrapped copy - if(q-r>0 && e>(q-r)){ - do{s.window[q++] = s.window[r++];} - while(--e!=0); - } - else{ - System.arraycopy(s.window, r, s.window, q, e); - q+=e; r+=e; e=0; - } - r = 0; // copy rest from start of window - } - - } - - // copy all or what's left - if(q-r>0 && c>(q-r)){ - do{s.window[q++] = s.window[r++];} - while(--c!=0); - } - else{ - System.arraycopy(s.window, r, s.window, q, c); - q+=c; r+=c; c=0; - } - break; - } - else if((e&64)==0){ - t+=tp[tp_index_t_3+2]; - t+=(b&inflate_mask[e]); - tp_index_t_3=(tp_index+t)*3; - e=tp[tp_index_t_3]; - } - else{ - z.msg = "invalid distance code"; - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_DATA_ERROR; - } - } - while(true); - break; - } - - if((e&64)==0){ - t+=tp[tp_index_t_3+2]; - t+=(b&inflate_mask[e]); - tp_index_t_3=(tp_index+t)*3; - if((e=tp[tp_index_t_3])==0){ - - b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); - - s.window[q++]=(byte)tp[tp_index_t_3+2]; - m--; - break; - } - } - else if((e&32)!=0){ - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_STREAM_END; - } - else{ - z.msg="invalid literal/length code"; - - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_DATA_ERROR; - } - } - while(true); - } - while(m>=258 && n>= 10); - - // not enough input or output--restore pointers and return - c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; - - s.bitb=b;s.bitk=k; - z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; - s.write=q; - - return Z_OK; - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfTree.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfTree.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,520 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -import org.apidesign.bck2brwsr.emul.lang.System; - -final class InfTree{ - - static final private int MANY=1440; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - static final int fixed_bl = 9; - static final int fixed_bd = 5; - - static final int[] fixed_tl = { - 96,7,256, 0,8,80, 0,8,16, 84,8,115, - 82,7,31, 0,8,112, 0,8,48, 0,9,192, - 80,7,10, 0,8,96, 0,8,32, 0,9,160, - 0,8,0, 0,8,128, 0,8,64, 0,9,224, - 80,7,6, 0,8,88, 0,8,24, 0,9,144, - 83,7,59, 0,8,120, 0,8,56, 0,9,208, - 81,7,17, 0,8,104, 0,8,40, 0,9,176, - 0,8,8, 0,8,136, 0,8,72, 0,9,240, - 80,7,4, 0,8,84, 0,8,20, 85,8,227, - 83,7,43, 0,8,116, 0,8,52, 0,9,200, - 81,7,13, 0,8,100, 0,8,36, 0,9,168, - 0,8,4, 0,8,132, 0,8,68, 0,9,232, - 80,7,8, 0,8,92, 0,8,28, 0,9,152, - 84,7,83, 0,8,124, 0,8,60, 0,9,216, - 82,7,23, 0,8,108, 0,8,44, 0,9,184, - 0,8,12, 0,8,140, 0,8,76, 0,9,248, - 80,7,3, 0,8,82, 0,8,18, 85,8,163, - 83,7,35, 0,8,114, 0,8,50, 0,9,196, - 81,7,11, 0,8,98, 0,8,34, 0,9,164, - 0,8,2, 0,8,130, 0,8,66, 0,9,228, - 80,7,7, 0,8,90, 0,8,26, 0,9,148, - 84,7,67, 0,8,122, 0,8,58, 0,9,212, - 82,7,19, 0,8,106, 0,8,42, 0,9,180, - 0,8,10, 0,8,138, 0,8,74, 0,9,244, - 80,7,5, 0,8,86, 0,8,22, 192,8,0, - 83,7,51, 0,8,118, 0,8,54, 0,9,204, - 81,7,15, 0,8,102, 0,8,38, 0,9,172, - 0,8,6, 0,8,134, 0,8,70, 0,9,236, - 80,7,9, 0,8,94, 0,8,30, 0,9,156, - 84,7,99, 0,8,126, 0,8,62, 0,9,220, - 82,7,27, 0,8,110, 0,8,46, 0,9,188, - 0,8,14, 0,8,142, 0,8,78, 0,9,252, - 96,7,256, 0,8,81, 0,8,17, 85,8,131, - 82,7,31, 0,8,113, 0,8,49, 0,9,194, - 80,7,10, 0,8,97, 0,8,33, 0,9,162, - 0,8,1, 0,8,129, 0,8,65, 0,9,226, - 80,7,6, 0,8,89, 0,8,25, 0,9,146, - 83,7,59, 0,8,121, 0,8,57, 0,9,210, - 81,7,17, 0,8,105, 0,8,41, 0,9,178, - 0,8,9, 0,8,137, 0,8,73, 0,9,242, - 80,7,4, 0,8,85, 0,8,21, 80,8,258, - 83,7,43, 0,8,117, 0,8,53, 0,9,202, - 81,7,13, 0,8,101, 0,8,37, 0,9,170, - 0,8,5, 0,8,133, 0,8,69, 0,9,234, - 80,7,8, 0,8,93, 0,8,29, 0,9,154, - 84,7,83, 0,8,125, 0,8,61, 0,9,218, - 82,7,23, 0,8,109, 0,8,45, 0,9,186, - 0,8,13, 0,8,141, 0,8,77, 0,9,250, - 80,7,3, 0,8,83, 0,8,19, 85,8,195, - 83,7,35, 0,8,115, 0,8,51, 0,9,198, - 81,7,11, 0,8,99, 0,8,35, 0,9,166, - 0,8,3, 0,8,131, 0,8,67, 0,9,230, - 80,7,7, 0,8,91, 0,8,27, 0,9,150, - 84,7,67, 0,8,123, 0,8,59, 0,9,214, - 82,7,19, 0,8,107, 0,8,43, 0,9,182, - 0,8,11, 0,8,139, 0,8,75, 0,9,246, - 80,7,5, 0,8,87, 0,8,23, 192,8,0, - 83,7,51, 0,8,119, 0,8,55, 0,9,206, - 81,7,15, 0,8,103, 0,8,39, 0,9,174, - 0,8,7, 0,8,135, 0,8,71, 0,9,238, - 80,7,9, 0,8,95, 0,8,31, 0,9,158, - 84,7,99, 0,8,127, 0,8,63, 0,9,222, - 82,7,27, 0,8,111, 0,8,47, 0,9,190, - 0,8,15, 0,8,143, 0,8,79, 0,9,254, - 96,7,256, 0,8,80, 0,8,16, 84,8,115, - 82,7,31, 0,8,112, 0,8,48, 0,9,193, - - 80,7,10, 0,8,96, 0,8,32, 0,9,161, - 0,8,0, 0,8,128, 0,8,64, 0,9,225, - 80,7,6, 0,8,88, 0,8,24, 0,9,145, - 83,7,59, 0,8,120, 0,8,56, 0,9,209, - 81,7,17, 0,8,104, 0,8,40, 0,9,177, - 0,8,8, 0,8,136, 0,8,72, 0,9,241, - 80,7,4, 0,8,84, 0,8,20, 85,8,227, - 83,7,43, 0,8,116, 0,8,52, 0,9,201, - 81,7,13, 0,8,100, 0,8,36, 0,9,169, - 0,8,4, 0,8,132, 0,8,68, 0,9,233, - 80,7,8, 0,8,92, 0,8,28, 0,9,153, - 84,7,83, 0,8,124, 0,8,60, 0,9,217, - 82,7,23, 0,8,108, 0,8,44, 0,9,185, - 0,8,12, 0,8,140, 0,8,76, 0,9,249, - 80,7,3, 0,8,82, 0,8,18, 85,8,163, - 83,7,35, 0,8,114, 0,8,50, 0,9,197, - 81,7,11, 0,8,98, 0,8,34, 0,9,165, - 0,8,2, 0,8,130, 0,8,66, 0,9,229, - 80,7,7, 0,8,90, 0,8,26, 0,9,149, - 84,7,67, 0,8,122, 0,8,58, 0,9,213, - 82,7,19, 0,8,106, 0,8,42, 0,9,181, - 0,8,10, 0,8,138, 0,8,74, 0,9,245, - 80,7,5, 0,8,86, 0,8,22, 192,8,0, - 83,7,51, 0,8,118, 0,8,54, 0,9,205, - 81,7,15, 0,8,102, 0,8,38, 0,9,173, - 0,8,6, 0,8,134, 0,8,70, 0,9,237, - 80,7,9, 0,8,94, 0,8,30, 0,9,157, - 84,7,99, 0,8,126, 0,8,62, 0,9,221, - 82,7,27, 0,8,110, 0,8,46, 0,9,189, - 0,8,14, 0,8,142, 0,8,78, 0,9,253, - 96,7,256, 0,8,81, 0,8,17, 85,8,131, - 82,7,31, 0,8,113, 0,8,49, 0,9,195, - 80,7,10, 0,8,97, 0,8,33, 0,9,163, - 0,8,1, 0,8,129, 0,8,65, 0,9,227, - 80,7,6, 0,8,89, 0,8,25, 0,9,147, - 83,7,59, 0,8,121, 0,8,57, 0,9,211, - 81,7,17, 0,8,105, 0,8,41, 0,9,179, - 0,8,9, 0,8,137, 0,8,73, 0,9,243, - 80,7,4, 0,8,85, 0,8,21, 80,8,258, - 83,7,43, 0,8,117, 0,8,53, 0,9,203, - 81,7,13, 0,8,101, 0,8,37, 0,9,171, - 0,8,5, 0,8,133, 0,8,69, 0,9,235, - 80,7,8, 0,8,93, 0,8,29, 0,9,155, - 84,7,83, 0,8,125, 0,8,61, 0,9,219, - 82,7,23, 0,8,109, 0,8,45, 0,9,187, - 0,8,13, 0,8,141, 0,8,77, 0,9,251, - 80,7,3, 0,8,83, 0,8,19, 85,8,195, - 83,7,35, 0,8,115, 0,8,51, 0,9,199, - 81,7,11, 0,8,99, 0,8,35, 0,9,167, - 0,8,3, 0,8,131, 0,8,67, 0,9,231, - 80,7,7, 0,8,91, 0,8,27, 0,9,151, - 84,7,67, 0,8,123, 0,8,59, 0,9,215, - 82,7,19, 0,8,107, 0,8,43, 0,9,183, - 0,8,11, 0,8,139, 0,8,75, 0,9,247, - 80,7,5, 0,8,87, 0,8,23, 192,8,0, - 83,7,51, 0,8,119, 0,8,55, 0,9,207, - 81,7,15, 0,8,103, 0,8,39, 0,9,175, - 0,8,7, 0,8,135, 0,8,71, 0,9,239, - 80,7,9, 0,8,95, 0,8,31, 0,9,159, - 84,7,99, 0,8,127, 0,8,63, 0,9,223, - 82,7,27, 0,8,111, 0,8,47, 0,9,191, - 0,8,15, 0,8,143, 0,8,79, 0,9,255 - }; - static final int[] fixed_td = { - 80,5,1, 87,5,257, 83,5,17, 91,5,4097, - 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, - 80,5,3, 88,5,513, 84,5,33, 92,5,8193, - 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, - 80,5,2, 87,5,385, 83,5,25, 91,5,6145, - 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, - 80,5,4, 88,5,769, 84,5,49, 92,5,12289, - 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 - }; - - // Tables for deflate from PKZIP's appnote.txt. - static final int[] cplens = { // Copy lengths for literal codes 257..285 - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - }; - - // see note #13 above about 258 - static final int[] cplext = { // Extra bits for literal codes 257..285 - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid - }; - - static final int[] cpdist = { // Copy offsets for distance codes 0..29 - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577 - }; - - static final int[] cpdext = { // Extra bits for distance codes - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - - // If BMAX needs to be larger than 16, then h and x[] should be uLong. - static final int BMAX=15; // maximum bit length of any code - - int[] hn = null; // hufts used in space - int[] v = null; // work area for huft_build - int[] c = null; // bit length count table - int[] r = null; // table entry for structure assignment - int[] u = null; // table stack - int[] x = null; // bit offsets, then code stack - - private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) - int bindex, - int n, // number of codes (assumed <= 288) - int s, // number of simple-valued codes (0..s-1) - int[] d, // list of base values for non-simple codes - int[] e, // list of extra bits for non-simple codes - int[] t, // result: starting table - int[] m, // maximum lookup bits, returns actual - int[] hp,// space for trees - int[] hn,// hufts used in space - int[] v // working area: values in order of bit length - ){ - // Given a list of code lengths and a maximum table size, make a set of - // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - // if the given code set is incomplete (the tables are still built in this - // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - // lengths), or Z_MEM_ERROR if not enough memory. - - int a; // counter for codes of length k - int f; // i repeats in table every f entries - int g; // maximum code length - int h; // table level - int i; // counter, current code - int j; // counter - int k; // number of bits in current code - int l; // bits per table (returned in m) - int mask; // (1 << w) - 1, to avoid cc -O bug on HP - int p; // pointer into c[], b[], or v[] - int q; // points to current table - int w; // bits before this table == (l * h) - int xp; // pointer into x - int y; // number of dummy codes added - int z; // number of entries in current table - - // Generate counts for each bit length - - p = 0; i = n; - do { - c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX - }while(i!=0); - - if(c[0] == n){ // null input--all zero length codes - t[0] = -1; - m[0] = 0; - return Z_OK; - } - - // Find minimum and maximum length, bound *m by those - l = m[0]; - for (j = 1; j <= BMAX; j++) - if(c[j]!=0) break; - k = j; // minimum code length - if(l < j){ - l = j; - } - for (i = BMAX; i!=0; i--){ - if(c[i]!=0) break; - } - g = i; // maximum code length - if(l > i){ - l = i; - } - m[0] = l; - - // Adjust last length count to fill out codes, if needed - for (y = 1 << j; j < i; j++, y <<= 1){ - if ((y -= c[j]) < 0){ - return Z_DATA_ERROR; - } - } - if ((y -= c[i]) < 0){ - return Z_DATA_ERROR; - } - c[i] += y; - - // Generate starting offsets into the value table for each length - x[1] = j = 0; - p = 1; xp = 2; - while (--i!=0) { // note that i == g from above - x[xp] = (j += c[p]); - xp++; - p++; - } - - // Make a table of values in order of bit lengths - i = 0; p = 0; - do { - if ((j = b[bindex+p]) != 0){ - v[x[j]++] = i; - } - p++; - } - while (++i < n); - n = x[g]; // set n to length of v - - // Generate the Huffman codes and for each, make the table entries - x[0] = i = 0; // first Huffman code is zero - p = 0; // grab values in bit order - h = -1; // no tables yet--level -1 - w = -l; // bits decoded == (l * h) - u[0] = 0; // just to keep compilers happy - q = 0; // ditto - z = 0; // ditto - - // go through the bit lengths (k already is bits in shortest code) - for (; k <= g; k++){ - a = c[k]; - while (a--!=0){ - // here i is the Huffman code of length k bits for value *p - // make tables up to required level - while (k > w + l){ - h++; - w += l; // previous table always l bits - // compute minimum size table less than or equal to l bits - z = g - w; - z = (z > l) ? l : z; // table size upper limit - if((f=1<<(j=k-w))>a+1){ // try a k-w bit table - // too few codes for k-w bit table - f -= a + 1; // deduct codes from patterns left - xp = k; - if(j < z){ - while (++j < z){ // try smaller tables up to z bits - if((f <<= 1) <= c[++xp]) - break; // enough codes to use up j bits - f -= c[xp]; // else deduct codes from patterns - } - } - } - z = 1 << j; // table entries for j-bit table - - // allocate new table - if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) - return Z_DATA_ERROR; // overflow of MANY - } - u[h] = q = /*hp+*/ hn[0]; // DEBUG - hn[0] += z; - - // connect to last table, if there is one - if(h!=0){ - x[h]=i; // save pattern for backing up - r[0]=(byte)j; // bits in this table - r[1]=(byte)l; // bits to dump before this table - j=i>>>(w - l); - r[2] = (int)(q - u[h-1] - j); // offset to this table - System.arraycopy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table - } - else{ - t[0] = q; // first table is returned result - } - } - - // set up table entry in r - r[1] = (byte)(k - w); - if (p >= n){ - r[0] = 128 + 64; // out of values--invalid code - } - else if (v[p] < s){ - r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block - r[2] = v[p++]; // simple code is just the value - } - else{ - r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists - r[2]=d[v[p++] - s]; - } - - // fill code-like entries with r - f=1<<(k-w); - for (j=i>>>w;j>>= 1){ - i ^= j; - } - i ^= j; - - // backup over finished tables - mask = (1 << w) - 1; // needed on HP, cc -O bug - while ((i & mask) != x[h]){ - h--; // don't need to update q - w -= l; - mask = (1 << w) - 1; - } - } - } - // Return Z_BUF_ERROR if we were given an incomplete table - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; - } - - int inflate_trees_bits(int[] c, // 19 code lengths - int[] bb, // bits tree desired/actual depth - int[] tb, // bits tree result - int[] hp, // space for trees - ZStream z // for messages - ){ - int result; - initWorkArea(19); - hn[0]=0; - result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); - - if(result == Z_DATA_ERROR){ - z.msg = "oversubscribed dynamic bit lengths tree"; - } - else if(result == Z_BUF_ERROR || bb[0] == 0){ - z.msg = "incomplete dynamic bit lengths tree"; - result = Z_DATA_ERROR; - } - return result; - } - - int inflate_trees_dynamic(int nl, // number of literal/length codes - int nd, // number of distance codes - int[] c, // that many (total) code lengths - int[] bl, // literal desired/actual bit depth - int[] bd, // distance desired/actual bit depth - int[] tl, // literal/length tree result - int[] td, // distance tree result - int[] hp, // space for trees - ZStream z // for messages - ){ - int result; - - // build literal/length tree - initWorkArea(288); - hn[0]=0; - result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); - if (result != Z_OK || bl[0] == 0){ - if(result == Z_DATA_ERROR){ - z.msg = "oversubscribed literal/length tree"; - } - else if (result != Z_MEM_ERROR){ - z.msg = "incomplete literal/length tree"; - result = Z_DATA_ERROR; - } - return result; - } - - // build distance tree - initWorkArea(288); - result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); - - if (result != Z_OK || (bd[0] == 0 && nl > 257)){ - if (result == Z_DATA_ERROR){ - z.msg = "oversubscribed distance tree"; - } - else if (result == Z_BUF_ERROR) { - z.msg = "incomplete distance tree"; - result = Z_DATA_ERROR; - } - else if (result != Z_MEM_ERROR){ - z.msg = "empty distance tree with lengths"; - result = Z_DATA_ERROR; - } - return result; - } - - return Z_OK; - } - - static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth - int[] bd, //distance desired/actual bit depth - int[][] tl,//literal/length tree result - int[][] td,//distance tree result - ZStream z //for memory allocation - ){ - bl[0]=fixed_bl; - bd[0]=fixed_bd; - tl[0]=fixed_tl; - td[0]=fixed_td; - return Z_OK; - } - - private void initWorkArea(int vsize){ - if(hn==null){ - hn=new int[1]; - v=new int[vsize]; - c=new int[BMAX+1]; - r=new int[3]; - u=new int[BMAX]; - x=new int[BMAX+1]; - } - if(v.length> 4) + 1; - if(w < 48) - w &= 15; - } - - if(w<8 ||w>15){ - inflateEnd(); - return Z_STREAM_ERROR; - } - if(blocks != null && wbits != w){ - blocks.free(); - blocks=null; - } - - // set window size - wbits=w; - - this.blocks=new InfBlocks(z, 1<>8))&0xff; - - if((wrap&1)==0 || // check if zlib header allowed - (((this.method << 8)+b) % 31)!=0){ - this.mode = BAD; - z.msg = "incorrect header check"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - if((this.method&0xf)!=Z_DEFLATED){ - this.mode = BAD; - z.msg="unknown compression method"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - if((this.method>>4)+8>this.wbits){ - this.mode = BAD; - z.msg="invalid window size"; - // since zlib 1.2, it is allowted to inflateSync for this case. - /* - this.marker = 5; // can't try inflateSync - */ - break; - } - - z.adler=new Adler32(); - - if((b&PRESET_DICT)==0){ - this.mode = BLOCKS; - break; - } - this.mode = DICT4; - case DICT4: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; - this.mode=DICT3; - case DICT3: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; - this.mode=DICT2; - case DICT2: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; - this.mode=DICT1; - case DICT1: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need += (z.next_in[z.next_in_index++]&0xffL); - z.adler.reset(this.need); - this.mode = DICT0; - return Z_NEED_DICT; - case DICT0: - this.mode = BAD; - z.msg = "need dictionary"; - this.marker = 0; // can try inflateSync - return Z_STREAM_ERROR; - case BLOCKS: - r = this.blocks.proc(r); - if(r == Z_DATA_ERROR){ - this.mode = BAD; - this.marker = 0; // can try inflateSync - break; - } - if(r == Z_OK){ - r = f; - } - if(r != Z_STREAM_END){ - return r; - } - r = f; - this.was=z.adler.getValue(); - this.blocks.reset(); - if(this.wrap==0){ - this.mode=DONE; - break; - } - this.mode=CHECK4; - case CHECK4: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; - this.mode=CHECK3; - case CHECK3: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; - this.mode = CHECK2; - case CHECK2: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; - this.mode = CHECK1; - case CHECK1: - - if(z.avail_in==0)return r;r=f; - - z.avail_in--; z.total_in++; - this.need+=(z.next_in[z.next_in_index++]&0xffL); - - if(flags!=0){ // gzip - this.need = ((this.need&0xff000000)>>24 | - (this.need&0x00ff0000)>>8 | - (this.need&0x0000ff00)<<8 | - (this.need&0x0000ffff)<<24)&0xffffffffL; - } - - if(((int)(this.was)) != ((int)(this.need))){ - z.msg = "incorrect data check"; - // chack is delayed - /* - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - */ - } - else if(flags!=0 && gheader!=null){ - gheader.crc = this.need; - } - - this.mode = LENGTH; - case LENGTH: - if (wrap!=0 && flags!=0) { - - try { r=readBytes(4, r, f); } - catch(Return e){ return e.r; } - - if(z.msg!=null && z.msg.equals("incorrect data check")){ - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - } - - if (this.need != (z.total_out & 0xffffffffL)) { - z.msg = "incorrect length check"; - this.mode = BAD; - break; - } - z.msg = null; - } - else { - if(z.msg!=null && z.msg.equals("incorrect data check")){ - this.mode = BAD; - this.marker = 5; // can't try inflateSync - break; - } - } - - this.mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - - case FLAGS: - - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - - flags = ((int)this.need)&0xffff; - - if ((flags & 0xff) != Z_DEFLATED) { - z.msg = "unknown compression method"; - this.mode = BAD; - break; - } - if ((flags & 0xe000)!=0) { - z.msg = "unknown header flags set"; - this.mode = BAD; - break; - } - - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - - this.mode = TIME; - - case TIME: - try { r=readBytes(4, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null) - gheader.time = this.need; - if ((flags & 0x0200)!=0){ - checksum(4, this.need); - } - this.mode = OS; - case OS: - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.xflags = ((int)this.need)&0xff; - gheader.os = (((int)this.need)>>8)&0xff; - } - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - this.mode = EXLEN; - case EXLEN: - if ((flags & 0x0400)!=0) { - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.extra = new byte[((int)this.need)&0xffff]; - } - if ((flags & 0x0200)!=0){ - checksum(2, this.need); - } - } - else if(gheader!=null){ - gheader.extra=null; - } - this.mode = EXTRA; - - case EXTRA: - if ((flags & 0x0400)!=0) { - try { - r=readBytes(r, f); - if(gheader!=null){ - byte[] foo = tmp_array; - tmp_array=null; - if(foo.length == gheader.extra.length){ - System.arraycopy(foo, 0, gheader.extra, 0, foo.length); - } - else{ - z.msg = "bad extra field length"; - this.mode = BAD; - break; - } - } - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.extra=null; - } - this.mode = NAME; - case NAME: - if ((flags & 0x0800)!=0) { - try { - r=readString(r, f); - if(gheader!=null){ - gheader.name=tmp_array; - } - tmp_array=null; - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.name=null; - } - this.mode = COMMENT; - case COMMENT: - if ((flags & 0x1000)!=0) { - try { - r=readString(r, f); - if(gheader!=null){ - gheader.comment=tmp_array; - } - tmp_array=null; - } - catch(Return e){ return e.r; } - } - else if(gheader!=null){ - gheader.comment=null; - } - this.mode = HCRC; - case HCRC: - if ((flags & 0x0200)!=0) { - try { r=readBytes(2, r, f); } - catch(Return e){ return e.r; } - if(gheader!=null){ - gheader.hcrc=(int)(this.need&0xffff); - } - if(this.need != (z.adler.getValue()&0xffffL)){ - this.mode = BAD; - z.msg = "header crc mismatch"; - this.marker = 5; // can't try inflateSync - break; - } - } - z.adler = new CRC32(); - - this.mode = BLOCKS; - break; - default: - return Z_STREAM_ERROR; - } - } - } - - int inflateSetDictionary(byte[] dictionary, int dictLength){ - if(z==null || (this.mode != DICT0 && this.wrap != 0)){ - return Z_STREAM_ERROR; - } - - int index=0; - int length = dictLength; - - if(this.mode==DICT0){ - long adler_need=z.adler.getValue(); - z.adler.reset(); - z.adler.update(dictionary, 0, dictLength); - if(z.adler.getValue()!=adler_need){ - return Z_DATA_ERROR; - } - } - - z.adler.reset(); - - if(length >= (1<0){ - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - this.need = this.need | - ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); - need_bytes--; - } - if(n==2){ - this.need&=0xffffL; - } - else if(n==4) { - this.need&=0xffffffffL; - } - need_bytes=-1; - return r; - } - class Return extends Exception{ - int r; - Return(int r){this.r=r; } - } - - private byte[] tmp_array; - private int readString(int r, int f) throws Return{ - int b=0; - byte[] arr = new byte[4092]; - int at = 0; - do { - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - b = z.next_in[z.next_in_index]; - if(b!=0) arr = append(arr, z.next_in[z.next_in_index], at++); - z.adler.update(z.next_in, z.next_in_index, 1); - z.next_in_index++; - }while(b!=0); - - tmp_array = copy(arr, at); - - return r; - } - - private int readBytes(int r, int f) throws Return{ - int b=0; - byte[] arr = new byte[4092]; - int at = 0; - while(this.need>0){ - if(z.avail_in==0){ throw new Return(r); }; r=f; - z.avail_in--; z.total_in++; - b = z.next_in[z.next_in_index]; - arr = append(arr, z.next_in[z.next_in_index], at++); - z.adler.update(z.next_in, z.next_in_index, 1); - z.next_in_index++; - this.need--; - } - - tmp_array = copy(arr, at); - - return r; - } - - private static byte[] copy(byte[] arr, int len) { - byte[] ret = new byte[len]; - org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, 0, ret, 0, len); - return ret; - } - private static byte[] append(byte[] arr, byte b, int index) { - arr[index] = b; - return arr; - } - - private void checksum(int n, long v){ - for(int i=0; i>=8; - } - z.adler.update(crcbuf, 0, n); - } - - public GZIPHeader getGZIPHeader(){ - return gheader; - } - - boolean inParsingHeader(){ - switch(mode){ - case HEAD: - case DICT4: - case DICT3: - case DICT2: - case DICT1: - case FLAGS: - case TIME: - case OS: - case EXLEN: - case EXTRA: - case NAME: - case COMMENT: - case HCRC: - return true; - default: - return false; - } - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Inflater.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Inflater.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,338 +0,0 @@ -/* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -import java.util.zip.*; -import java.io.IOException; - -/** - * This class provides support for general purpose decompression using the - * popular ZLIB compression library. The ZLIB compression library was - * initially developed as part of the PNG graphics standard and is not - * protected by patents. It is fully described in the specifications at - * the java.util.zip - * package description. - * - *

The following code fragment demonstrates a trivial compression - * and decompression of a string using Deflater and - * Inflater. - * - *

- * try {
- *     // Encode a String into bytes
- *     String inputString = "blahblahblah\u20AC\u20AC";
- *     byte[] input = inputString.getBytes("UTF-8");
- *
- *     // Compress the bytes
- *     byte[] output = new byte[100];
- *     Deflater compresser = new Deflater();
- *     compresser.setInput(input);
- *     compresser.finish();
- *     int compressedDataLength = compresser.deflate(output);
- *
- *     // Decompress the bytes
- *     Inflater decompresser = new Inflater();
- *     decompresser.setInput(output, 0, compressedDataLength);
- *     byte[] result = new byte[100];
- *     int resultLength = decompresser.inflate(result);
- *     decompresser.end();
- *
- *     // Decode the bytes into a String
- *     String outputString = new String(result, 0, resultLength, "UTF-8");
- * } catch(java.io.UnsupportedEncodingException ex) {
- *     // handle
- * } catch (java.util.zip.DataFormatException ex) {
- *     // handle
- * }
- * 
- * - * @see Deflater - * @author David Connelly - * - */ -public -class Inflater extends java.util.zip.Inflater { - private final boolean nowrap; - private JzLibInflater impl; - - /** - * Creates a new decompressor. If the parameter 'nowrap' is true then - * the ZLIB header and checksum fields will not be used. This provides - * compatibility with the compression format used by both GZIP and PKZIP. - *

- * Note: When using the 'nowrap' option it is also necessary to provide - * an extra "dummy" byte as input. This is required by the ZLIB native - * library in order to support certain optimizations. - * - * @param nowrap if true then support GZIP compatible compression - */ - public Inflater(boolean nowrap) { - this.nowrap = nowrap; - reset(); - } - - /** - * Creates a new decompressor. - */ - public Inflater() { - this(false); - } - - /** - * Sets input data for decompression. Should be called whenever - * needsInput() returns true indicating that more input data is - * required. - * @param b the input data bytes - * @param off the start offset of the input data - * @param len the length of the input data - * @see Inflater#needsInput - */ - public void setInput(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } - if (off < 0 || len < 0 || off > b.length - len) { - throw new ArrayIndexOutOfBoundsException(); - } - impl.setInput(b, off, len, false); - } - - /** - * Sets input data for decompression. Should be called whenever - * needsInput() returns true indicating that more input data is - * required. - * @param b the input data bytes - * @see Inflater#needsInput - */ - public void setInput(byte[] b) { - setInput(b, 0, b.length); - } - - /** - * Sets the preset dictionary to the given array of bytes. Should be - * called when inflate() returns 0 and needsDictionary() returns true - * indicating that a preset dictionary is required. The method getAdler() - * can be used to get the Adler-32 value of the dictionary needed. - * @param b the dictionary data bytes - * @param off the start offset of the data - * @param len the length of the data - * @see Inflater#needsDictionary - * @see Inflater#getAdler - */ - public void setDictionary(byte[] b, int off, int len) { - if (b == null) { - throw new NullPointerException(); - } - if (off < 0 || len < 0 || off > b.length - len) { - throw new ArrayIndexOutOfBoundsException(); - } - byte[] arr; - if (off == 0) { - arr = b; - } else { - arr = new byte[len]; - org.apidesign.bck2brwsr.emul.lang.System.arraycopy(b, off, arr, 0, len); - } - impl.setDictionary(arr, len); - } - - /** - * Sets the preset dictionary to the given array of bytes. Should be - * called when inflate() returns 0 and needsDictionary() returns true - * indicating that a preset dictionary is required. The method getAdler() - * can be used to get the Adler-32 value of the dictionary needed. - * @param b the dictionary data bytes - * @see Inflater#needsDictionary - * @see Inflater#getAdler - */ - public void setDictionary(byte[] b) { - impl.setDictionary(b, b.length); - } - - /** - * Returns the total number of bytes remaining in the input buffer. - * This can be used to find out what bytes still remain in the input - * buffer after decompression has finished. - * @return the total number of bytes remaining in the input buffer - */ - public int getRemaining() { - return impl.getAvailIn(); - } - - /** - * Returns true if no data remains in the input buffer. This can - * be used to determine if #setInput should be called in order - * to provide more input. - * @return true if no data remains in the input buffer - */ - public boolean needsInput() { - return getRemaining() <= 0; - } - - /** - * Returns true if a preset dictionary is needed for decompression. - * @return true if a preset dictionary is needed for decompression - * @see Inflater#setDictionary - */ - public boolean needsDictionary() { - return impl.needDict(); - } - - /** - * Returns true if the end of the compressed data stream has been - * reached. - * @return true if the end of the compressed data stream has been - * reached - */ - public boolean finished() { - return impl.finished(); - } - - /** - * Uncompresses bytes into specified buffer. Returns actual number - * of bytes uncompressed. A return value of 0 indicates that - * needsInput() or needsDictionary() should be called in order to - * determine if more input data or a preset dictionary is required. - * In the latter case, getAdler() can be used to get the Adler-32 - * value of the dictionary required. - * @param b the buffer for the uncompressed data - * @param off the start offset of the data - * @param len the maximum number of uncompressed bytes - * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid - * @see Inflater#needsInput - * @see Inflater#needsDictionary - */ - public int inflate(byte[] b, int off, int len) - throws DataFormatException - { - if (b == null) { - throw new NullPointerException(); - } - if (off < 0 || len < 0 || off > b.length - len) { - throw new ArrayIndexOutOfBoundsException(); - } - impl.setOutput(b, off, len); - int err = impl.inflate(JzLibInflater.Z_NO_FLUSH); - return impl.next_out_index - off; - } - - /** - * Uncompresses bytes into specified buffer. Returns actual number - * of bytes uncompressed. A return value of 0 indicates that - * needsInput() or needsDictionary() should be called in order to - * determine if more input data or a preset dictionary is required. - * In the latter case, getAdler() can be used to get the Adler-32 - * value of the dictionary required. - * @param b the buffer for the uncompressed data - * @return the actual number of uncompressed bytes - * @exception DataFormatException if the compressed data format is invalid - * @see Inflater#needsInput - * @see Inflater#needsDictionary - */ - public int inflate(byte[] b) throws DataFormatException { - return inflate(b, 0, b.length); - } - - /** - * Returns the ADLER-32 value of the uncompressed data. - * @return the ADLER-32 value of the uncompressed data - */ - public int getAdler() { - return (int) impl.getAdler(); - } - - /** - * Returns the total number of compressed bytes input so far. - * - *

Since the number of bytes may be greater than - * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now - * the preferred means of obtaining this information.

- * - * @return the total number of compressed bytes input so far - */ - public int getTotalIn() { - return (int) getBytesRead(); - } - - /** - * Returns the total number of compressed bytes input so far.

- * - * @return the total (non-negative) number of compressed bytes input so far - * @since 1.5 - */ - public long getBytesRead() { - return impl.total_in; - } - - /** - * Returns the total number of uncompressed bytes output so far. - * - *

Since the number of bytes may be greater than - * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now - * the preferred means of obtaining this information.

- * - * @return the total number of uncompressed bytes output so far - */ - public int getTotalOut() { - return (int) getBytesWritten(); - } - - /** - * Returns the total number of uncompressed bytes output so far.

- * - * @return the total (non-negative) number of uncompressed bytes output so far - * @since 1.5 - */ - public long getBytesWritten() { - return impl.total_out; - } - - /** - * Resets inflater so that a new set of input data can be processed. - */ - public void reset() { - impl = new JzLibInflater(15, nowrap); - } - - /** - * Closes the decompressor and discards any unprocessed input. - * This method should be called when the decompressor is no longer - * being used, but will also be called automatically by the finalize() - * method. Once this method is called, the behavior of the Inflater - * object is undefined. - */ - public void end() { - impl.end(); - } - - /** - * Closes the decompressor when garbage is collected. - */ - protected void finalize() { - end(); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/JzLibInflater.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/JzLibInflater.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -final class JzLibInflater extends ZStream{ - - static final private int MAX_WBITS=15; // 32K LZ77 window - static final private int DEF_WBITS=MAX_WBITS; - - public static final int Z_NO_FLUSH=0; - static final private int Z_PARTIAL_FLUSH=1; - static final private int Z_SYNC_FLUSH=2; - static final private int Z_FULL_FLUSH=3; - static final private int Z_FINISH=4; - - static final private int MAX_MEM_LEVEL=9; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - public JzLibInflater() { - super(); - init(); - } - - public JzLibInflater(int w) { - this(w, false); - } - - public JzLibInflater(int w, boolean nowrap) { - super(); - int ret = init(w, nowrap); - if(ret!=Z_OK) - throw new IllegalStateException(ret+": "+msg); - } - - private boolean finished = false; - - public int init(){ - return init(DEF_WBITS); - } - - public int init(boolean nowrap){ - return init(DEF_WBITS, nowrap); - } - - public int init(int w){ - return init(w, false); - } - - public int init(int w, boolean nowrap){ - finished = false; - istate=new Inflate(this); - return istate.inflateInit(nowrap?-w:w); - } - - public int inflate(int f){ - if(istate==null) return Z_STREAM_ERROR; - int ret = istate.inflate(f); - if(ret == Z_STREAM_END) - finished = true; - return ret; - } - - public int end(){ - finished = true; - if(istate==null) return Z_STREAM_ERROR; - int ret=istate.inflateEnd(); -// istate = null; - return ret; - } - - public int sync(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSync(); - } - - public int syncPoint(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSyncPoint(); - } - - public int setDictionary(byte[] dictionary, int dictLength){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSetDictionary(dictionary, dictLength); - } - - public boolean finished(){ - return istate.mode==12 /*DONE*/; - } - - public boolean needDict() { - return istate == null ? false : istate.mode == Inflate.DICT0; - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZStream.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZStream.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,253 +0,0 @@ -/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ -/* -Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This program is based on zlib-1.1.3, so all credit should go authors - * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) - * and contributors of zlib. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -import org.apidesign.bck2brwsr.emul.lang.System; - -/** - * ZStream - * - * @deprecated Not for public use in the future. - */ -@Deprecated -class ZStream{ - - static final private int MAX_WBITS=15; // 32K LZ77 window - static final private int DEF_WBITS=MAX_WBITS; - - static final private int Z_NO_FLUSH=0; - static final private int Z_PARTIAL_FLUSH=1; - static final private int Z_SYNC_FLUSH=2; - static final private int Z_FULL_FLUSH=3; - static final private int Z_FINISH=4; - - static final private int MAX_MEM_LEVEL=9; - - static final private int Z_OK=0; - static final private int Z_STREAM_END=1; - static final private int Z_NEED_DICT=2; - static final private int Z_ERRNO=-1; - static final private int Z_STREAM_ERROR=-2; - static final private int Z_DATA_ERROR=-3; - static final private int Z_MEM_ERROR=-4; - static final private int Z_BUF_ERROR=-5; - static final private int Z_VERSION_ERROR=-6; - - public byte[] next_in; // next input byte - public int next_in_index; - public int avail_in; // number of bytes available at next_in - public long total_in; // total nb of input bytes read so far - - public byte[] next_out; // next output byte should be put there - public int next_out_index; - public int avail_out; // remaining free space at next_out - public long total_out; // total nb of bytes output so far - - public String msg; - - Inflate istate; - - int data_type; // best guess about the data type: ascii or binary - - Checksum adler; - - public ZStream(){ - this(new Adler32()); - } - - public ZStream(Checksum adler){ - this.adler=adler; - } - - public int inflateInit(){ - return inflateInit(DEF_WBITS); - } - public int inflateInit(boolean nowrap){ - return inflateInit(DEF_WBITS, nowrap); - } - public int inflateInit(int w){ - return inflateInit(w, false); - } - - public int inflateInit(int w, boolean nowrap){ - istate=new Inflate(this); - return istate.inflateInit(nowrap?-w:w); - } - - public int inflate(int f){ - if(istate==null) return Z_STREAM_ERROR; - return istate.inflate(f); - } - public int inflateEnd(){ - if(istate==null) return Z_STREAM_ERROR; - int ret=istate.inflateEnd(); -// istate = null; - return ret; - } - - public int inflateSync(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSync(); - } - public int inflateSyncPoint(){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSyncPoint(); - } - public int inflateSetDictionary(byte[] dictionary, int dictLength){ - if(istate == null) - return Z_STREAM_ERROR; - return istate.inflateSetDictionary(dictionary, dictLength); - } - public boolean inflateFinished(){ - return istate.mode==12 /*DONE*/; - } - - - public long getAdler(){ - return adler.getValue(); - } - - public void free(){ - next_in=null; - next_out=null; - msg=null; - } - - public void setOutput(byte[] buf){ - setOutput(buf, 0, buf.length); - } - - public void setOutput(byte[] buf, int off, int len){ - next_out = buf; - next_out_index = off; - avail_out = len; - } - - public void setInput(byte[] buf){ - setInput(buf, 0, buf.length, false); - } - - public void setInput(byte[] buf, boolean append){ - setInput(buf, 0, buf.length, append); - } - - public void setInput(byte[] buf, int off, int len, boolean append){ - if(len<=0 && append && next_in!=null) return; - - if(avail_in>0 && append){ - byte[] tmp = new byte[avail_in+len]; - System.arraycopy(next_in, next_in_index, tmp, 0, avail_in); - System.arraycopy(buf, off, tmp, avail_in, len); - next_in=tmp; - next_in_index=0; - avail_in+=len; - } - else{ - next_in=buf; - next_in_index=off; - avail_in=len; - } - } - - public byte[] getNextIn(){ - return next_in; - } - - public void setNextIn(byte[] next_in){ - this.next_in = next_in; - } - - public int getNextInIndex(){ - return next_in_index; - } - - public void setNextInIndex(int next_in_index){ - this.next_in_index = next_in_index; - } - - public int getAvailIn(){ - return avail_in; - } - - public void setAvailIn(int avail_in){ - this.avail_in = avail_in; - } - - public byte[] getNextOut(){ - return next_out; - } - - public void setNextOut(byte[] next_out){ - this.next_out = next_out; - } - - public int getNextOutIndex(){ - return next_out_index; - } - - public void setNextOutIndex(int next_out_index){ - this.next_out_index = next_out_index; - } - - public int getAvailOut(){ - return avail_out; - - } - - public void setAvailOut(int avail_out){ - this.avail_out = avail_out; - } - - public long getTotalOut(){ - return total_out; - } - - public long getTotalIn(){ - return total_in; - } - - public String getMessage(){ - return msg; - } - - /** - * Those methods are expected to be override by Inflater and Deflater. - * In the future, they will become abstract methods. - */ - public int end(){ return Z_OK; } - public boolean finished(){ return false; } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZipConstants64.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZipConstants64.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -/* - * This class defines the constants that are used by the classes - * which manipulate Zip64 files. - */ - -public class ZipConstants64 { - - /* - * ZIP64 constants - */ - static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006" - static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007" - static final int ZIP64_ENDHDR = 56; // ZIP64 end header size - static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size - static final int ZIP64_EXTHDR = 24; // EXT header size - static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID - - static final int ZIP64_MAGICCOUNT = 0xFFFF; - static final long ZIP64_MAGICVAL = 0xFFFFFFFFL; - - /* - * Zip64 End of central directory (END) header field offsets - */ - static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir - static final int ZIP64_ENDVEM = 12; // version made by - static final int ZIP64_ENDVER = 14; // version needed to extract - static final int ZIP64_ENDNMD = 16; // number of this disk - static final int ZIP64_ENDDSK = 20; // disk number of start - static final int ZIP64_ENDTOD = 24; // total number of entries on this disk - static final int ZIP64_ENDTOT = 32; // total number of entries - static final int ZIP64_ENDSIZ = 40; // central directory size in bytes - static final int ZIP64_ENDOFF = 48; // offset of first CEN header - static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector - - /* - * Zip64 End of central directory locator field offsets - */ - static final int ZIP64_LOCDSK = 4; // disk number start - static final int ZIP64_LOCOFF = 8; // offset of zip64 end - static final int ZIP64_LOCTOT = 16; // total number of disks - - /* - * Zip64 Extra local (EXT) header field offsets - */ - static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value - static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte - static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte - - /* - * Language encoding flag EFS - */ - static final int EFS = 0x800; // If this bit is set the filename and - // comment fields for this file must be - // encoded using UTF-8. - - private ZipConstants64() {} -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZipInputStream.java --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZipInputStream.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,468 +0,0 @@ -/* - * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package org.apidesign.bck2brwsr.emul.zip; - -import java.util.zip.*; -import java.io.InputStream; -import java.io.IOException; -import java.io.EOFException; -import java.io.PushbackInputStream; -import static org.apidesign.bck2brwsr.emul.zip.ZipConstants64.*; -import static java.util.zip.ZipInputStream.*; - -/** - * This class implements an input stream filter for reading files in the - * ZIP file format. Includes support for both compressed and uncompressed - * entries. - * - * @author David Connelly - */ -public -class ZipInputStream extends InflaterInputStream { - private ZipEntry entry; - private int flag; - private CRC32 crc = new CRC32(); - private long remaining; - private byte[] tmpbuf = new byte[512]; - - private static final int STORED = ZipEntry.STORED; - private static final int DEFLATED = ZipEntry.DEFLATED; - - private boolean closed = false; - // this flag is set to true after EOF has reached for - // one entry - private boolean entryEOF = false; - - /** - * Check to make sure that this stream has not been closed - */ - private void ensureOpen() throws IOException { - if (closed) { - throw new IOException("Stream closed"); - } - } - - /** - * Creates a new ZIP input stream. - * - *

The UTF-8 {@link java.nio.charset.Charset charset} is used to - * decode the entry names. - * - * @param in the actual input stream - */ - public ZipInputStream(InputStream in) { -// this(in, "UTF-8"); - super(new PushbackInputStream(in, 512), new Inflater(true), 512); - //usesDefaultInflater = true; - if(in == null) { - throw new NullPointerException("in is null"); - } - } - - /** - * Creates a new ZIP input stream. - * - * @param in the actual input stream - * - * @param charset - * The {@linkplain java.nio.charset.Charset charset} to be - * used to decode the ZIP entry name (ignored if the - * language - * encoding bit of the ZIP entry's general purpose bit - * flag is set). - * - * @since 1.7 - * - public ZipInputStream(InputStream in, Charset charset) { - super(new PushbackInputStream(in, 512), new Inflater(true), 512); - usesDefaultInflater = true; - if(in == null) { - throw new NullPointerException("in is null"); - } - if (charset == null) - throw new NullPointerException("charset is null"); - this.zc = ZipCoder.get(charset); - } - */ - - /** - * Reads the next ZIP file entry and positions the stream at the - * beginning of the entry data. - * @return the next ZIP file entry, or null if there are no more entries - * @exception ZipException if a ZIP file error has occurred - * @exception IOException if an I/O error has occurred - */ - public ZipEntry getNextEntry() throws IOException { - ensureOpen(); - if (entry != null) { - closeEntry(); - } - crc.reset(); - inf.reset(); - if ((entry = readLOC()) == null) { - return null; - } - if (entry.getMethod() == STORED) { - remaining = entry.getSize(); - } - entryEOF = false; - return entry; - } - - /** - * Closes the current ZIP entry and positions the stream for reading the - * next entry. - * @exception ZipException if a ZIP file error has occurred - * @exception IOException if an I/O error has occurred - */ - public void closeEntry() throws IOException { - ensureOpen(); - while (read(tmpbuf, 0, tmpbuf.length) != -1) ; - entryEOF = true; - } - - /** - * Returns 0 after EOF has reached for the current entry data, - * otherwise always return 1. - *

- * Programs should not count on this method to return the actual number - * of bytes that could be read without blocking. - * - * @return 1 before EOF and 0 after EOF has reached for current entry. - * @exception IOException if an I/O error occurs. - * - */ - public int available() throws IOException { - ensureOpen(); - if (entryEOF) { - return 0; - } else { - return 1; - } - } - - /** - * Reads from the current ZIP entry into an array of bytes. - * If len is not zero, the method - * blocks until some input is available; otherwise, no - * bytes are read and 0 is returned. - * @param b the buffer into which the data is read - * @param off the start offset in the destination array b - * @param len the maximum number of bytes read - * @return the actual number of bytes read, or -1 if the end of the - * entry is reached - * @exception NullPointerException if b is null. - * @exception IndexOutOfBoundsException if off is negative, - * len is negative, or len is greater than - * b.length - off - * @exception ZipException if a ZIP file error has occurred - * @exception IOException if an I/O error has occurred - */ - public int read(byte[] b, int off, int len) throws IOException { - ensureOpen(); - if (off < 0 || len < 0 || off > b.length - len) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return 0; - } - - if (entry == null) { - return -1; - } - switch (entry.getMethod()) { - case DEFLATED: - len = super.read(b, off, len); - if (len == -1) { - readEnd(entry); - entryEOF = true; - entry = null; - } else { - crc.update(b, off, len); - } - return len; - case STORED: - if (remaining <= 0) { - entryEOF = true; - entry = null; - return -1; - } - if (len > remaining) { - len = (int)remaining; - } - len = in.read(b, off, len); - if (len == -1) { - throw new ZipException("unexpected EOF"); - } - crc.update(b, off, len); - remaining -= len; - if (remaining == 0 && entry.getCrc() != crc.getValue()) { - throw new ZipException( - "invalid entry CRC (expected 0x" + Long.toHexString(entry.getCrc()) + - " but got 0x" + Long.toHexString(crc.getValue()) + ")"); - } - return len; - default: - throw new ZipException("invalid compression method"); - } - } - - /** - * Skips specified number of bytes in the current ZIP entry. - * @param n the number of bytes to skip - * @return the actual number of bytes skipped - * @exception ZipException if a ZIP file error has occurred - * @exception IOException if an I/O error has occurred - * @exception IllegalArgumentException if n < 0 - */ - public long skip(long n) throws IOException { - if (n < 0) { - throw new IllegalArgumentException("negative skip length"); - } - ensureOpen(); - int max = (int)Math.min(n, Integer.MAX_VALUE); - int total = 0; - while (total < max) { - int len = max - total; - if (len > tmpbuf.length) { - len = tmpbuf.length; - } - len = read(tmpbuf, 0, len); - if (len == -1) { - entryEOF = true; - break; - } - total += len; - } - return total; - } - - /** - * Closes this input stream and releases any system resources associated - * with the stream. - * @exception IOException if an I/O error has occurred - */ - public void close() throws IOException { - if (!closed) { - super.close(); - closed = true; - } - } - - private byte[] b = new byte[256]; - - /* - * Reads local file (LOC) header for next entry. - */ - private ZipEntry readLOC() throws IOException { - try { - readFully(tmpbuf, 0, LOCHDR); - } catch (EOFException e) { - return null; - } - if (get32(tmpbuf, 0) != LOCSIG) { - return null; - } - // get flag first, we need check EFS. - flag = get16(tmpbuf, LOCFLG); - // get the entry name and create the ZipEntry first - int len = get16(tmpbuf, LOCNAM); - int blen = b.length; - if (len > blen) { - do - blen = blen * 2; - while (len > blen); - b = new byte[blen]; - } - readFully(b, 0, len); - // Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8 - ZipEntry e = createZipEntry(((flag & EFS) != 0) - ? toStringUTF8(b, len) - : toString(b, len)); - // now get the remaining fields for the entry - if ((flag & 1) == 1) { - throw new ZipException("encrypted ZIP entry not supported"); - } - e.setMethod(get16(tmpbuf, LOCHOW)); - e.setTime(get32(tmpbuf, LOCTIM)); - if ((flag & 8) == 8) { - /* "Data Descriptor" present */ - if (e.getMethod() != DEFLATED) { - throw new ZipException( - "only DEFLATED entries can have EXT descriptor"); - } - } else { - e.setCrc(get32(tmpbuf, LOCCRC)); - e.setCompressedSize(get32(tmpbuf, LOCSIZ)); - e.setSize(get32(tmpbuf, LOCLEN)); - } - len = get16(tmpbuf, LOCEXT); - if (len > 0) { - byte[] bb = new byte[len]; - readFully(bb, 0, len); - e.setExtra(bb); - // extra fields are in "HeaderID(2)DataSize(2)Data... format - if (e.getCompressedSize() == ZIP64_MAGICVAL || e.getCompressedSize() == ZIP64_MAGICVAL) { - int off = 0; - while (off + 4 < len) { - int sz = get16(bb, off + 2); - if (get16(bb, off) == ZIP64_EXTID) { - off += 4; - // LOC extra zip64 entry MUST include BOTH original and - // compressed file size fields - if (sz < 16 || (off + sz) > len ) { - // Invalid zip64 extra fields, simply skip. Even it's - // rare, it's possible the entry size happens to be - // the magic value and it "accidnetly" has some bytes - // in extra match the id. - return e; - } - e.setSize(get64(bb, off)); - e.setCompressedSize(get64(bb, off + 8)); - break; - } - off += (sz + 4); - } - } - } - return e; - } - - /** - * Creates a new ZipEntry object for the specified - * entry name. - * - * @param name the ZIP file entry name - * @return the ZipEntry just created - */ - protected ZipEntry createZipEntry(String name) { - return new ZipEntry(name); - } - - /* - * Reads end of deflated entry as well as EXT descriptor if present. - */ - private void readEnd(ZipEntry e) throws IOException { - int n = inf.getRemaining(); - if (n > 0) { - ((PushbackInputStream)in).unread(buf, len - n, n); - } - if ((flag & 8) == 8) { - /* "Data Descriptor" present */ - if (inf.getBytesWritten() > ZIP64_MAGICVAL || - inf.getBytesRead() > ZIP64_MAGICVAL) { - // ZIP64 format - readFully(tmpbuf, 0, ZIP64_EXTHDR); - long sig = get32(tmpbuf, 0); - if (sig != EXTSIG) { // no EXTSIG present - e.setCrc(sig); - e.setCompressedSize(get64(tmpbuf, ZIP64_EXTSIZ - ZIP64_EXTCRC)); - e.setSize(get64(tmpbuf, ZIP64_EXTLEN - ZIP64_EXTCRC)); - ((PushbackInputStream)in).unread( - tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC - 1, ZIP64_EXTCRC); - } else { - e.setCrc(get32(tmpbuf, ZIP64_EXTCRC)); - e.setCompressedSize(get64(tmpbuf, ZIP64_EXTSIZ)); - e.setSize(get64(tmpbuf, ZIP64_EXTLEN)); - } - } else { - readFully(tmpbuf, 0, EXTHDR); - long sig = get32(tmpbuf, 0); - if (sig != EXTSIG) { // no EXTSIG present - e.setCrc(sig); - e.setCompressedSize(get32(tmpbuf, EXTSIZ - EXTCRC)); - e.setSize(get32(tmpbuf, EXTLEN - EXTCRC)); - ((PushbackInputStream)in).unread( - tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC); - } else { - e.setCrc(get32(tmpbuf, EXTCRC)); - e.setCompressedSize(get32(tmpbuf, EXTSIZ)); - e.setSize(get32(tmpbuf, EXTLEN)); - } - } - } - if (e.getSize() != inf.getBytesWritten()) { - throw new ZipException( - "invalid entry size (expected " + e.getSize() + - " but got " + inf.getBytesWritten() + " bytes)"); - } - if (e.getCompressedSize() != inf.getBytesRead()) { - throw new ZipException( - "invalid entry compressed size (expected " + e.getCompressedSize() + - " but got " + inf.getBytesRead() + " bytes)"); - } - if (e.getCrc() != crc.getValue()) { - throw new ZipException( - "invalid entry CRC (expected 0x" + Long.toHexString(e.getCrc()) + - " but got 0x" + Long.toHexString(crc.getValue()) + ")"); - } - } - - /* - * Reads bytes, blocking until all bytes are read. - */ - private void readFully(byte[] b, int off, int len) throws IOException { - while (len > 0) { - int n = in.read(b, off, len); - if (n == -1) { - throw new EOFException(); - } - off += n; - len -= n; - } - } - - /* - * Fetches unsigned 16-bit value from byte array at specified offset. - * The bytes are assumed to be in Intel (little-endian) byte order. - */ - private static final int get16(byte b[], int off) { - return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8); - } - - /* - * Fetches unsigned 32-bit value from byte array at specified offset. - * The bytes are assumed to be in Intel (little-endian) byte order. - */ - private static final long get32(byte b[], int off) { - return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL; - } - - /* - * Fetches signed 64-bit value from byte array at specified offset. - * The bytes are assumed to be in Intel (little-endian) byte order. - */ - private static final long get64(byte b[], int off) { - return get32(b, off) | (get32(b, off+4) << 32); - } - - private static String toStringUTF8(byte[] arr, int len) { - return new String(arr, 0, len); - } - - private static String toString(byte[] b, int len) { - return new String(b, 0, len); - } -} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/pom.xml --- a/rt/emul/pom.xml Tue May 06 17:46:47 2014 +0200 +++ b/rt/emul/pom.xml Sun May 11 14:01:18 2014 +0200 @@ -16,5 +16,6 @@ compact brwsrtest fake + zip diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/pom.xml Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,70 @@ + + + 4.0.0 + + org.apidesign.bck2brwsr + emul.pom + 0.9-SNAPSHOT + + emul.zip + Unzip by JCraft for Bck2Brwsr + > + 100% pure Java re-implementation of Zlib + that allows usage of JAR files with Bck2Brwsr + virtual machine. + + jar + + + + org.apache.maven.plugins + maven-surefire-plugin + + + brwsr + + + + + + + + org.apidesign.bck2brwsr + core + ${project.version} + jar + + + org.testng + testng + test + + + org.apidesign.bck2brwsr + emul.mini + ${project.version} + compile + jar + + + org.apidesign.bck2brwsr + vmtest + ${project.version} + test + jar + + + org.apidesign.bck2brwsr + launcher.http + ${project.version} + test + jar + + + org.apidesign.bck2brwsr + vm4brwsr + ${project.version} + jar + + + diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/Adler32.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/Adler32.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,205 @@ +/* Adler32.java - Computes Adler32 data checksum of a data stream + Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.util.zip; + +/* + * Written using on-line Java Platform 1.2 API Specification, as well + * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). + * The actual Adler32 algorithm is taken from RFC 1950. + * Status: Believed complete and correct. + */ + +/** + * Computes Adler32 checksum for a stream of data. An Adler32 + * checksum is not as reliable as a CRC32 checksum, but a lot faster to + * compute. + *

+ * The specification for Adler32 may be found in RFC 1950. + * (ZLIB Compressed Data Format Specification version 3.3) + *

+ *

+ * From that document: + *

+ * "ADLER32 (Adler-32 checksum) + * This contains a checksum value of the uncompressed data + * (excluding any dictionary data) computed according to Adler-32 + * algorithm. This algorithm is a 32-bit extension and improvement + * of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 + * standard. + *

+ * Adler-32 is composed of two sums accumulated per byte: s1 is + * the sum of all bytes, s2 is the sum of all s1 values. Both sums + * are done modulo 65521. s1 is initialized to 1, s2 to zero. The + * Adler-32 checksum is stored as s2*65536 + s1 in most- + * significant-byte first (network) order." + *

+ * "8.2. The Adler-32 algorithm + *

+ * The Adler-32 algorithm is much faster than the CRC32 algorithm yet + * still provides an extremely low probability of undetected errors. + *

+ * The modulo on unsigned long accumulators can be delayed for 5552 + * bytes, so the modulo operation time is negligible. If the bytes + * are a, b, c, the second sum is 3a + 2b + c + 3, and so is position + * and order sensitive, unlike the first sum, which is just a + * checksum. That 65521 is prime is important to avoid a possible + * large class of two-byte errors that leave the check unchanged. + * (The Fletcher checksum uses 255, which is not prime and which also + * makes the Fletcher check insensitive to single byte changes 0 <-> + * 255.) + *

+ * The sum s1 is initialized to 1 instead of zero to make the length + * of the sequence part of s2, so that the length does not have to be + * checked separately. (Any sequence of zeroes has a Fletcher + * checksum of zero.)" + * + * @author John Leuner, Per Bothner + * @since JDK 1.1 + * + * @see InflaterInputStream + * @see DeflaterOutputStream + */ +public class Adler32 implements Checksum +{ + + /** largest prime smaller than 65536 */ + private static final int BASE = 65521; + + private int checksum; //we do all in int. + + //Note that java doesn't have unsigned integers, + //so we have to be careful with what arithmetic + //we do. We return the checksum as a long to + //avoid sign confusion. + + /** + * Creates a new instance of the Adler32 class. + * The checksum starts off with a value of 1. + */ + public Adler32 () + { + reset(); + } + + /** + * Resets the Adler32 checksum to the initial value. + */ + public void reset () + { + checksum = 1; //Initialize to 1 + } + + /** + * Updates the checksum with the byte b. + * + * @param bval the data value to add. The high byte of the int is ignored. + */ + public void update (int bval) + { + //We could make a length 1 byte array and call update again, but I + //would rather not have that overhead + int s1 = checksum & 0xffff; + int s2 = checksum >>> 16; + + s1 = (s1 + (bval & 0xFF)) % BASE; + s2 = (s1 + s2) % BASE; + + checksum = (s2 << 16) + s1; + } + + /** + * Updates the checksum with the bytes taken from the array. + * + * @param buffer an array of bytes + */ + public void update (byte[] buffer) + { + update(buffer, 0, buffer.length); + } + + /** + * Updates the checksum with the bytes taken from the array. + * + * @param buf an array of bytes + * @param off the start of the data used for this update + * @param len the number of bytes to use for this update + */ + public void update (byte[] buf, int off, int len) + { + //(By Per Bothner) + int s1 = checksum & 0xffff; + int s2 = checksum >>> 16; + + while (len > 0) + { + // We can defer the modulo operation: + // s1 maximally grows from 65521 to 65521 + 255 * 3800 + // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31 + int n = 3800; + if (n > len) + n = len; + len -= n; + while (--n >= 0) + { + s1 = s1 + (buf[off++] & 0xFF); + s2 = s2 + s1; + } + s1 %= BASE; + s2 %= BASE; + } + + /*Old implementation, borrowed from somewhere: + int n; + + while (len-- > 0) { + + s1 = (s1 + (bs[offset++] & 0xff)) % BASE; + s2 = (s2 + s1) % BASE; + }*/ + + checksum = (s2 << 16) | s1; + } + + /** + * Returns the Adler32 data checksum computed so far. + */ + public long getValue() + { + return (long) checksum & 0xffffffffL; + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/CRC32.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/CRC32.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,132 @@ +/* CRC32.java - Computes CRC32 data checksum of a data stream + Copyright (C) 1999. 2000, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package java.util.zip; + +/* + * Written using on-line Java Platform 1.2 API Specification, as well + * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). + * The actual CRC32 algorithm is taken from RFC 1952. + * Status: Believed complete and correct. + */ + +/** + * Computes CRC32 data checksum of a data stream. + * The actual CRC32 algorithm is described in RFC 1952 + * (GZIP file format specification version 4.3). + * Can be used to get the CRC32 over a stream if used with checked input/output + * streams. + * + * @see InflaterInputStream + * @see DeflaterOutputStream + * + * @author Per Bothner + * @date April 1, 1999. + */ +public class CRC32 implements Checksum +{ + /** The crc data checksum so far. */ + private int crc = 0; + + /** The fast CRC table. Computed once when the CRC32 class is loaded. */ + private static int[] crc_table = make_crc_table(); + + /** Make the table for a fast CRC. */ + private static int[] make_crc_table () + { + int[] crc_table = new int[256]; + for (int n = 0; n < 256; n++) + { + int c = n; + for (int k = 8; --k >= 0; ) + { + if ((c & 1) != 0) + c = 0xedb88320 ^ (c >>> 1); + else + c = c >>> 1; + } + crc_table[n] = c; + } + return crc_table; + } + + /** + * Returns the CRC32 data checksum computed so far. + */ + public long getValue () + { + return (long) crc & 0xffffffffL; + } + + /** + * Resets the CRC32 data checksum as if no update was ever called. + */ + public void reset () { crc = 0; } + + /** + * Updates the checksum with the int bval. + * + * @param bval (the byte is taken as the lower 8 bits of bval) + */ + + public void update (int bval) + { + int c = ~crc; + c = crc_table[(c ^ bval) & 0xff] ^ (c >>> 8); + crc = ~c; + } + + /** + * Adds the byte array to the data checksum. + * + * @param buf the buffer which contains the data + * @param off the offset in the buffer where the data starts + * @param len the length of the data + */ + public void update (byte[] buf, int off, int len) + { + int c = ~crc; + while (--len >= 0) + c = crc_table[(c ^ buf[off++]) & 0xff] ^ (c >>> 8); + crc = ~c; + } + + /** + * Adds the complete byte array to the data checksum. + */ + public void update (byte[] buf) { update(buf, 0, buf.length); } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/Checksum.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/Checksum.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util.zip; + +/** + * An interface representing a data checksum. + * + * @author David Connelly + */ +public +interface Checksum { + /** + * Updates the current checksum with the specified byte. + * + * @param b the byte to update the checksum with + */ + public void update(int b); + + /** + * Updates the current checksum with the specified array of bytes. + * @param b the byte array to update the checksum with + * @param off the start offset of the data + * @param len the number of bytes to use for the update + */ + public void update(byte[] b, int off, int len); + + /** + * Returns the current checksum value. + * @return the current checksum value + */ + public long getValue(); + + /** + * Resets the checksum to its initial value. + */ + public void reset(); +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/DataFormatException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/DataFormatException.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util.zip; + +/** + * Signals that a data format error has occurred. + * + * @author David Connelly + */ +public +class DataFormatException extends Exception { + private static final long serialVersionUID = 2219632870893641452L; + + /** + * Constructs a DataFormatException with no detail message. + */ + public DataFormatException() { + super(); + } + + /** + * Constructs a DataFormatException with the specified detail message. + * A detail message is a String that describes this particular exception. + * @param s the String containing a detail message + */ + public DataFormatException(String s) { + super(s); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/Inflater.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/Inflater.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,310 @@ +/* + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util.zip; + +/** + * This class provides support for general purpose decompression using the + * popular ZLIB compression library. The ZLIB compression library was + * initially developed as part of the PNG graphics standard and is not + * protected by patents. It is fully described in the specifications at + * the java.util.zip + * package description. + * + *

The following code fragment demonstrates a trivial compression + * and decompression of a string using Deflater and + * Inflater. + * + *

+ * try {
+ *     // Encode a String into bytes
+ *     String inputString = "blahblahblah\u20AC\u20AC";
+ *     byte[] input = inputString.getBytes("UTF-8");
+ *
+ *     // Compress the bytes
+ *     byte[] output = new byte[100];
+ *     Deflater compresser = new Deflater();
+ *     compresser.setInput(input);
+ *     compresser.finish();
+ *     int compressedDataLength = compresser.deflate(output);
+ *
+ *     // Decompress the bytes
+ *     Inflater decompresser = new Inflater();
+ *     decompresser.setInput(output, 0, compressedDataLength);
+ *     byte[] result = new byte[100];
+ *     int resultLength = decompresser.inflate(result);
+ *     decompresser.end();
+ *
+ *     // Decode the bytes into a String
+ *     String outputString = new String(result, 0, resultLength, "UTF-8");
+ * } catch(java.io.UnsupportedEncodingException ex) {
+ *     // handle
+ * } catch (java.util.zip.DataFormatException ex) {
+ *     // handle
+ * }
+ * 
+ * + * @see Deflater + * @author David Connelly + * + */ +public +class Inflater { + private final org.apidesign.bck2brwsr.emul.zip.Inflater impl; + + /** + * Creates a new decompressor. If the parameter 'nowrap' is true then + * the ZLIB header and checksum fields will not be used. This provides + * compatibility with the compression format used by both GZIP and PKZIP. + *

+ * Note: When using the 'nowrap' option it is also necessary to provide + * an extra "dummy" byte as input. This is required by the ZLIB native + * library in order to support certain optimizations. + * + * @param nowrap if true then support GZIP compatible compression + */ + public Inflater(boolean nowrap) { + if (getClass() == org.apidesign.bck2brwsr.emul.zip.Inflater.class) { + impl = null; + } else { + impl = new org.apidesign.bck2brwsr.emul.zip.Inflater(nowrap); + } + } + + /** + * Creates a new decompressor. + */ + public Inflater() { + this(false); + } + + /** + * Sets input data for decompression. Should be called whenever + * needsInput() returns true indicating that more input data is + * required. + * @param b the input data bytes + * @param off the start offset of the input data + * @param len the length of the input data + * @see Inflater#needsInput + */ + public void setInput(byte[] b, int off, int len) { + impl.setInput(b, off, len); + } + + /** + * Sets input data for decompression. Should be called whenever + * needsInput() returns true indicating that more input data is + * required. + * @param b the input data bytes + * @see Inflater#needsInput + */ + public void setInput(byte[] b) { + impl.setInput(b); + } + + /** + * Sets the preset dictionary to the given array of bytes. Should be + * called when inflate() returns 0 and needsDictionary() returns true + * indicating that a preset dictionary is required. The method getAdler() + * can be used to get the Adler-32 value of the dictionary needed. + * @param b the dictionary data bytes + * @param off the start offset of the data + * @param len the length of the data + * @see Inflater#needsDictionary + * @see Inflater#getAdler + */ + public void setDictionary(byte[] b, int off, int len) { + impl.setDictionary(b, off, len); + } + + /** + * Sets the preset dictionary to the given array of bytes. Should be + * called when inflate() returns 0 and needsDictionary() returns true + * indicating that a preset dictionary is required. The method getAdler() + * can be used to get the Adler-32 value of the dictionary needed. + * @param b the dictionary data bytes + * @see Inflater#needsDictionary + * @see Inflater#getAdler + */ + public void setDictionary(byte[] b) { + impl.setDictionary(b); + } + + /** + * Returns the total number of bytes remaining in the input buffer. + * This can be used to find out what bytes still remain in the input + * buffer after decompression has finished. + * @return the total number of bytes remaining in the input buffer + */ + public int getRemaining() { + return impl.getRemaining(); + } + + /** + * Returns true if no data remains in the input buffer. This can + * be used to determine if #setInput should be called in order + * to provide more input. + * @return true if no data remains in the input buffer + */ + public boolean needsInput() { + return impl.needsInput(); + } + + /** + * Returns true if a preset dictionary is needed for decompression. + * @return true if a preset dictionary is needed for decompression + * @see Inflater#setDictionary + */ + public boolean needsDictionary() { + return impl.needsDictionary(); + } + + /** + * Returns true if the end of the compressed data stream has been + * reached. + * @return true if the end of the compressed data stream has been + * reached + */ + public boolean finished() { + return impl.finished(); + } + + /** + * Uncompresses bytes into specified buffer. Returns actual number + * of bytes uncompressed. A return value of 0 indicates that + * needsInput() or needsDictionary() should be called in order to + * determine if more input data or a preset dictionary is required. + * In the latter case, getAdler() can be used to get the Adler-32 + * value of the dictionary required. + * @param b the buffer for the uncompressed data + * @param off the start offset of the data + * @param len the maximum number of uncompressed bytes + * @return the actual number of uncompressed bytes + * @exception DataFormatException if the compressed data format is invalid + * @see Inflater#needsInput + * @see Inflater#needsDictionary + */ + public int inflate(byte[] b, int off, int len) + throws DataFormatException + { + return impl.inflate(b, off, len); + } + + /** + * Uncompresses bytes into specified buffer. Returns actual number + * of bytes uncompressed. A return value of 0 indicates that + * needsInput() or needsDictionary() should be called in order to + * determine if more input data or a preset dictionary is required. + * In the latter case, getAdler() can be used to get the Adler-32 + * value of the dictionary required. + * @param b the buffer for the uncompressed data + * @return the actual number of uncompressed bytes + * @exception DataFormatException if the compressed data format is invalid + * @see Inflater#needsInput + * @see Inflater#needsDictionary + */ + public int inflate(byte[] b) throws DataFormatException { + return impl.inflate(b); + } + + /** + * Returns the ADLER-32 value of the uncompressed data. + * @return the ADLER-32 value of the uncompressed data + */ + public int getAdler() { + return impl.getAdler(); + } + + /** + * Returns the total number of compressed bytes input so far. + * + *

Since the number of bytes may be greater than + * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now + * the preferred means of obtaining this information.

+ * + * @return the total number of compressed bytes input so far + */ + public int getTotalIn() { + return impl.getTotalIn(); + } + + /** + * Returns the total number of compressed bytes input so far.

+ * + * @return the total (non-negative) number of compressed bytes input so far + * @since 1.5 + */ + public long getBytesRead() { + return impl.getBytesRead(); + } + + /** + * Returns the total number of uncompressed bytes output so far. + * + *

Since the number of bytes may be greater than + * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now + * the preferred means of obtaining this information.

+ * + * @return the total number of uncompressed bytes output so far + */ + public int getTotalOut() { + return impl.getTotalOut(); + } + + /** + * Returns the total number of uncompressed bytes output so far.

+ * + * @return the total (non-negative) number of uncompressed bytes output so far + * @since 1.5 + */ + public long getBytesWritten() { + return impl.getBytesWritten(); + } + + /** + * Resets inflater so that a new set of input data can be processed. + */ + public void reset() { + impl.reset(); + } + + /** + * Closes the decompressor and discards any unprocessed input. + * This method should be called when the decompressor is no longer + * being used, but will also be called automatically by the finalize() + * method. Once this method is called, the behavior of the Inflater + * object is undefined. + */ + public void end() { + impl.end(); + } + + /** + * Closes the decompressor when garbage is collected. + */ + protected void finalize() { + end(); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/InflaterInputStream.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/InflaterInputStream.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,288 @@ +/* + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util.zip; + +import java.io.FilterInputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.EOFException; + +/** + * This class implements a stream filter for uncompressing data in the + * "deflate" compression format. It is also used as the basis for other + * decompression filters, such as GZIPInputStream. + * + * @see Inflater + * @author David Connelly + */ +public +class InflaterInputStream extends FilterInputStream { + /** + * Decompressor for this stream. + */ + protected Inflater inf; + + /** + * Input buffer for decompression. + */ + protected byte[] buf; + + /** + * Length of input buffer. + */ + protected int len; + + private boolean closed = false; + // this flag is set to true after EOF has reached + private boolean reachEOF = false; + + /** + * Check to make sure that this stream has not been closed + */ + private void ensureOpen() throws IOException { + if (closed) { + throw new IOException("Stream closed"); + } + } + + + /** + * Creates a new input stream with the specified decompressor and + * buffer size. + * @param in the input stream + * @param inf the decompressor ("inflater") + * @param size the input buffer size + * @exception IllegalArgumentException if size is <= 0 + */ + public InflaterInputStream(InputStream in, Inflater inf, int size) { + super(in); + if (in == null || inf == null) { + throw new NullPointerException(); + } else if (size <= 0) { + throw new IllegalArgumentException("buffer size <= 0"); + } + this.inf = inf; + buf = new byte[size]; + } + + /** + * Creates a new input stream with the specified decompressor and a + * default buffer size. + * @param in the input stream + * @param inf the decompressor ("inflater") + */ + public InflaterInputStream(InputStream in, Inflater inf) { + this(in, inf, 512); + } + + boolean usesDefaultInflater = false; + + /** + * Creates a new input stream with a default decompressor and buffer size. + * @param in the input stream + */ + public InflaterInputStream(InputStream in) { + this(in, new Inflater()); + usesDefaultInflater = true; + } + + private byte[] singleByteBuf = new byte[1]; + + /** + * Reads a byte of uncompressed data. This method will block until + * enough input is available for decompression. + * @return the byte read, or -1 if end of compressed input is reached + * @exception IOException if an I/O error has occurred + */ + public int read() throws IOException { + ensureOpen(); + return read(singleByteBuf, 0, 1) == -1 ? -1 : singleByteBuf[0] & 0xff; + } + + /** + * Reads uncompressed data into an array of bytes. If len is not + * zero, the method will block until some input can be decompressed; otherwise, + * no bytes are read and 0 is returned. + * @param b the buffer into which the data is read + * @param off the start offset in the destination array b + * @param len the maximum number of bytes read + * @return the actual number of bytes read, or -1 if the end of the + * compressed input is reached or a preset dictionary is needed + * @exception NullPointerException If b is null. + * @exception IndexOutOfBoundsException If off is negative, + * len is negative, or len is greater than + * b.length - off + * @exception ZipException if a ZIP format error has occurred + * @exception IOException if an I/O error has occurred + */ + public int read(byte[] b, int off, int len) throws IOException { + ensureOpen(); + if (b == null) { + throw new NullPointerException(); + } else if (off < 0 || len < 0 || len > b.length - off) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } + try { + int n; + while ((n = inf.inflate(b, off, len)) == 0) { + if (inf.finished() || inf.needsDictionary()) { + reachEOF = true; + return -1; + } + if (inf.needsInput()) { + fill(); + } + } + return n; + } catch (DataFormatException e) { + String s = e.getMessage(); + throw new ZipException(s != null ? s : "Invalid ZLIB data format"); + } + } + + /** + * Returns 0 after EOF has been reached, otherwise always return 1. + *

+ * Programs should not count on this method to return the actual number + * of bytes that could be read without blocking. + * + * @return 1 before EOF and 0 after EOF. + * @exception IOException if an I/O error occurs. + * + */ + public int available() throws IOException { + ensureOpen(); + if (reachEOF) { + return 0; + } else { + return 1; + } + } + + private byte[] b = new byte[512]; + + /** + * Skips specified number of bytes of uncompressed data. + * @param n the number of bytes to skip + * @return the actual number of bytes skipped. + * @exception IOException if an I/O error has occurred + * @exception IllegalArgumentException if n < 0 + */ + public long skip(long n) throws IOException { + if (n < 0) { + throw new IllegalArgumentException("negative skip length"); + } + ensureOpen(); + int max = (int)Math.min(n, Integer.MAX_VALUE); + int total = 0; + while (total < max) { + int len = max - total; + if (len > b.length) { + len = b.length; + } + len = read(b, 0, len); + if (len == -1) { + reachEOF = true; + break; + } + total += len; + } + return total; + } + + /** + * Closes this input stream and releases any system resources associated + * with the stream. + * @exception IOException if an I/O error has occurred + */ + public void close() throws IOException { + if (!closed) { + if (usesDefaultInflater) + inf.end(); + in.close(); + closed = true; + } + } + + /** + * Fills input buffer with more data to decompress. + * @exception IOException if an I/O error has occurred + */ + protected void fill() throws IOException { + ensureOpen(); + len = in.read(buf, 0, buf.length); + if (len == -1) { + throw new EOFException("Unexpected end of ZLIB input stream"); + } + inf.setInput(buf, 0, len); + } + + /** + * Tests if this input stream supports the mark and + * reset methods. The markSupported + * method of InflaterInputStream returns + * false. + * + * @return a boolean indicating if this stream type supports + * the mark and reset methods. + * @see java.io.InputStream#mark(int) + * @see java.io.InputStream#reset() + */ + public boolean markSupported() { + return false; + } + + /** + * Marks the current position in this input stream. + * + *

The mark method of InflaterInputStream + * does nothing. + * + * @param readlimit the maximum limit of bytes that can be read before + * the mark position becomes invalid. + * @see java.io.InputStream#reset() + */ + public synchronized void mark(int readlimit) { + } + + /** + * Repositions this stream to the position at the time the + * mark method was last called on this input stream. + * + *

The method reset for class + * InflaterInputStream does nothing except throw an + * IOException. + * + * @exception IOException if this method is invoked. + * @see java.io.InputStream#mark(int) + * @see java.io.IOException + */ + public synchronized void reset() throws IOException { + throw new IOException("mark/reset not supported"); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/ZStreamRef.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/ZStreamRef.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util.zip; + +/** + * A reference to the native zlib's z_stream structure. + */ + +class ZStreamRef { + + private long address; + ZStreamRef (long address) { + this.address = address; + } + + long address() { + return address; + } + + void clear() { + address = 0; + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/ZipConstants.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/ZipConstants.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util.zip; + +/* + * This interface defines the constants that are used by the classes + * which manipulate ZIP files. + * + * @author David Connelly + */ +interface ZipConstants { + /* + * Header signatures + */ + static long LOCSIG = 0x04034b50L; // "PK\003\004" + static long EXTSIG = 0x08074b50L; // "PK\007\008" + static long CENSIG = 0x02014b50L; // "PK\001\002" + static long ENDSIG = 0x06054b50L; // "PK\005\006" + + /* + * Header sizes in bytes (including signatures) + */ + static final int LOCHDR = 30; // LOC header size + static final int EXTHDR = 16; // EXT header size + static final int CENHDR = 46; // CEN header size + static final int ENDHDR = 22; // END header size + + /* + * Local file (LOC) header field offsets + */ + static final int LOCVER = 4; // version needed to extract + static final int LOCFLG = 6; // general purpose bit flag + static final int LOCHOW = 8; // compression method + static final int LOCTIM = 10; // modification time + static final int LOCCRC = 14; // uncompressed file crc-32 value + static final int LOCSIZ = 18; // compressed size + static final int LOCLEN = 22; // uncompressed size + static final int LOCNAM = 26; // filename length + static final int LOCEXT = 28; // extra field length + + /* + * Extra local (EXT) header field offsets + */ + static final int EXTCRC = 4; // uncompressed file crc-32 value + static final int EXTSIZ = 8; // compressed size + static final int EXTLEN = 12; // uncompressed size + + /* + * Central directory (CEN) header field offsets + */ + static final int CENVEM = 4; // version made by + static final int CENVER = 6; // version needed to extract + static final int CENFLG = 8; // encrypt, decrypt flags + static final int CENHOW = 10; // compression method + static final int CENTIM = 12; // modification time + static final int CENCRC = 16; // uncompressed file crc-32 value + static final int CENSIZ = 20; // compressed size + static final int CENLEN = 24; // uncompressed size + static final int CENNAM = 28; // filename length + static final int CENEXT = 30; // extra field length + static final int CENCOM = 32; // comment length + static final int CENDSK = 34; // disk number start + static final int CENATT = 36; // internal file attributes + static final int CENATX = 38; // external file attributes + static final int CENOFF = 42; // LOC header offset + + /* + * End of central directory (END) header field offsets + */ + static final int ENDSUB = 8; // number of entries on this disk + static final int ENDTOT = 10; // total number of entries + static final int ENDSIZ = 12; // central directory size in bytes + static final int ENDOFF = 16; // offset of first CEN header + static final int ENDCOM = 20; // zip file comment length +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/ZipEntry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/ZipEntry.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,331 @@ +/* + * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util.zip; + +/** + * This class is used to represent a ZIP file entry. + * + * @author David Connelly + */ +public +class ZipEntry implements ZipConstants, Cloneable { + String name; // entry name + long time = -1; // modification time (in DOS time) + long crc = -1; // crc-32 of entry data + long size = -1; // uncompressed size of entry data + long csize = -1; // compressed size of entry data + int method = -1; // compression method + int flag = 0; // general purpose flag + byte[] extra; // optional extra field data for entry + String comment; // optional comment string for entry + + /** + * Compression method for uncompressed entries. + */ + public static final int STORED = 0; + + /** + * Compression method for compressed (deflated) entries. + */ + public static final int DEFLATED = 8; + + /** + * Creates a new zip entry with the specified name. + * + * @param name the entry name + * @exception NullPointerException if the entry name is null + * @exception IllegalArgumentException if the entry name is longer than + * 0xFFFF bytes + */ + public ZipEntry(String name) { + if (name == null) { + throw new NullPointerException(); + } + if (name.length() > 0xFFFF) { + throw new IllegalArgumentException("entry name too long"); + } + this.name = name; + } + + /** + * Creates a new zip entry with fields taken from the specified + * zip entry. + * @param e a zip Entry object + */ + public ZipEntry(ZipEntry e) { + name = e.name; + time = e.time; + crc = e.crc; + size = e.size; + csize = e.csize; + method = e.method; + flag = e.flag; + extra = e.extra; + comment = e.comment; + } + + /* + * Creates a new un-initialized zip entry + */ + ZipEntry() {} + + /** + * Returns the name of the entry. + * @return the name of the entry + */ + public String getName() { + return name; + } + + /** + * Sets the modification time of the entry. + * @param time the entry modification time in number of milliseconds + * since the epoch + * @see #getTime() + */ + public void setTime(long time) { + this.time = javaToDosTime(time); + } + + /** + * Returns the modification time of the entry, or -1 if not specified. + * @return the modification time of the entry, or -1 if not specified + * @see #setTime(long) + */ + public long getTime() { + return time != -1 ? dosToJavaTime(time) : -1; + } + + /** + * Sets the uncompressed size of the entry data. + * @param size the uncompressed size in bytes + * @exception IllegalArgumentException if the specified size is less + * than 0, is greater than 0xFFFFFFFF when + * ZIP64 format is not supported, + * or is less than 0 when ZIP64 is supported + * @see #getSize() + */ + public void setSize(long size) { + if (size < 0) { + throw new IllegalArgumentException("invalid entry size"); + } + this.size = size; + } + + /** + * Returns the uncompressed size of the entry data, or -1 if not known. + * @return the uncompressed size of the entry data, or -1 if not known + * @see #setSize(long) + */ + public long getSize() { + return size; + } + + /** + * Returns the size of the compressed entry data, or -1 if not known. + * In the case of a stored entry, the compressed size will be the same + * as the uncompressed size of the entry. + * @return the size of the compressed entry data, or -1 if not known + * @see #setCompressedSize(long) + */ + public long getCompressedSize() { + return csize; + } + + /** + * Sets the size of the compressed entry data. + * @param csize the compressed size to set to + * @see #getCompressedSize() + */ + public void setCompressedSize(long csize) { + this.csize = csize; + } + + /** + * Sets the CRC-32 checksum of the uncompressed entry data. + * @param crc the CRC-32 value + * @exception IllegalArgumentException if the specified CRC-32 value is + * less than 0 or greater than 0xFFFFFFFF + * @see #getCrc() + */ + public void setCrc(long crc) { + if (crc < 0 || crc > 0xFFFFFFFFL) { + throw new IllegalArgumentException("invalid entry crc-32"); + } + this.crc = crc; + } + + /** + * Returns the CRC-32 checksum of the uncompressed entry data, or -1 if + * not known. + * @return the CRC-32 checksum of the uncompressed entry data, or -1 if + * not known + * @see #setCrc(long) + */ + public long getCrc() { + return crc; + } + + /** + * Sets the compression method for the entry. + * @param method the compression method, either STORED or DEFLATED + * @exception IllegalArgumentException if the specified compression + * method is invalid + * @see #getMethod() + */ + public void setMethod(int method) { + if (method != STORED && method != DEFLATED) { + throw new IllegalArgumentException("invalid compression method"); + } + this.method = method; + } + + /** + * Returns the compression method of the entry, or -1 if not specified. + * @return the compression method of the entry, or -1 if not specified + * @see #setMethod(int) + */ + public int getMethod() { + return method; + } + + /** + * Sets the optional extra field data for the entry. + * @param extra the extra field data bytes + * @exception IllegalArgumentException if the length of the specified + * extra field data is greater than 0xFFFF bytes + * @see #getExtra() + */ + public void setExtra(byte[] extra) { + if (extra != null && extra.length > 0xFFFF) { + throw new IllegalArgumentException("invalid extra field length"); + } + this.extra = extra; + } + + /** + * Returns the extra field data for the entry, or null if none. + * @return the extra field data for the entry, or null if none + * @see #setExtra(byte[]) + */ + public byte[] getExtra() { + return extra; + } + + /** + * Sets the optional comment string for the entry. + * + *

ZIP entry comments have maximum length of 0xffff. If the length of the + * specified comment string is greater than 0xFFFF bytes after encoding, only + * the first 0xFFFF bytes are output to the ZIP file entry. + * + * @param comment the comment string + * + * @see #getComment() + */ + public void setComment(String comment) { + this.comment = comment; + } + + /** + * Returns the comment string for the entry, or null if none. + * @return the comment string for the entry, or null if none + * @see #setComment(String) + */ + public String getComment() { + return comment; + } + + /** + * Returns true if this is a directory entry. A directory entry is + * defined to be one whose name ends with a '/'. + * @return true if this is a directory entry + */ + public boolean isDirectory() { + return name.endsWith("/"); + } + + /** + * Returns a string representation of the ZIP entry. + */ + public String toString() { + return getName(); + } + + /* + * Converts DOS time to Java time (number of milliseconds since epoch). + */ + private static long dosToJavaTime(long dtime) { + return dtime; + /* XXX: + Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80), + (int)(((dtime >> 21) & 0x0f) - 1), + (int)((dtime >> 16) & 0x1f), + (int)((dtime >> 11) & 0x1f), + (int)((dtime >> 5) & 0x3f), + (int)((dtime << 1) & 0x3e)); + return d.getTime(); + */ + } + + /* + * Converts Java time to DOS time. + */ + private static long javaToDosTime(long time) { + return time; + /* XXX: + Date d = new Date(time); + int year = d.getYear() + 1900; + if (year < 1980) { + return (1 << 21) | (1 << 16); + } + return (year - 1980) << 25 | (d.getMonth() + 1) << 21 | + d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 | + d.getSeconds() >> 1; + */ + } + + /** + * Returns the hash code value for this entry. + */ + public int hashCode() { + return name.hashCode(); + } + + /** + * Returns a copy of this entry. + */ + public Object clone() { + try { + ZipEntry e = (ZipEntry)super.clone(); + e.extra = (extra == null) ? null : extra.clone(); + return e; + } catch (CloneNotSupportedException e) { + // This should never happen, since we are Cloneable + throw new IllegalStateException(); + } + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/ZipException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/ZipException.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util.zip; + +import java.io.IOException; + +/** + * Signals that a Zip exception of some sort has occurred. + * + * @author unascribed + * @see java.io.IOException + * @since JDK1.0 + */ + +public +class ZipException extends IOException { + private static final long serialVersionUID = 8000196834066748623L; + + /** + * Constructs a ZipException with null + * as its error detail message. + */ + public ZipException() { + super(); + } + + /** + * Constructs a ZipException with the specified detail + * message. + * + * @param s the detail message. + */ + + public ZipException(String s) { + super(s); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/ZipInputStream.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/ZipInputStream.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,194 @@ +/* + * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.util.zip; + +import java.io.InputStream; +import java.io.IOException; + +/** + * This class implements an input stream filter for reading files in the + * ZIP file format. Includes support for both compressed and uncompressed + * entries. + * + * @author David Connelly + */ +public +class ZipInputStream extends InflaterInputStream implements ZipConstants { + private final org.apidesign.bck2brwsr.emul.zip.ZipInputStream impl; + + /** + * Creates a new ZIP input stream. + * + *

The UTF-8 {@link java.nio.charset.Charset charset} is used to + * decode the entry names. + * + * @param in the actual input stream + */ + public ZipInputStream(InputStream in) { + super(in); + impl = new org.apidesign.bck2brwsr.emul.zip.ZipInputStream(in); + } + + /** + * Creates a new ZIP input stream. + * + * @param in the actual input stream + * + * @param charset + * The {@linkplain java.nio.charset.Charset charset} to be + * used to decode the ZIP entry name (ignored if the + * language + * encoding bit of the ZIP entry's general purpose bit + * flag is set). + * + * @since 1.7 + * + public ZipInputStream(InputStream in, Charset charset) { + super(new PushbackInputStream(in, 512), new Inflater(true), 512); + usesDefaultInflater = true; + if(in == null) { + throw new NullPointerException("in is null"); + } + if (charset == null) + throw new NullPointerException("charset is null"); + this.zc = ZipCoder.get(charset); + } + */ + + /** + * Reads the next ZIP file entry and positions the stream at the + * beginning of the entry data. + * @return the next ZIP file entry, or null if there are no more entries + * @exception ZipException if a ZIP file error has occurred + * @exception IOException if an I/O error has occurred + */ + public ZipEntry getNextEntry() throws IOException { + return impl.getNextEntry(); + } + + /** + * Closes the current ZIP entry and positions the stream for reading the + * next entry. + * @exception ZipException if a ZIP file error has occurred + * @exception IOException if an I/O error has occurred + */ + public void closeEntry() throws IOException { + impl.closeEntry(); + } + + /** + * Returns 0 after EOF has reached for the current entry data, + * otherwise always return 1. + *

+ * Programs should not count on this method to return the actual number + * of bytes that could be read without blocking. + * + * @return 1 before EOF and 0 after EOF has reached for current entry. + * @exception IOException if an I/O error occurs. + * + */ + public int available() throws IOException { + return impl.available(); + } + + /** + * Reads from the current ZIP entry into an array of bytes. + * If len is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and 0 is returned. + * @param b the buffer into which the data is read + * @param off the start offset in the destination array b + * @param len the maximum number of bytes read + * @return the actual number of bytes read, or -1 if the end of the + * entry is reached + * @exception NullPointerException if b is null. + * @exception IndexOutOfBoundsException if off is negative, + * len is negative, or len is greater than + * b.length - off + * @exception ZipException if a ZIP file error has occurred + * @exception IOException if an I/O error has occurred + */ + public int read(byte[] b, int off, int len) throws IOException { + return impl.read(b, off, len); + } + + /** + * Skips specified number of bytes in the current ZIP entry. + * @param n the number of bytes to skip + * @return the actual number of bytes skipped + * @exception ZipException if a ZIP file error has occurred + * @exception IOException if an I/O error has occurred + * @exception IllegalArgumentException if n < 0 + */ + public long skip(long n) throws IOException { + return impl.skip(n); + } + + /** + * Closes this input stream and releases any system resources associated + * with the stream. + * @exception IOException if an I/O error has occurred + */ + public void close() throws IOException { + impl.close(); + } + + /** + * Creates a new ZipEntry object for the specified + * entry name. + * + * @param name the ZIP file entry name + * @return the ZipEntry just created + */ + protected ZipEntry createZipEntry(String name) { + return new ZipEntry(name); + } + + @Override + public int read() throws IOException { + return impl.read(); + } + + @Override + public boolean markSupported() { + return impl.markSupported(); + } + + @Override + public void mark(int readlimit) { + impl.mark(readlimit); + } + + @Override + public void reset() throws IOException { + impl.reset(); + } + + @Override + public int read(byte[] b) throws IOException { + return impl.read(b); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/package-info.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,22 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +@Exported +package java.util.zip; + +import org.apidesign.bck2brwsr.core.Exported; + diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/java/util/zip/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/java/util/zip/package.html Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,98 @@ + + + + + + + + +Provides classes for reading and writing the standard ZIP and GZIP +file formats. Also includes classes for compressing and decompressing +data using the DEFLATE compression algorithm, which is used by the +ZIP and GZIP file formats. Additionally, there are utility classes +for computing the CRC-32 and Adler-32 checksums of arbitrary +input streams. + + +

Package Specification

+ + + + + + + +@since JDK1.1 + + + + diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/Adler32.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/Adler32.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,139 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package org.apidesign.bck2brwsr.emul.zip; + +final class Adler32 implements Checksum { + + // largest prime smaller than 65536 + static final private int BASE=65521; + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 + static final private int NMAX=5552; + + private long s1=1L; + private long s2=0L; + + public void reset(long init){ + s1=init&0xffff; + s2=(init>>16)&0xffff; + } + + public void reset(){ + s1=1L; + s2=0L; + } + + public long getValue(){ + return ((s2<<16)|s1); + } + + public void update(byte[] buf, int index, int len){ + + if(len==1){ + s1+=buf[index++]&0xff; s2+=s1; + s1%=BASE; + s2%=BASE; + return; + } + + int len1 = len/NMAX; + int len2 = len%NMAX; + while(len1-->0) { + int k=NMAX; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + int k=len2; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + public Adler32 copy(){ + Adler32 foo = new Adler32(); + foo.s1 = this.s1; + foo.s2 = this.s2; + return foo; + } + + // The following logic has come from zlib.1.2. + static long combine(long adler1, long adler2, long len2){ + long BASEL = (long)BASE; + long sum1; + long sum2; + long rem; // unsigned int + + rem = len2 % BASEL; + sum1 = adler1 & 0xffffL; + sum2 = rem * sum1; + sum2 %= BASEL; // MOD(sum2); + sum1 += (adler2 & 0xffffL) + BASEL - 1; + sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); + if (sum2 >= BASEL) sum2 -= BASEL; + return sum1 | (sum2 << 16); + } + +/* + private java.util.zip.Adler32 adler=new java.util.zip.Adler32(); + public void update(byte[] buf, int index, int len){ + if(buf==null) {adler.reset();} + else{adler.update(buf, index, len);} + } + public void reset(){ + adler.reset(); + } + public void reset(long init){ + if(init==1L){ + adler.reset(); + } + else{ + System.err.println("unsupported operation"); + } + } + public long getValue(){ + return adler.getValue(); + } +*/ +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/CRC32.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/CRC32.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,181 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package org.apidesign.bck2brwsr.emul.zip; + + + +final class CRC32 implements Checksum { + + /* + * The following logic has come from RFC1952. + */ + private int v = 0; + private static int[] crc_table = null; + static { + crc_table = new int[256]; + for (int n = 0; n < 256; n++) { + int c = n; + for (int k = 8; --k >= 0; ) { + if ((c & 1) != 0) + c = 0xedb88320 ^ (c >>> 1); + else + c = c >>> 1; + } + crc_table[n] = c; + } + } + + public void update (byte[] buf, int index, int len) { + int c = ~v; + while (--len >= 0) + c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); + v = ~c; + } + + public void reset(){ + v = 0; + } + + public void reset(long vv){ + v = (int)(vv&0xffffffffL); + } + + public long getValue(){ + return (long)(v&0xffffffffL); + } + + // The following logic has come from zlib.1.2. + private static final int GF2_DIM = 32; + static long combine(long crc1, long crc2, long len2){ + long row; + long[] even = new long[GF2_DIM]; + long[] odd = new long[GF2_DIM]; + + // degenerate case (also disallow negative lengths) + if (len2 <= 0) + return crc1; + + // put operator for one zero bit in odd + odd[0] = 0xedb88320L; // CRC-32 polynomial + row = 1; + for (int n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + // put operator for two zero bits in even + gf2_matrix_square(even, odd); + + // put operator for four zero bits in odd + gf2_matrix_square(odd, even); + + // apply len2 zeros to crc1 (first square will put the operator for one + // zero byte, eight zero bits, in even) + do { + // apply zeros operator for this bit of len2 + gf2_matrix_square(even, odd); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + // if no more bits set, then done + if (len2 == 0) + break; + + // another iteration of the loop with odd and even swapped + gf2_matrix_square(odd, even); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + // if no more bits set, then done + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; + } + + private static long gf2_matrix_times(long[] mat, long vec){ + long sum = 0; + int index = 0; + while (vec!=0) { + if ((vec & 1)!=0) + sum ^= mat[index]; + vec >>= 1; + index++; + } + return sum; + } + + static final void gf2_matrix_square(long[] square, long[] mat) { + for (int n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); + } + + /* + private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32(); + + public void update(byte[] buf, int index, int len){ + if(buf==null) {crc32.reset();} + else{crc32.update(buf, index, len);} + } + public void reset(){ + crc32.reset(); + } + public void reset(long init){ + if(init==0L){ + crc32.reset(); + } + else{ + System.err.println("unsupported operation"); + } + } + public long getValue(){ + return crc32.getValue(); + } +*/ + public CRC32 copy(){ + CRC32 foo = new CRC32(); + foo.v = this.v; + return foo; + } + + public static int[] getCRC32Table(){ + int[] tmp = new int[crc_table.length]; + FastJar.arraycopy(crc_table, 0, tmp, 0, tmp.length); + return tmp; + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/Checksum.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/Checksum.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,43 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package org.apidesign.bck2brwsr.emul.zip; + +interface Checksum { + void update(byte[] buf, int index, int len); + void reset(); + void reset(long init); + long getValue(); + Checksum copy(); +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/FastJar.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/FastJar.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,198 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * Portions Copyrighted 2007 Sun Microsystems, Inc. + */ +package org.apidesign.bck2brwsr.emul.zip; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import org.apidesign.bck2brwsr.core.JavaScriptBody; + +/** + * + * @author Tomas Zezula + */ +public final class FastJar { + private final byte[] arr; + + public FastJar(byte[] arr) { + this.arr = arr; + } + + + private static final int GIVE_UP = 1<<16; + + public static final class Entry { + + public final String name; + final long offset; + private final long dosTime; + + Entry (String name, long offset, long time) { + assert name != null; + this.name = name; + this.offset = offset; + this.dosTime = time; + } +/* + public long getTime () { + Date d = new Date((int)(((dosTime >> 25) & 0x7f) + 80), + (int)(((dosTime >> 21) & 0x0f) - 1), + (int)((dosTime >> 16) & 0x1f), + (int)((dosTime >> 11) & 0x1f), + (int)((dosTime >> 5) & 0x3f), + (int)((dosTime << 1) & 0x3e)); + return d.getTime(); + } + */ + } + + public InputStream getInputStream (final Entry e) throws IOException { + return getInputStream(arr, e.offset); + } + + private static InputStream getInputStream (byte[] arr, final long offset) throws IOException { + ByteArrayInputStream is = new ByteArrayInputStream(arr); + is.skip(offset); + ZipInputStream in = new ZipInputStream (is); + ZipEntry e = in.getNextEntry(); + if (e != null && e.getCrc() == 0L && e.getMethod() == ZipEntry.STORED) { + int cp = arr.length - is.available(); + return new ByteArrayInputStream(arr, cp, (int)e.getSize()); + } + return in; + } + + public Entry[] list() throws IOException { + final int size = arr.length; + + int at = size - ZipInputStream.ENDHDR; + + byte[] data = new byte[ZipInputStream.ENDHDR]; + int giveup = 0; + + do { + FastJar.arraycopy(arr, at, data, 0, data.length); + at--; + giveup++; + if (giveup > GIVE_UP) { + throw new IOException (); + } + } while (getsig(data) != ZipInputStream.ENDSIG); + + + final long censize = endsiz(data); + final long cenoff = endoff(data); + at = (int) cenoff; + + Entry[] result = new Entry[0]; + int cenread = 0; + data = new byte[ZipInputStream.CENHDR]; + while (cenread < censize) { + FastJar.arraycopy(arr, at, data, 0, data.length); + at += data.length; + if (getsig(data) != ZipInputStream.CENSIG) { + throw new IOException("No central table"); //NOI18N + } + int cennam = cennam(data); + int cenext = cenext(data); + int cencom = cencom(data); + long lhoff = cenoff(data); + long centim = centim(data); + String name = new String(arr, at, cennam, "UTF-8"); + at += cennam; + int seekby = cenext+cencom; + int cendatalen = ZipInputStream.CENHDR + cennam + seekby; + cenread+=cendatalen; + result = addEntry(result, new Entry(name,lhoff, centim)); + at += seekby; + } + return result; + } + + private Entry[] addEntry(Entry[] result, Entry entry) { + Entry[] e = new Entry[result.length + 1]; + e[result.length] = entry; + FastJar.arraycopy(result, 0, e, 0, result.length); + return e; + } + + private static final long getsig(final byte[] b) throws IOException {return get32(b,0);} + private static final long endsiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.ENDSIZ);} + private static final long endoff(final byte[] b) throws IOException {return get32(b,ZipInputStream.ENDOFF);} + private static final long cenlen(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENLEN);} + private static final long censiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENSIZ);} + private static final long centim(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENTIM);} + private static final int cennam(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENNAM);} + private static final int cenext(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENEXT);} + private static final int cencom(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENCOM);} + private static final long cenoff (final byte[] b) throws IOException {return get32(b,ZipInputStream.CENOFF);} + private static final int lochow(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCHOW);} + private static final int locname(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCNAM);} + private static final int locext(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCEXT);} + private static final long locsiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.LOCSIZ);} + + private static final int get16(final byte[] b, int off) throws IOException { + final int b1 = b[off]; + final int b2 = b[off+1]; + return (b1 & 0xff) | ((b2 & 0xff) << 8); + } + + private static final long get32(final byte[] b, int off) throws IOException { + final int s1 = get16(b, off); + final int s2 = get16(b, off+2); + return s1 | ((long)s2 << 16); + } + + @JavaScriptBody(args = {"value", "srcBegin", "dst", "dstBegin", "count"}, body + = "if (srcBegin < dstBegin) {\n" + + " while (count-- > 0) {\n" + + " dst[dstBegin + count] = value[srcBegin + count];\n" + + " }\n" + + "} else {\n" + + " while (count-- > 0) {\n" + + " dst[dstBegin++] = value[srcBegin++];\n" + + " }\n" + + "}" + ) + static void arraycopy(Object src, int srcBegin, Object dst, int dstBegin, int count) { + try { + Class system = Class.forName("java.lang.System"); + Method m = system.getMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class); + m.invoke(null, src, srcBegin, dst, dstBegin, count); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/GZIPHeader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/GZIPHeader.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,215 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package org.apidesign.bck2brwsr.emul.zip; + + +import java.io.UnsupportedEncodingException; + +/** + * @see "http://www.ietf.org/rfc/rfc1952.txt" + */ +final class GZIPHeader implements Cloneable { + + public static final byte OS_MSDOS = (byte) 0x00; + public static final byte OS_AMIGA = (byte) 0x01; + public static final byte OS_VMS = (byte) 0x02; + public static final byte OS_UNIX = (byte) 0x03; + public static final byte OS_ATARI = (byte) 0x05; + public static final byte OS_OS2 = (byte) 0x06; + public static final byte OS_MACOS = (byte) 0x07; + public static final byte OS_TOPS20 = (byte) 0x0a; + public static final byte OS_WIN32 = (byte) 0x0b; + public static final byte OS_VMCMS = (byte) 0x04; + public static final byte OS_ZSYSTEM = (byte) 0x08; + public static final byte OS_CPM = (byte) 0x09; + public static final byte OS_QDOS = (byte) 0x0c; + public static final byte OS_RISCOS = (byte) 0x0d; + public static final byte OS_UNKNOWN = (byte) 0xff; + + boolean text = false; + private boolean fhcrc = false; + long time; + int xflags; + int os = 255; + byte[] extra; + byte[] name; + byte[] comment; + int hcrc; + long crc; + boolean done = false; + long mtime = 0; + + public void setModifiedTime(long mtime) { + this.mtime = mtime; + } + + public long getModifiedTime() { + return mtime; + } + + public void setOS(int os) { + if((0<=os && os <=13) || os==255) + this.os=os; + else + throw new IllegalArgumentException("os: "+os); + } + + public int getOS(){ + return os; + } + + public void setName(String name) { + try{ + this.name=name.getBytes("ISO-8859-1"); + } + catch(UnsupportedEncodingException e){ + throw new IllegalArgumentException("name must be in ISO-8859-1 "+name); + } + } + + public String getName(){ + if(name==null) return ""; + try { + return new String(name, "ISO-8859-1"); + } + catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException(e.toString()); + } + } + + public void setComment(String comment) { + try{ + this.comment=comment.getBytes("ISO-8859-1"); + } + catch(UnsupportedEncodingException e){ + throw new IllegalArgumentException("comment must be in ISO-8859-1 "+name); + } + } + + public String getComment(){ + if(comment==null) return ""; + try { + return new String(comment, "ISO-8859-1"); + } + catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException(e.toString()); + } + } + + public void setCRC(long crc){ + this.crc = crc; + } + + public long getCRC(){ + return crc; + } +/* + void put(Deflate d){ + int flag = 0; + if(text){ + flag |= 1; // FTEXT + } + if(fhcrc){ + flag |= 2; // FHCRC + } + if(extra!=null){ + flag |= 4; // FEXTRA + } + if(name!=null){ + flag |= 8; // FNAME + } + if(comment!=null){ + flag |= 16; // FCOMMENT + } + int xfl = 0; + if(d.level == JZlib.Z_BEST_SPEED){ + xfl |= 4; + } + else if (d.level == JZlib.Z_BEST_COMPRESSION){ + xfl |= 2; + } + + d.put_short((short)0x8b1f); // ID1 ID2 + d.put_byte((byte)8); // CM(Compression Method) + d.put_byte((byte)flag); + d.put_byte((byte)mtime); + d.put_byte((byte)(mtime>>8)); + d.put_byte((byte)(mtime>>16)); + d.put_byte((byte)(mtime>>24)); + d.put_byte((byte)xfl); + d.put_byte((byte)os); + + if(extra!=null){ + d.put_byte((byte)extra.length); + d.put_byte((byte)(extra.length>>8)); + d.put_byte(extra, 0, extra.length); + } + + if(name!=null){ + d.put_byte(name, 0, name.length); + d.put_byte((byte)0); + } + + if(comment!=null){ + d.put_byte(comment, 0, comment.length); + d.put_byte((byte)0); + } + } +*/ + @Override + public Object clone() throws CloneNotSupportedException { + GZIPHeader gheader = (GZIPHeader)super.clone(); + byte[] tmp; + if(gheader.extra!=null){ + tmp=new byte[gheader.extra.length]; + FastJar.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); + gheader.extra = tmp; + } + + if(gheader.name!=null){ + tmp=new byte[gheader.name.length]; + FastJar.arraycopy(gheader.name, 0, tmp, 0, tmp.length); + gheader.name = tmp; + } + + if(gheader.comment!=null){ + tmp=new byte[gheader.comment.length]; + FastJar.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); + gheader.comment = tmp; + } + + return gheader; + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfBlocks.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfBlocks.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,616 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package org.apidesign.bck2brwsr.emul.zip; + + + +final class InfBlocks{ + static final private int MANY=1440; + + // And'ing with mask[n] masks the lower n bits + static final private int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + // Table for deflate from PKZIP's appnote.txt. + static final int[] border = { // Order of the bit length code lengths + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + }; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final private int TYPE=0; // get type bits (3, including end bit) + static final private int LENS=1; // get lengths for stored + static final private int STORED=2;// processing stored block + static final private int TABLE=3; // get table lengths + static final private int BTREE=4; // get bit lengths tree for a dynamic block + static final private int DTREE=5; // get length, distance trees for a dynamic block + static final private int CODES=6; // processing fixed or dynamic block + static final private int DRY=7; // output remaining window bytes + static final private int DONE=8; // finished last block, done + static final private int BAD=9; // ot a data error--stuck here + + int mode; // current inflate_block mode + + int left; // if STORED, bytes left to copy + + int table; // table lengths (14 bits) + int index; // index into blens (or border) + int[] blens; // bit lengths of codes + int[] bb=new int[1]; // bit length tree depth + int[] tb=new int[1]; // bit length decoding tree + + int[] bl=new int[1]; + int[] bd=new int[1]; + + int[][] tl=new int[1][]; + int[][] td=new int[1][]; + int[] tli=new int[1]; // tl_index + int[] tdi=new int[1]; // td_index + + private final InfCodes codes; // if CODES, current state + + int last; // true if this block is the last block + + // mode independent information + int bitk; // bits in bit buffer + int bitb; // bit buffer + int[] hufts; // single malloc for tree space + byte[] window; // sliding window + int end; // one byte after sliding window + int read; // window read pointer + int write; // window write pointer + private boolean check; + + private final InfTree inftree=new InfTree(); + + private final ZStream z; + + InfBlocks(ZStream z, int w){ + this.z=z; + this.codes=new InfCodes(this.z, this); + hufts=new int[MANY*3]; + window=new byte[w]; + end=w; + this.check = (z.istate.wrap==0) ? false : true; + mode = TYPE; + reset(); + } + + void reset(){ + if(mode==BTREE || mode==DTREE){ + } + if(mode==CODES){ + codes.free(z); + } + mode=TYPE; + bitk=0; + bitb=0; + read=write=0; + if(check){ + z.adler.reset(); + } + } + + int proc(int r){ + int t; // temporary storage + int b; // bit buffer + int k; // bits in bit buffer + int p; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + + // copy input/output information to locals (UPDATE macro restores) + {p=z.next_in_index;n=z.avail_in;b=bitb;k=bitk;} + {q=write;m=(int)(q>> 1){ + case 0: // stored + {b>>>=(3);k-=(3);} + t = k & 7; // go to byte boundary + + {b>>>=(t);k-=(t);} + mode = LENS; // get length of stored block + break; + case 1: // fixed + InfTree.inflate_trees_fixed(bl, bd, tl, td, z); + codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); + + {b>>>=(3);k-=(3);} + + mode = CODES; + break; + case 2: // dynamic + + {b>>>=(3);k-=(3);} + + mode = TABLE; + break; + case 3: // illegal + + {b>>>=(3);k-=(3);} + mode = BAD; + z.msg = "invalid block type"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + break; + case LENS: + + while(k<(32)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>> 16) & 0xffff) != (b & 0xffff)){ + mode = BAD; + z.msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + left = (b & 0xffff); + b = k = 0; // dump bits + mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); + break; + case STORED: + if (n == 0){ + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + if(m==0){ + if(q==end&&read!=0){ + q=0; m=(int)(qn) t = n; + if(t>m) t = m; + FastJar.arraycopy(z.next_in, p, window, q, t); + p += t; n -= t; + q += t; m -= t; + if ((left -= t) != 0) + break; + mode = last!=0 ? DRY : TYPE; + break; + case TABLE: + + while(k<(14)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) + { + mode = BAD; + z.msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if(blens==null || blens.length>>=(14);k-=(14);} + + index = 0; + mode = BTREE; + case BTREE: + while (index < 4 + (table >>> 10)){ + while(k<(3)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} + } + + while(index < 19){ + blens[border[index++]] = 0; + } + + bb[0] = 7; + t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); + if (t != Z_OK){ + r = t; + if (r == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + index = 0; + mode = DTREE; + case DTREE: + while (true){ + t = table; + if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ + break; + } + + int[] h; + int i, j, c; + + t = bb[0]; + + while(k<(t)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); + blens[index++] = c; + } + else { // c == 16..18 + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + + while(k<(t+i)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); + + j += (b & inflate_mask[i]); + + b>>>=(i);k-=(i); + + i = index; + t = table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)){ + blens=null; + mode = BAD; + z.msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + c = c == 16 ? blens[i-1] : 0; + do{ + blens[i++] = c; + } + while (--j!=0); + index = i; + } + } + + tb[0]=-1; + { + bl[0] = 9; // must be <= 9 for lookahead assumptions + bd[0] = 6; // must be <= 9 for lookahead assumptions + t = table; + t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), + 1 + ((t >> 5) & 0x1f), + blens, bl, bd, tli, tdi, hufts, z); + + if (t != Z_OK){ + if (t == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + r = t; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); + } + mode = CODES; + case CODES: + bitb=b; bitk=k; + z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + + if ((r = codes.proc(r)) != Z_STREAM_END){ + return inflate_flush(r); + } + r = Z_OK; + codes.free(z); + + p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; + q=write;m=(int)(q z.avail_out) n = z.avail_out; + if(n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(check && n>0){ + z.adler.update(window, q, n); + } + + // copy as far as end of window + FastJar.arraycopy(window, q, z.next_out, p, n); + p += n; + q += n; + + // see if more to copy at beginning of window + if (q == end){ + // wrap pointers + q = 0; + if (write == end) + write = 0; + + // compute bytes to copy + n = write - q; + if (n > z.avail_out) n = z.avail_out; + if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(check && n>0){ + z.adler.update(window, q, n); + } + + // copy + FastJar.arraycopy(window, q, z.next_out, p, n); + p += n; + q += n; + } + + // update pointers + z.next_out_index = p; + read = q; + + // done + return r; + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfCodes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfCodes.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,612 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package org.apidesign.bck2brwsr.emul.zip; + + + +final class InfCodes{ + + static final private int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + // waiting for "i:"=input, + // "o:"=output, + // "x:"=nothing + static final private int START=0; // x: set up for LEN + static final private int LEN=1; // i: get length/literal/eob next + static final private int LENEXT=2; // i: getting length extra (have base) + static final private int DIST=3; // i: get distance next + static final private int DISTEXT=4;// i: getting distance extra + static final private int COPY=5; // o: copying bytes in window, waiting for space + static final private int LIT=6; // o: got literal, waiting for output space + static final private int WASH=7; // o: got eob, possibly still output waiting + static final private int END=8; // x: got eob and all data flushed + static final private int BADCODE=9;// x: got error + + int mode; // current inflate_codes mode + + // mode dependent information + int len; + + int[] tree; // pointer into tree + int tree_index=0; + int need; // bits needed + + int lit; + + // if EXT or COPY, where and how much + int get; // bits to get for extra + int dist; // distance back to copy from + + byte lbits; // ltree bits decoded per branch + byte dbits; // dtree bits decoder per branch + int[] ltree; // literal/length/eob tree + int ltree_index; // literal/length/eob tree + int[] dtree; // distance tree + int dtree_index; // distance tree + + private final ZStream z; + private final InfBlocks s; + InfCodes(ZStream z, InfBlocks s){ + this.z=z; + this.s=s; + } + + void init(int bl, int bd, + int[] tl, int tl_index, + int[] td, int td_index){ + mode=START; + lbits=(byte)bl; + dbits=(byte)bd; + ltree=tl; + ltree_index=tl_index; + dtree = td; + dtree_index=td_index; + tree=null; + } + + int proc(int r){ + int j; // temporary storage + int[] t; // temporary pointer + int tindex; // temporary pointer + int e; // extra bits or operation + int b=0; // bit buffer + int k=0; // bits in bit buffer + int p=0; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int f; // pointer to copy strings from + + // copy input/output information to locals (UPDATE macro restores) + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q= 258 && n >= 10){ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + r = inflate_fast(lbits, dbits, + ltree, ltree_index, + dtree, dtree_index, + s, z); + + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q>>=(tree[tindex+1]); + k-=(tree[tindex+1]); + + e=tree[tindex]; + + if(e == 0){ // literal + lit = tree[tindex+2]; + mode = LIT; + break; + } + if((e & 16)!=0 ){ // length + get = e & 15; + len = tree[tindex+2]; + mode = LENEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3+tree[tindex+2]; + break; + } + if ((e & 32)!=0){ // end of block + mode = WASH; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + + case LENEXT: // i: getting length extra (have base) + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + need = dbits; + tree = dtree; + tree_index=dtree_index; + mode = DIST; + case DIST: // i: get distance next + j = need; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; + k-=tree[tindex+1]; + + e = (tree[tindex]); + if((e & 16)!=0){ // distance + get = e & 15; + dist = tree[tindex+2]; + mode = DISTEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3 + tree[tindex+2]; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid distance code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + + case DISTEXT: // i: getting distance extra + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + mode = COPY; + case COPY: // o: copying bytes in window, waiting for space + f = q - dist; + while(f < 0){ // modulo window size-"while" instead + f += s.end; // of "if" handles invalid distances + } + while (len!=0){ + + if(m==0){ + if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any + k -= 8; + n++; + p--; // can always return one + } + + s.write=q; r=s.inflate_flush(r); + q=s.write;m=q= 258 && n >= 10 + // get literal/length code + while(k<(20)){ // max bits for literal/length code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++] = (byte)tp[tp_index_t_3+2]; + m--; + continue; + } + do { + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + e &= 15; + c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]); + + b>>=e; k-=e; + + // decode distance base of block to copy + while(k<(15)){ // max bits for distance code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + // get extra bits to add to distance base + e &= 15; + while(k<(e)){ // get extra bits (up to 13) + n--; + b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); + + // do the copy + m -= c; + if (q >= d){ // offset before dest + // just copy + r=q-d; + if(q-r>0 && 2>(q-r)){ + s.window[q++]=s.window[r++]; // minimum count is three, + s.window[q++]=s.window[r++]; // so unroll loop a little + c-=2; + } + else{ + FastJar.arraycopy(s.window, r, s.window, q, 2); + q+=2; r+=2; c-=2; + } + } + else{ // else offset after destination + r=q-d; + do{ + r+=s.end; // force pointer in window + }while(r<0); // covers invalid distances + e=s.end-r; + if(c>e){ // if source crosses, + c-=e; // wrapped copy + if(q-r>0 && e>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--e!=0); + } + else{ + FastJar.arraycopy(s.window, r, s.window, q, e); + q+=e; r+=e; e=0; + } + r = 0; // copy rest from start of window + } + + } + + // copy all or what's left + if(q-r>0 && c>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--c!=0); + } + else{ + FastJar.arraycopy(s.window, r, s.window, q, c); + q+=c; r+=c; c=0; + } + break; + } + else if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + e=tp[tp_index_t_3]; + } + else{ + z.msg = "invalid distance code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + break; + } + + if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + if((e=tp[tp_index_t_3])==0){ + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++]=(byte)tp[tp_index_t_3+2]; + m--; + break; + } + } + else if((e&32)!=0){ + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_STREAM_END; + } + else{ + z.msg="invalid literal/length code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + } + while(m>=258 && n>= 10); + + // not enough input or output--restore pointers and return + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_OK; + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfTree.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfTree.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,520 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package org.apidesign.bck2brwsr.emul.zip; + + + +final class InfTree{ + + static final private int MANY=1440; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final int fixed_bl = 9; + static final int fixed_bd = 5; + + static final int[] fixed_tl = { + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,192, + 80,7,10, 0,8,96, 0,8,32, 0,9,160, + 0,8,0, 0,8,128, 0,8,64, 0,9,224, + 80,7,6, 0,8,88, 0,8,24, 0,9,144, + 83,7,59, 0,8,120, 0,8,56, 0,9,208, + 81,7,17, 0,8,104, 0,8,40, 0,9,176, + 0,8,8, 0,8,136, 0,8,72, 0,9,240, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,200, + 81,7,13, 0,8,100, 0,8,36, 0,9,168, + 0,8,4, 0,8,132, 0,8,68, 0,9,232, + 80,7,8, 0,8,92, 0,8,28, 0,9,152, + 84,7,83, 0,8,124, 0,8,60, 0,9,216, + 82,7,23, 0,8,108, 0,8,44, 0,9,184, + 0,8,12, 0,8,140, 0,8,76, 0,9,248, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,196, + 81,7,11, 0,8,98, 0,8,34, 0,9,164, + 0,8,2, 0,8,130, 0,8,66, 0,9,228, + 80,7,7, 0,8,90, 0,8,26, 0,9,148, + 84,7,67, 0,8,122, 0,8,58, 0,9,212, + 82,7,19, 0,8,106, 0,8,42, 0,9,180, + 0,8,10, 0,8,138, 0,8,74, 0,9,244, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,204, + 81,7,15, 0,8,102, 0,8,38, 0,9,172, + 0,8,6, 0,8,134, 0,8,70, 0,9,236, + 80,7,9, 0,8,94, 0,8,30, 0,9,156, + 84,7,99, 0,8,126, 0,8,62, 0,9,220, + 82,7,27, 0,8,110, 0,8,46, 0,9,188, + 0,8,14, 0,8,142, 0,8,78, 0,9,252, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,194, + 80,7,10, 0,8,97, 0,8,33, 0,9,162, + 0,8,1, 0,8,129, 0,8,65, 0,9,226, + 80,7,6, 0,8,89, 0,8,25, 0,9,146, + 83,7,59, 0,8,121, 0,8,57, 0,9,210, + 81,7,17, 0,8,105, 0,8,41, 0,9,178, + 0,8,9, 0,8,137, 0,8,73, 0,9,242, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,202, + 81,7,13, 0,8,101, 0,8,37, 0,9,170, + 0,8,5, 0,8,133, 0,8,69, 0,9,234, + 80,7,8, 0,8,93, 0,8,29, 0,9,154, + 84,7,83, 0,8,125, 0,8,61, 0,9,218, + 82,7,23, 0,8,109, 0,8,45, 0,9,186, + 0,8,13, 0,8,141, 0,8,77, 0,9,250, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,198, + 81,7,11, 0,8,99, 0,8,35, 0,9,166, + 0,8,3, 0,8,131, 0,8,67, 0,9,230, + 80,7,7, 0,8,91, 0,8,27, 0,9,150, + 84,7,67, 0,8,123, 0,8,59, 0,9,214, + 82,7,19, 0,8,107, 0,8,43, 0,9,182, + 0,8,11, 0,8,139, 0,8,75, 0,9,246, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,206, + 81,7,15, 0,8,103, 0,8,39, 0,9,174, + 0,8,7, 0,8,135, 0,8,71, 0,9,238, + 80,7,9, 0,8,95, 0,8,31, 0,9,158, + 84,7,99, 0,8,127, 0,8,63, 0,9,222, + 82,7,27, 0,8,111, 0,8,47, 0,9,190, + 0,8,15, 0,8,143, 0,8,79, 0,9,254, + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,193, + + 80,7,10, 0,8,96, 0,8,32, 0,9,161, + 0,8,0, 0,8,128, 0,8,64, 0,9,225, + 80,7,6, 0,8,88, 0,8,24, 0,9,145, + 83,7,59, 0,8,120, 0,8,56, 0,9,209, + 81,7,17, 0,8,104, 0,8,40, 0,9,177, + 0,8,8, 0,8,136, 0,8,72, 0,9,241, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,201, + 81,7,13, 0,8,100, 0,8,36, 0,9,169, + 0,8,4, 0,8,132, 0,8,68, 0,9,233, + 80,7,8, 0,8,92, 0,8,28, 0,9,153, + 84,7,83, 0,8,124, 0,8,60, 0,9,217, + 82,7,23, 0,8,108, 0,8,44, 0,9,185, + 0,8,12, 0,8,140, 0,8,76, 0,9,249, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,197, + 81,7,11, 0,8,98, 0,8,34, 0,9,165, + 0,8,2, 0,8,130, 0,8,66, 0,9,229, + 80,7,7, 0,8,90, 0,8,26, 0,9,149, + 84,7,67, 0,8,122, 0,8,58, 0,9,213, + 82,7,19, 0,8,106, 0,8,42, 0,9,181, + 0,8,10, 0,8,138, 0,8,74, 0,9,245, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,205, + 81,7,15, 0,8,102, 0,8,38, 0,9,173, + 0,8,6, 0,8,134, 0,8,70, 0,9,237, + 80,7,9, 0,8,94, 0,8,30, 0,9,157, + 84,7,99, 0,8,126, 0,8,62, 0,9,221, + 82,7,27, 0,8,110, 0,8,46, 0,9,189, + 0,8,14, 0,8,142, 0,8,78, 0,9,253, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,195, + 80,7,10, 0,8,97, 0,8,33, 0,9,163, + 0,8,1, 0,8,129, 0,8,65, 0,9,227, + 80,7,6, 0,8,89, 0,8,25, 0,9,147, + 83,7,59, 0,8,121, 0,8,57, 0,9,211, + 81,7,17, 0,8,105, 0,8,41, 0,9,179, + 0,8,9, 0,8,137, 0,8,73, 0,9,243, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,203, + 81,7,13, 0,8,101, 0,8,37, 0,9,171, + 0,8,5, 0,8,133, 0,8,69, 0,9,235, + 80,7,8, 0,8,93, 0,8,29, 0,9,155, + 84,7,83, 0,8,125, 0,8,61, 0,9,219, + 82,7,23, 0,8,109, 0,8,45, 0,9,187, + 0,8,13, 0,8,141, 0,8,77, 0,9,251, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,199, + 81,7,11, 0,8,99, 0,8,35, 0,9,167, + 0,8,3, 0,8,131, 0,8,67, 0,9,231, + 80,7,7, 0,8,91, 0,8,27, 0,9,151, + 84,7,67, 0,8,123, 0,8,59, 0,9,215, + 82,7,19, 0,8,107, 0,8,43, 0,9,183, + 0,8,11, 0,8,139, 0,8,75, 0,9,247, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,207, + 81,7,15, 0,8,103, 0,8,39, 0,9,175, + 0,8,7, 0,8,135, 0,8,71, 0,9,239, + 80,7,9, 0,8,95, 0,8,31, 0,9,159, + 84,7,99, 0,8,127, 0,8,63, 0,9,223, + 82,7,27, 0,8,111, 0,8,47, 0,9,191, + 0,8,15, 0,8,143, 0,8,79, 0,9,255 + }; + static final int[] fixed_td = { + 80,5,1, 87,5,257, 83,5,17, 91,5,4097, + 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, + 80,5,3, 88,5,513, 84,5,33, 92,5,8193, + 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, + 80,5,2, 87,5,385, 83,5,25, 91,5,6145, + 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, + 80,5,4, 88,5,769, 84,5,49, 92,5,12289, + 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 + }; + + // Tables for deflate from PKZIP's appnote.txt. + static final int[] cplens = { // Copy lengths for literal codes 257..285 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 + }; + + // see note #13 above about 258 + static final int[] cplext = { // Extra bits for literal codes 257..285 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid + }; + + static final int[] cpdist = { // Copy offsets for distance codes 0..29 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577 + }; + + static final int[] cpdext = { // Extra bits for distance codes + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + // If BMAX needs to be larger than 16, then h and x[] should be uLong. + static final int BMAX=15; // maximum bit length of any code + + int[] hn = null; // hufts used in space + int[] v = null; // work area for huft_build + int[] c = null; // bit length count table + int[] r = null; // table entry for structure assignment + int[] u = null; // table stack + int[] x = null; // bit offsets, then code stack + + private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) + int bindex, + int n, // number of codes (assumed <= 288) + int s, // number of simple-valued codes (0..s-1) + int[] d, // list of base values for non-simple codes + int[] e, // list of extra bits for non-simple codes + int[] t, // result: starting table + int[] m, // maximum lookup bits, returns actual + int[] hp,// space for trees + int[] hn,// hufts used in space + int[] v // working area: values in order of bit length + ){ + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + int a; // counter for codes of length k + int f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + int i; // counter, current code + int j; // counter + int k; // number of bits in current code + int l; // bits per table (returned in m) + int mask; // (1 << w) - 1, to avoid cc -O bug on HP + int p; // pointer into c[], b[], or v[] + int q; // points to current table + int w; // bits before this table == (l * h) + int xp; // pointer into x + int y; // number of dummy codes added + int z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; i = n; + do { + c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX + }while(i!=0); + + if(c[0] == n){ // null input--all zero length codes + t[0] = -1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + for (j = 1; j <= BMAX; j++) + if(c[j]!=0) break; + k = j; // minimum code length + if(l < j){ + l = j; + } + for (i = BMAX; i!=0; i--){ + if(c[i]!=0) break; + } + g = i; // maximum code length + if(l > i){ + l = i; + } + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1){ + if ((y -= c[j]) < 0){ + return Z_DATA_ERROR; + } + } + if ((y -= c[i]) < 0){ + return Z_DATA_ERROR; + } + c[i] += y; + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = 1; xp = 2; + while (--i!=0) { // note that i == g from above + x[xp] = (j += c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; p = 0; + do { + if ((j = b[bindex+p]) != 0){ + v[x[j]++] = i; + } + p++; + } + while (++i < n); + n = x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = -1; // no tables yet--level -1 + w = -l; // bits decoded == (l * h) + u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++){ + a = c[k]; + while (a--!=0){ + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l){ + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l) ? l : z; // table size upper limit + if((f=1<<(j=k-w))>a+1){ // try a k-w bit table + // too few codes for k-w bit table + f -= a + 1; // deduct codes from patterns left + xp = k; + if(j < z){ + while (++j < z){ // try smaller tables up to z bits + if((f <<= 1) <= c[++xp]) + break; // enough codes to use up j bits + f -= c[xp]; // else deduct codes from patterns + } + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + u[h] = q = /*hp+*/ hn[0]; // DEBUG + hn[0] += z; + + // connect to last table, if there is one + if(h!=0){ + x[h]=i; // save pattern for backing up + r[0]=(byte)j; // bits in this table + r[1]=(byte)l; // bits to dump before this table + j=i>>>(w - l); + r[2] = (int)(q - u[h-1] - j); // offset to this table + FastJar.arraycopy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table + } + else{ + t[0] = q; // first table is returned result + } + } + + // set up table entry in r + r[1] = (byte)(k - w); + if (p >= n){ + r[0] = 128 + 64; // out of values--invalid code + } + else if (v[p] < s){ + r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block + r[2] = v[p++]; // simple code is just the value + } + else{ + r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists + r[2]=d[v[p++] - s]; + } + + // fill code-like entries with r + f=1<<(k-w); + for (j=i>>>w;j>>= 1){ + i ^= j; + } + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]){ + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; + } + + int inflate_trees_bits(int[] c, // 19 code lengths + int[] bb, // bits tree desired/actual depth + int[] tb, // bits tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + initWorkArea(19); + hn[0]=0; + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed dynamic bit lengths tree"; + } + else if(result == Z_BUF_ERROR || bb[0] == 0){ + z.msg = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + return result; + } + + int inflate_trees_dynamic(int nl, // number of literal/length codes + int nd, // number of distance codes + int[] c, // that many (total) code lengths + int[] bl, // literal desired/actual bit depth + int[] bd, // distance desired/actual bit depth + int[] tl, // literal/length tree result + int[] td, // distance tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + + // build literal/length tree + initWorkArea(288); + hn[0]=0; + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (result != Z_OK || bl[0] == 0){ + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed literal/length tree"; + } + else if (result != Z_MEM_ERROR){ + z.msg = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + return result; + } + + // build distance tree + initWorkArea(288); + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)){ + if (result == Z_DATA_ERROR){ + z.msg = "oversubscribed distance tree"; + } + else if (result == Z_BUF_ERROR) { + z.msg = "incomplete distance tree"; + result = Z_DATA_ERROR; + } + else if (result != Z_MEM_ERROR){ + z.msg = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + return result; + } + + return Z_OK; + } + + static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth + int[] bd, //distance desired/actual bit depth + int[][] tl,//literal/length tree result + int[][] td,//distance tree result + ZStream z //for memory allocation + ){ + bl[0]=fixed_bl; + bd[0]=fixed_bd; + tl[0]=fixed_tl; + td[0]=fixed_td; + return Z_OK; + } + + private void initWorkArea(int vsize){ + if(hn==null){ + hn=new int[1]; + v=new int[vsize]; + c=new int[BMAX+1]; + r=new int[3]; + u=new int[BMAX]; + x=new int[BMAX+1]; + } + if(v.length> 4) + 1; + if(w < 48) + w &= 15; + } + + if(w<8 ||w>15){ + inflateEnd(); + return Z_STREAM_ERROR; + } + if(blocks != null && wbits != w){ + blocks.free(); + blocks=null; + } + + // set window size + wbits=w; + + this.blocks=new InfBlocks(z, 1<>8))&0xff; + + if((wrap&1)==0 || // check if zlib header allowed + (((this.method << 8)+b) % 31)!=0){ + this.mode = BAD; + z.msg = "incorrect header check"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if((this.method&0xf)!=Z_DEFLATED){ + this.mode = BAD; + z.msg="unknown compression method"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if((this.method>>4)+8>this.wbits){ + this.mode = BAD; + z.msg="invalid window size"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + z.adler=new Adler32(); + + if((b&PRESET_DICT)==0){ + this.mode = BLOCKS; + break; + } + this.mode = DICT4; + case DICT4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=DICT3; + case DICT3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode=DICT2; + case DICT2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode=DICT1; + case DICT1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need += (z.next_in[z.next_in_index++]&0xffL); + z.adler.reset(this.need); + this.mode = DICT0; + return Z_NEED_DICT; + case DICT0: + this.mode = BAD; + z.msg = "need dictionary"; + this.marker = 0; // can try inflateSync + return Z_STREAM_ERROR; + case BLOCKS: + r = this.blocks.proc(r); + if(r == Z_DATA_ERROR){ + this.mode = BAD; + this.marker = 0; // can try inflateSync + break; + } + if(r == Z_OK){ + r = f; + } + if(r != Z_STREAM_END){ + return r; + } + r = f; + this.was=z.adler.getValue(); + this.blocks.reset(); + if(this.wrap==0){ + this.mode=DONE; + break; + } + this.mode=CHECK4; + case CHECK4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=CHECK3; + case CHECK3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode = CHECK2; + case CHECK2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode = CHECK1; + case CHECK1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=(z.next_in[z.next_in_index++]&0xffL); + + if(flags!=0){ // gzip + this.need = ((this.need&0xff000000)>>24 | + (this.need&0x00ff0000)>>8 | + (this.need&0x0000ff00)<<8 | + (this.need&0x0000ffff)<<24)&0xffffffffL; + } + + if(((int)(this.was)) != ((int)(this.need))){ + z.msg = "incorrect data check"; + // chack is delayed + /* + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + */ + } + else if(flags!=0 && gheader!=null){ + gheader.crc = this.need; + } + + this.mode = LENGTH; + case LENGTH: + if (wrap!=0 && flags!=0) { + + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + + if (this.need != (z.total_out & 0xffffffffL)) { + z.msg = "incorrect length check"; + this.mode = BAD; + break; + } + z.msg = null; + } + else { + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + } + + this.mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + + case FLAGS: + + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + + flags = ((int)this.need)&0xffff; + + if ((flags & 0xff) != Z_DEFLATED) { + z.msg = "unknown compression method"; + this.mode = BAD; + break; + } + if ((flags & 0xe000)!=0) { + z.msg = "unknown header flags set"; + this.mode = BAD; + break; + } + + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + + this.mode = TIME; + + case TIME: + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null) + gheader.time = this.need; + if ((flags & 0x0200)!=0){ + checksum(4, this.need); + } + this.mode = OS; + case OS: + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.xflags = ((int)this.need)&0xff; + gheader.os = (((int)this.need)>>8)&0xff; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + this.mode = EXLEN; + case EXLEN: + if ((flags & 0x0400)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.extra = new byte[((int)this.need)&0xffff]; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = EXTRA; + + case EXTRA: + if ((flags & 0x0400)!=0) { + try { + r=readBytes(r, f); + if(gheader!=null){ + byte[] foo = tmp_array; + tmp_array=null; + if(foo.length == gheader.extra.length){ + FastJar.arraycopy(foo, 0, gheader.extra, 0, foo.length); + } + else{ + z.msg = "bad extra field length"; + this.mode = BAD; + break; + } + } + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = NAME; + case NAME: + if ((flags & 0x0800)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.name=tmp_array; + } + tmp_array=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.name=null; + } + this.mode = COMMENT; + case COMMENT: + if ((flags & 0x1000)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.comment=tmp_array; + } + tmp_array=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.comment=null; + } + this.mode = HCRC; + case HCRC: + if ((flags & 0x0200)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.hcrc=(int)(this.need&0xffff); + } + if(this.need != (z.adler.getValue()&0xffffL)){ + this.mode = BAD; + z.msg = "header crc mismatch"; + this.marker = 5; // can't try inflateSync + break; + } + } + z.adler = new CRC32(); + + this.mode = BLOCKS; + break; + default: + return Z_STREAM_ERROR; + } + } + } + + int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(z==null || (this.mode != DICT0 && this.wrap != 0)){ + return Z_STREAM_ERROR; + } + + int index=0; + int length = dictLength; + + if(this.mode==DICT0){ + long adler_need=z.adler.getValue(); + z.adler.reset(); + z.adler.update(dictionary, 0, dictLength); + if(z.adler.getValue()!=adler_need){ + return Z_DATA_ERROR; + } + } + + z.adler.reset(); + + if(length >= (1<0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + this.need = this.need | + ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); + need_bytes--; + } + if(n==2){ + this.need&=0xffffL; + } + else if(n==4) { + this.need&=0xffffffffL; + } + need_bytes=-1; + return r; + } + class Return extends Exception{ + int r; + Return(int r){this.r=r; } + } + + private byte[] tmp_array; + private int readString(int r, int f) throws Return{ + int b=0; + byte[] arr = new byte[4092]; + int at = 0; + do { + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + if(b!=0) arr = append(arr, z.next_in[z.next_in_index], at++); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + }while(b!=0); + + tmp_array = copy(arr, at); + + return r; + } + + private int readBytes(int r, int f) throws Return{ + int b=0; + byte[] arr = new byte[4092]; + int at = 0; + while(this.need>0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + arr = append(arr, z.next_in[z.next_in_index], at++); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + this.need--; + } + + tmp_array = copy(arr, at); + + return r; + } + + private static byte[] copy(byte[] arr, int len) { + byte[] ret = new byte[len]; + FastJar.arraycopy(arr, 0, ret, 0, len); + return ret; + } + private static byte[] append(byte[] arr, byte b, int index) { + arr[index] = b; + return arr; + } + + private void checksum(int n, long v){ + for(int i=0; i>=8; + } + z.adler.update(crcbuf, 0, n); + } + + public GZIPHeader getGZIPHeader(){ + return gheader; + } + + boolean inParsingHeader(){ + switch(mode){ + case HEAD: + case DICT4: + case DICT3: + case DICT2: + case DICT1: + case FLAGS: + case TIME: + case OS: + case EXLEN: + case EXTRA: + case NAME: + case COMMENT: + case HCRC: + return true; + default: + return false; + } + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/Inflater.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/Inflater.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,338 @@ +/* + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.apidesign.bck2brwsr.emul.zip; + +import java.util.zip.*; +import java.io.IOException; + +/** + * This class provides support for general purpose decompression using the + * popular ZLIB compression library. The ZLIB compression library was + * initially developed as part of the PNG graphics standard and is not + * protected by patents. It is fully described in the specifications at + * the java.util.zip + * package description. + * + *

The following code fragment demonstrates a trivial compression + * and decompression of a string using Deflater and + * Inflater. + * + *

+ * try {
+ *     // Encode a String into bytes
+ *     String inputString = "blahblahblah\u20AC\u20AC";
+ *     byte[] input = inputString.getBytes("UTF-8");
+ *
+ *     // Compress the bytes
+ *     byte[] output = new byte[100];
+ *     Deflater compresser = new Deflater();
+ *     compresser.setInput(input);
+ *     compresser.finish();
+ *     int compressedDataLength = compresser.deflate(output);
+ *
+ *     // Decompress the bytes
+ *     Inflater decompresser = new Inflater();
+ *     decompresser.setInput(output, 0, compressedDataLength);
+ *     byte[] result = new byte[100];
+ *     int resultLength = decompresser.inflate(result);
+ *     decompresser.end();
+ *
+ *     // Decode the bytes into a String
+ *     String outputString = new String(result, 0, resultLength, "UTF-8");
+ * } catch(java.io.UnsupportedEncodingException ex) {
+ *     // handle
+ * } catch (java.util.zip.DataFormatException ex) {
+ *     // handle
+ * }
+ * 
+ * + * @see Deflater + * @author David Connelly + * + */ +public +class Inflater extends java.util.zip.Inflater { + private final boolean nowrap; + private JzLibInflater impl; + + /** + * Creates a new decompressor. If the parameter 'nowrap' is true then + * the ZLIB header and checksum fields will not be used. This provides + * compatibility with the compression format used by both GZIP and PKZIP. + *

+ * Note: When using the 'nowrap' option it is also necessary to provide + * an extra "dummy" byte as input. This is required by the ZLIB native + * library in order to support certain optimizations. + * + * @param nowrap if true then support GZIP compatible compression + */ + public Inflater(boolean nowrap) { + this.nowrap = nowrap; + reset(); + } + + /** + * Creates a new decompressor. + */ + public Inflater() { + this(false); + } + + /** + * Sets input data for decompression. Should be called whenever + * needsInput() returns true indicating that more input data is + * required. + * @param b the input data bytes + * @param off the start offset of the input data + * @param len the length of the input data + * @see Inflater#needsInput + */ + public void setInput(byte[] b, int off, int len) { + if (b == null) { + throw new NullPointerException(); + } + if (off < 0 || len < 0 || off > b.length - len) { + throw new ArrayIndexOutOfBoundsException(); + } + impl.setInput(b, off, len, false); + } + + /** + * Sets input data for decompression. Should be called whenever + * needsInput() returns true indicating that more input data is + * required. + * @param b the input data bytes + * @see Inflater#needsInput + */ + public void setInput(byte[] b) { + setInput(b, 0, b.length); + } + + /** + * Sets the preset dictionary to the given array of bytes. Should be + * called when inflate() returns 0 and needsDictionary() returns true + * indicating that a preset dictionary is required. The method getAdler() + * can be used to get the Adler-32 value of the dictionary needed. + * @param b the dictionary data bytes + * @param off the start offset of the data + * @param len the length of the data + * @see Inflater#needsDictionary + * @see Inflater#getAdler + */ + public void setDictionary(byte[] b, int off, int len) { + if (b == null) { + throw new NullPointerException(); + } + if (off < 0 || len < 0 || off > b.length - len) { + throw new ArrayIndexOutOfBoundsException(); + } + byte[] arr; + if (off == 0) { + arr = b; + } else { + arr = new byte[len]; + FastJar.arraycopy(b, off, arr, 0, len); + } + impl.setDictionary(arr, len); + } + + /** + * Sets the preset dictionary to the given array of bytes. Should be + * called when inflate() returns 0 and needsDictionary() returns true + * indicating that a preset dictionary is required. The method getAdler() + * can be used to get the Adler-32 value of the dictionary needed. + * @param b the dictionary data bytes + * @see Inflater#needsDictionary + * @see Inflater#getAdler + */ + public void setDictionary(byte[] b) { + impl.setDictionary(b, b.length); + } + + /** + * Returns the total number of bytes remaining in the input buffer. + * This can be used to find out what bytes still remain in the input + * buffer after decompression has finished. + * @return the total number of bytes remaining in the input buffer + */ + public int getRemaining() { + return impl.getAvailIn(); + } + + /** + * Returns true if no data remains in the input buffer. This can + * be used to determine if #setInput should be called in order + * to provide more input. + * @return true if no data remains in the input buffer + */ + public boolean needsInput() { + return getRemaining() <= 0; + } + + /** + * Returns true if a preset dictionary is needed for decompression. + * @return true if a preset dictionary is needed for decompression + * @see Inflater#setDictionary + */ + public boolean needsDictionary() { + return impl.needDict(); + } + + /** + * Returns true if the end of the compressed data stream has been + * reached. + * @return true if the end of the compressed data stream has been + * reached + */ + public boolean finished() { + return impl.finished(); + } + + /** + * Uncompresses bytes into specified buffer. Returns actual number + * of bytes uncompressed. A return value of 0 indicates that + * needsInput() or needsDictionary() should be called in order to + * determine if more input data or a preset dictionary is required. + * In the latter case, getAdler() can be used to get the Adler-32 + * value of the dictionary required. + * @param b the buffer for the uncompressed data + * @param off the start offset of the data + * @param len the maximum number of uncompressed bytes + * @return the actual number of uncompressed bytes + * @exception DataFormatException if the compressed data format is invalid + * @see Inflater#needsInput + * @see Inflater#needsDictionary + */ + public int inflate(byte[] b, int off, int len) + throws DataFormatException + { + if (b == null) { + throw new NullPointerException(); + } + if (off < 0 || len < 0 || off > b.length - len) { + throw new ArrayIndexOutOfBoundsException(); + } + impl.setOutput(b, off, len); + int err = impl.inflate(JzLibInflater.Z_NO_FLUSH); + return impl.next_out_index - off; + } + + /** + * Uncompresses bytes into specified buffer. Returns actual number + * of bytes uncompressed. A return value of 0 indicates that + * needsInput() or needsDictionary() should be called in order to + * determine if more input data or a preset dictionary is required. + * In the latter case, getAdler() can be used to get the Adler-32 + * value of the dictionary required. + * @param b the buffer for the uncompressed data + * @return the actual number of uncompressed bytes + * @exception DataFormatException if the compressed data format is invalid + * @see Inflater#needsInput + * @see Inflater#needsDictionary + */ + public int inflate(byte[] b) throws DataFormatException { + return inflate(b, 0, b.length); + } + + /** + * Returns the ADLER-32 value of the uncompressed data. + * @return the ADLER-32 value of the uncompressed data + */ + public int getAdler() { + return (int) impl.getAdler(); + } + + /** + * Returns the total number of compressed bytes input so far. + * + *

Since the number of bytes may be greater than + * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now + * the preferred means of obtaining this information.

+ * + * @return the total number of compressed bytes input so far + */ + public int getTotalIn() { + return (int) getBytesRead(); + } + + /** + * Returns the total number of compressed bytes input so far.

+ * + * @return the total (non-negative) number of compressed bytes input so far + * @since 1.5 + */ + public long getBytesRead() { + return impl.total_in; + } + + /** + * Returns the total number of uncompressed bytes output so far. + * + *

Since the number of bytes may be greater than + * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now + * the preferred means of obtaining this information.

+ * + * @return the total number of uncompressed bytes output so far + */ + public int getTotalOut() { + return (int) getBytesWritten(); + } + + /** + * Returns the total number of uncompressed bytes output so far.

+ * + * @return the total (non-negative) number of uncompressed bytes output so far + * @since 1.5 + */ + public long getBytesWritten() { + return impl.total_out; + } + + /** + * Resets inflater so that a new set of input data can be processed. + */ + public void reset() { + impl = new JzLibInflater(15, nowrap); + } + + /** + * Closes the decompressor and discards any unprocessed input. + * This method should be called when the decompressor is no longer + * being used, but will also be called automatically by the finalize() + * method. Once this method is called, the behavior of the Inflater + * object is undefined. + */ + public void end() { + impl.end(); + } + + /** + * Closes the decompressor when garbage is collected. + */ + protected void finalize() { + end(); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/JzLibInflater.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/JzLibInflater.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,137 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package org.apidesign.bck2brwsr.emul.zip; + +final class JzLibInflater extends ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + public static final int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + public JzLibInflater() { + super(); + init(); + } + + public JzLibInflater(int w) { + this(w, false); + } + + public JzLibInflater(int w, boolean nowrap) { + super(); + int ret = init(w, nowrap); + if(ret!=Z_OK) + throw new IllegalStateException(ret+": "+msg); + } + + private boolean finished = false; + + public int init(){ + return init(DEF_WBITS); + } + + public int init(boolean nowrap){ + return init(DEF_WBITS, nowrap); + } + + public int init(int w){ + return init(w, false); + } + + public int init(int w, boolean nowrap){ + finished = false; + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); + } + + public int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + int ret = istate.inflate(f); + if(ret == Z_STREAM_END) + finished = true; + return ret; + } + + public int end(){ + finished = true; + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(); +// istate = null; + return ret; + } + + public int sync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(); + } + + public int syncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); + } + + public int setDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(dictionary, dictLength); + } + + public boolean finished(){ + return istate.mode==12 /*DONE*/; + } + + public boolean needDict() { + return istate == null ? false : istate.mode == Inflate.DICT0; + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZStream.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZStream.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,253 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + + 3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package org.apidesign.bck2brwsr.emul.zip; + + + +/** + * ZStream + * + * @deprecated Not for public use in the future. + */ +@Deprecated +class ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + public byte[] next_in; // next input byte + public int next_in_index; + public int avail_in; // number of bytes available at next_in + public long total_in; // total nb of input bytes read so far + + public byte[] next_out; // next output byte should be put there + public int next_out_index; + public int avail_out; // remaining free space at next_out + public long total_out; // total nb of bytes output so far + + public String msg; + + Inflate istate; + + int data_type; // best guess about the data type: ascii or binary + + Checksum adler; + + public ZStream(){ + this(new Adler32()); + } + + public ZStream(Checksum adler){ + this.adler=adler; + } + + public int inflateInit(){ + return inflateInit(DEF_WBITS); + } + public int inflateInit(boolean nowrap){ + return inflateInit(DEF_WBITS, nowrap); + } + public int inflateInit(int w){ + return inflateInit(w, false); + } + + public int inflateInit(int w, boolean nowrap){ + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); + } + + public int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + return istate.inflate(f); + } + public int inflateEnd(){ + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(); +// istate = null; + return ret; + } + + public int inflateSync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(); + } + public int inflateSyncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); + } + public int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(dictionary, dictLength); + } + public boolean inflateFinished(){ + return istate.mode==12 /*DONE*/; + } + + + public long getAdler(){ + return adler.getValue(); + } + + public void free(){ + next_in=null; + next_out=null; + msg=null; + } + + public void setOutput(byte[] buf){ + setOutput(buf, 0, buf.length); + } + + public void setOutput(byte[] buf, int off, int len){ + next_out = buf; + next_out_index = off; + avail_out = len; + } + + public void setInput(byte[] buf){ + setInput(buf, 0, buf.length, false); + } + + public void setInput(byte[] buf, boolean append){ + setInput(buf, 0, buf.length, append); + } + + public void setInput(byte[] buf, int off, int len, boolean append){ + if(len<=0 && append && next_in!=null) return; + + if(avail_in>0 && append){ + byte[] tmp = new byte[avail_in+len]; + FastJar.arraycopy(next_in, next_in_index, tmp, 0, avail_in); + FastJar.arraycopy(buf, off, tmp, avail_in, len); + next_in=tmp; + next_in_index=0; + avail_in+=len; + } + else{ + next_in=buf; + next_in_index=off; + avail_in=len; + } + } + + public byte[] getNextIn(){ + return next_in; + } + + public void setNextIn(byte[] next_in){ + this.next_in = next_in; + } + + public int getNextInIndex(){ + return next_in_index; + } + + public void setNextInIndex(int next_in_index){ + this.next_in_index = next_in_index; + } + + public int getAvailIn(){ + return avail_in; + } + + public void setAvailIn(int avail_in){ + this.avail_in = avail_in; + } + + public byte[] getNextOut(){ + return next_out; + } + + public void setNextOut(byte[] next_out){ + this.next_out = next_out; + } + + public int getNextOutIndex(){ + return next_out_index; + } + + public void setNextOutIndex(int next_out_index){ + this.next_out_index = next_out_index; + } + + public int getAvailOut(){ + return avail_out; + + } + + public void setAvailOut(int avail_out){ + this.avail_out = avail_out; + } + + public long getTotalOut(){ + return total_out; + } + + public long getTotalIn(){ + return total_in; + } + + public String getMessage(){ + return msg; + } + + /** + * Those methods are expected to be override by Inflater and Deflater. + * In the future, they will become abstract methods. + */ + public int end(){ return Z_OK; } + public boolean finished(){ return false; } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZipConstants64.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZipConstants64.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.apidesign.bck2brwsr.emul.zip; + +/* + * This class defines the constants that are used by the classes + * which manipulate Zip64 files. + */ + +public class ZipConstants64 { + + /* + * ZIP64 constants + */ + static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006" + static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007" + static final int ZIP64_ENDHDR = 56; // ZIP64 end header size + static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size + static final int ZIP64_EXTHDR = 24; // EXT header size + static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID + + static final int ZIP64_MAGICCOUNT = 0xFFFF; + static final long ZIP64_MAGICVAL = 0xFFFFFFFFL; + + /* + * Zip64 End of central directory (END) header field offsets + */ + static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir + static final int ZIP64_ENDVEM = 12; // version made by + static final int ZIP64_ENDVER = 14; // version needed to extract + static final int ZIP64_ENDNMD = 16; // number of this disk + static final int ZIP64_ENDDSK = 20; // disk number of start + static final int ZIP64_ENDTOD = 24; // total number of entries on this disk + static final int ZIP64_ENDTOT = 32; // total number of entries + static final int ZIP64_ENDSIZ = 40; // central directory size in bytes + static final int ZIP64_ENDOFF = 48; // offset of first CEN header + static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector + + /* + * Zip64 End of central directory locator field offsets + */ + static final int ZIP64_LOCDSK = 4; // disk number start + static final int ZIP64_LOCOFF = 8; // offset of zip64 end + static final int ZIP64_LOCTOT = 16; // total number of disks + + /* + * Zip64 Extra local (EXT) header field offsets + */ + static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value + static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte + static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte + + /* + * Language encoding flag EFS + */ + static final int EFS = 0x800; // If this bit is set the filename and + // comment fields for this file must be + // encoded using UTF-8. + + private ZipConstants64() {} +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZipInputStream.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZipInputStream.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,468 @@ +/* + * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.apidesign.bck2brwsr.emul.zip; + +import java.util.zip.*; +import java.io.InputStream; +import java.io.IOException; +import java.io.EOFException; +import java.io.PushbackInputStream; +import static org.apidesign.bck2brwsr.emul.zip.ZipConstants64.*; +import static java.util.zip.ZipInputStream.*; + +/** + * This class implements an input stream filter for reading files in the + * ZIP file format. Includes support for both compressed and uncompressed + * entries. + * + * @author David Connelly + */ +public +class ZipInputStream extends InflaterInputStream { + private ZipEntry entry; + private int flag; + private CRC32 crc = new CRC32(); + private long remaining; + private byte[] tmpbuf = new byte[512]; + + private static final int STORED = ZipEntry.STORED; + private static final int DEFLATED = ZipEntry.DEFLATED; + + private boolean closed = false; + // this flag is set to true after EOF has reached for + // one entry + private boolean entryEOF = false; + + /** + * Check to make sure that this stream has not been closed + */ + private void ensureOpen() throws IOException { + if (closed) { + throw new IOException("Stream closed"); + } + } + + /** + * Creates a new ZIP input stream. + * + *

The UTF-8 {@link java.nio.charset.Charset charset} is used to + * decode the entry names. + * + * @param in the actual input stream + */ + public ZipInputStream(InputStream in) { +// this(in, "UTF-8"); + super(new PushbackInputStream(in, 512), new Inflater(true), 512); + //usesDefaultInflater = true; + if(in == null) { + throw new NullPointerException("in is null"); + } + } + + /** + * Creates a new ZIP input stream. + * + * @param in the actual input stream + * + * @param charset + * The {@linkplain java.nio.charset.Charset charset} to be + * used to decode the ZIP entry name (ignored if the + * language + * encoding bit of the ZIP entry's general purpose bit + * flag is set). + * + * @since 1.7 + * + public ZipInputStream(InputStream in, Charset charset) { + super(new PushbackInputStream(in, 512), new Inflater(true), 512); + usesDefaultInflater = true; + if(in == null) { + throw new NullPointerException("in is null"); + } + if (charset == null) + throw new NullPointerException("charset is null"); + this.zc = ZipCoder.get(charset); + } + */ + + /** + * Reads the next ZIP file entry and positions the stream at the + * beginning of the entry data. + * @return the next ZIP file entry, or null if there are no more entries + * @exception ZipException if a ZIP file error has occurred + * @exception IOException if an I/O error has occurred + */ + public ZipEntry getNextEntry() throws IOException { + ensureOpen(); + if (entry != null) { + closeEntry(); + } + crc.reset(); + inf.reset(); + if ((entry = readLOC()) == null) { + return null; + } + if (entry.getMethod() == STORED) { + remaining = entry.getSize(); + } + entryEOF = false; + return entry; + } + + /** + * Closes the current ZIP entry and positions the stream for reading the + * next entry. + * @exception ZipException if a ZIP file error has occurred + * @exception IOException if an I/O error has occurred + */ + public void closeEntry() throws IOException { + ensureOpen(); + while (read(tmpbuf, 0, tmpbuf.length) != -1) ; + entryEOF = true; + } + + /** + * Returns 0 after EOF has reached for the current entry data, + * otherwise always return 1. + *

+ * Programs should not count on this method to return the actual number + * of bytes that could be read without blocking. + * + * @return 1 before EOF and 0 after EOF has reached for current entry. + * @exception IOException if an I/O error occurs. + * + */ + public int available() throws IOException { + ensureOpen(); + if (entryEOF) { + return 0; + } else { + return 1; + } + } + + /** + * Reads from the current ZIP entry into an array of bytes. + * If len is not zero, the method + * blocks until some input is available; otherwise, no + * bytes are read and 0 is returned. + * @param b the buffer into which the data is read + * @param off the start offset in the destination array b + * @param len the maximum number of bytes read + * @return the actual number of bytes read, or -1 if the end of the + * entry is reached + * @exception NullPointerException if b is null. + * @exception IndexOutOfBoundsException if off is negative, + * len is negative, or len is greater than + * b.length - off + * @exception ZipException if a ZIP file error has occurred + * @exception IOException if an I/O error has occurred + */ + public int read(byte[] b, int off, int len) throws IOException { + ensureOpen(); + if (off < 0 || len < 0 || off > b.length - len) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } + + if (entry == null) { + return -1; + } + switch (entry.getMethod()) { + case DEFLATED: + len = super.read(b, off, len); + if (len == -1) { + readEnd(entry); + entryEOF = true; + entry = null; + } else { + crc.update(b, off, len); + } + return len; + case STORED: + if (remaining <= 0) { + entryEOF = true; + entry = null; + return -1; + } + if (len > remaining) { + len = (int)remaining; + } + len = in.read(b, off, len); + if (len == -1) { + throw new ZipException("unexpected EOF"); + } + crc.update(b, off, len); + remaining -= len; + if (remaining == 0 && entry.getCrc() != crc.getValue()) { + throw new ZipException( + "invalid entry CRC (expected 0x" + Long.toHexString(entry.getCrc()) + + " but got 0x" + Long.toHexString(crc.getValue()) + ")"); + } + return len; + default: + throw new ZipException("invalid compression method"); + } + } + + /** + * Skips specified number of bytes in the current ZIP entry. + * @param n the number of bytes to skip + * @return the actual number of bytes skipped + * @exception ZipException if a ZIP file error has occurred + * @exception IOException if an I/O error has occurred + * @exception IllegalArgumentException if n < 0 + */ + public long skip(long n) throws IOException { + if (n < 0) { + throw new IllegalArgumentException("negative skip length"); + } + ensureOpen(); + int max = (int)Math.min(n, Integer.MAX_VALUE); + int total = 0; + while (total < max) { + int len = max - total; + if (len > tmpbuf.length) { + len = tmpbuf.length; + } + len = read(tmpbuf, 0, len); + if (len == -1) { + entryEOF = true; + break; + } + total += len; + } + return total; + } + + /** + * Closes this input stream and releases any system resources associated + * with the stream. + * @exception IOException if an I/O error has occurred + */ + public void close() throws IOException { + if (!closed) { + super.close(); + closed = true; + } + } + + private byte[] b = new byte[256]; + + /* + * Reads local file (LOC) header for next entry. + */ + private ZipEntry readLOC() throws IOException { + try { + readFully(tmpbuf, 0, LOCHDR); + } catch (EOFException e) { + return null; + } + if (get32(tmpbuf, 0) != LOCSIG) { + return null; + } + // get flag first, we need check EFS. + flag = get16(tmpbuf, LOCFLG); + // get the entry name and create the ZipEntry first + int len = get16(tmpbuf, LOCNAM); + int blen = b.length; + if (len > blen) { + do + blen = blen * 2; + while (len > blen); + b = new byte[blen]; + } + readFully(b, 0, len); + // Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8 + ZipEntry e = createZipEntry(((flag & EFS) != 0) + ? toStringUTF8(b, len) + : toString(b, len)); + // now get the remaining fields for the entry + if ((flag & 1) == 1) { + throw new ZipException("encrypted ZIP entry not supported"); + } + e.setMethod(get16(tmpbuf, LOCHOW)); + e.setTime(get32(tmpbuf, LOCTIM)); + if ((flag & 8) == 8) { + /* "Data Descriptor" present */ + if (e.getMethod() != DEFLATED) { + throw new ZipException( + "only DEFLATED entries can have EXT descriptor"); + } + } else { + e.setCrc(get32(tmpbuf, LOCCRC)); + e.setCompressedSize(get32(tmpbuf, LOCSIZ)); + e.setSize(get32(tmpbuf, LOCLEN)); + } + len = get16(tmpbuf, LOCEXT); + if (len > 0) { + byte[] bb = new byte[len]; + readFully(bb, 0, len); + e.setExtra(bb); + // extra fields are in "HeaderID(2)DataSize(2)Data... format + if (e.getCompressedSize() == ZIP64_MAGICVAL || e.getCompressedSize() == ZIP64_MAGICVAL) { + int off = 0; + while (off + 4 < len) { + int sz = get16(bb, off + 2); + if (get16(bb, off) == ZIP64_EXTID) { + off += 4; + // LOC extra zip64 entry MUST include BOTH original and + // compressed file size fields + if (sz < 16 || (off + sz) > len ) { + // Invalid zip64 extra fields, simply skip. Even it's + // rare, it's possible the entry size happens to be + // the magic value and it "accidnetly" has some bytes + // in extra match the id. + return e; + } + e.setSize(get64(bb, off)); + e.setCompressedSize(get64(bb, off + 8)); + break; + } + off += (sz + 4); + } + } + } + return e; + } + + /** + * Creates a new ZipEntry object for the specified + * entry name. + * + * @param name the ZIP file entry name + * @return the ZipEntry just created + */ + protected ZipEntry createZipEntry(String name) { + return new ZipEntry(name); + } + + /* + * Reads end of deflated entry as well as EXT descriptor if present. + */ + private void readEnd(ZipEntry e) throws IOException { + int n = inf.getRemaining(); + if (n > 0) { + ((PushbackInputStream)in).unread(buf, len - n, n); + } + if ((flag & 8) == 8) { + /* "Data Descriptor" present */ + if (inf.getBytesWritten() > ZIP64_MAGICVAL || + inf.getBytesRead() > ZIP64_MAGICVAL) { + // ZIP64 format + readFully(tmpbuf, 0, ZIP64_EXTHDR); + long sig = get32(tmpbuf, 0); + if (sig != EXTSIG) { // no EXTSIG present + e.setCrc(sig); + e.setCompressedSize(get64(tmpbuf, ZIP64_EXTSIZ - ZIP64_EXTCRC)); + e.setSize(get64(tmpbuf, ZIP64_EXTLEN - ZIP64_EXTCRC)); + ((PushbackInputStream)in).unread( + tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC - 1, ZIP64_EXTCRC); + } else { + e.setCrc(get32(tmpbuf, ZIP64_EXTCRC)); + e.setCompressedSize(get64(tmpbuf, ZIP64_EXTSIZ)); + e.setSize(get64(tmpbuf, ZIP64_EXTLEN)); + } + } else { + readFully(tmpbuf, 0, EXTHDR); + long sig = get32(tmpbuf, 0); + if (sig != EXTSIG) { // no EXTSIG present + e.setCrc(sig); + e.setCompressedSize(get32(tmpbuf, EXTSIZ - EXTCRC)); + e.setSize(get32(tmpbuf, EXTLEN - EXTCRC)); + ((PushbackInputStream)in).unread( + tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC); + } else { + e.setCrc(get32(tmpbuf, EXTCRC)); + e.setCompressedSize(get32(tmpbuf, EXTSIZ)); + e.setSize(get32(tmpbuf, EXTLEN)); + } + } + } + if (e.getSize() != inf.getBytesWritten()) { + throw new ZipException( + "invalid entry size (expected " + e.getSize() + + " but got " + inf.getBytesWritten() + " bytes)"); + } + if (e.getCompressedSize() != inf.getBytesRead()) { + throw new ZipException( + "invalid entry compressed size (expected " + e.getCompressedSize() + + " but got " + inf.getBytesRead() + " bytes)"); + } + if (e.getCrc() != crc.getValue()) { + throw new ZipException( + "invalid entry CRC (expected 0x" + Long.toHexString(e.getCrc()) + + " but got 0x" + Long.toHexString(crc.getValue()) + ")"); + } + } + + /* + * Reads bytes, blocking until all bytes are read. + */ + private void readFully(byte[] b, int off, int len) throws IOException { + while (len > 0) { + int n = in.read(b, off, len); + if (n == -1) { + throw new EOFException(); + } + off += n; + len -= n; + } + } + + /* + * Fetches unsigned 16-bit value from byte array at specified offset. + * The bytes are assumed to be in Intel (little-endian) byte order. + */ + private static final int get16(byte b[], int off) { + return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8); + } + + /* + * Fetches unsigned 32-bit value from byte array at specified offset. + * The bytes are assumed to be in Intel (little-endian) byte order. + */ + private static final long get32(byte b[], int off) { + return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL; + } + + /* + * Fetches signed 64-bit value from byte array at specified offset. + * The bytes are assumed to be in Intel (little-endian) byte order. + */ + private static final long get64(byte b[], int off) { + return get32(b, off) | (get32(b, off+4) << 32); + } + + private static String toStringUTF8(byte[] arr, int len) { + return new String(arr, 0, len); + } + + private static String toString(byte[] b, int len) { + return new String(b, 0, len); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/vmzip/ZipResources.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/main/java/org/apidesign/bck2brwsr/vmzip/ZipResources.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,108 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.vmzip; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import org.apidesign.bck2brwsr.core.Exported; +import org.apidesign.bck2brwsr.core.JavaScriptBody; +import org.apidesign.bck2brwsr.emul.zip.FastJar; +import org.apidesign.vm4brwsr.Bck2Brwsr; + +/** Conversion from classpath to load function. + * + * @author Jaroslav Tulach + */ +@Exported +public final class ZipResources implements Bck2Brwsr.Resources { + private final FastJar fj; + + @Exported + public ZipResources(byte[] zipData) throws IOException { +// long bef = timeNow(); + fj = new FastJar(zipData); + for (FastJar.Entry e : fj.list()) { + putRes(e.name, e); + } +// log("Iterating thru " + path + " took " + (timeNow() - bef) + "ms"); + } + + @JavaScriptBody(args = { "arr" }, body = "return arr.length;") + private static native int length(Object arr); + @JavaScriptBody(args = { "arr", "index", "value" }, body = "arr[index] = value; return value;") + private static native Object set(Object arr, int index, Object value); + + @JavaScriptBody(args = { "msg" }, body = "if (typeof console !== 'undefined') console.log(msg.toString());") + private static native void log(String msg); + + private byte[] findRes(String res) throws IOException { + Object arr = findResImpl(res); + if (arr instanceof FastJar.Entry) { + double bef = timeNow(); + InputStream zip = fj.getInputStream((FastJar.Entry)arr); + arr = readFully(new byte[512], zip); + putRes(res, arr); + log("Reading " + res + " took " + (timeNow() - bef) + "ms"); + } + return (byte[]) arr; + } + + @Override + public InputStream get(String resource) throws IOException { + byte[] arr = findRes(resource); + return arr == null ? null : new ByteArrayInputStream(arr); + } + + @JavaScriptBody(args = { "res" }, body = "var r = this[res]; return r ? r : null;") + private native Object findResImpl(String res); + + @JavaScriptBody(args = { "res", "arr" }, body = "this[res] = arr;") + private native void putRes(String res, Object arr); + + @JavaScriptBody(args = { "arr", "len" }, body = "while (arr.length < len) arr.push(0);") + private static native void enlargeBytes(byte[] arr, int len); + + @JavaScriptBody(args = { "arr", "len" }, body = "arr.splice(len, arr.length - len);") + private static native void sliceArray(byte[] arr, int len); + + private static Object readFully(byte[] arr, InputStream zip) throws IOException { + int offset = 0; + for (;;) { + int len = zip.read(arr, offset, arr.length - offset); + if (len == -1) { + break; + } + offset += len; + if (offset == arr.length) { + enlargeBytes(arr, arr.length + 4096); + } + } + sliceArray(arr, offset); + return arr; + } + + @JavaScriptBody(args = {}, body = + "if (typeof window.performance === 'undefined') return -1;\n" + + "if (typeof window.performance.now === 'undefined') return -1;\n" + + "return window.performance.now();" + ) + private static native double timeNow(); + + +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/CRC32Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/CRC32Test.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,41 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.emul.zip; + +import java.io.UnsupportedEncodingException; +import java.util.zip.CRC32; +import org.apidesign.bck2brwsr.vmtest.Compare; +import org.apidesign.bck2brwsr.vmtest.VMTest; +import org.testng.annotations.Factory; + +/** + * + * @author Jaroslav Tulach + */ +public class CRC32Test { + + @Compare public long crc1() throws UnsupportedEncodingException { + CRC32 crc = new CRC32(); + crc.update("Hello World!".getBytes("UTF-8")); + return crc.getValue(); + } + + @Factory public static Object[] create() { + return VMTest.create(CRC32Test.class); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/ZipArchive.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/ZipArchive.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,184 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.emul.zip; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.ZipEntry; + +/** + * + * @author Jaroslav Tulach + */ +final class ZipArchive { + private Entry first; + + public static ZipArchive createZip(InputStream is) throws IOException { + ZipArchive a = new ZipArchive(); + readZip(is, a); + return a; + } + + public static ZipArchive createReal(InputStream is) throws IOException { + ZipArchive a = new ZipArchive(); + realZip(is, a); + return a; + } + + /** + * Registers entry name and data + */ + final void register(String entry, InputStream is) throws IOException { + byte[] arr = new byte[12 * 4096]; + for (int i = 0; i < arr.length; i++) { + int ch = is.read(); + if (ch == -1) { + byte[] tmp = new byte[i]; + FastJar.arraycopy(arr, 0, tmp, 0, i); + arr = tmp; + break; + } + arr[i] = (byte) ch; + } + first = new Entry (entry, arr, first); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + Entry e = first; + while (e != null) { + String string = e.name; + byte[] bs = e.arr; + sb.append(string).append(" = ").append(toString(bs)).append("\n"); + e = e.next; + } + return sb.toString(); + } + + public void assertEquals(ZipArchive zip, String msg) { + boolean ok = true; + StringBuilder sb = new StringBuilder(); + sb.append(msg); + Entry e = first; + while (e != null) { + String string = e.name; + byte[] bs = e.arr; + byte[] other = zip.find(string); + e = e.next; + + sb.append("\n"); + if (other == null) { + sb.append("EXTRA ").append(string).append(" = ").append(toString(bs)); + ok = false; + continue; + } + if (equals(bs, other)) { + sb.append("OK ").append(string); + continue; + } else { + sb.append("DIFF ").append(string).append(" = ").append(toString(bs)).append("\n"); + sb.append(" TO").append(string).append(" = ").append(toString(other)).append("\n"); + ok = false; + continue; + } + } + e = zip.first; + while (e != null) { + String string = e.name; + if (find(string) == null) { + sb.append("MISS ").append(string).append(" = ").append(toString(e.arr)); + ok = false; + } + e = e.next; + } + if (!ok) { + assert false : sb.toString(); + } + } + + public static void readZip(InputStream is, ZipArchive data) throws IOException { + ZipInputStream zip = new org.apidesign.bck2brwsr.emul.zip.ZipInputStream(is); + for (;;) { + ZipEntry en = zip.getNextEntry(); + if (en == null) { + return; + } + data.register(en.getName(), zip); + } + } + + public static void realZip(InputStream is, ZipArchive data) throws IOException { + java.util.zip.ZipInputStream zip = new java.util.zip.ZipInputStream(is); + for (;;) { + ZipEntry en = zip.getNextEntry(); + if (en == null) { + return; + } + data.register(en.getName(), zip); + } + } + + private byte[] find(String name) { + Entry e = first; + while (e != null) { + if (e.name.equals(name)) { + return e.arr; + } + e = e.next; + } + return null; + } + + private boolean equals(byte[] bs, byte[] other) { + if (bs.length != other.length) { + return false; + } + for (int i = 0; i < bs.length; i++) { + if (bs[i] != other[i]) { + return false; + } + } + return true; + } + + private Object toString(byte[] arr) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + String sep = ""; + for (int i = 0; i < arr.length; i++) { + sb.append(sep).append(arr[i]); + sep = ", "; + } + sb.append("]"); + return sb.toString(); + } + + private static final class Entry { + final String name; + final byte[] arr; + final Entry next; + + public Entry(String name, byte[] arr, Entry next) { + this.name = name; + this.arr = arr; + this.next = next; + } + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/ZipCompatibilityTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/ZipCompatibilityTest.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,43 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.emul.zip; + +import java.io.IOException; +import java.io.InputStream; +import org.apidesign.bck2brwsr.vmtest.Compare; +import org.apidesign.bck2brwsr.vmtest.VMTest; +import org.testng.annotations.Factory; + +/** + * + * @author Jaroslav Tulach + */ +public class ZipCompatibilityTest { + @Compare + public String testDemoStaticCalculator() throws IOException { + InputStream is = getClass().getResourceAsStream("demo.static.calculator-TEST.jar"); + ZipArchive zip = ZipArchive.createZip(is); + final String ts = zip.toString(); + return ts.substring(0, 4096) + ts.hashCode(); + } + + @Factory + public static Object[] create() { + return VMTest.create(ZipCompatibilityTest.class); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/ZipVsJzLibTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/ZipVsJzLibTest.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,39 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.emul.zip; + +import java.io.IOException; +import java.io.InputStream; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public class ZipVsJzLibTest { + @Test public void r() throws IOException { + InputStream is = getClass().getResourceAsStream("demo.static.calculator-TEST.jar"); + ZipArchive zip = ZipArchive.createZip(is); + + is = getClass().getResourceAsStream("demo.static.calculator-TEST.jar"); + ZipArchive real = ZipArchive.createReal(is); + + real.assertEquals(zip, "Are they the same?"); + } + +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipEntryTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipEntryTest.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,66 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.vmtest.impl; + +import java.io.IOException; +import java.io.InputStream; +import org.apidesign.bck2brwsr.emul.zip.FastJar; +import org.testng.annotations.Test; +import static org.testng.Assert.*; + +/** + * + * @author Jaroslav Tulach + */ +@GenerateZip(name = "five.zip", contents = { + "1.txt", "one", + "2.txt", "duo", + "3.txt", "three", + "4.txt", "four", + "5.txt", "five" +}) +public class ZipEntryTest { + @Test + public void readEntriesEffectively() throws IOException { + InputStream is = ZipEntryTest.class.getResourceAsStream("five.zip"); + byte[] arr = new byte[is.available()]; + int len = is.read(arr); + assertEquals(len, arr.length, "Read fully"); + + FastJar fj = new FastJar(arr); + FastJar.Entry[] entrs = fj.list(); + + assertEquals(5, entrs.length, "Five entries"); + + for (int i = 1; i <= 5; i++) { + FastJar.Entry en = entrs[i - 1]; + assertEquals(en.name, i + ".txt"); +// assertEquals(cis.cnt, 0, "Content of the file should be skipped, not read"); + } + + assertContent("three", fj.getInputStream(entrs[3 - 1]), "read OK"); + assertContent("five", fj.getInputStream(entrs[5 - 1]), "read OK"); + } + + private static void assertContent(String exp, InputStream is, String msg) throws IOException { + byte[] arr = new byte[512]; + int len = is.read(arr); + String s = new String(arr, 0, len); + assertEquals(exp, s, msg); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,116 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.vmtest.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import org.apidesign.bck2brwsr.core.JavaScriptBody; +import org.apidesign.bck2brwsr.vmtest.BrwsrTest; +import org.apidesign.bck2brwsr.vmtest.Compare; +import org.apidesign.bck2brwsr.vmtest.Http; +import org.apidesign.bck2brwsr.vmtest.VMTest; +import org.testng.annotations.Factory; + +/** + * + * @author Jaroslav Tulach + */ +@GenerateZip(name = "readAnEntry.zip", contents = { + "my/main/file.txt", "Hello World!" +}) +public class ZipFileTest { + + @Compare public String readAnEntry() throws IOException { + InputStream is = ZipFileTest.class.getResourceAsStream("readAnEntry.zip"); + ZipInputStream zip = new ZipInputStream(is); + ZipEntry entry = zip.getNextEntry(); + assertEquals(entry.getName(), "my/main/file.txt", "Correct entry"); + + byte[] arr = new byte[4096]; + int len = zip.read(arr); + + assertEquals(zip.getNextEntry(), null, "No next entry"); + + final String ret = new String(arr, 0, len, "UTF-8"); + return ret; + } + + @JavaScriptBody(args = { "res", "path" }, body = + "var myvm = bck2brwsr.apply(null, path);\n" + + "var cls = myvm.loadClass('java.lang.String');\n" + + "return cls.getClass__Ljava_lang_Class_2().getResourceAsStream__Ljava_io_InputStream_2Ljava_lang_String_2(res);\n" + ) + private static native Object loadVMResource(String res, String...path); + + @Http({ + @Http.Resource(path = "/readAnEntry.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip") + }) + @BrwsrTest public void canVmLoadResourceFromZip() throws IOException { + Object res = loadVMResource("/my/main/file.txt", "/readAnEntry.jar"); + assert res instanceof InputStream : "Got array of bytes: " + res; + InputStream is = (InputStream)res; + + byte[] arr = new byte[4096]; + int len = is.read(arr); + + final String ret = new String(arr, 0, len, "UTF-8"); + + assertEquals(ret, "Hello World!", "Can read the bytes"); + } + + @GenerateZip(name = "cpattr.zip", contents = { + "META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n" + + "Created-By: hand\n" + + "Class-Path: realJar.jar\n\n\n" + }) + @Http({ + @Http.Resource(path = "/readComplexEntry.jar", mimeType = "x-application/zip", content = "", resource="cpattr.zip"), + @Http.Resource(path = "/realJar.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip"), + }) + @BrwsrTest public void understandsClassPathAttr() throws IOException { + Object res = loadVMResource("/my/main/file.txt", "/readComplexEntry.jar"); + assert res instanceof InputStream : "Got array of bytes: " + res; + InputStream is = (InputStream)res; + + byte[] arr = new byte[4096]; + int len = is.read(arr); + + final String ret = new String(arr, 0, len, "UTF-8"); + + assertEquals(ret, "Hello World!", "Can read the bytes from secondary JAR"); + } + + private static void assertEquals(Object real, Object exp, String msg) { + if (real == null) { + if (exp == null) { + return; + } + } else { + if (real.equals(exp)) { + return; + } + } + assert false : msg + " exp: " + exp + " real: " + real; + } + + @Factory public static Object[] create() { + return VMTest.create(ZipFileTest.class); + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/emul/zip/src/test/resources/org/apidesign/bck2brwsr/emul/zip/demo.static.calculator-TEST.jar Binary file rt/emul/zip/src/test/resources/org/apidesign/bck2brwsr/emul/zip/demo.static.calculator-TEST.jar has changed diff -r ae8575329e1b -r bfda398c3a68 rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue May 06 17:46:47 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun May 11 14:01:18 2014 +0200 @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; +import java.util.Locale; import static org.apidesign.vm4brwsr.ByteCodeParser.*; /** Translator of the code inside class files to JavaScript. @@ -1118,7 +1119,11 @@ break; case opc_dup: { final Variable v = smapper.get(0); - emit(smapper, this, "var @1 = @2;", smapper.pushT(v.getType()), v); + if (smapper.isDirty()) { + emit(smapper, this, "var @1 = @2;", smapper.pushT(v.getType()), v); + } else { + smapper.assign(this, v.getType(), v); + } break; } case opc_dup2: { @@ -1529,7 +1534,18 @@ case '_': sb.append("_1"); break; case ';': sb.append("_2"); break; case '[': sb.append("_3"); break; - default: sb.append(ch); break; + default: + if (Character.isJavaIdentifierPart(ch)) { + sb.append(ch); + } else { + sb.append("_0"); + String hex = Integer.toHexString(ch).toLowerCase(Locale.ENGLISH); + for (int m = hex.length(); m < 4; m++) { + sb.append("0"); + } + sb.append(hex); + } + break; } } return sb.toString(); diff -r ae8575329e1b -r bfda398c3a68 rt/vm/src/main/java/org/apidesign/vm4brwsr/ClassPath.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClassPath.java Sun May 11 14:01:18 2014 +0200 @@ -0,0 +1,156 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.vm4brwsr; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import org.apidesign.bck2brwsr.core.JavaScriptBody; + +/** Conversion from classpath to load function. + * + * @author Jaroslav Tulach + */ +final class ClassPath { + private ClassPath() { + } + + public static void init() { + } + @JavaScriptBody(args = { "arr" }, body = "return arr.length;") + private static native int length(Object arr); + @JavaScriptBody(args = { "arr", "index" }, body = "return arr[index];") + private static native Object at(Object arr, int index); + @JavaScriptBody(args = { "arr", "index", "value" }, body = "arr[index] = value; return value;") + private static native Object set(Object arr, int index, Object value); + + private static boolean doingToZip; + public static byte[] loadFromCp(Object classpath, String res, int skip) + throws IOException, ClassNotFoundException { + for (int i = 0; i < length(classpath); i++) { + Object c = at(classpath, i); + if (c instanceof String && !doingToZip) { + try { + doingToZip = true; + String url = (String)c; + final Bck2Brwsr.Resources z = toZip(url); + c = set(classpath, i, z); + final byte[] man = readBytes(z, "META-INF/MANIFEST.MF"); + if (man != null) { + String mainClass = processClassPathAttr(man, url, classpath); +// if (mainClass != null) { +// Class.forName(mainClass); +// } + } + } catch (IOException ex) { + set(classpath, i, ex); + log("Cannot load " + c + " - " + ex.getClass().getName() + ":" + ex.getMessage()); + } finally { + doingToZip = false; + } + } + if (res != null) { + byte[] checkRes; + if (c instanceof Bck2Brwsr.Resources) { + checkRes = readBytes((Bck2Brwsr.Resources)c, res); + if (checkRes != null && --skip < 0) { + return checkRes; + } + } else { + checkRes = callFunction(c, res, skip); + if (checkRes != null) { + return checkRes; + } + } + } + } + return null; + } + + @JavaScriptBody(args = { "fn", "res", "skip" }, body = + "if (typeof fn === 'function') return fn(res, skip);\n" + + "return null;" + ) + private static native byte[] callFunction(Object fn, String res, int skip); + + @JavaScriptBody(args = { "msg" }, body = "if (typeof console !== 'undefined') console.log(msg.toString());") + private static native void log(String msg); + + private static String processClassPathAttr(final byte[] man, String url, Object classpath) throws IOException { + try (ParseMan is = new ParseMan(new ByteArrayInputStream(man))) { + String cp = is.toString(); + if (cp != null) { + cp = cp.trim(); + for (int p = 0; p < cp.length();) { + int n = cp.indexOf(' ', p); + if (n == -1) { + n = cp.length(); + } + String el = cp.substring(p, n); + URL u = new URL(new URL(url), el); + classpath = addToArray(classpath, u.toString()); + p = n + 1; + } + } + return is.getMainClass(); + } + } + + private static Object addToArray(Object arr, String value) { + final int last = length(arr); + Object ret = enlargeArray(arr, last + 1); + set(ret, last, value); + return ret; + } + + @JavaScriptBody(args = { "arr", "len" }, body = "while (arr.length < len) arr.push(null); return arr;") + private static native Object enlargeArray(Object arr, int len); + + private static Bck2Brwsr.Resources toZip(String path) throws IOException { + URL u = new URL(path); + byte[] zipData = (byte[]) u.getContent(new Class[]{byte[].class}); + Bck2Brwsr.Resources r; + try { + Class fastJar = Class.forName("org.apidesign.bck2brwsr.vmzip.ZipResources"); + return (Bck2Brwsr.Resources) fastJar.getConstructor(byte[].class).newInstance(zipData); + } catch (Exception ex) { + log("Reading JARs is only possible with enum.zip module included: " + ex.getMessage()); + ex.printStackTrace(); + throw new IOException(ex); + } + } + + private static byte[] readBytes(Bck2Brwsr.Resources r, String res) throws IOException { + InputStream is = r.get(res); + if (is == null) { + return null; + } + byte[] arr = new byte[is.available()]; + int off = 0; + for (;;) { + int len = is.read(arr, off, arr.length - off); + if (len == -1) { + break; + } + off += len; + } + is.close(); + return arr; + } +} diff -r ae8575329e1b -r bfda398c3a68 rt/vm/src/main/java/org/apidesign/vm4brwsr/StackMapper.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/StackMapper.java Tue May 06 17:46:47 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/StackMapper.java Sun May 11 14:01:18 2014 +0200 @@ -23,6 +23,7 @@ final class StackMapper { private final TypeArray stackTypeIndexPairs; private final StringArray stackValues; + private boolean dirty; public StackMapper() { stackTypeIndexPairs = new TypeArray(); @@ -32,6 +33,7 @@ public void clear() { stackTypeIndexPairs.clear(); stackValues.clear(); + dirty = false; } public void syncWithFrameStack(final TypeArray frameStack) { @@ -70,7 +72,7 @@ void assign(Appendable out, int varType, CharSequence s) throws IOException { pushTypeAndValue(varType, s); } - + void replace(Appendable out, int varType, String format, CharSequence... arr) throws IOException { StringBuilder sb = new StringBuilder(); @@ -78,6 +80,7 @@ String[] values = stackValues.toArray(); final int last = stackTypeIndexPairs.getSize() - 1; values[last] = sb.toString(); + dirty = true; final int value = (last << 8) | (varType & 0xff); stackTypeIndexPairs.set(last, value); } @@ -92,6 +95,11 @@ CharSequence var = getVariable(stackTypeIndexPairs.get(i)); ByteCodeToJavaScript.emitImpl(out, "var @1 = @2;", var, val); } + dirty = false; + } + + public boolean isDirty() { + return dirty; } public CharSequence popI() { @@ -216,6 +224,7 @@ } else { stackValues.add(val); } + dirty = true; } private void popImpl(final int count) { diff -r ae8575329e1b -r bfda398c3a68 rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Tue May 06 17:46:47 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Sun May 11 14:01:18 2014 +0200 @@ -55,7 +55,7 @@ assert assertsOn = true; if (assertsOn) { VMLazy.init(); - Zips.init(); + ClassPath.init(); } } @@ -612,15 +612,18 @@ protected void generatePrologue() throws IOException { append("bck2brwsr.registerExtension(function(exports) {\n" + " var vm = {};\n"); - append(" function link(n, inst) {\n" - + " var cls = n['replace__Ljava_lang_String_2CC']" - + "('/', '_').toString();\n" - + " var dot = n['replace__Ljava_lang_String_2CC']" - + "('/', '.').toString();\n" - + " exports.loadClass(dot);\n" - + " vm[cls] = exports[cls];\n" - + " return vm[cls](inst);\n" - + " };\n"); + append(" function link(n) {\n" + + " return function() {\n" + + " var cls = n['replace__Ljava_lang_String_2CC']" + + "('/', '_').toString();\n" + + " var dot = n['replace__Ljava_lang_String_2CC']" + + "('/', '.').toString();\n" + + " exports.loadClass(dot);\n" + + " vm[cls] = exports[cls];\n" + + " return vm[cls](arguments);\n" + + " };\n" + + " };\n" + ); } @Override @@ -633,10 +636,9 @@ if (isExternalClass(className)) { append("\n").append(assignClass( className.replace('/', '_'))) - .append("function() {\n return link('") + .append("link('") .append(className) - .append("', arguments.length == 0 || arguments[0] === true);" - + "\n};"); + .append("');"); return null; } diff -r ae8575329e1b -r bfda398c3a68 rt/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Tue May 06 17:46:47 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Sun May 11 14:01:18 2014 +0200 @@ -49,13 +49,13 @@ } static byte[] loadBytes(Object loader, String name, Object[] arguments, int skip) throws Exception { - return Zips.loadFromCp(arguments, name, skip); + return ClassPath.loadFromCp(arguments, name, skip); } private Object load(String name, boolean instance) throws IOException, ClassNotFoundException { String res = name.replace('.', '/') + ".class"; - byte[] arr = Zips.loadFromCp(args, res, 0); + byte[] arr = ClassPath.loadFromCp(args, res, 0); if (arr == null) { throw new ClassNotFoundException(name); } diff -r ae8575329e1b -r bfda398c3a68 rt/vm/src/main/java/org/apidesign/vm4brwsr/Zips.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Zips.java Tue May 06 17:46:47 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.vm4brwsr; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import org.apidesign.bck2brwsr.core.JavaScriptBody; -import org.apidesign.bck2brwsr.emul.zip.FastJar; - -/** Conversion from classpath to load function. - * - * @author Jaroslav Tulach - */ -final class Zips { - private final FastJar fj; - - private Zips(String path, byte[] zipData) throws IOException { - long bef = timeNow(); - fj = new FastJar(zipData); - for (FastJar.Entry e : fj.list()) { - putRes(e.name, e); - } - log("Iterating thru " + path + " took " + (timeNow() - bef) + "ms"); - } - - public static void init() { - } - @JavaScriptBody(args = { "arr" }, body = "return arr.length;") - private static native int length(Object arr); - @JavaScriptBody(args = { "arr", "index" }, body = "return arr[index];") - private static native Object at(Object arr, int index); - @JavaScriptBody(args = { "arr", "index", "value" }, body = "arr[index] = value; return value;") - private static native Object set(Object arr, int index, Object value); - - public static byte[] loadFromCp(Object classpath, String res, int skip) - throws IOException, ClassNotFoundException { - for (int i = 0; i < length(classpath); i++) { - Object c = at(classpath, i); - if (c instanceof String) { - try { - String url = (String)c; - final Zips z = toZip(url); - c = set(classpath, i, z); - final byte[] man = z.findRes("META-INF/MANIFEST.MF"); - if (man != null) { - String mainClass = processClassPathAttr(man, url, classpath); -// if (mainClass != null) { -// Class.forName(mainClass); -// } - } - } catch (IOException ex) { - set(classpath, i, ex); - log("Cannot load " + c + " - " + ex.getClass().getName() + ":" + ex.getMessage()); - } - } - if (res != null) { - byte[] checkRes; - if (c instanceof Zips) { - checkRes = ((Zips)c).findRes(res); - if (checkRes != null && --skip < 0) { - return checkRes; - } - } else { - checkRes = callFunction(c, res, skip); - if (checkRes != null) { - return checkRes; - } - } - } - } - return null; - } - - @JavaScriptBody(args = { "fn", "res", "skip" }, body = - "if (typeof fn === 'function') return fn(res, skip);\n" - + "return null;" - ) - private static native byte[] callFunction(Object fn, String res, int skip); - - @JavaScriptBody(args = { "msg" }, body = "if (typeof console !== 'undefined') console.log(msg.toString());") - private static native void log(String msg); - - private byte[] findRes(String res) throws IOException { - Object arr = findResImpl(res); - if (arr instanceof FastJar.Entry) { - long bef = timeNow(); - InputStream zip = fj.getInputStream((FastJar.Entry)arr); - arr = readFully(new byte[512], zip); - putRes(res, arr); - log("Reading " + res + " took " + (timeNow() - bef) + "ms"); - } - return (byte[]) arr; - } - - @JavaScriptBody(args = { "res" }, body = "var r = this[res]; return r ? r : null;") - private native Object findResImpl(String res); - - @JavaScriptBody(args = { "res", "arr" }, body = "this[res] = arr;") - private native void putRes(String res, Object arr); - - private static Zips toZip(String path) throws IOException { - URL u = new URL(path); - byte[] zipData = (byte[]) u.getContent(new Class[] { byte[].class }); - return new Zips(path, zipData); - } - - private static String processClassPathAttr(final byte[] man, String url, Object classpath) throws IOException { - try (ParseMan is = new ParseMan(new ByteArrayInputStream(man))) { - String cp = is.toString(); - if (cp != null) { - cp = cp.trim(); - for (int p = 0; p < cp.length();) { - int n = cp.indexOf(' ', p); - if (n == -1) { - n = cp.length(); - } - String el = cp.substring(p, n); - URL u = new URL(new URL(url), el); - classpath = addToArray(classpath, u.toString()); - p = n + 1; - } - } - return is.getMainClass(); - } - } - - private static Object addToArray(Object arr, String value) { - final int last = length(arr); - Object ret = enlargeArray(arr, last + 1); - set(ret, last, value); - return ret; - } - - @JavaScriptBody(args = { "arr", "len" }, body = "while (arr.length < len) arr.push(null); return arr;") - private static native Object enlargeArray(Object arr, int len); - @JavaScriptBody(args = { "arr", "len" }, body = "while (arr.length < len) arr.push(0);") - private static native void enlargeBytes(byte[] arr, int len); - - @JavaScriptBody(args = { "arr", "len" }, body = "arr.splice(len, arr.length - len);") - private static native void sliceArray(byte[] arr, int len); - - private static Object readFully(byte[] arr, InputStream zip) throws IOException { - int offset = 0; - for (;;) { - int len = zip.read(arr, offset, arr.length - offset); - if (len == -1) { - break; - } - offset += len; - if (offset == arr.length) { - enlargeBytes(arr, arr.length + 4096); - } - } - sliceArray(arr, offset); - return arr; - } - - private static long timeNow() { - double time = m(); - if (time >= 0) { - return (long)time; - } - return org.apidesign.bck2brwsr.emul.lang.System.currentTimeMillis(); - } - @JavaScriptBody(args = {}, body = - "if (typeof window.performance === 'undefined') return -1;\n" - + "if (typeof window.performance.now === 'undefined') return -1;\n" - + "return window.performance.now();" - ) - private static native double m(); - - -} diff -r ae8575329e1b -r bfda398c3a68 rt/vm/src/test/java/org/apidesign/vm4brwsr/SizeOfAMethodTest.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/SizeOfAMethodTest.java Tue May 06 17:46:47 2014 +0200 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/SizeOfAMethodTest.java Sun May 11 14:01:18 2014 +0200 @@ -25,8 +25,7 @@ import java.io.IOException; import java.io.InputStream; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; +import static org.testng.Assert.*; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -52,6 +51,32 @@ assertEquals(method.indexOf("st"), -1, "There should be no stack operations:\n" + method); } + @Test public void betterConstructor() { + String s = code; + int beg = s.indexOf("c.initInflater__IIZ"); + int end = s.indexOf("c.initInflater__IIZ.access"); + + assertTrue(beg > 0, "Found initInflater method in " + code); + assertTrue(beg < end, "Found end of initInflater method in " + code); + + String method = s.substring(beg, end); + + assertEquals(method.indexOf("stA1"), -1, "No need for stA1 register:\n" + method); + } + + @Test public void deepConstructor() { + String s = code; + int beg = s.indexOf("c.intHolder__I"); + int end = s.indexOf("c.intHolder__I.access"); + + assertTrue(beg > 0, "Found intHolder method in " + code); + assertTrue(beg < end, "Found end of intHolder method in " + code); + + String method = s.substring(beg, end); + + assertEquals(method.indexOf("stA3"), -1, "No need for stA3 register on second constructor:\n" + method); + } + @Test public void emptyConstructorRequiresNoStack() { String s = code; int beg = s.indexOf("CLS.cons__V"); diff -r ae8575329e1b -r bfda398c3a68 rt/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java Tue May 06 17:46:47 2014 +0200 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java Sun May 11 14:01:18 2014 +0200 @@ -142,6 +142,18 @@ return i.sum(nowrap?-w:w, 1); } + public static int intHolder() { + return new IntHolder(new Integer(10)).i.intValue(); + } + + private static class IntHolder { + Integer i; + + public IntHolder(Integer i) { + this.i = i; + } + } + public static String toStringArr() { class N implements Next { int idx = 0; diff -r ae8575329e1b -r bfda398c3a68 rt/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/LaunchSetup.java --- a/rt/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/LaunchSetup.java Tue May 06 17:46:47 2014 +0200 +++ b/rt/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/LaunchSetup.java Sun May 11 14:01:18 2014 +0200 @@ -18,8 +18,10 @@ package org.apidesign.bck2brwsr.vmtest.impl; import java.io.IOException; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Set; import org.apidesign.bck2brwsr.launcher.Launcher; import org.testng.annotations.AfterGroups; import org.testng.annotations.BeforeGroups; @@ -44,7 +46,14 @@ if (js == null && create) { final String p = System.getProperty("vmtest.js", "script"); // NOI18N switch (p) { - case "brwsr": js = Launcher.createBrowser(null); break; // NOI18N + case "brwsr": // NOI18N + String cmd = null; + String pb = System.getProperty("vmtest.brwsrs"); // NOI18N + if (pb != null) { + cmd = pb.split(",")[0]; // NOI18N + } + js = brwsr(cmd); + break; case "script": js = Launcher.createJavaScript(); break; // NOI18N default: throw new IllegalArgumentException( "Unknown value of vmtest.js property: " + p @@ -65,20 +74,22 @@ @BeforeGroups("run") public void initializeLauncher() throws IOException { + Set all = new HashSet<>(brwsrs.values()); if (js(false) != null) { - js(true).initialize(); + all.add(js(true)); } - for (Launcher launcher : brwsrs.values()) { + for (Launcher launcher : all) { launcher.initialize(); } } @AfterGroups("run") public void shutDownLauncher() throws IOException, InterruptedException { + Set all = new HashSet<>(brwsrs.values()); if (js(false) != null) { - js(true).shutdown(); + all.add(js(true)); } - for (Launcher launcher : brwsrs.values()) { + for (Launcher launcher : all) { launcher.shutdown(); } }