# HG changeset patch # User Jaroslav Tulach # Date 1399617440 -7200 # Node ID 0002739b6d1fc0cd2b9ccf9fb6d6987662a38bf4 # Parent cb9e273dfd517b9181c66663fbba82b25fa8879d Moving Zip tests into right locations diff -r cb9e273dfd51 -r 0002739b6d1f 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 cb9e273dfd51 -r 0002739b6d1f rt/emul/zip/pom.xml --- a/rt/emul/zip/pom.xml Wed May 07 17:24:29 2014 +0200 +++ b/rt/emul/zip/pom.xml Fri May 09 08:37:20 2014 +0200 @@ -47,5 +47,11 @@ test jar + + org.apidesign.bck2brwsr + vm4brwsr + ${project.version} + jar + - \ No newline at end of file + diff -r cb9e273dfd51 -r 0002739b6d1f 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 Fri May 09 08:37:20 2014 +0200 @@ -0,0 +1,115 @@ +/** + * 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) { + 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; + } + + @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; + } + + 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 cb9e273dfd51 -r 0002739b6d1f rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/ZipEntryTest.java --- a/rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/ZipEntryTest.java Wed May 07 17:24:29 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 cb9e273dfd51 -r 0002739b6d1f rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/ZipFileTest.java --- a/rt/emul/zip/src/test/java/org/apidesign/bck2brwsr/emul/zip/ZipFileTest.java Wed May 07 17:24:29 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 cb9e273dfd51 -r 0002739b6d1f 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 Fri May 09 08:37:20 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 cb9e273dfd51 -r 0002739b6d1f 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 Fri May 09 08:37:20 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.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 cb9e273dfd51 -r 0002739b6d1f 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 cb9e273dfd51 -r 0002739b6d1f rt/vm/src/main/java/org/apidesign/vm4brwsr/ClassPath.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClassPath.java Wed May 07 17:24:29 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClassPath.java Fri May 09 08:37:20 2014 +0200 @@ -19,6 +19,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.net.URL; import org.apidesign.bck2brwsr.core.JavaScriptBody; @@ -46,9 +47,9 @@ if (c instanceof String) { try { String url = (String)c; - final ZipHandler z = ZipHandler.toZip(url); + final Bck2Brwsr.Resources z = toZip(url); c = set(classpath, i, z); - final byte[] man = z.findRes("META-INF/MANIFEST.MF"); + final byte[] man = readBytes(z, "META-INF/MANIFEST.MF"); if (man != null) { String mainClass = processClassPathAttr(man, url, classpath); // if (mainClass != null) { @@ -62,8 +63,8 @@ } if (res != null) { byte[] checkRes; - if (c instanceof ZipHandler) { - checkRes = ((ZipHandler)c).findRes(res); + if (c instanceof Bck2Brwsr.Resources) { + checkRes = readBytes((Bck2Brwsr.Resources)c, res); if (checkRes != null && --skip < 0) { return checkRes; } @@ -116,4 +117,36 @@ @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 cb9e273dfd51 -r 0002739b6d1f rt/vm/src/main/java/org/apidesign/vm4brwsr/ZipHandler.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ZipHandler.java Wed May 07 17:24:29 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +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.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 ZipHandler { - private final FastJar fj; - - private ZipHandler(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", "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); - - 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); - - static ZipHandler toZip(String path) throws IOException { - URL u = new URL(path); - byte[] zipData = (byte[]) u.getContent(new Class[] { byte[].class }); - return new ZipHandler(path, zipData); - } - - @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(); - - -}