jaroslav@694: /** jaroslav@694: * Back 2 Browser Bytecode Translator jaroslav@694: * Copyright (C) 2012 Jaroslav Tulach jaroslav@694: * jaroslav@694: * This program is free software: you can redistribute it and/or modify jaroslav@694: * it under the terms of the GNU General Public License as published by jaroslav@694: * the Free Software Foundation, version 2 of the License. jaroslav@694: * jaroslav@694: * This program is distributed in the hope that it will be useful, jaroslav@694: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@694: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@694: * GNU General Public License for more details. jaroslav@694: * jaroslav@694: * You should have received a copy of the GNU General Public License jaroslav@694: * along with this program. Look for COPYING file in the top folder. jaroslav@694: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@694: */ jaroslav@1549: package org.apidesign.bck2brwsr.emul.zip; jaroslav@694: jaroslav@694: import java.io.ByteArrayOutputStream; jaroslav@694: import java.io.IOException; jaroslav@694: import java.io.InputStream; jaroslav@694: import java.util.zip.ZipEntry; jaroslav@694: jaroslav@694: /** jaroslav@694: * jaroslav@694: * @author Jaroslav Tulach jaroslav@694: */ jaroslav@694: final class ZipArchive { jaroslav@1556: private Entry first; jaroslav@694: jaroslav@694: public static ZipArchive createZip(InputStream is) throws IOException { jaroslav@694: ZipArchive a = new ZipArchive(); jaroslav@694: readZip(is, a); jaroslav@694: return a; jaroslav@694: } jaroslav@694: jaroslav@694: public static ZipArchive createReal(InputStream is) throws IOException { jaroslav@694: ZipArchive a = new ZipArchive(); jaroslav@694: realZip(is, a); jaroslav@694: return a; jaroslav@694: } jaroslav@694: jaroslav@694: /** jaroslav@694: * Registers entry name and data jaroslav@694: */ jaroslav@694: final void register(String entry, InputStream is) throws IOException { jaroslav@1556: byte[] arr = new byte[12 * 4096]; jaroslav@1556: for (int i = 0; i < arr.length; i++) { jaroslav@694: int ch = is.read(); jaroslav@694: if (ch == -1) { jaroslav@1556: byte[] tmp = new byte[i]; jaroslav@1556: FastJar.arraycopy(arr, 0, tmp, 0, i); jaroslav@1556: arr = tmp; jaroslav@694: break; jaroslav@694: } jaroslav@1556: arr[i] = (byte) ch; jaroslav@694: } jaroslav@1556: first = new Entry (entry, arr, first); jaroslav@694: } jaroslav@1556: jaroslav@694: @Override jaroslav@694: public String toString() { jaroslav@694: StringBuilder sb = new StringBuilder(); jaroslav@1556: Entry e = first; jaroslav@1556: while (e != null) { jaroslav@1556: String string = e.name; jaroslav@1556: byte[] bs = e.arr; jaroslav@1556: sb.append(string).append(" = ").append(toString(bs)).append("\n"); jaroslav@1556: e = e.next; jaroslav@694: } jaroslav@694: return sb.toString(); jaroslav@694: } jaroslav@694: jaroslav@694: public void assertEquals(ZipArchive zip, String msg) { jaroslav@694: boolean ok = true; jaroslav@694: StringBuilder sb = new StringBuilder(); jaroslav@694: sb.append(msg); jaroslav@1556: Entry e = first; jaroslav@1556: while (e != null) { jaroslav@1556: String string = e.name; jaroslav@1556: byte[] bs = e.arr; jaroslav@1556: byte[] other = zip.find(string); jaroslav@1556: e = e.next; jaroslav@1556: jaroslav@694: sb.append("\n"); jaroslav@694: if (other == null) { jaroslav@1556: sb.append("EXTRA ").append(string).append(" = ").append(toString(bs)); jaroslav@694: ok = false; jaroslav@694: continue; jaroslav@694: } jaroslav@1556: if (equals(bs, other)) { jaroslav@694: sb.append("OK ").append(string); jaroslav@694: continue; jaroslav@694: } else { jaroslav@1556: sb.append("DIFF ").append(string).append(" = ").append(toString(bs)).append("\n"); jaroslav@1556: sb.append(" TO").append(string).append(" = ").append(toString(other)).append("\n"); jaroslav@694: ok = false; jaroslav@694: continue; jaroslav@694: } jaroslav@694: } jaroslav@1556: e = zip.first; jaroslav@1556: while (e != null) { jaroslav@1556: String string = e.name; jaroslav@1556: if (find(string) == null) { jaroslav@1556: sb.append("MISS ").append(string).append(" = ").append(toString(e.arr)); jaroslav@694: ok = false; jaroslav@694: } jaroslav@1556: e = e.next; jaroslav@694: } jaroslav@694: if (!ok) { jaroslav@694: assert false : sb.toString(); jaroslav@694: } jaroslav@694: } jaroslav@694: jaroslav@694: public static void readZip(InputStream is, ZipArchive data) throws IOException { jaroslav@694: ZipInputStream zip = new org.apidesign.bck2brwsr.emul.zip.ZipInputStream(is); jaroslav@694: for (;;) { jaroslav@694: ZipEntry en = zip.getNextEntry(); jaroslav@694: if (en == null) { jaroslav@694: return; jaroslav@694: } jaroslav@694: data.register(en.getName(), zip); jaroslav@694: } jaroslav@694: } jaroslav@694: jaroslav@694: public static void realZip(InputStream is, ZipArchive data) throws IOException { jaroslav@694: java.util.zip.ZipInputStream zip = new java.util.zip.ZipInputStream(is); jaroslav@694: for (;;) { jaroslav@694: ZipEntry en = zip.getNextEntry(); jaroslav@694: if (en == null) { jaroslav@694: return; jaroslav@694: } jaroslav@694: data.register(en.getName(), zip); jaroslav@694: } jaroslav@694: } jaroslav@1556: jaroslav@1556: private byte[] find(String name) { jaroslav@1556: Entry e = first; jaroslav@1556: while (e != null) { jaroslav@1556: if (e.name.equals(name)) { jaroslav@1556: return e.arr; jaroslav@1556: } jaroslav@1556: e = e.next; jaroslav@1556: } jaroslav@1556: return null; jaroslav@1556: } jaroslav@1556: jaroslav@1556: private boolean equals(byte[] bs, byte[] other) { jaroslav@1556: if (bs.length != other.length) { jaroslav@1556: return false; jaroslav@1556: } jaroslav@1556: for (int i = 0; i < bs.length; i++) { jaroslav@1556: if (bs[i] != other[i]) { jaroslav@1556: return false; jaroslav@1556: } jaroslav@1556: } jaroslav@1556: return true; jaroslav@1556: } jaroslav@1556: jaroslav@1556: private Object toString(byte[] arr) { jaroslav@1556: StringBuilder sb = new StringBuilder(); jaroslav@1556: sb.append("["); jaroslav@1556: String sep = ""; jaroslav@1556: for (int i = 0; i < arr.length; i++) { jaroslav@1556: sb.append(sep).append(arr[i]); jaroslav@1556: sep = ", "; jaroslav@1556: } jaroslav@1556: sb.append("]"); jaroslav@1556: return sb.toString(); jaroslav@1556: } jaroslav@1556: jaroslav@1556: private static final class Entry { jaroslav@1556: final String name; jaroslav@1556: final byte[] arr; jaroslav@1556: final Entry next; jaroslav@1556: jaroslav@1556: public Entry(String name, byte[] arr, Entry next) { jaroslav@1556: this.name = name; jaroslav@1556: this.arr = arr; jaroslav@1556: this.next = next; jaroslav@1556: } jaroslav@1556: } jaroslav@694: }