rt/vm/src/main/java/org/apidesign/vm4brwsr/ZipHandler.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 07 May 2014 17:24:29 +0200
branchclosure
changeset 1550 cb9e273dfd51
parent 1387 rt/vm/src/main/java/org/apidesign/vm4brwsr/Zips.java@350f8aee0f60
permissions -rw-r--r--
Splitting into two classes: one that deals with classpath, one that deals with ZIP content
jaroslav@644
     1
/**
jaroslav@644
     2
 * Back 2 Browser Bytecode Translator
jaroslav@644
     3
 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
jaroslav@644
     4
 *
jaroslav@644
     5
 * This program is free software: you can redistribute it and/or modify
jaroslav@644
     6
 * it under the terms of the GNU General Public License as published by
jaroslav@644
     7
 * the Free Software Foundation, version 2 of the License.
jaroslav@644
     8
 *
jaroslav@644
     9
 * This program is distributed in the hope that it will be useful,
jaroslav@644
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
jaroslav@644
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
jaroslav@644
    12
 * GNU General Public License for more details.
jaroslav@644
    13
 *
jaroslav@644
    14
 * You should have received a copy of the GNU General Public License
jaroslav@644
    15
 * along with this program. Look for COPYING file in the top folder.
jaroslav@644
    16
 * If not, see http://opensource.org/licenses/GPL-2.0.
jaroslav@644
    17
 */
jaroslav@644
    18
package org.apidesign.vm4brwsr;
jaroslav@644
    19
jaroslav@644
    20
import java.io.IOException;
jaroslav@706
    21
import java.io.InputStream;
jaroslav@644
    22
import java.net.URL;
jaroslav@644
    23
import org.apidesign.bck2brwsr.core.JavaScriptBody;
jaroslav@706
    24
import org.apidesign.bck2brwsr.emul.zip.FastJar;
jaroslav@644
    25
jaroslav@644
    26
/** Conversion from classpath to load function.
jaroslav@644
    27
 *
jaroslav@644
    28
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jaroslav@644
    29
 */
jaroslav@1550
    30
final class ZipHandler {
jaroslav@706
    31
    private final FastJar fj;
jaroslav@706
    32
jaroslav@1550
    33
    private ZipHandler(String path, byte[] zipData) throws IOException {
jaroslav@715
    34
        long bef = timeNow();
jaroslav@706
    35
        fj = new FastJar(zipData);
jaroslav@706
    36
        for (FastJar.Entry e : fj.list()) {
jaroslav@706
    37
            putRes(e.name, e);
jaroslav@706
    38
        }
jaroslav@715
    39
        log("Iterating thru " + path + " took " + (timeNow() - bef) + "ms");
jaroslav@644
    40
    }
jaroslav@644
    41
    
jaroslav@644
    42
    public static void init() {
jaroslav@644
    43
    }
jaroslav@729
    44
    @JavaScriptBody(args = { "arr" }, body = "return arr.length;")
jaroslav@729
    45
    private static native int length(Object arr);
jaroslav@729
    46
    @JavaScriptBody(args = { "arr", "index", "value" }, body = "arr[index] = value; return value;")
jaroslav@729
    47
    private static native Object set(Object arr, int index, Object value);
jaroslav@644
    48
    
jaroslav@1358
    49
    @JavaScriptBody(args = { "msg" }, body = "if (typeof console !== 'undefined') console.log(msg.toString());")
jaroslav@706
    50
    private static native void log(String msg);
jaroslav@706
    51
jaroslav@1550
    52
    byte[] findRes(String res) throws IOException {
jaroslav@706
    53
        Object arr = findResImpl(res);
jaroslav@706
    54
        if (arr instanceof FastJar.Entry) {
jaroslav@715
    55
            long bef = timeNow();
jaroslav@706
    56
            InputStream zip = fj.getInputStream((FastJar.Entry)arr);
jaroslav@706
    57
            arr = readFully(new byte[512], zip);
jaroslav@706
    58
            putRes(res, arr);
jaroslav@715
    59
            log("Reading " + res + " took " + (timeNow() - bef) + "ms");
jaroslav@706
    60
        }
jaroslav@706
    61
        return (byte[]) arr;
jaroslav@706
    62
    }
jaroslav@644
    63
jaroslav@644
    64
    @JavaScriptBody(args = { "res" }, body = "var r = this[res]; return r ? r : null;")
jaroslav@706
    65
    private native Object findResImpl(String res);
jaroslav@644
    66
jaroslav@644
    67
    @JavaScriptBody(args = { "res", "arr" }, body = "this[res] = arr;")
jaroslav@706
    68
    private native void putRes(String res, Object arr);
jaroslav@644
    69
    
jaroslav@1550
    70
    static ZipHandler toZip(String path) throws IOException {
jaroslav@644
    71
        URL u = new URL(path);
jaroslav@706
    72
        byte[] zipData = (byte[]) u.getContent(new Class[] { byte[].class });
jaroslav@1550
    73
        return new ZipHandler(path, zipData);
jaroslav@644
    74
    }
jaroslav@644
    75
jaroslav@644
    76
    @JavaScriptBody(args = { "arr", "len" }, body = "while (arr.length < len) arr.push(0);")
jaroslav@729
    77
    private static native void enlargeBytes(byte[] arr, int len);
jaroslav@644
    78
jaroslav@644
    79
    @JavaScriptBody(args = { "arr", "len" }, body = "arr.splice(len, arr.length - len);")
jaroslav@644
    80
    private static native void sliceArray(byte[] arr, int len);
jaroslav@706
    81
jaroslav@706
    82
    private static Object readFully(byte[] arr, InputStream zip) throws IOException {
jaroslav@706
    83
        int offset = 0;
jaroslav@706
    84
        for (;;) {
jaroslav@706
    85
            int len = zip.read(arr, offset, arr.length - offset);
jaroslav@706
    86
            if (len == -1) {
jaroslav@706
    87
                break;
jaroslav@706
    88
            }
jaroslav@706
    89
            offset += len;
jaroslav@706
    90
            if (offset == arr.length) {
jaroslav@729
    91
                enlargeBytes(arr, arr.length + 4096);
jaroslav@706
    92
            }
jaroslav@706
    93
        }
jaroslav@706
    94
        sliceArray(arr, offset);
jaroslav@706
    95
        return arr;
jaroslav@706
    96
    }
jaroslav@706
    97
jaroslav@715
    98
    private static long timeNow() {
jaroslav@715
    99
        double time = m();
jaroslav@715
   100
        if (time >= 0) {
jaroslav@715
   101
            return (long)time;
jaroslav@715
   102
        }
jaroslav@715
   103
        return org.apidesign.bck2brwsr.emul.lang.System.currentTimeMillis();
jaroslav@706
   104
    }
jaroslav@715
   105
    @JavaScriptBody(args = {}, body = 
jaroslav@715
   106
        "if (typeof window.performance === 'undefined') return -1;\n"
jaroslav@715
   107
      + "if (typeof window.performance.now === 'undefined') return -1;\n"
jaroslav@715
   108
      + "return window.performance.now();"
jaroslav@715
   109
    )
jaroslav@706
   110
    private static native double m();
jaroslav@644
   111
    
jaroslav@644
   112
    
jaroslav@644
   113
}