# HG changeset patch # User Jaroslav Tulach # Date 1359551029 -3600 # Node ID 9839e9a75bcf5a4b5a430a5d6d3ef12bb5a19e8d # Parent 0127bd22630c302fbc0c0f6fd2461f2e96300712 Implementation of ZipInputStream diff -r 0127bd22630c -r 9839e9a75bcf emul/mini/src/main/java/java/lang/Cloneable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/mini/src/main/java/java/lang/Cloneable.java Wed Jan 30 14:03:49 2013 +0100 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1995, 2004, 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.lang; + +/** + * A class implements the Cloneable interface to + * indicate to the {@link java.lang.Object#clone()} method that it + * is legal for that method to make a + * field-for-field copy of instances of that class. + *

+ * Invoking Object's clone method on an instance that does not implement the + * Cloneable interface results in the exception + * CloneNotSupportedException being thrown. + *

+ * By convention, classes that implement this interface should override + * Object.clone (which is protected) with a public method. + * See {@link java.lang.Object#clone()} for details on overriding this + * method. + *

+ * Note that this interface does not contain the clone method. + * Therefore, it is not possible to clone an object merely by virtue of the + * fact that it implements this interface. Even if the clone method is invoked + * reflectively, there is no guarantee that it will succeed. + * + * @author unascribed + * @see java.lang.CloneNotSupportedException + * @see java.lang.Object#clone() + * @since JDK1.0 + */ +public interface Cloneable { +} diff -r 0127bd22630c -r 9839e9a75bcf emul/mini/src/main/java/java/lang/String.java --- a/emul/mini/src/main/java/java/lang/String.java Wed Jan 30 14:01:52 2013 +0100 +++ b/emul/mini/src/main/java/java/lang/String.java Wed Jan 30 14:03:49 2013 +0100 @@ -201,6 +201,10 @@ * If the {@code offset} and {@code count} arguments index * characters outside the bounds of the {@code value} array */ + public String(char value[], int offset, int count) { + initFromCharArray(value, offset, count); + } + @JavaScriptBody(args = { "charArr", "off", "cnt" }, body = "var up = off + cnt;\n" + "for (var i = off; i < up; i++) {\n" + @@ -208,8 +212,7 @@ "}\n" + "this._r(charArr.slice(off, up).join(\"\"));\n" ) - public String(char value[], int offset, int count) { - } + private native void initFromCharArray(char value[], int offset, int count); /** * Allocates a new {@code String} that contains characters from a subarray @@ -555,7 +558,7 @@ int ch = nextChar(bytes, at); v[chlen++] = (char)ch; } - this.r = new String(v, 0, chlen); + initFromCharArray(v, 0, chlen); } /** diff -r 0127bd22630c -r 9839e9a75bcf emul/mini/src/main/java/java/util/zip/CRC32.java --- a/emul/mini/src/main/java/java/util/zip/CRC32.java Wed Jan 30 14:01:52 2013 +0100 +++ b/emul/mini/src/main/java/java/util/zip/CRC32.java Wed Jan 30 14:03:49 2013 +0100 @@ -33,7 +33,7 @@ */ public class CRC32 implements Checksum { - private int crc; + private int crc = 0xFFFFFFFF; /** * Creates a new CRC32 object. @@ -49,7 +49,8 @@ * @param b the byte to update the checksum with */ public void update(int b) { - crc = update(crc, b); + byte[] arr = { (byte)b }; + update(arr); } /** @@ -88,6 +89,25 @@ return (long)crc & 0xffffffffL; } - private native static int update(int crc, int b); - private native static int updateBytes(int crc, byte[] b, int off, int len); + // XXX: taken from + // http://introcs.cs.princeton.edu/java/51data/CRC32.java.html + private static int updateBytes(int crc, byte[] arr, int off, int len) { + int poly = 0xEDB88320; // reverse polynomial + + while (len-- > 0) { + byte b = arr[off++]; + int temp = (crc ^ b) & 0xff; + + // read 8 bits one at a time + for (int i = 0; i < 8; i++) { + if ((temp & 1) == 1) { + temp = (temp >>> 1) ^ poly; + } else { + temp = (temp >>> 1); + } + } + crc = (crc >>> 8) ^ temp; + } + return crc ^ 0xffffffff; + } } diff -r 0127bd22630c -r 9839e9a75bcf emul/mini/src/main/java/java/util/zip/Inflater.java --- a/emul/mini/src/main/java/java/util/zip/Inflater.java Wed Jan 30 14:01:52 2013 +0100 +++ b/emul/mini/src/main/java/java/util/zip/Inflater.java Wed Jan 30 14:03:49 2013 +0100 @@ -25,6 +25,9 @@ package java.util.zip; +import org.apidesign.bck2brwsr.core.ExtraJavaScript; +import org.apidesign.bck2brwsr.core.JavaScriptBody; + /** * This class provides support for general purpose decompression using the * popular ZLIB compression library. The ZLIB compression library was @@ -70,22 +73,19 @@ * @author David Connelly * */ +@ExtraJavaScript( + resource = "/org/apidesign/vm4brwsr/emul/zip/js-inflate.min.js" +) public class Inflater { - - private final ZStreamRef zsRef; - private byte[] buf = defaultBuf; - private int off, len; + private String data = ""; + private int offset; + private long counter; private boolean finished; private boolean needDict; private static final byte[] defaultBuf = new byte[0]; - static { - /* Zip library is loaded from System.initializeSystemClass */ - initIDs(); - } - /** * Creates a new decompressor. If the parameter 'nowrap' is true then * the ZLIB header and checksum fields will not be used. This provides @@ -98,7 +98,6 @@ * @param nowrap if true then support GZIP compatible compression */ public Inflater(boolean nowrap) { - zsRef = new ZStreamRef(init(nowrap)); } /** @@ -124,11 +123,7 @@ if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } - synchronized (zsRef) { - this.buf = b; - this.off = off; - this.len = len; - } + data = (String) infl(b, off, len); } /** @@ -160,11 +155,7 @@ if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } - synchronized (zsRef) { - ensureOpen(); - setDictionary(zsRef.address(), b, off, len); - needDict = false; - } + needDict = false; } /** @@ -187,9 +178,7 @@ * @return the total number of bytes remaining in the input buffer */ public int getRemaining() { - synchronized (zsRef) { - return len; - } + return data.length() - offset; } /** @@ -199,9 +188,7 @@ * @return true if no data remains in the input buffer */ public boolean needsInput() { - synchronized (zsRef) { - return len <= 0; - } + return getRemaining() <= 0; } /** @@ -210,9 +197,7 @@ * @see Inflater#setDictionary */ public boolean needsDictionary() { - synchronized (zsRef) { - return needDict; - } + return needDict; } /** @@ -222,9 +207,7 @@ * reached */ public boolean finished() { - synchronized (zsRef) { - return finished; - } + return finished; } /** @@ -251,11 +234,21 @@ if (off < 0 || len < 0 || off > b.length - len) { throw new ArrayIndexOutOfBoundsException(); } - synchronized (zsRef) { - ensureOpen(); - return inflateBytes(zsRef.address(), b, off, len); + int cnt = 0; + while (offset < data.length()) { + b[off++] = (byte)data.charAt(offset++); + cnt++; + counter++; } + return cnt; } + + @JavaScriptBody(args = { "arr", "offset", "len" }, body = + "var r = {};\n" + + "r.charCodeAt = function(idx) { return arr[offset + idx]; };\n" + + "return JSInflate.inflate(r);" + ) + private static native Object infl(byte[] arr, int offset, int len); /** * Uncompresses bytes into specified buffer. Returns actual number @@ -279,10 +272,7 @@ * @return the ADLER-32 value of the uncompressed data */ public int getAdler() { - synchronized (zsRef) { - ensureOpen(); - return getAdler(zsRef.address()); - } + return 0; } /** @@ -305,10 +295,7 @@ * @since 1.5 */ public long getBytesRead() { - synchronized (zsRef) { - ensureOpen(); - return getBytesRead(zsRef.address()); - } + return counter; } /** @@ -331,24 +318,17 @@ * @since 1.5 */ public long getBytesWritten() { - synchronized (zsRef) { - ensureOpen(); - return getBytesWritten(zsRef.address()); - } + return counter; } /** * Resets inflater so that a new set of input data can be processed. */ public void reset() { - synchronized (zsRef) { - ensureOpen(); - reset(zsRef.address()); - buf = defaultBuf; - finished = false; - needDict = false; - off = len = 0; - } + data = ""; + finished = false; + needDict = false; + offset = 0; } /** @@ -359,44 +339,5 @@ * object is undefined. */ public void end() { - synchronized (zsRef) { - long addr = zsRef.address(); - zsRef.clear(); - if (addr != 0) { - end(addr); - buf = null; - } - } } - - /** - * Closes the decompressor when garbage is collected. - */ - protected void finalize() { - end(); - } - - private void ensureOpen () { - assert Thread.holdsLock(zsRef); - if (zsRef.address() == 0) - throw new NullPointerException("Inflater has been closed"); - } - - boolean ended() { - synchronized (zsRef) { - return zsRef.address() == 0; - } - } - - private native static void initIDs(); - private native static long init(boolean nowrap); - private native static void setDictionary(long addr, byte[] b, int off, - int len); - private native int inflateBytes(long addr, byte[] b, int off, int len) - throws DataFormatException; - private native static int getAdler(long addr); - private native static long getBytesRead(long addr); - private native static long getBytesWritten(long addr); - private native static void reset(long addr); - private native static void end(long addr); } diff -r 0127bd22630c -r 9839e9a75bcf emul/mini/src/main/java/java/util/zip/ZipEntry.java --- a/emul/mini/src/main/java/java/util/zip/ZipEntry.java Wed Jan 30 14:01:52 2013 +0100 +++ b/emul/mini/src/main/java/java/util/zip/ZipEntry.java Wed Jan 30 14:03:49 2013 +0100 @@ -25,8 +25,6 @@ package java.util.zip; -import java.util.Date; - /** * This class is used to represent a ZIP file entry. * @@ -281,6 +279,8 @@ * 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), @@ -288,12 +288,15 @@ (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) { @@ -302,6 +305,7 @@ return (year - 1980) << 25 | (d.getMonth() + 1) << 21 | d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 | d.getSeconds() >> 1; + */ } /** @@ -321,7 +325,7 @@ return e; } catch (CloneNotSupportedException e) { // This should never happen, since we are Cloneable - throw new InternalError(); + throw new IllegalStateException(); } } } diff -r 0127bd22630c -r 9839e9a75bcf emul/mini/src/main/java/java/util/zip/ZipInputStream.java --- a/emul/mini/src/main/java/java/util/zip/ZipInputStream.java Wed Jan 30 14:01:52 2013 +0100 +++ b/emul/mini/src/main/java/java/util/zip/ZipInputStream.java Wed Jan 30 14:03:49 2013 +0100 @@ -29,9 +29,8 @@ import java.io.IOException; import java.io.EOFException; import java.io.PushbackInputStream; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import static java.util.zip.ZipConstants64.*; +import org.apidesign.bck2brwsr.core.JavaScriptBody; /** * This class implements an input stream filter for reading files in the @@ -56,8 +55,6 @@ // one entry private boolean entryEOF = false; - private ZipCoder zc; - /** * Check to make sure that this stream has not been closed */ @@ -76,7 +73,12 @@ * @param in the actual input stream */ public ZipInputStream(InputStream in) { - this(in, StandardCharsets.UTF_8); +// this(in, "UTF-8"); + super(new PushbackInputStream(in, 512), new Inflater(true), 512); + usesDefaultInflater = true; + if(in == null) { + throw new NullPointerException("in is null"); + } } /** @@ -92,7 +94,7 @@ * flag is set). * * @since 1.7 - */ + * public ZipInputStream(InputStream in, Charset charset) { super(new PushbackInputStream(in, 512), new Inflater(true), 512); usesDefaultInflater = true; @@ -103,6 +105,7 @@ throw new NullPointerException("charset is null"); this.zc = ZipCoder.get(charset); } + */ /** * Reads the next ZIP file entry and positions the stream at the @@ -295,8 +298,8 @@ 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) - ? zc.toStringUTF8(b, len) - : zc.toString(b, len)); + ? 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"); @@ -453,4 +456,12 @@ 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 0127bd22630c -r 9839e9a75bcf emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/zip/js-inflate.min.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/zip/js-inflate.min.js Wed Jan 30 14:03:49 2013 +0100 @@ -0,0 +1,1 @@ +(function(G){var n=32768;var w=0;var I=1;var i=2;var S=9;var h=6;var t=32768;var a=64;var C;var k;var Q=null;var b;var M,D;var s;var r;var U;var N;var T;var y;var m,p;var f,j;var B;var E;var P=new Array(0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535);var c=new Array(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);var L=new Array(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,99,99);var J=new Array(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);var z=new Array(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);var q=new Array(16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15);function x(){this.next=null;this.list=null}function H(){this.e=0;this.b=0;this.n=0;this.t=null}function l(ax,al,ag,av,au,aq){this.BMAX=16;this.N_MAX=288;this.status=0;this.root=null;this.m=0;var ay;var aw=new Array(this.BMAX+1);var V;var at;var ar;var ap;var ao;var an;var am;var W=new Array(this.BMAX+1);var aj;var X;var ai;var ah=new H();var af=new Array(this.BMAX);var ae=new Array(this.N_MAX);var ad;var ab=new Array(this.BMAX+1);var ac;var aa;var Z;var ak;var Y;Y=this.root=null;for(ao=0;ao256?ax[256]:this.BMAX;aj=ax;X=0;ao=al;do{aw[aj[X]]++;X++}while(--ao>0);if(aw[0]==al){this.root=null;this.m=0;this.status=0;return}for(an=1;an<=this.BMAX;an++){if(aw[an]!=0){break}}am=an;if(aqao){aq=ao}for(aa=1<0){ab[ac++]=(an+=aj[X++])}aj=ax;X=0;ao=0;do{if((an=aj[X++])!=0){ae[ab[an]++]=ao}}while(++ao0){while(am>ad+W[1+ap]){ad+=W[1+ap];ap++;Z=(Z=ar-ad)>aq?aq:Z;if((at=1<<(an=am-ad))>ay+1){at-=ay+1;ac=am;while(++anV&&ad0){ab[ap]=ao;ah.b=W[ap];ah.e=16+an;ah.t=ai;an=(ao&((1<>(ad-W[ap]);af[ap-1][an].e=ah.e;af[ap-1][an].b=ah.b;af[ap-1][an].n=ah.n;af[ap-1][an].t=ah.t}}ah.b=am-ad;if(X>=al){ah.e=99}else{if(aj[X]>ad;an>=1){ao^=an}ao^=an;while((ao&((1<>=V;r-=V}function g(aa,Y,W){var X;var V;var Z;if(W==0){return 0}Z=0;for(;;){R(f);V=m.list[u(f)];X=V.e;while(X>16){if(X==99){return -1}d(V.b);X-=16;R(X);V=V.t[u(X)];X=V.e}d(V.b);if(X==16){k&=n-1;aa[Y+Z++]=C[k++]=V.n;if(Z==W){return W}continue}if(X==15){break}R(X);T=V.n+u(X);d(X);R(j);V=p.list[u(j)];X=V.e;while(X>16){if(X==99){return -1}d(V.b);X-=16;R(X);V=V.t[u(X)];X=V.e}d(V.b);R(X);y=k-V.n-u(X);d(X);while(T>0&&Z0&&X1){Q=null;alert("HufBuild error: "+Y.status);return -1}b=Y.root;zip_fixed_bd=Y.m}m=Q;p=b;f=M;j=zip_fixed_bd;return g(aa,Z,X)}function A(af,X,ah){var ab;var aa;var Y;var W;var ag;var ad;var V;var Z;var ae=new Array(286+30);var ac;for(ab=0;ab286||Z>30){return -1}for(aa=0;aaW){return -1}while(aa-->0){ae[ab++]=Y}}else{if(aa==17){R(3);aa=3+u(3);d(3);if(ab+aa>W){return -1}while(aa-->0){ae[ab++]=0}Y=0}else{R(7);aa=11+u(7);d(7);if(ab+aa>W){return -1}while(aa-->0){ae[ab++]=0}Y=0}}}}f=S;ac=new l(ae,V,257,c,L,f);if(f==0){ac.status=1}if(ac.status!=0){if(ac.status==1){}return -1}m=ac.root;f=ac.m;for(ab=0;ab257){return -1}if(ac.status==1){}if(ac.status!=0){return -1}return g(af,X,ah)}function O(){var V;if(C==null){C=new Array(2*n)}k=0;s=0;r=0;U=-1;N=false;T=y=0;m=null}function F(Z,X,W){var Y,V;Y=0;while(Y0){if(U!=w){while(T>0&&Y0&&Y0){for(V=0;V + * + * 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.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** Annotation to generate a ZIP or JAR file during build. + * + * @author Jaroslav Tulach + */ +@Retention(RetentionPolicy.SOURCE) +@interface GenerateZip { + String name(); + + /** manifest for the file */ + String manifest() default ""; + + /** Array of names (at odd positions) and their content (on even) */ + String[] contents(); +} diff -r 0127bd22630c -r 9839e9a75bcf vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/GenerateZipProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/GenerateZipProcessor.java Wed Jan 30 14:03:49 2013 +0100 @@ -0,0 +1,98 @@ +/** + * 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.OutputStream; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.Processor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.FileObject; +import javax.tools.StandardLocation; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author Jaroslav Tulach + */ +@ServiceProvider(service = Processor.class) +@SupportedAnnotationTypes("org.apidesign.bck2brwsr.vmtest.impl.GenerateZip") +public class GenerateZipProcessor extends AbstractProcessor { + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + for (Element e : roundEnv.getElementsAnnotatedWith(GenerateZip.class)) { + GenerateZip gz = e.getAnnotation(GenerateZip.class); + if (gz == null) { + continue; + } + PackageElement pe = findPackage(e); + try { + generateJar(pe, gz, e); + } catch (IOException ex) { + processingEnv.getMessager().printMessage( + Diagnostic.Kind.ERROR, + "Can't generate JAR " + gz.name() + ": " + ex.getMessage() + ); + } + } + return true; + } + + private static PackageElement findPackage(Element e) { + while (e.getKind() != ElementKind.PACKAGE) { + e = e.getEnclosingElement(); + } + return (PackageElement)e; + } + + private void generateJar(PackageElement pe, GenerateZip gz, Element e) throws IOException { + FileObject res = processingEnv.getFiler().createResource( + StandardLocation.CLASS_OUTPUT, + pe.getQualifiedName().toString(), + gz.name(), e + ); + OutputStream os = res.openOutputStream(); + JarOutputStream jar; + if (gz.manifest().isEmpty()) { + jar = new JarOutputStream(os); + } else { + Manifest mf = new Manifest(new ByteArrayInputStream(gz.manifest().getBytes("UTF-8"))); + jar = new JarOutputStream(os, mf); + } + String[] arr = gz.contents(); + for (int i = 0; i < arr.length; i += 2) { + JarEntry je = new JarEntry(arr[i]); + jar.putNextEntry(je); + jar.write(arr[i + 1].getBytes("UTF-8")); + jar.closeEntry(); + } + } + +} diff -r 0127bd22630c -r 9839e9a75bcf vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CRC32Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/CRC32Test.java Wed Jan 30 14:03:49 2013 +0100 @@ -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.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 0127bd22630c -r 9839e9a75bcf vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java Wed Jan 30 14:03:49 2013 +0100 @@ -0,0 +1,54 @@ +/** + * 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.vmtest.Compare; +import org.apidesign.bck2brwsr.vmtest.VMTest; +import org.testng.annotations.Factory; + +/** + * + * @author Jaroslav Tulach + */ +public class ZipFileTest { + + @GenerateZip(name = "readAnEntry.zip", contents = { "my/main/file.txt", "Hello World!" }) + @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); + + return new String(arr, 0, len, "UTF-8"); + } + + private static void assertEquals(String real, String exp, String msg) { + assert exp.equals(real) : msg + " exp: " + exp + " real: " + real; + } + + @Factory public static Object[] create() { + return VMTest.create(ZipFileTest.class); + } +}