# HG changeset patch # User Jaroslav Tulach # Date 1398675552 -7200 # Node ID d5dd07b45f797be9e511c08a1aa6139241ee5aa1 # Parent 3b03a81af4b1e9352f4c170798c0e0bd8b15a860 Being able to compile resources into the generated JavaScript file and use them. diff -r 3b03a81af4b1 -r d5dd07b45f79 rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Mon Apr 28 08:54:51 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Mon Apr 28 10:59:12 2014 +0200 @@ -253,6 +253,10 @@ String[] allClasses() { return classes.addAndNew(rootcls.toArray()).toArray(); } + StringArray allResources() { + return resources; + } + StringArray rootClasses() { return rootcls; diff -r 3b03a81af4b1 -r d5dd07b45f79 rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Mon Apr 28 08:54:51 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Mon Apr 28 10:59:12 2014 +0200 @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; +import org.apidesign.bck2brwsr.core.JavaScriptBody; import org.apidesign.vm4brwsr.ByteCodeParser.ClassData; import org.apidesign.vm4brwsr.ByteCodeParser.FieldData; import org.apidesign.vm4brwsr.ByteCodeParser.MethodData; @@ -79,10 +80,10 @@ fixedNames.add(fixedClass.getName().replace('.', '/')); } - vm.doCompile(fixedNames.addAndNew(both)); + vm.doCompile(fixedNames.addAndNew(both), config.allResources()); } - private void doCompile(StringArray names) throws IOException { + private void doCompile(StringArray names, StringArray asBinary) throws IOException { generatePrologue(); out.append( "\n var invoker = function Invoker() {" @@ -97,10 +98,29 @@ + "\n return invoker;" + "\n };"); } + + for (String r : asBinary.toArray()) { + out.append("\n ").append(getExportsObject()).append(".registerResource('"); + out.append(r).append("', '"); + InputStream is = this.resources.get(r); + byte[] arr = new byte[is.available()]; + int len = is.read(arr); + if (len != arr.length) { + throw new IOException("Not read as much as expected for " + r + " expected: " + arr.length + " was: " + len); + } + out.append(btoa(arr)); + out.append("');"); + } + out.append("\n"); generateEpilogue(); } + @JavaScriptBody(args = { "arr" }, body = "return btoa(arr);") + private static String btoa(byte[] arr) { + return javax.xml.bind.DatatypeConverter.printBase64Binary(arr); + } + protected abstract void generatePrologue() throws IOException; protected abstract void generateEpilogue() throws IOException; @@ -435,10 +455,19 @@ + " var extensions = [];\n" + " global.bck2brwsr = function() {\n" + " var args = Array.prototype.slice.apply(arguments);\n" - + " var vm = fillInVMSkeleton({});\n" + + " var resources = {};\n" + + " function registerResource(n, a64) {\n" + + " var str = atob(a64);\n" + + " var arr = [];\n" + + " for (var i = 0; i < str.length; i++) arr.push(str.charCodeAt(i) & 0xff);\n" + + " if (!resources[n]) resources[n] = [arr];\n" + + " else resources[n].push(arr);\n" + + " }\n" + + " var vm = fillInVMSkeleton({ 'registerResource' : registerResource });\n" + " for (var i = 0; i < extensions.length; ++i) {\n" + " extensions[i](vm);\n" + " }\n" + + " vm.registerResource = null;\n" + " var knownExtensions = extensions.length;\n" + " var loader = {};\n" + " loader.vm = vm;\n" @@ -451,7 +480,9 @@ + " load__Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n" + " } catch (err) {\n" + " while (knownExtensions < extensions.length) {\n" + + " vm.registerResource = registerResource;\n" + " extensions[knownExtensions++](vm);\n" + + " vm.registerResource = null;\n" + " }\n" + " fn = vm[attr];\n" + " if (fn) return fn(false);\n" @@ -463,6 +494,7 @@ + " }\n" + " vm.loadClass = loader.loadClass;\n" + " vm.loadBytes = function(name) {\n" + + " if (resources[name]) return resources[name][0];\n" + " return vm.org_apidesign_vm4brwsr_VMLazy(false).\n" + " loadBytes___3BLjava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n" + " }\n" diff -r 3b03a81af4b1 -r d5dd07b45f79 rt/vm/src/test/java/org/apidesign/vm4brwsr/Resources.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/Resources.java Mon Apr 28 08:54:51 2014 +0200 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/Resources.java Mon Apr 28 10:59:12 2014 +0200 @@ -35,6 +35,7 @@ if (len == -1) { return "No data read!"; } - return new String(arr, 0, len, "UTF-8"); + final Object str = new String(arr, 0, len, "UTF-8"); + return str.toString(); } } diff -r 3b03a81af4b1 -r d5dd07b45f79 rt/vm/src/test/java/org/apidesign/vm4brwsr/ResourcesTest.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/ResourcesTest.java Mon Apr 28 08:54:51 2014 +0200 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/ResourcesTest.java Mon Apr 28 10:59:12 2014 +0200 @@ -17,8 +17,7 @@ */ package org.apidesign.vm4brwsr; -import javax.script.ScriptEngine; -import static org.testng.Assert.*; +import java.io.UnsupportedEncodingException; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -55,4 +54,8 @@ ) throws Exception { code.assertExec(msg, clazz, method, ret, args); } + + public static String parseBase64Binary(String s) throws UnsupportedEncodingException { + return new String(javax.xml.bind.DatatypeConverter.parseBase64Binary(s), "UTF-8"); + } } diff -r 3b03a81af4b1 -r d5dd07b45f79 rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Mon Apr 28 08:54:51 2014 +0200 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Mon Apr 28 10:59:12 2014 +0200 @@ -169,6 +169,11 @@ eng[0] = js; } try { + js.eval("atob = function(s) { return org.apidesign.vm4brwsr.ResourcesTest.parseBase64Binary(s); }"); + + Object ahoj = js.eval("atob('QWhvag==')"); + assertEquals(ahoj, "Ahoj", "Verify the atob function behaves properly"); + Object res = js.eval(sb.toString()); assertTrue(js instanceof Invocable, "It is invocable object: " + res); return new TestVM((Invocable) js, sb);