1.1 --- a/dew/src/main/java/org/apidesign/bck2brwsr/dew/Dew.java Tue Feb 19 15:33:32 2013 +0100
1.2 +++ b/dew/src/main/java/org/apidesign/bck2brwsr/dew/Dew.java Tue Feb 19 15:59:27 2013 +0100
1.3 @@ -96,7 +96,9 @@
1.4 }
1.5 if (r.equals("/result.html")) {
1.6 response.setContentType("text/html");
1.7 - response.getOutputBuffer().write(data.getHtml());
1.8 + if (data != null) {
1.9 + response.getOutputBuffer().write(data.getHtml());
1.10 + }
1.11 response.setStatus(HttpStatus.OK_200);
1.12 return;
1.13 }
2.1 --- a/dew/src/main/resources/org/apidesign/bck2brwsr/dew/js/app.js Tue Feb 19 15:33:32 2013 +0100
2.2 +++ b/dew/src/main/resources/org/apidesign/bck2brwsr/dew/js/app.js Tue Feb 19 15:59:27 2013 +0100
2.3 @@ -112,7 +112,7 @@
2.4 " var arr = eval('(' + request.responseText + ')');\n" +
2.5 " return arr;\n" +
2.6 " }\n" +
2.7 -" var vm = new bck2brwsr(ldCls);\n" +
2.8 +" var vm = bck2brwsr(ldCls);\n" +
2.9 " vm.loadClass('${fqn}');\n" +
2.10 " </script>\n" +
2.11 "</body></html>";
3.1 --- a/emul/compact/pom.xml Tue Feb 19 15:33:32 2013 +0100
3.2 +++ b/emul/compact/pom.xml Tue Feb 19 15:59:27 2013 +0100
3.3 @@ -10,7 +10,7 @@
3.4 <groupId>org.apidesign.bck2brwsr</groupId>
3.5 <artifactId>emul</artifactId>
3.6 <version>0.3-SNAPSHOT</version>
3.7 - <name>Compact API Profile</name>
3.8 + <name>Bck2Brwsr API Profile</name>
3.9 <url>http://maven.apache.org</url>
3.10 <properties>
3.11 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3.12 @@ -20,6 +20,7 @@
3.13 <groupId>${project.groupId}</groupId>
3.14 <artifactId>emul.mini</artifactId>
3.15 <version>${project.version}</version>
3.16 + <scope>provided</scope>
3.17 </dependency>
3.18 <dependency>
3.19 <groupId>${project.groupId}</groupId>
3.20 @@ -47,6 +48,25 @@
3.21 <target>1.7</target>
3.22 </configuration>
3.23 </plugin>
3.24 + <plugin>
3.25 + <artifactId>maven-assembly-plugin</artifactId>
3.26 + <version>2.4</version>
3.27 + <executions>
3.28 + <execution>
3.29 + <id>rt</id>
3.30 + <phase>package</phase>
3.31 + <goals>
3.32 + <goal>single</goal>
3.33 + </goals>
3.34 + <configuration>
3.35 + <descriptors>
3.36 + <descriptor>src/main/assembly/rt.xml</descriptor>
3.37 + </descriptors>
3.38 + <finalName>bck2brwsr-${project.version}</finalName>
3.39 + </configuration>
3.40 + </execution>
3.41 + </executions>
3.42 + </plugin>
3.43 </plugins>
3.44 </build>
3.45 </project>
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/emul/compact/src/main/assembly/rt.xml Tue Feb 19 15:59:27 2013 +0100
4.3 @@ -0,0 +1,26 @@
4.4 +<?xml version="1.0"?>
4.5 +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
4.6 + <id>rt</id>
4.7 + <formats>
4.8 + <format>jar</format>
4.9 + </formats>
4.10 + <includeBaseDirectory>false</includeBaseDirectory>
4.11 + <dependencySets>
4.12 + <dependencySet>
4.13 + <useProjectArtifact>true</useProjectArtifact>
4.14 + <unpack>true</unpack>
4.15 + <scope>provided</scope>
4.16 + <unpackOptions>
4.17 + <excludes>
4.18 + <exclude>META-INF/maven/**</exclude>
4.19 + </excludes>
4.20 + </unpackOptions>
4.21 + </dependencySet>
4.22 + </dependencySets>
4.23 + <fileSets>
4.24 + <fileSet>
4.25 + <directory>${project.build.outputDirectory}</directory>
4.26 + <outputDirectory>/</outputDirectory>
4.27 + </fileSet>
4.28 + </fileSets>
4.29 +</assembly>
4.30 \ No newline at end of file
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/emul/compact/src/main/java/java/io/BufferedOutputStream.java Tue Feb 19 15:59:27 2013 +0100
5.3 @@ -0,0 +1,143 @@
5.4 +/*
5.5 + * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5.7 + *
5.8 + * This code is free software; you can redistribute it and/or modify it
5.9 + * under the terms of the GNU General Public License version 2 only, as
5.10 + * published by the Free Software Foundation. Oracle designates this
5.11 + * particular file as subject to the "Classpath" exception as provided
5.12 + * by Oracle in the LICENSE file that accompanied this code.
5.13 + *
5.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
5.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5.17 + * version 2 for more details (a copy is included in the LICENSE file that
5.18 + * accompanied this code).
5.19 + *
5.20 + * You should have received a copy of the GNU General Public License version
5.21 + * 2 along with this work; if not, write to the Free Software Foundation,
5.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5.23 + *
5.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5.25 + * or visit www.oracle.com if you need additional information or have any
5.26 + * questions.
5.27 + */
5.28 +
5.29 +package java.io;
5.30 +
5.31 +/**
5.32 + * The class implements a buffered output stream. By setting up such
5.33 + * an output stream, an application can write bytes to the underlying
5.34 + * output stream without necessarily causing a call to the underlying
5.35 + * system for each byte written.
5.36 + *
5.37 + * @author Arthur van Hoff
5.38 + * @since JDK1.0
5.39 + */
5.40 +public
5.41 +class BufferedOutputStream extends FilterOutputStream {
5.42 + /**
5.43 + * The internal buffer where data is stored.
5.44 + */
5.45 + protected byte buf[];
5.46 +
5.47 + /**
5.48 + * The number of valid bytes in the buffer. This value is always
5.49 + * in the range <tt>0</tt> through <tt>buf.length</tt>; elements
5.50 + * <tt>buf[0]</tt> through <tt>buf[count-1]</tt> contain valid
5.51 + * byte data.
5.52 + */
5.53 + protected int count;
5.54 +
5.55 + /**
5.56 + * Creates a new buffered output stream to write data to the
5.57 + * specified underlying output stream.
5.58 + *
5.59 + * @param out the underlying output stream.
5.60 + */
5.61 + public BufferedOutputStream(OutputStream out) {
5.62 + this(out, 8192);
5.63 + }
5.64 +
5.65 + /**
5.66 + * Creates a new buffered output stream to write data to the
5.67 + * specified underlying output stream with the specified buffer
5.68 + * size.
5.69 + *
5.70 + * @param out the underlying output stream.
5.71 + * @param size the buffer size.
5.72 + * @exception IllegalArgumentException if size <= 0.
5.73 + */
5.74 + public BufferedOutputStream(OutputStream out, int size) {
5.75 + super(out);
5.76 + if (size <= 0) {
5.77 + throw new IllegalArgumentException("Buffer size <= 0");
5.78 + }
5.79 + buf = new byte[size];
5.80 + }
5.81 +
5.82 + /** Flush the internal buffer */
5.83 + private void flushBuffer() throws IOException {
5.84 + if (count > 0) {
5.85 + out.write(buf, 0, count);
5.86 + count = 0;
5.87 + }
5.88 + }
5.89 +
5.90 + /**
5.91 + * Writes the specified byte to this buffered output stream.
5.92 + *
5.93 + * @param b the byte to be written.
5.94 + * @exception IOException if an I/O error occurs.
5.95 + */
5.96 + public synchronized void write(int b) throws IOException {
5.97 + if (count >= buf.length) {
5.98 + flushBuffer();
5.99 + }
5.100 + buf[count++] = (byte)b;
5.101 + }
5.102 +
5.103 + /**
5.104 + * Writes <code>len</code> bytes from the specified byte array
5.105 + * starting at offset <code>off</code> to this buffered output stream.
5.106 + *
5.107 + * <p> Ordinarily this method stores bytes from the given array into this
5.108 + * stream's buffer, flushing the buffer to the underlying output stream as
5.109 + * needed. If the requested length is at least as large as this stream's
5.110 + * buffer, however, then this method will flush the buffer and write the
5.111 + * bytes directly to the underlying output stream. Thus redundant
5.112 + * <code>BufferedOutputStream</code>s will not copy data unnecessarily.
5.113 + *
5.114 + * @param b the data.
5.115 + * @param off the start offset in the data.
5.116 + * @param len the number of bytes to write.
5.117 + * @exception IOException if an I/O error occurs.
5.118 + */
5.119 + public synchronized void write(byte b[], int off, int len) throws IOException {
5.120 + if (len >= buf.length) {
5.121 + /* If the request length exceeds the size of the output buffer,
5.122 + flush the output buffer and then write the data directly.
5.123 + In this way buffered streams will cascade harmlessly. */
5.124 + flushBuffer();
5.125 + out.write(b, off, len);
5.126 + return;
5.127 + }
5.128 + if (len > buf.length - count) {
5.129 + flushBuffer();
5.130 + }
5.131 + System.arraycopy(b, off, buf, count, len);
5.132 + count += len;
5.133 + }
5.134 +
5.135 + /**
5.136 + * Flushes this buffered output stream. This forces any buffered
5.137 + * output bytes to be written out to the underlying output stream.
5.138 + *
5.139 + * @exception IOException if an I/O error occurs.
5.140 + * @see java.io.FilterOutputStream#out
5.141 + */
5.142 + public synchronized void flush() throws IOException {
5.143 + flushBuffer();
5.144 + out.flush();
5.145 + }
5.146 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/emul/compact/src/main/java/java/io/ByteArrayOutputStream.java Tue Feb 19 15:59:27 2013 +0100
6.3 @@ -0,0 +1,272 @@
6.4 +/*
6.5 + * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6.7 + *
6.8 + * This code is free software; you can redistribute it and/or modify it
6.9 + * under the terms of the GNU General Public License version 2 only, as
6.10 + * published by the Free Software Foundation. Oracle designates this
6.11 + * particular file as subject to the "Classpath" exception as provided
6.12 + * by Oracle in the LICENSE file that accompanied this code.
6.13 + *
6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6.17 + * version 2 for more details (a copy is included in the LICENSE file that
6.18 + * accompanied this code).
6.19 + *
6.20 + * You should have received a copy of the GNU General Public License version
6.21 + * 2 along with this work; if not, write to the Free Software Foundation,
6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6.23 + *
6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6.25 + * or visit www.oracle.com if you need additional information or have any
6.26 + * questions.
6.27 + */
6.28 +
6.29 +package java.io;
6.30 +
6.31 +import java.util.Arrays;
6.32 +
6.33 +/**
6.34 + * This class implements an output stream in which the data is
6.35 + * written into a byte array. The buffer automatically grows as data
6.36 + * is written to it.
6.37 + * The data can be retrieved using <code>toByteArray()</code> and
6.38 + * <code>toString()</code>.
6.39 + * <p>
6.40 + * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
6.41 + * this class can be called after the stream has been closed without
6.42 + * generating an <tt>IOException</tt>.
6.43 + *
6.44 + * @author Arthur van Hoff
6.45 + * @since JDK1.0
6.46 + */
6.47 +
6.48 +public class ByteArrayOutputStream extends OutputStream {
6.49 +
6.50 + /**
6.51 + * The buffer where data is stored.
6.52 + */
6.53 + protected byte buf[];
6.54 +
6.55 + /**
6.56 + * The number of valid bytes in the buffer.
6.57 + */
6.58 + protected int count;
6.59 +
6.60 + /**
6.61 + * Creates a new byte array output stream. The buffer capacity is
6.62 + * initially 32 bytes, though its size increases if necessary.
6.63 + */
6.64 + public ByteArrayOutputStream() {
6.65 + this(32);
6.66 + }
6.67 +
6.68 + /**
6.69 + * Creates a new byte array output stream, with a buffer capacity of
6.70 + * the specified size, in bytes.
6.71 + *
6.72 + * @param size the initial size.
6.73 + * @exception IllegalArgumentException if size is negative.
6.74 + */
6.75 + public ByteArrayOutputStream(int size) {
6.76 + if (size < 0) {
6.77 + throw new IllegalArgumentException("Negative initial size: "
6.78 + + size);
6.79 + }
6.80 + buf = new byte[size];
6.81 + }
6.82 +
6.83 + /**
6.84 + * Increases the capacity if necessary to ensure that it can hold
6.85 + * at least the number of elements specified by the minimum
6.86 + * capacity argument.
6.87 + *
6.88 + * @param minCapacity the desired minimum capacity
6.89 + * @throws OutOfMemoryError if {@code minCapacity < 0}. This is
6.90 + * interpreted as a request for the unsatisfiably large capacity
6.91 + * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
6.92 + */
6.93 + private void ensureCapacity(int minCapacity) {
6.94 + // overflow-conscious code
6.95 + if (minCapacity - buf.length > 0)
6.96 + grow(minCapacity);
6.97 + }
6.98 +
6.99 + /**
6.100 + * Increases the capacity to ensure that it can hold at least the
6.101 + * number of elements specified by the minimum capacity argument.
6.102 + *
6.103 + * @param minCapacity the desired minimum capacity
6.104 + */
6.105 + private void grow(int minCapacity) {
6.106 + // overflow-conscious code
6.107 + int oldCapacity = buf.length;
6.108 + int newCapacity = oldCapacity << 1;
6.109 + if (newCapacity - minCapacity < 0)
6.110 + newCapacity = minCapacity;
6.111 + if (newCapacity < 0) {
6.112 + if (minCapacity < 0) // overflow
6.113 + throw new OutOfMemoryError();
6.114 + newCapacity = Integer.MAX_VALUE;
6.115 + }
6.116 + buf = Arrays.copyOf(buf, newCapacity);
6.117 + }
6.118 +
6.119 + /**
6.120 + * Writes the specified byte to this byte array output stream.
6.121 + *
6.122 + * @param b the byte to be written.
6.123 + */
6.124 + public synchronized void write(int b) {
6.125 + ensureCapacity(count + 1);
6.126 + buf[count] = (byte) b;
6.127 + count += 1;
6.128 + }
6.129 +
6.130 + /**
6.131 + * Writes <code>len</code> bytes from the specified byte array
6.132 + * starting at offset <code>off</code> to this byte array output stream.
6.133 + *
6.134 + * @param b the data.
6.135 + * @param off the start offset in the data.
6.136 + * @param len the number of bytes to write.
6.137 + */
6.138 + public synchronized void write(byte b[], int off, int len) {
6.139 + if ((off < 0) || (off > b.length) || (len < 0) ||
6.140 + ((off + len) - b.length > 0)) {
6.141 + throw new IndexOutOfBoundsException();
6.142 + }
6.143 + ensureCapacity(count + len);
6.144 + System.arraycopy(b, off, buf, count, len);
6.145 + count += len;
6.146 + }
6.147 +
6.148 + /**
6.149 + * Writes the complete contents of this byte array output stream to
6.150 + * the specified output stream argument, as if by calling the output
6.151 + * stream's write method using <code>out.write(buf, 0, count)</code>.
6.152 + *
6.153 + * @param out the output stream to which to write the data.
6.154 + * @exception IOException if an I/O error occurs.
6.155 + */
6.156 + public synchronized void writeTo(OutputStream out) throws IOException {
6.157 + out.write(buf, 0, count);
6.158 + }
6.159 +
6.160 + /**
6.161 + * Resets the <code>count</code> field of this byte array output
6.162 + * stream to zero, so that all currently accumulated output in the
6.163 + * output stream is discarded. The output stream can be used again,
6.164 + * reusing the already allocated buffer space.
6.165 + *
6.166 + * @see java.io.ByteArrayInputStream#count
6.167 + */
6.168 + public synchronized void reset() {
6.169 + count = 0;
6.170 + }
6.171 +
6.172 + /**
6.173 + * Creates a newly allocated byte array. Its size is the current
6.174 + * size of this output stream and the valid contents of the buffer
6.175 + * have been copied into it.
6.176 + *
6.177 + * @return the current contents of this output stream, as a byte array.
6.178 + * @see java.io.ByteArrayOutputStream#size()
6.179 + */
6.180 + public synchronized byte toByteArray()[] {
6.181 + return Arrays.copyOf(buf, count);
6.182 + }
6.183 +
6.184 + /**
6.185 + * Returns the current size of the buffer.
6.186 + *
6.187 + * @return the value of the <code>count</code> field, which is the number
6.188 + * of valid bytes in this output stream.
6.189 + * @see java.io.ByteArrayOutputStream#count
6.190 + */
6.191 + public synchronized int size() {
6.192 + return count;
6.193 + }
6.194 +
6.195 + /**
6.196 + * Converts the buffer's contents into a string decoding bytes using the
6.197 + * platform's default character set. The length of the new <tt>String</tt>
6.198 + * is a function of the character set, and hence may not be equal to the
6.199 + * size of the buffer.
6.200 + *
6.201 + * <p> This method always replaces malformed-input and unmappable-character
6.202 + * sequences with the default replacement string for the platform's
6.203 + * default character set. The {@linkplain java.nio.charset.CharsetDecoder}
6.204 + * class should be used when more control over the decoding process is
6.205 + * required.
6.206 + *
6.207 + * @return String decoded from the buffer's contents.
6.208 + * @since JDK1.1
6.209 + */
6.210 + public synchronized String toString() {
6.211 + return new String(buf, 0, count);
6.212 + }
6.213 +
6.214 + /**
6.215 + * Converts the buffer's contents into a string by decoding the bytes using
6.216 + * the specified {@link java.nio.charset.Charset charsetName}. The length of
6.217 + * the new <tt>String</tt> is a function of the charset, and hence may not be
6.218 + * equal to the length of the byte array.
6.219 + *
6.220 + * <p> This method always replaces malformed-input and unmappable-character
6.221 + * sequences with this charset's default replacement string. The {@link
6.222 + * java.nio.charset.CharsetDecoder} class should be used when more control
6.223 + * over the decoding process is required.
6.224 + *
6.225 + * @param charsetName the name of a supported
6.226 + * {@linkplain java.nio.charset.Charset </code>charset<code>}
6.227 + * @return String decoded from the buffer's contents.
6.228 + * @exception UnsupportedEncodingException
6.229 + * If the named charset is not supported
6.230 + * @since JDK1.1
6.231 + */
6.232 + public synchronized String toString(String charsetName)
6.233 + throws UnsupportedEncodingException
6.234 + {
6.235 + return new String(buf, 0, count, charsetName);
6.236 + }
6.237 +
6.238 + /**
6.239 + * Creates a newly allocated string. Its size is the current size of
6.240 + * the output stream and the valid contents of the buffer have been
6.241 + * copied into it. Each character <i>c</i> in the resulting string is
6.242 + * constructed from the corresponding element <i>b</i> in the byte
6.243 + * array such that:
6.244 + * <blockquote><pre>
6.245 + * c == (char)(((hibyte & 0xff) << 8) | (b & 0xff))
6.246 + * </pre></blockquote>
6.247 + *
6.248 + * @deprecated This method does not properly convert bytes into characters.
6.249 + * As of JDK 1.1, the preferred way to do this is via the
6.250 + * <code>toString(String enc)</code> method, which takes an encoding-name
6.251 + * argument, or the <code>toString()</code> method, which uses the
6.252 + * platform's default character encoding.
6.253 + *
6.254 + * @param hibyte the high byte of each resulting Unicode character.
6.255 + * @return the current contents of the output stream, as a string.
6.256 + * @see java.io.ByteArrayOutputStream#size()
6.257 + * @see java.io.ByteArrayOutputStream#toString(String)
6.258 + * @see java.io.ByteArrayOutputStream#toString()
6.259 + */
6.260 + @Deprecated
6.261 + public synchronized String toString(int hibyte) {
6.262 + return new String(buf, hibyte, 0, count);
6.263 + }
6.264 +
6.265 + /**
6.266 + * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
6.267 + * this class can be called after the stream has been closed without
6.268 + * generating an <tt>IOException</tt>.
6.269 + * <p>
6.270 + *
6.271 + */
6.272 + public void close() throws IOException {
6.273 + }
6.274 +
6.275 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/emul/compact/src/main/java/java/util/Objects.java Tue Feb 19 15:59:27 2013 +0100
7.3 @@ -0,0 +1,229 @@
7.4 +/*
7.5 + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7.7 + *
7.8 + * This code is free software; you can redistribute it and/or modify it
7.9 + * under the terms of the GNU General Public License version 2 only, as
7.10 + * published by the Free Software Foundation. Oracle designates this
7.11 + * particular file as subject to the "Classpath" exception as provided
7.12 + * by Oracle in the LICENSE file that accompanied this code.
7.13 + *
7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7.17 + * version 2 for more details (a copy is included in the LICENSE file that
7.18 + * accompanied this code).
7.19 + *
7.20 + * You should have received a copy of the GNU General Public License version
7.21 + * 2 along with this work; if not, write to the Free Software Foundation,
7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7.23 + *
7.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7.25 + * or visit www.oracle.com if you need additional information or have any
7.26 + * questions.
7.27 + */
7.28 +
7.29 +package java.util;
7.30 +
7.31 +/**
7.32 + * This class consists of {@code static} utility methods for operating
7.33 + * on objects. These utilities include {@code null}-safe or {@code
7.34 + * null}-tolerant methods for computing the hash code of an object,
7.35 + * returning a string for an object, and comparing two objects.
7.36 + *
7.37 + * @since 1.7
7.38 + */
7.39 +public final class Objects {
7.40 + private Objects() {
7.41 + throw new AssertionError("No java.util.Objects instances for you!");
7.42 + }
7.43 +
7.44 + /**
7.45 + * Returns {@code true} if the arguments are equal to each other
7.46 + * and {@code false} otherwise.
7.47 + * Consequently, if both arguments are {@code null}, {@code true}
7.48 + * is returned and if exactly one argument is {@code null}, {@code
7.49 + * false} is returned. Otherwise, equality is determined by using
7.50 + * the {@link Object#equals equals} method of the first
7.51 + * argument.
7.52 + *
7.53 + * @param a an object
7.54 + * @param b an object to be compared with {@code a} for equality
7.55 + * @return {@code true} if the arguments are equal to each other
7.56 + * and {@code false} otherwise
7.57 + * @see Object#equals(Object)
7.58 + */
7.59 + public static boolean equals(Object a, Object b) {
7.60 + return (a == b) || (a != null && a.equals(b));
7.61 + }
7.62 +
7.63 + /**
7.64 + * Returns {@code true} if the arguments are deeply equal to each other
7.65 + * and {@code false} otherwise.
7.66 + *
7.67 + * Two {@code null} values are deeply equal. If both arguments are
7.68 + * arrays, the algorithm in {@link Arrays#deepEquals(Object[],
7.69 + * Object[]) Arrays.deepEquals} is used to determine equality.
7.70 + * Otherwise, equality is determined by using the {@link
7.71 + * Object#equals equals} method of the first argument.
7.72 + *
7.73 + * @param a an object
7.74 + * @param b an object to be compared with {@code a} for deep equality
7.75 + * @return {@code true} if the arguments are deeply equal to each other
7.76 + * and {@code false} otherwise
7.77 + * @see Arrays#deepEquals(Object[], Object[])
7.78 + * @see Objects#equals(Object, Object)
7.79 + */
7.80 + public static boolean deepEquals(Object a, Object b) {
7.81 + if (a == b)
7.82 + return true;
7.83 + else if (a == null || b == null)
7.84 + return false;
7.85 + else
7.86 + return Arrays.deepEquals0(a, b);
7.87 + }
7.88 +
7.89 + /**
7.90 + * Returns the hash code of a non-{@code null} argument and 0 for
7.91 + * a {@code null} argument.
7.92 + *
7.93 + * @param o an object
7.94 + * @return the hash code of a non-{@code null} argument and 0 for
7.95 + * a {@code null} argument
7.96 + * @see Object#hashCode
7.97 + */
7.98 + public static int hashCode(Object o) {
7.99 + return o != null ? o.hashCode() : 0;
7.100 + }
7.101 +
7.102 + /**
7.103 + * Generates a hash code for a sequence of input values. The hash
7.104 + * code is generated as if all the input values were placed into an
7.105 + * array, and that array were hashed by calling {@link
7.106 + * Arrays#hashCode(Object[])}.
7.107 + *
7.108 + * <p>This method is useful for implementing {@link
7.109 + * Object#hashCode()} on objects containing multiple fields. For
7.110 + * example, if an object that has three fields, {@code x}, {@code
7.111 + * y}, and {@code z}, one could write:
7.112 + *
7.113 + * <blockquote><pre>
7.114 + * @Override public int hashCode() {
7.115 + * return Objects.hash(x, y, z);
7.116 + * }
7.117 + * </pre></blockquote>
7.118 + *
7.119 + * <b>Warning: When a single object reference is supplied, the returned
7.120 + * value does not equal the hash code of that object reference.</b> This
7.121 + * value can be computed by calling {@link #hashCode(Object)}.
7.122 + *
7.123 + * @param values the values to be hashed
7.124 + * @return a hash value of the sequence of input values
7.125 + * @see Arrays#hashCode(Object[])
7.126 + * @see List#hashCode
7.127 + */
7.128 + public static int hash(Object... values) {
7.129 + return Arrays.hashCode(values);
7.130 + }
7.131 +
7.132 + /**
7.133 + * Returns the result of calling {@code toString} for a non-{@code
7.134 + * null} argument and {@code "null"} for a {@code null} argument.
7.135 + *
7.136 + * @param o an object
7.137 + * @return the result of calling {@code toString} for a non-{@code
7.138 + * null} argument and {@code "null"} for a {@code null} argument
7.139 + * @see Object#toString
7.140 + * @see String#valueOf(Object)
7.141 + */
7.142 + public static String toString(Object o) {
7.143 + return String.valueOf(o);
7.144 + }
7.145 +
7.146 + /**
7.147 + * Returns the result of calling {@code toString} on the first
7.148 + * argument if the first argument is not {@code null} and returns
7.149 + * the second argument otherwise.
7.150 + *
7.151 + * @param o an object
7.152 + * @param nullDefault string to return if the first argument is
7.153 + * {@code null}
7.154 + * @return the result of calling {@code toString} on the first
7.155 + * argument if it is not {@code null} and the second argument
7.156 + * otherwise.
7.157 + * @see Objects#toString(Object)
7.158 + */
7.159 + public static String toString(Object o, String nullDefault) {
7.160 + return (o != null) ? o.toString() : nullDefault;
7.161 + }
7.162 +
7.163 + /**
7.164 + * Returns 0 if the arguments are identical and {@code
7.165 + * c.compare(a, b)} otherwise.
7.166 + * Consequently, if both arguments are {@code null} 0
7.167 + * is returned.
7.168 + *
7.169 + * <p>Note that if one of the arguments is {@code null}, a {@code
7.170 + * NullPointerException} may or may not be thrown depending on
7.171 + * what ordering policy, if any, the {@link Comparator Comparator}
7.172 + * chooses to have for {@code null} values.
7.173 + *
7.174 + * @param <T> the type of the objects being compared
7.175 + * @param a an object
7.176 + * @param b an object to be compared with {@code a}
7.177 + * @param c the {@code Comparator} to compare the first two arguments
7.178 + * @return 0 if the arguments are identical and {@code
7.179 + * c.compare(a, b)} otherwise.
7.180 + * @see Comparable
7.181 + * @see Comparator
7.182 + */
7.183 + public static <T> int compare(T a, T b, Comparator<? super T> c) {
7.184 + return (a == b) ? 0 : c.compare(a, b);
7.185 + }
7.186 +
7.187 + /**
7.188 + * Checks that the specified object reference is not {@code null}. This
7.189 + * method is designed primarily for doing parameter validation in methods
7.190 + * and constructors, as demonstrated below:
7.191 + * <blockquote><pre>
7.192 + * public Foo(Bar bar) {
7.193 + * this.bar = Objects.requireNonNull(bar);
7.194 + * }
7.195 + * </pre></blockquote>
7.196 + *
7.197 + * @param obj the object reference to check for nullity
7.198 + * @param <T> the type of the reference
7.199 + * @return {@code obj} if not {@code null}
7.200 + * @throws NullPointerException if {@code obj} is {@code null}
7.201 + */
7.202 + public static <T> T requireNonNull(T obj) {
7.203 + if (obj == null)
7.204 + throw new NullPointerException();
7.205 + return obj;
7.206 + }
7.207 +
7.208 + /**
7.209 + * Checks that the specified object reference is not {@code null} and
7.210 + * throws a customized {@link NullPointerException} if it is. This method
7.211 + * is designed primarily for doing parameter validation in methods and
7.212 + * constructors with multiple parameters, as demonstrated below:
7.213 + * <blockquote><pre>
7.214 + * public Foo(Bar bar, Baz baz) {
7.215 + * this.bar = Objects.requireNonNull(bar, "bar must not be null");
7.216 + * this.baz = Objects.requireNonNull(baz, "baz must not be null");
7.217 + * }
7.218 + * </pre></blockquote>
7.219 + *
7.220 + * @param obj the object reference to check for nullity
7.221 + * @param message detail message to be used in the event that a {@code
7.222 + * NullPointerException} is thrown
7.223 + * @param <T> the type of the reference
7.224 + * @return {@code obj} if not {@code null}
7.225 + * @throws NullPointerException if {@code obj} is {@code null}
7.226 + */
7.227 + public static <T> T requireNonNull(T obj, String message) {
7.228 + if (obj == null)
7.229 + throw new NullPointerException(message);
7.230 + return obj;
7.231 + }
7.232 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ZipArchive.java Tue Feb 19 15:59:27 2013 +0100
8.3 @@ -0,0 +1,154 @@
8.4 +/**
8.5 + * Back 2 Browser Bytecode Translator
8.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
8.7 + *
8.8 + * This program is free software: you can redistribute it and/or modify
8.9 + * it under the terms of the GNU General Public License as published by
8.10 + * the Free Software Foundation, version 2 of the License.
8.11 + *
8.12 + * This program is distributed in the hope that it will be useful,
8.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8.15 + * GNU General Public License for more details.
8.16 + *
8.17 + * You should have received a copy of the GNU General Public License
8.18 + * along with this program. Look for COPYING file in the top folder.
8.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
8.20 + */
8.21 +package org.apidesign.bck2brwsr.compact.tck;
8.22 +
8.23 +import java.io.ByteArrayOutputStream;
8.24 +import java.io.IOException;
8.25 +import java.io.InputStream;
8.26 +import java.util.Arrays;
8.27 +import java.util.LinkedHashMap;
8.28 +import java.util.Map;
8.29 +import java.util.Objects;
8.30 +import java.util.zip.ZipEntry;
8.31 +import org.apidesign.bck2brwsr.emul.zip.ZipInputStream;
8.32 +
8.33 +/**
8.34 + *
8.35 + * @author Jaroslav Tulach <jtulach@netbeans.org>
8.36 + */
8.37 +final class ZipArchive {
8.38 + private final Map<String, byte[]> entries = new LinkedHashMap<>();
8.39 +
8.40 + public static ZipArchive createZip(InputStream is) throws IOException {
8.41 + ZipArchive a = new ZipArchive();
8.42 + readZip(is, a);
8.43 + return a;
8.44 + }
8.45 +
8.46 + public static ZipArchive createReal(InputStream is) throws IOException {
8.47 + ZipArchive a = new ZipArchive();
8.48 + realZip(is, a);
8.49 + return a;
8.50 + }
8.51 +
8.52 + /**
8.53 + * Registers entry name and data
8.54 + */
8.55 + final void register(String entry, InputStream is) throws IOException {
8.56 + ByteArrayOutputStream os = new ByteArrayOutputStream();
8.57 + for (;;) {
8.58 + int ch = is.read();
8.59 + if (ch == -1) {
8.60 + break;
8.61 + }
8.62 + os.write(ch);
8.63 + }
8.64 + os.close();
8.65 + entries.put(entry, os.toByteArray());
8.66 + }
8.67 +
8.68 + @Override
8.69 + public int hashCode() {
8.70 + return entries.hashCode();
8.71 + }
8.72 +
8.73 + @Override
8.74 + public boolean equals(Object obj) {
8.75 + if (obj == null) {
8.76 + return false;
8.77 + }
8.78 + if (getClass() != obj.getClass()) {
8.79 + return false;
8.80 + }
8.81 + final ZipArchive other = (ZipArchive) obj;
8.82 + if (!Objects.deepEquals(this.entries, other.entries)) {
8.83 + return false;
8.84 + }
8.85 + return true;
8.86 + }
8.87 +
8.88 + @Override
8.89 + public String toString() {
8.90 + StringBuilder sb = new StringBuilder();
8.91 + for (Map.Entry<String, byte[]> en : entries.entrySet()) {
8.92 + String string = en.getKey();
8.93 + byte[] bs = en.getValue();
8.94 + sb.append(string).append(" = ").append(Arrays.toString(bs)).append("\n");
8.95 + }
8.96 + return sb.toString();
8.97 + }
8.98 +
8.99 + public void assertEquals(ZipArchive zip, String msg) {
8.100 + boolean ok = true;
8.101 + StringBuilder sb = new StringBuilder();
8.102 + sb.append(msg);
8.103 + for (Map.Entry<String, byte[]> en : entries.entrySet()) {
8.104 + String string = en.getKey();
8.105 + byte[] bs = en.getValue();
8.106 + byte[] other = zip.entries.get(string);
8.107 + sb.append("\n");
8.108 + if (other == null) {
8.109 + sb.append("EXTRA ").append(string).append(" = ").append(Arrays.toString(bs));
8.110 + ok = false;
8.111 + continue;
8.112 + }
8.113 + if (Arrays.equals(bs, other)) {
8.114 + sb.append("OK ").append(string);
8.115 + continue;
8.116 + } else {
8.117 + sb.append("DIFF ").append(string).append(" = ").append(Arrays.toString(bs)).append("\n");
8.118 + sb.append(" TO").append(string).append(" = ").append(Arrays.toString(other)).append("\n");
8.119 + ok = false;
8.120 + continue;
8.121 + }
8.122 + }
8.123 + for (Map.Entry<String, byte[]> entry : zip.entries.entrySet()) {
8.124 + String string = entry.getKey();
8.125 + if (entries.get(string) == null) {
8.126 + sb.append("MISS ").append(string).append(" = ").append(Arrays.toString(entry.getValue()));
8.127 + ok = false;
8.128 + }
8.129 + }
8.130 + if (!ok) {
8.131 + assert false : sb.toString();
8.132 + }
8.133 + }
8.134 +
8.135 + public static void readZip(InputStream is, ZipArchive data) throws IOException {
8.136 + ZipInputStream zip = new org.apidesign.bck2brwsr.emul.zip.ZipInputStream(is);
8.137 + for (;;) {
8.138 + ZipEntry en = zip.getNextEntry();
8.139 + if (en == null) {
8.140 + return;
8.141 + }
8.142 + data.register(en.getName(), zip);
8.143 + }
8.144 + }
8.145 +
8.146 + public static void realZip(InputStream is, ZipArchive data) throws IOException {
8.147 + java.util.zip.ZipInputStream zip = new java.util.zip.ZipInputStream(is);
8.148 + for (;;) {
8.149 + ZipEntry en = zip.getNextEntry();
8.150 + if (en == null) {
8.151 + return;
8.152 + }
8.153 + data.register(en.getName(), zip);
8.154 + }
8.155 + }
8.156 +
8.157 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ZipCompatibilityTest.java Tue Feb 19 15:59:27 2013 +0100
9.3 @@ -0,0 +1,42 @@
9.4 +/**
9.5 + * Back 2 Browser Bytecode Translator
9.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
9.7 + *
9.8 + * This program is free software: you can redistribute it and/or modify
9.9 + * it under the terms of the GNU General Public License as published by
9.10 + * the Free Software Foundation, version 2 of the License.
9.11 + *
9.12 + * This program is distributed in the hope that it will be useful,
9.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.15 + * GNU General Public License for more details.
9.16 + *
9.17 + * You should have received a copy of the GNU General Public License
9.18 + * along with this program. Look for COPYING file in the top folder.
9.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
9.20 + */
9.21 +package org.apidesign.bck2brwsr.compact.tck;
9.22 +
9.23 +import java.io.IOException;
9.24 +import java.io.InputStream;
9.25 +import org.apidesign.bck2brwsr.vmtest.Compare;
9.26 +import org.apidesign.bck2brwsr.vmtest.VMTest;
9.27 +import org.testng.annotations.Factory;
9.28 +
9.29 +/**
9.30 + *
9.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
9.32 + */
9.33 +public class ZipCompatibilityTest {
9.34 + @Compare
9.35 + public String testDemoStaticCalculator() throws IOException {
9.36 + InputStream is = getClass().getResourceAsStream("demo.static.calculator-0.3-SNAPSHOT.jar");
9.37 + ZipArchive zip = ZipArchive.createZip(is);
9.38 + return zip.toString();
9.39 + }
9.40 +
9.41 + @Factory
9.42 + public static Object[] create() {
9.43 + return VMTest.create(ZipCompatibilityTest.class);
9.44 + }
9.45 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/ZipVsJzLibTest.java Tue Feb 19 15:59:27 2013 +0100
10.3 @@ -0,0 +1,39 @@
10.4 +/**
10.5 + * Back 2 Browser Bytecode Translator
10.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
10.7 + *
10.8 + * This program is free software: you can redistribute it and/or modify
10.9 + * it under the terms of the GNU General Public License as published by
10.10 + * the Free Software Foundation, version 2 of the License.
10.11 + *
10.12 + * This program is distributed in the hope that it will be useful,
10.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.15 + * GNU General Public License for more details.
10.16 + *
10.17 + * You should have received a copy of the GNU General Public License
10.18 + * along with this program. Look for COPYING file in the top folder.
10.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
10.20 + */
10.21 +package org.apidesign.bck2brwsr.compact.tck;
10.22 +
10.23 +import java.io.IOException;
10.24 +import java.io.InputStream;
10.25 +import org.testng.annotations.Test;
10.26 +
10.27 +/**
10.28 + *
10.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
10.30 + */
10.31 +public class ZipVsJzLibTest {
10.32 + @Test public void r() throws IOException {
10.33 + InputStream is = getClass().getResourceAsStream("demo.static.calculator-0.3-SNAPSHOT.jar");
10.34 + ZipArchive zip = ZipArchive.createZip(is);
10.35 +
10.36 + is = getClass().getResourceAsStream("demo.static.calculator-0.3-SNAPSHOT.jar");
10.37 + ZipArchive real = ZipArchive.createReal(is);
10.38 +
10.39 + real.assertEquals(zip, "Are they the same?");
10.40 + }
10.41 +
10.42 +}
11.1 Binary file emul/compact/src/test/resources/org/apidesign/bck2brwsr/compact/tck/demo.static.calculator-0.3-SNAPSHOT.jar has changed
12.1 --- a/emul/mini/pom.xml Tue Feb 19 15:33:32 2013 +0100
12.2 +++ b/emul/mini/pom.xml Tue Feb 19 15:59:27 2013 +0100
12.3 @@ -22,6 +22,12 @@
12.4 <version>0.3-SNAPSHOT</version>
12.5 <type>jar</type>
12.6 </dependency>
12.7 + <dependency>
12.8 + <groupId>org.testng</groupId>
12.9 + <artifactId>testng</artifactId>
12.10 + <version>6.5.2</version>
12.11 + <scope>test</scope>
12.12 + </dependency>
12.13 </dependencies>
12.14 <build>
12.15 <plugins>
13.1 --- a/emul/mini/src/main/java/java/lang/Class.java Tue Feb 19 15:33:32 2013 +0100
13.2 +++ b/emul/mini/src/main/java/java/lang/Class.java Tue Feb 19 15:59:27 2013 +0100
13.3 @@ -231,12 +231,14 @@
13.4 }
13.5
13.6 @JavaScriptBody(args = {"n", "c" }, body =
13.7 - "if (vm[c]) return vm[c].$class;\n"
13.8 - + "if (vm.loadClass) {\n"
13.9 - + " vm.loadClass(n);\n"
13.10 - + " if (vm[c]) return vm[c].$class;\n"
13.11 + "if (!vm[c]) {\n"
13.12 + + " if (vm.loadClass) {\n"
13.13 + + " vm.loadClass(n);\n"
13.14 + + " }\n"
13.15 + + " if (!vm[c]) return null;\n"
13.16 + "}\n"
13.17 - + "return null;"
13.18 + + "vm[c](false);"
13.19 + + "return vm[c].$class;"
13.20 )
13.21 private static native Class<?> loadCls(String n, String c);
13.22
14.1 --- a/emul/mini/src/main/java/java/lang/Object.java Tue Feb 19 15:33:32 2013 +0100
14.2 +++ b/emul/mini/src/main/java/java/lang/Object.java Tue Feb 19 15:59:27 2013 +0100
14.3 @@ -117,7 +117,7 @@
14.4 )
14.5 public native int hashCode();
14.6
14.7 - @JavaScriptBody(args = {}, body = "Math.random() * Math.pow(2, 32);")
14.8 + @JavaScriptBody(args = {}, body = "return Math.random() * Math.pow(2, 32);")
14.9 native int computeHashCode();
14.10
14.11 /**
15.1 --- a/emul/mini/src/main/java/java/lang/String.java Tue Feb 19 15:33:32 2013 +0100
15.2 +++ b/emul/mini/src/main/java/java/lang/String.java Tue Feb 19 15:59:27 2013 +0100
15.3 @@ -335,7 +335,7 @@
15.4 value[i] = (char) (hibyte | (ascii[i + offset] & 0xff));
15.5 }
15.6 }
15.7 - this.r = new String(value, 0, count);
15.8 + initFromCharArray(value, offset, count);
15.9 }
15.10
15.11 /**
16.1 --- a/emul/mini/src/main/java/java/util/zip/Inflater.java Tue Feb 19 15:33:32 2013 +0100
16.2 +++ b/emul/mini/src/main/java/java/util/zip/Inflater.java Tue Feb 19 15:59:27 2013 +0100
16.3 @@ -1,44 +1,30 @@
16.4 -/* Inflater.java - Decompress a data stream
16.5 - Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
16.6 -
16.7 -This file is part of GNU Classpath.
16.8 -
16.9 -GNU Classpath is free software; you can redistribute it and/or modify
16.10 -it under the terms of the GNU General Public License as published by
16.11 -the Free Software Foundation; either version 2, or (at your option)
16.12 -any later version.
16.13 -
16.14 -GNU Classpath is distributed in the hope that it will be useful, but
16.15 -WITHOUT ANY WARRANTY; without even the implied warranty of
16.16 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16.17 -General Public License for more details.
16.18 -
16.19 -You should have received a copy of the GNU General Public License
16.20 -along with GNU Classpath; see the file COPYING. If not, write to the
16.21 -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
16.22 -02111-1307 USA.
16.23 -
16.24 -Linking this library statically or dynamically with other modules is
16.25 -making a combined work based on this library. Thus, the terms and
16.26 -conditions of the GNU General Public License cover the whole
16.27 -combination.
16.28 -
16.29 -As a special exception, the copyright holders of this library give you
16.30 -permission to link this library with independent modules to produce an
16.31 -executable, regardless of the license terms of these independent
16.32 -modules, and to copy and distribute the resulting executable under
16.33 -terms of your choice, provided that you also meet, for each linked
16.34 -independent module, the terms and conditions of the license of that
16.35 -module. An independent module is a module which is not derived from
16.36 -or based on this library. If you modify this library, you may extend
16.37 -this exception to your version of the library, but you are not
16.38 -obligated to do so. If you do not wish to do so, delete this
16.39 -exception statement from your version. */
16.40 +/*
16.41 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
16.42 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
16.43 + *
16.44 + * This code is free software; you can redistribute it and/or modify it
16.45 + * under the terms of the GNU General Public License version 2 only, as
16.46 + * published by the Free Software Foundation. Oracle designates this
16.47 + * particular file as subject to the "Classpath" exception as provided
16.48 + * by Oracle in the LICENSE file that accompanied this code.
16.49 + *
16.50 + * This code is distributed in the hope that it will be useful, but WITHOUT
16.51 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16.52 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16.53 + * version 2 for more details (a copy is included in the LICENSE file that
16.54 + * accompanied this code).
16.55 + *
16.56 + * You should have received a copy of the GNU General Public License version
16.57 + * 2 along with this work; if not, write to the Free Software Foundation,
16.58 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
16.59 + *
16.60 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
16.61 + * or visit www.oracle.com if you need additional information or have any
16.62 + * questions.
16.63 + */
16.64
16.65 package java.util.zip;
16.66
16.67 -import org.apidesign.bck2brwsr.emul.lang.System;
16.68 -
16.69 /**
16.70 * This class provides support for general purpose decompression using the
16.71 * popular ZLIB compression library. The ZLIB compression library was
16.72 @@ -84,1392 +70,241 @@
16.73 * @author David Connelly
16.74 *
16.75 */
16.76 +public
16.77 +class Inflater {
16.78 + private final org.apidesign.bck2brwsr.emul.zip.Inflater impl;
16.79 +
16.80 + /**
16.81 + * Creates a new decompressor. If the parameter 'nowrap' is true then
16.82 + * the ZLIB header and checksum fields will not be used. This provides
16.83 + * compatibility with the compression format used by both GZIP and PKZIP.
16.84 + * <p>
16.85 + * Note: When using the 'nowrap' option it is also necessary to provide
16.86 + * an extra "dummy" byte as input. This is required by the ZLIB native
16.87 + * library in order to support certain optimizations.
16.88 + *
16.89 + * @param nowrap if true then support GZIP compatible compression
16.90 + */
16.91 + public Inflater(boolean nowrap) {
16.92 + if (getClass() == org.apidesign.bck2brwsr.emul.zip.Inflater.class) {
16.93 + impl = null;
16.94 + } else {
16.95 + impl = new org.apidesign.bck2brwsr.emul.zip.Inflater(nowrap);
16.96 + }
16.97 + }
16.98
16.99 -/* Written using on-line Java Platform 1.2 API Specification
16.100 - * and JCL book.
16.101 - * Believed complete and correct.
16.102 - */
16.103 + /**
16.104 + * Creates a new decompressor.
16.105 + */
16.106 + public Inflater() {
16.107 + this(false);
16.108 + }
16.109
16.110 -/**
16.111 - * Inflater is used to decompress data that has been compressed according
16.112 - * to the "deflate" standard described in rfc1950.
16.113 - *
16.114 - * The usage is as following. First you have to set some input with
16.115 - * <code>setInput()</code>, then inflate() it. If inflate doesn't
16.116 - * inflate any bytes there may be three reasons:
16.117 - * <ul>
16.118 - * <li>needsInput() returns true because the input buffer is empty.
16.119 - * You have to provide more input with <code>setInput()</code>.
16.120 - * NOTE: needsInput() also returns true when, the stream is finished.
16.121 - * </li>
16.122 - * <li>needsDictionary() returns true, you have to provide a preset
16.123 - * dictionary with <code>setDictionary()</code>.</li>
16.124 - * <li>finished() returns true, the inflater has finished.</li>
16.125 - * </ul>
16.126 - * Once the first output byte is produced, a dictionary will not be
16.127 - * needed at a later stage.
16.128 - *
16.129 - * @author John Leuner, Jochen Hoenicke
16.130 - * @author Tom Tromey
16.131 - * @date May 17, 1999
16.132 - * @since JDK 1.1
16.133 - */
16.134 -public class Inflater
16.135 -{
16.136 - /* Copy lengths for literal codes 257..285 */
16.137 - private static final int CPLENS[] =
16.138 - {
16.139 - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
16.140 - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
16.141 - };
16.142 -
16.143 - /* Extra bits for literal codes 257..285 */
16.144 - private static final int CPLEXT[] =
16.145 - {
16.146 - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
16.147 - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
16.148 - };
16.149 + /**
16.150 + * Sets input data for decompression. Should be called whenever
16.151 + * needsInput() returns true indicating that more input data is
16.152 + * required.
16.153 + * @param b the input data bytes
16.154 + * @param off the start offset of the input data
16.155 + * @param len the length of the input data
16.156 + * @see Inflater#needsInput
16.157 + */
16.158 + public void setInput(byte[] b, int off, int len) {
16.159 + impl.setInput(b, off, len);
16.160 + }
16.161
16.162 - /* Copy offsets for distance codes 0..29 */
16.163 - private static final int CPDIST[] = {
16.164 - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
16.165 - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
16.166 - 8193, 12289, 16385, 24577
16.167 - };
16.168 -
16.169 - /* Extra bits for distance codes */
16.170 - private static final int CPDEXT[] = {
16.171 - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
16.172 - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
16.173 - 12, 12, 13, 13
16.174 - };
16.175 + /**
16.176 + * Sets input data for decompression. Should be called whenever
16.177 + * needsInput() returns true indicating that more input data is
16.178 + * required.
16.179 + * @param b the input data bytes
16.180 + * @see Inflater#needsInput
16.181 + */
16.182 + public void setInput(byte[] b) {
16.183 + impl.setInput(b);
16.184 + }
16.185
16.186 - /* This are the state in which the inflater can be. */
16.187 - private static final int DECODE_HEADER = 0;
16.188 - private static final int DECODE_DICT = 1;
16.189 - private static final int DECODE_BLOCKS = 2;
16.190 - private static final int DECODE_STORED_LEN1 = 3;
16.191 - private static final int DECODE_STORED_LEN2 = 4;
16.192 - private static final int DECODE_STORED = 5;
16.193 - private static final int DECODE_DYN_HEADER = 6;
16.194 - private static final int DECODE_HUFFMAN = 7;
16.195 - private static final int DECODE_HUFFMAN_LENBITS = 8;
16.196 - private static final int DECODE_HUFFMAN_DIST = 9;
16.197 - private static final int DECODE_HUFFMAN_DISTBITS = 10;
16.198 - private static final int DECODE_CHKSUM = 11;
16.199 - private static final int FINISHED = 12;
16.200 + /**
16.201 + * Sets the preset dictionary to the given array of bytes. Should be
16.202 + * called when inflate() returns 0 and needsDictionary() returns true
16.203 + * indicating that a preset dictionary is required. The method getAdler()
16.204 + * can be used to get the Adler-32 value of the dictionary needed.
16.205 + * @param b the dictionary data bytes
16.206 + * @param off the start offset of the data
16.207 + * @param len the length of the data
16.208 + * @see Inflater#needsDictionary
16.209 + * @see Inflater#getAdler
16.210 + */
16.211 + public void setDictionary(byte[] b, int off, int len) {
16.212 + impl.setDictionary(b, off, len);
16.213 + }
16.214
16.215 - /** This variable contains the current state. */
16.216 - private int mode;
16.217 + /**
16.218 + * Sets the preset dictionary to the given array of bytes. Should be
16.219 + * called when inflate() returns 0 and needsDictionary() returns true
16.220 + * indicating that a preset dictionary is required. The method getAdler()
16.221 + * can be used to get the Adler-32 value of the dictionary needed.
16.222 + * @param b the dictionary data bytes
16.223 + * @see Inflater#needsDictionary
16.224 + * @see Inflater#getAdler
16.225 + */
16.226 + public void setDictionary(byte[] b) {
16.227 + impl.setDictionary(b);
16.228 + }
16.229
16.230 - /**
16.231 - * The adler checksum of the dictionary or of the decompressed
16.232 - * stream, as it is written in the header resp. footer of the
16.233 - * compressed stream. <br>
16.234 - *
16.235 - * Only valid if mode is DECODE_DICT or DECODE_CHKSUM.
16.236 - */
16.237 - private int readAdler;
16.238 - /**
16.239 - * The number of bits needed to complete the current state. This
16.240 - * is valid, if mode is DECODE_DICT, DECODE_CHKSUM,
16.241 - * DECODE_HUFFMAN_LENBITS or DECODE_HUFFMAN_DISTBITS.
16.242 - */
16.243 - private int neededBits;
16.244 - private int repLength, repDist;
16.245 - private int uncomprLen;
16.246 - /**
16.247 - * True, if the last block flag was set in the last block of the
16.248 - * inflated stream. This means that the stream ends after the
16.249 - * current block.
16.250 - */
16.251 - private boolean isLastBlock;
16.252 + /**
16.253 + * Returns the total number of bytes remaining in the input buffer.
16.254 + * This can be used to find out what bytes still remain in the input
16.255 + * buffer after decompression has finished.
16.256 + * @return the total number of bytes remaining in the input buffer
16.257 + */
16.258 + public int getRemaining() {
16.259 + return impl.getRemaining();
16.260 + }
16.261
16.262 - /**
16.263 - * The total number of inflated bytes.
16.264 - */
16.265 - private long totalOut;
16.266 - /**
16.267 - * The total number of bytes set with setInput(). This is not the
16.268 - * value returned by getTotalIn(), since this also includes the
16.269 - * unprocessed input.
16.270 - */
16.271 - private long totalIn;
16.272 - /**
16.273 - * This variable stores the nowrap flag that was given to the constructor.
16.274 - * True means, that the inflated stream doesn't contain a header nor the
16.275 - * checksum in the footer.
16.276 - */
16.277 - private boolean nowrap;
16.278 + /**
16.279 + * Returns true if no data remains in the input buffer. This can
16.280 + * be used to determine if #setInput should be called in order
16.281 + * to provide more input.
16.282 + * @return true if no data remains in the input buffer
16.283 + */
16.284 + public boolean needsInput() {
16.285 + return impl.needsInput();
16.286 + }
16.287
16.288 - private StreamManipulator input;
16.289 - private OutputWindow outputWindow;
16.290 - private InflaterDynHeader dynHeader;
16.291 - private InflaterHuffmanTree litlenTree, distTree;
16.292 - private Adler32 adler;
16.293 + /**
16.294 + * Returns true if a preset dictionary is needed for decompression.
16.295 + * @return true if a preset dictionary is needed for decompression
16.296 + * @see Inflater#setDictionary
16.297 + */
16.298 + public boolean needsDictionary() {
16.299 + return impl.needsDictionary();
16.300 + }
16.301
16.302 - /**
16.303 - * Creates a new inflater.
16.304 - */
16.305 - public Inflater ()
16.306 - {
16.307 - this (false);
16.308 - }
16.309 + /**
16.310 + * Returns true if the end of the compressed data stream has been
16.311 + * reached.
16.312 + * @return true if the end of the compressed data stream has been
16.313 + * reached
16.314 + */
16.315 + public boolean finished() {
16.316 + return impl.finished();
16.317 + }
16.318
16.319 - /**
16.320 - * Creates a new inflater.
16.321 - * @param nowrap true if no header and checksum field appears in the
16.322 - * stream. This is used for GZIPed input. For compatibility with
16.323 - * Sun JDK you should provide one byte of input more than needed in
16.324 - * this case.
16.325 - */
16.326 - public Inflater (boolean nowrap)
16.327 - {
16.328 - this.nowrap = nowrap;
16.329 - this.adler = new Adler32();
16.330 - input = new StreamManipulator();
16.331 - outputWindow = new OutputWindow();
16.332 - mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER;
16.333 - }
16.334 + /**
16.335 + * Uncompresses bytes into specified buffer. Returns actual number
16.336 + * of bytes uncompressed. A return value of 0 indicates that
16.337 + * needsInput() or needsDictionary() should be called in order to
16.338 + * determine if more input data or a preset dictionary is required.
16.339 + * In the latter case, getAdler() can be used to get the Adler-32
16.340 + * value of the dictionary required.
16.341 + * @param b the buffer for the uncompressed data
16.342 + * @param off the start offset of the data
16.343 + * @param len the maximum number of uncompressed bytes
16.344 + * @return the actual number of uncompressed bytes
16.345 + * @exception DataFormatException if the compressed data format is invalid
16.346 + * @see Inflater#needsInput
16.347 + * @see Inflater#needsDictionary
16.348 + */
16.349 + public int inflate(byte[] b, int off, int len)
16.350 + throws DataFormatException
16.351 + {
16.352 + return impl.inflate(b, off, len);
16.353 + }
16.354
16.355 - /**
16.356 - * Finalizes this object.
16.357 - */
16.358 - protected void finalize ()
16.359 - {
16.360 - /* Exists only for compatibility */
16.361 - }
16.362 + /**
16.363 + * Uncompresses bytes into specified buffer. Returns actual number
16.364 + * of bytes uncompressed. A return value of 0 indicates that
16.365 + * needsInput() or needsDictionary() should be called in order to
16.366 + * determine if more input data or a preset dictionary is required.
16.367 + * In the latter case, getAdler() can be used to get the Adler-32
16.368 + * value of the dictionary required.
16.369 + * @param b the buffer for the uncompressed data
16.370 + * @return the actual number of uncompressed bytes
16.371 + * @exception DataFormatException if the compressed data format is invalid
16.372 + * @see Inflater#needsInput
16.373 + * @see Inflater#needsDictionary
16.374 + */
16.375 + public int inflate(byte[] b) throws DataFormatException {
16.376 + return impl.inflate(b);
16.377 + }
16.378
16.379 - /**
16.380 - * Frees all objects allocated by the inflater. There's no reason
16.381 - * to call this, since you can just rely on garbage collection (even
16.382 - * for the Sun implementation). Exists only for compatibility
16.383 - * with Sun's JDK, where the compressor allocates native memory.
16.384 - * If you call any method (even reset) afterwards the behaviour is
16.385 - * <i>undefined</i>.
16.386 - * @deprecated Just clear all references to inflater instead.
16.387 - */
16.388 - public void end ()
16.389 - {
16.390 - outputWindow = null;
16.391 - input = null;
16.392 - dynHeader = null;
16.393 - litlenTree = null;
16.394 - distTree = null;
16.395 - adler = null;
16.396 - }
16.397 + /**
16.398 + * Returns the ADLER-32 value of the uncompressed data.
16.399 + * @return the ADLER-32 value of the uncompressed data
16.400 + */
16.401 + public int getAdler() {
16.402 + return impl.getAdler();
16.403 + }
16.404
16.405 - /**
16.406 - * Returns true, if the inflater has finished. This means, that no
16.407 - * input is needed and no output can be produced.
16.408 - */
16.409 - public boolean finished()
16.410 - {
16.411 - return mode == FINISHED && outputWindow.getAvailable() == 0;
16.412 - }
16.413 + /**
16.414 + * Returns the total number of compressed bytes input so far.
16.415 + *
16.416 + * <p>Since the number of bytes may be greater than
16.417 + * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now
16.418 + * the preferred means of obtaining this information.</p>
16.419 + *
16.420 + * @return the total number of compressed bytes input so far
16.421 + */
16.422 + public int getTotalIn() {
16.423 + return impl.getTotalIn();
16.424 + }
16.425
16.426 - /**
16.427 - * Gets the adler checksum. This is either the checksum of all
16.428 - * uncompressed bytes returned by inflate(), or if needsDictionary()
16.429 - * returns true (and thus no output was yet produced) this is the
16.430 - * adler checksum of the expected dictionary.
16.431 - * @returns the adler checksum.
16.432 - */
16.433 - public int getAdler()
16.434 - {
16.435 - return needsDictionary() ? readAdler : (int) adler.getValue();
16.436 - }
16.437 -
16.438 - /**
16.439 - * Gets the number of unprocessed input. Useful, if the end of the
16.440 - * stream is reached and you want to further process the bytes after
16.441 - * the deflate stream.
16.442 - * @return the number of bytes of the input which were not processed.
16.443 - */
16.444 - public int getRemaining()
16.445 - {
16.446 - return input.getAvailableBytes();
16.447 - }
16.448 -
16.449 - /**
16.450 - * Gets the total number of processed compressed input bytes.
16.451 - * @return the total number of bytes of processed input bytes.
16.452 - */
16.453 - public int getTotalIn()
16.454 - {
16.455 - return (int)getBytesRead();
16.456 - }
16.457 -
16.458 - /**
16.459 - * Gets the total number of output bytes returned by inflate().
16.460 - * @return the total number of output bytes.
16.461 - */
16.462 - public int getTotalOut()
16.463 - {
16.464 - return (int)totalOut;
16.465 - }
16.466 -
16.467 - public long getBytesWritten() {
16.468 - return totalOut;
16.469 - }
16.470 + /**
16.471 + * Returns the total number of compressed bytes input so far.</p>
16.472 + *
16.473 + * @return the total (non-negative) number of compressed bytes input so far
16.474 + * @since 1.5
16.475 + */
16.476 + public long getBytesRead() {
16.477 + return impl.getBytesRead();
16.478 + }
16.479
16.480 - public long getBytesRead() {
16.481 - return totalIn - getRemaining();
16.482 - }
16.483 -
16.484 + /**
16.485 + * Returns the total number of uncompressed bytes output so far.
16.486 + *
16.487 + * <p>Since the number of bytes may be greater than
16.488 + * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now
16.489 + * the preferred means of obtaining this information.</p>
16.490 + *
16.491 + * @return the total number of uncompressed bytes output so far
16.492 + */
16.493 + public int getTotalOut() {
16.494 + return impl.getTotalOut();
16.495 + }
16.496
16.497 - /**
16.498 - * Inflates the compressed stream to the output buffer. If this
16.499 - * returns 0, you should check, whether needsDictionary(),
16.500 - * needsInput() or finished() returns true, to determine why no
16.501 - * further output is produced.
16.502 - * @param buffer the output buffer.
16.503 - * @return the number of bytes written to the buffer, 0 if no further
16.504 - * output can be produced.
16.505 - * @exception DataFormatException if deflated stream is invalid.
16.506 - * @exception IllegalArgumentException if buf has length 0.
16.507 - */
16.508 - public int inflate (byte[] buf) throws DataFormatException
16.509 - {
16.510 - return inflate (buf, 0, buf.length);
16.511 - }
16.512 + /**
16.513 + * Returns the total number of uncompressed bytes output so far.</p>
16.514 + *
16.515 + * @return the total (non-negative) number of uncompressed bytes output so far
16.516 + * @since 1.5
16.517 + */
16.518 + public long getBytesWritten() {
16.519 + return impl.getBytesWritten();
16.520 + }
16.521
16.522 - /**
16.523 - * Inflates the compressed stream to the output buffer. If this
16.524 - * returns 0, you should check, whether needsDictionary(),
16.525 - * needsInput() or finished() returns true, to determine why no
16.526 - * further output is produced.
16.527 - * @param buffer the output buffer.
16.528 - * @param off the offset into buffer where the output should start.
16.529 - * @param len the maximum length of the output.
16.530 - * @return the number of bytes written to the buffer, 0 if no further
16.531 - * output can be produced.
16.532 - * @exception DataFormatException if deflated stream is invalid.
16.533 - * @exception IndexOutOfBoundsException if the off and/or len are wrong.
16.534 - */
16.535 - public int inflate (byte[] buf, int off, int len) throws DataFormatException
16.536 - {
16.537 - /* Special case: len may be zero */
16.538 - if (len == 0)
16.539 - return 0;
16.540 - /* Check for correct buff, off, len triple */
16.541 - if (0 > off || off > off + len || off + len > buf.length)
16.542 - throw new ArrayIndexOutOfBoundsException();
16.543 - int count = 0;
16.544 - int more;
16.545 - do
16.546 - {
16.547 - if (mode != DECODE_CHKSUM)
16.548 - {
16.549 - /* Don't give away any output, if we are waiting for the
16.550 - * checksum in the input stream.
16.551 - *
16.552 - * With this trick we have always:
16.553 - * needsInput() and not finished()
16.554 - * implies more output can be produced.
16.555 - */
16.556 - more = outputWindow.copyOutput(buf, off, len);
16.557 - adler.update(buf, off, more);
16.558 - off += more;
16.559 - count += more;
16.560 - totalOut += more;
16.561 - len -= more;
16.562 - if (len == 0)
16.563 - return count;
16.564 - }
16.565 - }
16.566 - while (decode() || (outputWindow.getAvailable() > 0
16.567 - && mode != DECODE_CHKSUM));
16.568 - return count;
16.569 - }
16.570 + /**
16.571 + * Resets inflater so that a new set of input data can be processed.
16.572 + */
16.573 + public void reset() {
16.574 + impl.reset();
16.575 + }
16.576
16.577 - /**
16.578 - * Returns true, if a preset dictionary is needed to inflate the input.
16.579 - */
16.580 - public boolean needsDictionary ()
16.581 - {
16.582 - return mode == DECODE_DICT && neededBits == 0;
16.583 - }
16.584 + /**
16.585 + * Closes the decompressor and discards any unprocessed input.
16.586 + * This method should be called when the decompressor is no longer
16.587 + * being used, but will also be called automatically by the finalize()
16.588 + * method. Once this method is called, the behavior of the Inflater
16.589 + * object is undefined.
16.590 + */
16.591 + public void end() {
16.592 + impl.end();
16.593 + }
16.594
16.595 - /**
16.596 - * Returns true, if the input buffer is empty.
16.597 - * You should then call setInput(). <br>
16.598 - *
16.599 - * <em>NOTE</em>: This method also returns true when the stream is finished.
16.600 - */
16.601 - public boolean needsInput ()
16.602 - {
16.603 - return input.needsInput ();
16.604 - }
16.605 -
16.606 - /**
16.607 - * Resets the inflater so that a new stream can be decompressed. All
16.608 - * pending input and output will be discarded.
16.609 - */
16.610 - public void reset ()
16.611 - {
16.612 - mode = nowrap ? DECODE_BLOCKS : DECODE_HEADER;
16.613 - totalIn = totalOut = 0;
16.614 - input.reset();
16.615 - outputWindow.reset();
16.616 - dynHeader = null;
16.617 - litlenTree = null;
16.618 - distTree = null;
16.619 - isLastBlock = false;
16.620 - adler.reset();
16.621 - }
16.622 -
16.623 - /**
16.624 - * Sets the preset dictionary. This should only be called, if
16.625 - * needsDictionary() returns true and it should set the same
16.626 - * dictionary, that was used for deflating. The getAdler()
16.627 - * function returns the checksum of the dictionary needed.
16.628 - * @param buffer the dictionary.
16.629 - * @exception IllegalStateException if no dictionary is needed.
16.630 - * @exception IllegalArgumentException if the dictionary checksum is
16.631 - * wrong.
16.632 - */
16.633 - public void setDictionary (byte[] buffer)
16.634 - {
16.635 - setDictionary(buffer, 0, buffer.length);
16.636 - }
16.637 -
16.638 - /**
16.639 - * Sets the preset dictionary. This should only be called, if
16.640 - * needsDictionary() returns true and it should set the same
16.641 - * dictionary, that was used for deflating. The getAdler()
16.642 - * function returns the checksum of the dictionary needed.
16.643 - * @param buffer the dictionary.
16.644 - * @param off the offset into buffer where the dictionary starts.
16.645 - * @param len the length of the dictionary.
16.646 - * @exception IllegalStateException if no dictionary is needed.
16.647 - * @exception IllegalArgumentException if the dictionary checksum is
16.648 - * wrong.
16.649 - * @exception IndexOutOfBoundsException if the off and/or len are wrong.
16.650 - */
16.651 - public void setDictionary (byte[] buffer, int off, int len)
16.652 - {
16.653 - if (!needsDictionary())
16.654 - throw new IllegalStateException();
16.655 -
16.656 - adler.update(buffer, off, len);
16.657 - if ((int) adler.getValue() != readAdler)
16.658 - throw new IllegalArgumentException("Wrong adler checksum");
16.659 - adler.reset();
16.660 - outputWindow.copyDict(buffer, off, len);
16.661 - mode = DECODE_BLOCKS;
16.662 - }
16.663 -
16.664 - /**
16.665 - * Sets the input. This should only be called, if needsInput()
16.666 - * returns true.
16.667 - * @param buffer the input.
16.668 - * @exception IllegalStateException if no input is needed.
16.669 - */
16.670 - public void setInput (byte[] buf)
16.671 - {
16.672 - setInput (buf, 0, buf.length);
16.673 - }
16.674 -
16.675 - /**
16.676 - * Sets the input. This should only be called, if needsInput()
16.677 - * returns true.
16.678 - * @param buffer the input.
16.679 - * @param off the offset into buffer where the input starts.
16.680 - * @param len the length of the input.
16.681 - * @exception IllegalStateException if no input is needed.
16.682 - * @exception IndexOutOfBoundsException if the off and/or len are wrong.
16.683 - */
16.684 - public void setInput (byte[] buf, int off, int len)
16.685 - {
16.686 - input.setInput (buf, off, len);
16.687 - totalIn += len;
16.688 - }
16.689 - private static final int DEFLATED = 8;
16.690 - /**
16.691 - * Decodes the deflate header.
16.692 - * @return false if more input is needed.
16.693 - * @exception DataFormatException if header is invalid.
16.694 - */
16.695 - private boolean decodeHeader () throws DataFormatException
16.696 - {
16.697 - int header = input.peekBits(16);
16.698 - if (header < 0)
16.699 - return false;
16.700 - input.dropBits(16);
16.701 -
16.702 - /* The header is written in "wrong" byte order */
16.703 - header = ((header << 8) | (header >> 8)) & 0xffff;
16.704 - if (header % 31 != 0)
16.705 - throw new DataFormatException("Header checksum illegal");
16.706 -
16.707 - if ((header & 0x0f00) != (DEFLATED << 8))
16.708 - throw new DataFormatException("Compression Method unknown");
16.709 -
16.710 - /* Maximum size of the backwards window in bits.
16.711 - * We currently ignore this, but we could use it to make the
16.712 - * inflater window more space efficient. On the other hand the
16.713 - * full window (15 bits) is needed most times, anyway.
16.714 - int max_wbits = ((header & 0x7000) >> 12) + 8;
16.715 + /**
16.716 + * Closes the decompressor when garbage is collected.
16.717 */
16.718 -
16.719 - if ((header & 0x0020) == 0) // Dictionary flag?
16.720 - {
16.721 - mode = DECODE_BLOCKS;
16.722 - }
16.723 - else
16.724 - {
16.725 - mode = DECODE_DICT;
16.726 - neededBits = 32;
16.727 - }
16.728 - return true;
16.729 - }
16.730 -
16.731 - /**
16.732 - * Decodes the dictionary checksum after the deflate header.
16.733 - * @return false if more input is needed.
16.734 - */
16.735 - private boolean decodeDict ()
16.736 - {
16.737 - while (neededBits > 0)
16.738 - {
16.739 - int dictByte = input.peekBits(8);
16.740 - if (dictByte < 0)
16.741 - return false;
16.742 - input.dropBits(8);
16.743 - readAdler = (readAdler << 8) | dictByte;
16.744 - neededBits -= 8;
16.745 - }
16.746 - return false;
16.747 - }
16.748 -
16.749 - /**
16.750 - * Decodes the huffman encoded symbols in the input stream.
16.751 - * @return false if more input is needed, true if output window is
16.752 - * full or the current block ends.
16.753 - * @exception DataFormatException if deflated stream is invalid.
16.754 - */
16.755 - private boolean decodeHuffman () throws DataFormatException
16.756 - {
16.757 - int free = outputWindow.getFreeSpace();
16.758 - while (free >= 258)
16.759 - {
16.760 - int symbol;
16.761 - switch (mode)
16.762 - {
16.763 - case DECODE_HUFFMAN:
16.764 - /* This is the inner loop so it is optimized a bit */
16.765 - while (((symbol = litlenTree.getSymbol(input)) & ~0xff) == 0)
16.766 - {
16.767 - outputWindow.write(symbol);
16.768 - if (--free < 258)
16.769 - return true;
16.770 - }
16.771 - if (symbol < 257)
16.772 - {
16.773 - if (symbol < 0)
16.774 - return false;
16.775 - else
16.776 - {
16.777 - /* symbol == 256: end of block */
16.778 - distTree = null;
16.779 - litlenTree = null;
16.780 - mode = DECODE_BLOCKS;
16.781 - return true;
16.782 - }
16.783 - }
16.784 -
16.785 - try
16.786 - {
16.787 - repLength = CPLENS[symbol - 257];
16.788 - neededBits = CPLEXT[symbol - 257];
16.789 - }
16.790 - catch (ArrayIndexOutOfBoundsException ex)
16.791 - {
16.792 - throw new DataFormatException("Illegal rep length code");
16.793 - }
16.794 - /* fall through */
16.795 - case DECODE_HUFFMAN_LENBITS:
16.796 - if (neededBits > 0)
16.797 - {
16.798 - mode = DECODE_HUFFMAN_LENBITS;
16.799 - int i = input.peekBits(neededBits);
16.800 - if (i < 0)
16.801 - return false;
16.802 - input.dropBits(neededBits);
16.803 - repLength += i;
16.804 - }
16.805 - mode = DECODE_HUFFMAN_DIST;
16.806 - /* fall through */
16.807 - case DECODE_HUFFMAN_DIST:
16.808 - symbol = distTree.getSymbol(input);
16.809 - if (symbol < 0)
16.810 - return false;
16.811 - try
16.812 - {
16.813 - repDist = CPDIST[symbol];
16.814 - neededBits = CPDEXT[symbol];
16.815 - }
16.816 - catch (ArrayIndexOutOfBoundsException ex)
16.817 - {
16.818 - throw new DataFormatException("Illegal rep dist code");
16.819 - }
16.820 - /* fall through */
16.821 - case DECODE_HUFFMAN_DISTBITS:
16.822 - if (neededBits > 0)
16.823 - {
16.824 - mode = DECODE_HUFFMAN_DISTBITS;
16.825 - int i = input.peekBits(neededBits);
16.826 - if (i < 0)
16.827 - return false;
16.828 - input.dropBits(neededBits);
16.829 - repDist += i;
16.830 - }
16.831 - outputWindow.repeat(repLength, repDist);
16.832 - free -= repLength;
16.833 - mode = DECODE_HUFFMAN;
16.834 - break;
16.835 - default:
16.836 - throw new IllegalStateException();
16.837 - }
16.838 - }
16.839 - return true;
16.840 - }
16.841 -
16.842 - /**
16.843 - * Decodes the adler checksum after the deflate stream.
16.844 - * @return false if more input is needed.
16.845 - * @exception DataFormatException if checksum doesn't match.
16.846 - */
16.847 - private boolean decodeChksum () throws DataFormatException
16.848 - {
16.849 - while (neededBits > 0)
16.850 - {
16.851 - int chkByte = input.peekBits(8);
16.852 - if (chkByte < 0)
16.853 - return false;
16.854 - input.dropBits(8);
16.855 - readAdler = (readAdler << 8) | chkByte;
16.856 - neededBits -= 8;
16.857 - }
16.858 - if ((int) adler.getValue() != readAdler)
16.859 - throw new DataFormatException("Adler chksum doesn't match: "
16.860 - +Integer.toHexString((int)adler.getValue())
16.861 - +" vs. "+Integer.toHexString(readAdler));
16.862 - mode = FINISHED;
16.863 - return false;
16.864 - }
16.865 -
16.866 - /**
16.867 - * Decodes the deflated stream.
16.868 - * @return false if more input is needed, or if finished.
16.869 - * @exception DataFormatException if deflated stream is invalid.
16.870 - */
16.871 - private boolean decode () throws DataFormatException
16.872 - {
16.873 - switch (mode)
16.874 - {
16.875 - case DECODE_HEADER:
16.876 - return decodeHeader();
16.877 - case DECODE_DICT:
16.878 - return decodeDict();
16.879 - case DECODE_CHKSUM:
16.880 - return decodeChksum();
16.881 -
16.882 - case DECODE_BLOCKS:
16.883 - if (isLastBlock)
16.884 - {
16.885 - if (nowrap)
16.886 - {
16.887 - mode = FINISHED;
16.888 - return false;
16.889 - }
16.890 - else
16.891 - {
16.892 - input.skipToByteBoundary();
16.893 - neededBits = 32;
16.894 - mode = DECODE_CHKSUM;
16.895 - return true;
16.896 - }
16.897 - }
16.898 -
16.899 - int type = input.peekBits(3);
16.900 - if (type < 0)
16.901 - return false;
16.902 - input.dropBits(3);
16.903 -
16.904 - if ((type & 1) != 0)
16.905 - isLastBlock = true;
16.906 - switch (type >> 1)
16.907 - {
16.908 - case DeflaterConstants.STORED_BLOCK:
16.909 - input.skipToByteBoundary();
16.910 - mode = DECODE_STORED_LEN1;
16.911 - break;
16.912 - case DeflaterConstants.STATIC_TREES:
16.913 - litlenTree = InflaterHuffmanTree.defLitLenTree;
16.914 - distTree = InflaterHuffmanTree.defDistTree;
16.915 - mode = DECODE_HUFFMAN;
16.916 - break;
16.917 - case DeflaterConstants.DYN_TREES:
16.918 - dynHeader = new InflaterDynHeader();
16.919 - mode = DECODE_DYN_HEADER;
16.920 - break;
16.921 - default:
16.922 - throw new DataFormatException("Unknown block type "+type);
16.923 - }
16.924 - return true;
16.925 -
16.926 - case DECODE_STORED_LEN1:
16.927 - {
16.928 - if ((uncomprLen = input.peekBits(16)) < 0)
16.929 - return false;
16.930 - input.dropBits(16);
16.931 - mode = DECODE_STORED_LEN2;
16.932 - }
16.933 - /* fall through */
16.934 - case DECODE_STORED_LEN2:
16.935 - {
16.936 - int nlen = input.peekBits(16);
16.937 - if (nlen < 0)
16.938 - return false;
16.939 - input.dropBits(16);
16.940 - if (nlen != (uncomprLen ^ 0xffff))
16.941 - throw new DataFormatException("broken uncompressed block");
16.942 - mode = DECODE_STORED;
16.943 - }
16.944 - /* fall through */
16.945 - case DECODE_STORED:
16.946 - {
16.947 - int more = outputWindow.copyStored(input, uncomprLen);
16.948 - uncomprLen -= more;
16.949 - if (uncomprLen == 0)
16.950 - {
16.951 - mode = DECODE_BLOCKS;
16.952 - return true;
16.953 - }
16.954 - return !input.needsInput();
16.955 - }
16.956 -
16.957 - case DECODE_DYN_HEADER:
16.958 - if (!dynHeader.decode(input))
16.959 - return false;
16.960 - litlenTree = dynHeader.buildLitLenTree();
16.961 - distTree = dynHeader.buildDistTree();
16.962 - mode = DECODE_HUFFMAN;
16.963 - /* fall through */
16.964 - case DECODE_HUFFMAN:
16.965 - case DECODE_HUFFMAN_LENBITS:
16.966 - case DECODE_HUFFMAN_DIST:
16.967 - case DECODE_HUFFMAN_DISTBITS:
16.968 - return decodeHuffman();
16.969 - case FINISHED:
16.970 - return false;
16.971 - default:
16.972 - throw new IllegalStateException();
16.973 - }
16.974 - }
16.975 -
16.976 -
16.977 - interface DeflaterConstants {
16.978 - final static boolean DEBUGGING = false;
16.979 -
16.980 - final static int STORED_BLOCK = 0;
16.981 - final static int STATIC_TREES = 1;
16.982 - final static int DYN_TREES = 2;
16.983 - final static int PRESET_DICT = 0x20;
16.984 -
16.985 - final static int DEFAULT_MEM_LEVEL = 8;
16.986 -
16.987 - final static int MAX_MATCH = 258;
16.988 - final static int MIN_MATCH = 3;
16.989 -
16.990 - final static int MAX_WBITS = 15;
16.991 - final static int WSIZE = 1 << MAX_WBITS;
16.992 - final static int WMASK = WSIZE - 1;
16.993 -
16.994 - final static int HASH_BITS = DEFAULT_MEM_LEVEL + 7;
16.995 - final static int HASH_SIZE = 1 << HASH_BITS;
16.996 - final static int HASH_MASK = HASH_SIZE - 1;
16.997 - final static int HASH_SHIFT = (HASH_BITS + MIN_MATCH - 1) / MIN_MATCH;
16.998 -
16.999 - final static int MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1;
16.1000 - final static int MAX_DIST = WSIZE - MIN_LOOKAHEAD;
16.1001 -
16.1002 - final static int PENDING_BUF_SIZE = 1 << (DEFAULT_MEM_LEVEL + 8);
16.1003 - final static int MAX_BLOCK_SIZE = Math.min(65535, PENDING_BUF_SIZE-5);
16.1004 -
16.1005 - final static int DEFLATE_STORED = 0;
16.1006 - final static int DEFLATE_FAST = 1;
16.1007 - final static int DEFLATE_SLOW = 2;
16.1008 -
16.1009 - final static int GOOD_LENGTH[] = { 0,4, 4, 4, 4, 8, 8, 8, 32, 32 };
16.1010 - final static int MAX_LAZY[] = { 0,4, 5, 6, 4,16, 16, 32, 128, 258 };
16.1011 - final static int NICE_LENGTH[] = { 0,8,16,32,16,32,128,128, 258, 258 };
16.1012 - final static int MAX_CHAIN[] = { 0,4, 8,32,16,32,128,256,1024,4096 };
16.1013 - final static int COMPR_FUNC[] = { 0,1, 1, 1, 1, 2, 2, 2, 2, 2 };
16.1014 + protected void finalize() {
16.1015 + end();
16.1016 }
16.1017 - private static class InflaterHuffmanTree {
16.1018 - private final static int MAX_BITLEN = 15;
16.1019 - private short[] tree;
16.1020 -
16.1021 - public static InflaterHuffmanTree defLitLenTree, defDistTree;
16.1022 -
16.1023 - static
16.1024 - {
16.1025 - try
16.1026 - {
16.1027 - byte[] codeLengths = new byte[288];
16.1028 - int i = 0;
16.1029 - while (i < 144)
16.1030 - codeLengths[i++] = 8;
16.1031 - while (i < 256)
16.1032 - codeLengths[i++] = 9;
16.1033 - while (i < 280)
16.1034 - codeLengths[i++] = 7;
16.1035 - while (i < 288)
16.1036 - codeLengths[i++] = 8;
16.1037 - defLitLenTree = new InflaterHuffmanTree(codeLengths);
16.1038 -
16.1039 - codeLengths = new byte[32];
16.1040 - i = 0;
16.1041 - while (i < 32)
16.1042 - codeLengths[i++] = 5;
16.1043 - defDistTree = new InflaterHuffmanTree(codeLengths);
16.1044 - }
16.1045 - catch (DataFormatException ex)
16.1046 - {
16.1047 - throw new IllegalStateException
16.1048 - ("InflaterHuffmanTree: static tree length illegal");
16.1049 - }
16.1050 - }
16.1051 -
16.1052 - /**
16.1053 - * Constructs a Huffman tree from the array of code lengths.
16.1054 - *
16.1055 - * @param codeLengths the array of code lengths
16.1056 - */
16.1057 - public InflaterHuffmanTree(byte[] codeLengths) throws DataFormatException
16.1058 - {
16.1059 - buildTree(codeLengths);
16.1060 - }
16.1061 -
16.1062 - private void buildTree(byte[] codeLengths) throws DataFormatException
16.1063 - {
16.1064 - int[] blCount = new int[MAX_BITLEN+1];
16.1065 - int[] nextCode = new int[MAX_BITLEN+1];
16.1066 - for (int i = 0; i < codeLengths.length; i++)
16.1067 - {
16.1068 - int bits = codeLengths[i];
16.1069 - if (bits > 0)
16.1070 - blCount[bits]++;
16.1071 - }
16.1072 -
16.1073 - int code = 0;
16.1074 - int treeSize = 512;
16.1075 - for (int bits = 1; bits <= MAX_BITLEN; bits++)
16.1076 - {
16.1077 - nextCode[bits] = code;
16.1078 - code += blCount[bits] << (16 - bits);
16.1079 - if (bits >= 10)
16.1080 - {
16.1081 - /* We need an extra table for bit lengths >= 10. */
16.1082 - int start = nextCode[bits] & 0x1ff80;
16.1083 - int end = code & 0x1ff80;
16.1084 - treeSize += (end - start) >> (16 - bits);
16.1085 - }
16.1086 - }
16.1087 - if (code != 65536)
16.1088 - throw new DataFormatException("Code lengths don't add up properly.");
16.1089 -
16.1090 - /* Now create and fill the extra tables from longest to shortest
16.1091 - * bit len. This way the sub trees will be aligned.
16.1092 - */
16.1093 - tree = new short[treeSize];
16.1094 - int treePtr = 512;
16.1095 - for (int bits = MAX_BITLEN; bits >= 10; bits--)
16.1096 - {
16.1097 - int end = code & 0x1ff80;
16.1098 - code -= blCount[bits] << (16 - bits);
16.1099 - int start = code & 0x1ff80;
16.1100 - for (int i = start; i < end; i += 1 << 7)
16.1101 - {
16.1102 - tree[bitReverse(i)]
16.1103 - = (short) ((-treePtr << 4) | bits);
16.1104 - treePtr += 1 << (bits-9);
16.1105 - }
16.1106 - }
16.1107 -
16.1108 - for (int i = 0; i < codeLengths.length; i++)
16.1109 - {
16.1110 - int bits = codeLengths[i];
16.1111 - if (bits == 0)
16.1112 - continue;
16.1113 - code = nextCode[bits];
16.1114 - int revcode = bitReverse(code);
16.1115 - if (bits <= 9)
16.1116 - {
16.1117 - do
16.1118 - {
16.1119 - tree[revcode] = (short) ((i << 4) | bits);
16.1120 - revcode += 1 << bits;
16.1121 - }
16.1122 - while (revcode < 512);
16.1123 - }
16.1124 - else
16.1125 - {
16.1126 - int subTree = tree[revcode & 511];
16.1127 - int treeLen = 1 << (subTree & 15);
16.1128 - subTree = -(subTree >> 4);
16.1129 - do
16.1130 - {
16.1131 - tree[subTree | (revcode >> 9)] = (short) ((i << 4) | bits);
16.1132 - revcode += 1 << bits;
16.1133 - }
16.1134 - while (revcode < treeLen);
16.1135 - }
16.1136 - nextCode[bits] = code + (1 << (16 - bits));
16.1137 - }
16.1138 - }
16.1139 - private final static String bit4Reverse =
16.1140 - "\000\010\004\014\002\012\006\016\001\011\005\015\003\013\007\017";
16.1141 - static short bitReverse(int value) {
16.1142 - return (short) (bit4Reverse.charAt(value & 0xf) << 12
16.1143 - | bit4Reverse.charAt((value >> 4) & 0xf) << 8
16.1144 - | bit4Reverse.charAt((value >> 8) & 0xf) << 4
16.1145 - | bit4Reverse.charAt(value >> 12));
16.1146 - }
16.1147 -
16.1148 - /**
16.1149 - * Reads the next symbol from input. The symbol is encoded using the
16.1150 - * huffman tree.
16.1151 - * @param input the input source.
16.1152 - * @return the next symbol, or -1 if not enough input is available.
16.1153 - */
16.1154 - public int getSymbol(StreamManipulator input) throws DataFormatException
16.1155 - {
16.1156 - int lookahead, symbol;
16.1157 - if ((lookahead = input.peekBits(9)) >= 0)
16.1158 - {
16.1159 - if ((symbol = tree[lookahead]) >= 0)
16.1160 - {
16.1161 - input.dropBits(symbol & 15);
16.1162 - return symbol >> 4;
16.1163 - }
16.1164 - int subtree = -(symbol >> 4);
16.1165 - int bitlen = symbol & 15;
16.1166 - if ((lookahead = input.peekBits(bitlen)) >= 0)
16.1167 - {
16.1168 - symbol = tree[subtree | (lookahead >> 9)];
16.1169 - input.dropBits(symbol & 15);
16.1170 - return symbol >> 4;
16.1171 - }
16.1172 - else
16.1173 - {
16.1174 - int bits = input.getAvailableBits();
16.1175 - lookahead = input.peekBits(bits);
16.1176 - symbol = tree[subtree | (lookahead >> 9)];
16.1177 - if ((symbol & 15) <= bits)
16.1178 - {
16.1179 - input.dropBits(symbol & 15);
16.1180 - return symbol >> 4;
16.1181 - }
16.1182 - else
16.1183 - return -1;
16.1184 - }
16.1185 - }
16.1186 - else
16.1187 - {
16.1188 - int bits = input.getAvailableBits();
16.1189 - lookahead = input.peekBits(bits);
16.1190 - symbol = tree[lookahead];
16.1191 - if (symbol >= 0 && (symbol & 15) <= bits)
16.1192 - {
16.1193 - input.dropBits(symbol & 15);
16.1194 - return symbol >> 4;
16.1195 - }
16.1196 - else
16.1197 - return -1;
16.1198 - }
16.1199 - }
16.1200 - }
16.1201 - private static class InflaterDynHeader
16.1202 - {
16.1203 - private static final int LNUM = 0;
16.1204 - private static final int DNUM = 1;
16.1205 - private static final int BLNUM = 2;
16.1206 - private static final int BLLENS = 3;
16.1207 - private static final int LENS = 4;
16.1208 - private static final int REPS = 5;
16.1209 -
16.1210 - private static final int repMin[] = { 3, 3, 11 };
16.1211 - private static final int repBits[] = { 2, 3, 7 };
16.1212 -
16.1213 -
16.1214 - private byte[] blLens;
16.1215 - private byte[] litdistLens;
16.1216 -
16.1217 - private InflaterHuffmanTree blTree;
16.1218 -
16.1219 - private int mode;
16.1220 - private int lnum, dnum, blnum, num;
16.1221 - private int repSymbol;
16.1222 - private byte lastLen;
16.1223 - private int ptr;
16.1224 -
16.1225 - private static final int[] BL_ORDER =
16.1226 - { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
16.1227 -
16.1228 - public InflaterDynHeader()
16.1229 - {
16.1230 - }
16.1231 -
16.1232 - public boolean decode(StreamManipulator input) throws DataFormatException
16.1233 - {
16.1234 - decode_loop:
16.1235 - for (;;)
16.1236 - {
16.1237 - switch (mode)
16.1238 - {
16.1239 - case LNUM:
16.1240 - lnum = input.peekBits(5);
16.1241 - if (lnum < 0)
16.1242 - return false;
16.1243 - lnum += 257;
16.1244 - input.dropBits(5);
16.1245 - // System.err.println("LNUM: "+lnum);
16.1246 - mode = DNUM;
16.1247 - /* fall through */
16.1248 - case DNUM:
16.1249 - dnum = input.peekBits(5);
16.1250 - if (dnum < 0)
16.1251 - return false;
16.1252 - dnum++;
16.1253 - input.dropBits(5);
16.1254 - // System.err.println("DNUM: "+dnum);
16.1255 - num = lnum+dnum;
16.1256 - litdistLens = new byte[num];
16.1257 - mode = BLNUM;
16.1258 - /* fall through */
16.1259 - case BLNUM:
16.1260 - blnum = input.peekBits(4);
16.1261 - if (blnum < 0)
16.1262 - return false;
16.1263 - blnum += 4;
16.1264 - input.dropBits(4);
16.1265 - blLens = new byte[19];
16.1266 - ptr = 0;
16.1267 - // System.err.println("BLNUM: "+blnum);
16.1268 - mode = BLLENS;
16.1269 - /* fall through */
16.1270 - case BLLENS:
16.1271 - while (ptr < blnum)
16.1272 - {
16.1273 - int len = input.peekBits(3);
16.1274 - if (len < 0)
16.1275 - return false;
16.1276 - input.dropBits(3);
16.1277 - // System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len);
16.1278 - blLens[BL_ORDER[ptr]] = (byte) len;
16.1279 - ptr++;
16.1280 - }
16.1281 - blTree = new InflaterHuffmanTree(blLens);
16.1282 - blLens = null;
16.1283 - ptr = 0;
16.1284 - mode = LENS;
16.1285 - /* fall through */
16.1286 - case LENS:
16.1287 - {
16.1288 - int symbol;
16.1289 - while (((symbol = blTree.getSymbol(input)) & ~15) == 0)
16.1290 - {
16.1291 - /* Normal case: symbol in [0..15] */
16.1292 -
16.1293 - // System.err.println("litdistLens["+ptr+"]: "+symbol);
16.1294 - litdistLens[ptr++] = lastLen = (byte) symbol;
16.1295 -
16.1296 - if (ptr == num)
16.1297 - {
16.1298 - /* Finished */
16.1299 - return true;
16.1300 - }
16.1301 - }
16.1302 -
16.1303 - /* need more input ? */
16.1304 - if (symbol < 0)
16.1305 - return false;
16.1306 -
16.1307 - /* otherwise repeat code */
16.1308 - if (symbol >= 17)
16.1309 - {
16.1310 - /* repeat zero */
16.1311 - // System.err.println("repeating zero");
16.1312 - lastLen = 0;
16.1313 - }
16.1314 - else
16.1315 - {
16.1316 - if (ptr == 0)
16.1317 - throw new DataFormatException();
16.1318 - }
16.1319 - repSymbol = symbol-16;
16.1320 - mode = REPS;
16.1321 - }
16.1322 - /* fall through */
16.1323 -
16.1324 - case REPS:
16.1325 - {
16.1326 - int bits = repBits[repSymbol];
16.1327 - int count = input.peekBits(bits);
16.1328 - if (count < 0)
16.1329 - return false;
16.1330 - input.dropBits(bits);
16.1331 - count += repMin[repSymbol];
16.1332 - // System.err.println("litdistLens repeated: "+count);
16.1333 -
16.1334 - if (ptr + count > num)
16.1335 - throw new DataFormatException();
16.1336 - while (count-- > 0)
16.1337 - litdistLens[ptr++] = lastLen;
16.1338 -
16.1339 - if (ptr == num)
16.1340 - {
16.1341 - /* Finished */
16.1342 - return true;
16.1343 - }
16.1344 - }
16.1345 - mode = LENS;
16.1346 - continue decode_loop;
16.1347 - }
16.1348 - }
16.1349 - }
16.1350 -
16.1351 - public InflaterHuffmanTree buildLitLenTree() throws DataFormatException
16.1352 - {
16.1353 - byte[] litlenLens = new byte[lnum];
16.1354 - System.arraycopy(litdistLens, 0, litlenLens, 0, lnum);
16.1355 - return new InflaterHuffmanTree(litlenLens);
16.1356 - }
16.1357 -
16.1358 - public InflaterHuffmanTree buildDistTree() throws DataFormatException
16.1359 - {
16.1360 - byte[] distLens = new byte[dnum];
16.1361 - System.arraycopy(litdistLens, lnum, distLens, 0, dnum);
16.1362 - return new InflaterHuffmanTree(distLens);
16.1363 - }
16.1364 - }
16.1365 - /**
16.1366 - * This class allows us to retrieve a specified amount of bits from
16.1367 - * the input buffer, as well as copy big byte blocks.
16.1368 - *
16.1369 - * It uses an int buffer to store up to 31 bits for direct
16.1370 - * manipulation. This guarantees that we can get at least 16 bits,
16.1371 - * but we only need at most 15, so this is all safe.
16.1372 - *
16.1373 - * There are some optimizations in this class, for example, you must
16.1374 - * never peek more then 8 bits more than needed, and you must first
16.1375 - * peek bits before you may drop them. This is not a general purpose
16.1376 - * class but optimized for the behaviour of the Inflater.
16.1377 - *
16.1378 - * @author John Leuner, Jochen Hoenicke
16.1379 - */
16.1380 -
16.1381 - private static class StreamManipulator
16.1382 - {
16.1383 - private byte[] window;
16.1384 - private int window_start = 0;
16.1385 - private int window_end = 0;
16.1386 -
16.1387 - private int buffer = 0;
16.1388 - private int bits_in_buffer = 0;
16.1389 -
16.1390 - /**
16.1391 - * Get the next n bits but don't increase input pointer. n must be
16.1392 - * less or equal 16 and if you if this call succeeds, you must drop
16.1393 - * at least n-8 bits in the next call.
16.1394 - *
16.1395 - * @return the value of the bits, or -1 if not enough bits available. */
16.1396 - public final int peekBits(int n)
16.1397 - {
16.1398 - if (bits_in_buffer < n)
16.1399 - {
16.1400 - if (window_start == window_end)
16.1401 - return -1;
16.1402 - buffer |= (window[window_start++] & 0xff
16.1403 - | (window[window_start++] & 0xff) << 8) << bits_in_buffer;
16.1404 - bits_in_buffer += 16;
16.1405 - }
16.1406 - return buffer & ((1 << n) - 1);
16.1407 - }
16.1408 -
16.1409 - /* Drops the next n bits from the input. You should have called peekBits
16.1410 - * with a bigger or equal n before, to make sure that enough bits are in
16.1411 - * the bit buffer.
16.1412 - */
16.1413 - public final void dropBits(int n)
16.1414 - {
16.1415 - buffer >>>= n;
16.1416 - bits_in_buffer -= n;
16.1417 - }
16.1418 -
16.1419 - /**
16.1420 - * Gets the next n bits and increases input pointer. This is equivalent
16.1421 - * to peekBits followed by dropBits, except for correct error handling.
16.1422 - * @return the value of the bits, or -1 if not enough bits available.
16.1423 - */
16.1424 - public final int getBits(int n)
16.1425 - {
16.1426 - int bits = peekBits(n);
16.1427 - if (bits >= 0)
16.1428 - dropBits(n);
16.1429 - return bits;
16.1430 - }
16.1431 - /**
16.1432 - * Gets the number of bits available in the bit buffer. This must be
16.1433 - * only called when a previous peekBits() returned -1.
16.1434 - * @return the number of bits available.
16.1435 - */
16.1436 - public final int getAvailableBits()
16.1437 - {
16.1438 - return bits_in_buffer;
16.1439 - }
16.1440 -
16.1441 - /**
16.1442 - * Gets the number of bytes available.
16.1443 - * @return the number of bytes available.
16.1444 - */
16.1445 - public final int getAvailableBytes()
16.1446 - {
16.1447 - return window_end - window_start + (bits_in_buffer >> 3);
16.1448 - }
16.1449 -
16.1450 - /**
16.1451 - * Skips to the next byte boundary.
16.1452 - */
16.1453 - public void skipToByteBoundary()
16.1454 - {
16.1455 - buffer >>= (bits_in_buffer & 7);
16.1456 - bits_in_buffer &= ~7;
16.1457 - }
16.1458 -
16.1459 - public final boolean needsInput() {
16.1460 - return window_start == window_end;
16.1461 - }
16.1462 -
16.1463 -
16.1464 - /* Copies length bytes from input buffer to output buffer starting
16.1465 - * at output[offset]. You have to make sure, that the buffer is
16.1466 - * byte aligned. If not enough bytes are available, copies fewer
16.1467 - * bytes.
16.1468 - * @param length the length to copy, 0 is allowed.
16.1469 - * @return the number of bytes copied, 0 if no byte is available.
16.1470 - */
16.1471 - public int copyBytes(byte[] output, int offset, int length)
16.1472 - {
16.1473 - if (length < 0)
16.1474 - throw new IllegalArgumentException("length negative");
16.1475 - if ((bits_in_buffer & 7) != 0)
16.1476 - /* bits_in_buffer may only be 0 or 8 */
16.1477 - throw new IllegalStateException("Bit buffer is not aligned!");
16.1478 -
16.1479 - int count = 0;
16.1480 - while (bits_in_buffer > 0 && length > 0)
16.1481 - {
16.1482 - output[offset++] = (byte) buffer;
16.1483 - buffer >>>= 8;
16.1484 - bits_in_buffer -= 8;
16.1485 - length--;
16.1486 - count++;
16.1487 - }
16.1488 - if (length == 0)
16.1489 - return count;
16.1490 -
16.1491 - int avail = window_end - window_start;
16.1492 - if (length > avail)
16.1493 - length = avail;
16.1494 - System.arraycopy(window, window_start, output, offset, length);
16.1495 - window_start += length;
16.1496 -
16.1497 - if (((window_start - window_end) & 1) != 0)
16.1498 - {
16.1499 - /* We always want an even number of bytes in input, see peekBits */
16.1500 - buffer = (window[window_start++] & 0xff);
16.1501 - bits_in_buffer = 8;
16.1502 - }
16.1503 - return count + length;
16.1504 - }
16.1505 -
16.1506 - public StreamManipulator()
16.1507 - {
16.1508 - }
16.1509 -
16.1510 - public void reset()
16.1511 - {
16.1512 - window_start = window_end = buffer = bits_in_buffer = 0;
16.1513 - }
16.1514 -
16.1515 - public void setInput(byte[] buf, int off, int len)
16.1516 - {
16.1517 - if (window_start < window_end)
16.1518 - throw new IllegalStateException
16.1519 - ("Old input was not completely processed");
16.1520 -
16.1521 - int end = off + len;
16.1522 -
16.1523 - /* We want to throw an ArrayIndexOutOfBoundsException early. The
16.1524 - * check is very tricky: it also handles integer wrap around.
16.1525 - */
16.1526 - if (0 > off || off > end || end > buf.length)
16.1527 - throw new ArrayIndexOutOfBoundsException();
16.1528 -
16.1529 - if ((len & 1) != 0)
16.1530 - {
16.1531 - /* We always want an even number of bytes in input, see peekBits */
16.1532 - buffer |= (buf[off++] & 0xff) << bits_in_buffer;
16.1533 - bits_in_buffer += 8;
16.1534 - }
16.1535 -
16.1536 - window = buf;
16.1537 - window_start = off;
16.1538 - window_end = end;
16.1539 - }
16.1540 - }
16.1541 - /*
16.1542 - * Contains the output from the Inflation process.
16.1543 - *
16.1544 - * We need to have a window so that we can refer backwards into the output stream
16.1545 - * to repeat stuff.
16.1546 - *
16.1547 - * @author John Leuner
16.1548 - * @since JDK 1.1
16.1549 - */
16.1550 -
16.1551 - private static class OutputWindow
16.1552 - {
16.1553 - private final int WINDOW_SIZE = 1 << 15;
16.1554 - private final int WINDOW_MASK = WINDOW_SIZE - 1;
16.1555 -
16.1556 - private byte[] window = new byte[WINDOW_SIZE]; //The window is 2^15 bytes
16.1557 - private int window_end = 0;
16.1558 - private int window_filled = 0;
16.1559 -
16.1560 - public void write(int abyte)
16.1561 - {
16.1562 - if (window_filled++ == WINDOW_SIZE)
16.1563 - throw new IllegalStateException("Window full");
16.1564 - window[window_end++] = (byte) abyte;
16.1565 - window_end &= WINDOW_MASK;
16.1566 - }
16.1567 -
16.1568 -
16.1569 - private final void slowRepeat(int rep_start, int len, int dist)
16.1570 - {
16.1571 - while (len-- > 0)
16.1572 - {
16.1573 - window[window_end++] = window[rep_start++];
16.1574 - window_end &= WINDOW_MASK;
16.1575 - rep_start &= WINDOW_MASK;
16.1576 - }
16.1577 - }
16.1578 -
16.1579 - public void repeat(int len, int dist)
16.1580 - {
16.1581 - if ((window_filled += len) > WINDOW_SIZE)
16.1582 - throw new IllegalStateException("Window full");
16.1583 -
16.1584 - int rep_start = (window_end - dist) & WINDOW_MASK;
16.1585 - int border = WINDOW_SIZE - len;
16.1586 - if (rep_start <= border && window_end < border)
16.1587 - {
16.1588 - if (len <= dist)
16.1589 - {
16.1590 - System.arraycopy(window, rep_start, window, window_end, len);
16.1591 - window_end += len;
16.1592 - }
16.1593 - else
16.1594 - {
16.1595 - /* We have to copy manually, since the repeat pattern overlaps.
16.1596 - */
16.1597 - while (len-- > 0)
16.1598 - window[window_end++] = window[rep_start++];
16.1599 - }
16.1600 - }
16.1601 - else
16.1602 - slowRepeat(rep_start, len, dist);
16.1603 - }
16.1604 -
16.1605 - public int copyStored(StreamManipulator input, int len)
16.1606 - {
16.1607 - len = Math.min(Math.min(len, WINDOW_SIZE - window_filled),
16.1608 - input.getAvailableBytes());
16.1609 - int copied;
16.1610 -
16.1611 - int tailLen = WINDOW_SIZE - window_end;
16.1612 - if (len > tailLen)
16.1613 - {
16.1614 - copied = input.copyBytes(window, window_end, tailLen);
16.1615 - if (copied == tailLen)
16.1616 - copied += input.copyBytes(window, 0, len - tailLen);
16.1617 - }
16.1618 - else
16.1619 - copied = input.copyBytes(window, window_end, len);
16.1620 -
16.1621 - window_end = (window_end + copied) & WINDOW_MASK;
16.1622 - window_filled += copied;
16.1623 - return copied;
16.1624 - }
16.1625 -
16.1626 - public void copyDict(byte[] dict, int offset, int len)
16.1627 - {
16.1628 - if (window_filled > 0)
16.1629 - throw new IllegalStateException();
16.1630 -
16.1631 - if (len > WINDOW_SIZE)
16.1632 - {
16.1633 - offset += len - WINDOW_SIZE;
16.1634 - len = WINDOW_SIZE;
16.1635 - }
16.1636 - System.arraycopy(dict, offset, window, 0, len);
16.1637 - window_end = len & WINDOW_MASK;
16.1638 - }
16.1639 -
16.1640 - public int getFreeSpace()
16.1641 - {
16.1642 - return WINDOW_SIZE - window_filled;
16.1643 - }
16.1644 -
16.1645 - public int getAvailable()
16.1646 - {
16.1647 - return window_filled;
16.1648 - }
16.1649 -
16.1650 - public int copyOutput(byte[] output, int offset, int len)
16.1651 - {
16.1652 - int copy_end = window_end;
16.1653 - if (len > window_filled)
16.1654 - len = window_filled;
16.1655 - else
16.1656 - copy_end = (window_end - window_filled + len) & WINDOW_MASK;
16.1657 -
16.1658 - int copied = len;
16.1659 - int tailLen = len - copy_end;
16.1660 -
16.1661 - if (tailLen > 0)
16.1662 - {
16.1663 - System.arraycopy(window, WINDOW_SIZE - tailLen,
16.1664 - output, offset, tailLen);
16.1665 - offset += tailLen;
16.1666 - len = copy_end;
16.1667 - }
16.1668 - System.arraycopy(window, copy_end - len, output, offset, len);
16.1669 - window_filled -= copied;
16.1670 - if (window_filled < 0)
16.1671 - throw new IllegalStateException();
16.1672 - return copied;
16.1673 - }
16.1674 -
16.1675 - public void reset() {
16.1676 - window_filled = window_end = 0;
16.1677 - }
16.1678 - }
16.1679 -
16.1680 }
17.1 --- a/emul/mini/src/main/java/java/util/zip/ZipConstants64.java Tue Feb 19 15:33:32 2013 +0100
17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3 @@ -1,84 +0,0 @@
17.4 -/*
17.5 - * Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved.
17.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
17.7 - *
17.8 - * This code is free software; you can redistribute it and/or modify it
17.9 - * under the terms of the GNU General Public License version 2 only, as
17.10 - * published by the Free Software Foundation. Oracle designates this
17.11 - * particular file as subject to the "Classpath" exception as provided
17.12 - * by Oracle in the LICENSE file that accompanied this code.
17.13 - *
17.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
17.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17.17 - * version 2 for more details (a copy is included in the LICENSE file that
17.18 - * accompanied this code).
17.19 - *
17.20 - * You should have received a copy of the GNU General Public License version
17.21 - * 2 along with this work; if not, write to the Free Software Foundation,
17.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17.23 - *
17.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
17.25 - * or visit www.oracle.com if you need additional information or have any
17.26 - * questions.
17.27 - */
17.28 -
17.29 -package java.util.zip;
17.30 -
17.31 -/*
17.32 - * This class defines the constants that are used by the classes
17.33 - * which manipulate Zip64 files.
17.34 - */
17.35 -
17.36 -class ZipConstants64 {
17.37 -
17.38 - /*
17.39 - * ZIP64 constants
17.40 - */
17.41 - static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006"
17.42 - static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007"
17.43 - static final int ZIP64_ENDHDR = 56; // ZIP64 end header size
17.44 - static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size
17.45 - static final int ZIP64_EXTHDR = 24; // EXT header size
17.46 - static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID
17.47 -
17.48 - static final int ZIP64_MAGICCOUNT = 0xFFFF;
17.49 - static final long ZIP64_MAGICVAL = 0xFFFFFFFFL;
17.50 -
17.51 - /*
17.52 - * Zip64 End of central directory (END) header field offsets
17.53 - */
17.54 - static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir
17.55 - static final int ZIP64_ENDVEM = 12; // version made by
17.56 - static final int ZIP64_ENDVER = 14; // version needed to extract
17.57 - static final int ZIP64_ENDNMD = 16; // number of this disk
17.58 - static final int ZIP64_ENDDSK = 20; // disk number of start
17.59 - static final int ZIP64_ENDTOD = 24; // total number of entries on this disk
17.60 - static final int ZIP64_ENDTOT = 32; // total number of entries
17.61 - static final int ZIP64_ENDSIZ = 40; // central directory size in bytes
17.62 - static final int ZIP64_ENDOFF = 48; // offset of first CEN header
17.63 - static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector
17.64 -
17.65 - /*
17.66 - * Zip64 End of central directory locator field offsets
17.67 - */
17.68 - static final int ZIP64_LOCDSK = 4; // disk number start
17.69 - static final int ZIP64_LOCOFF = 8; // offset of zip64 end
17.70 - static final int ZIP64_LOCTOT = 16; // total number of disks
17.71 -
17.72 - /*
17.73 - * Zip64 Extra local (EXT) header field offsets
17.74 - */
17.75 - static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value
17.76 - static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte
17.77 - static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte
17.78 -
17.79 - /*
17.80 - * Language encoding flag EFS
17.81 - */
17.82 - static final int EFS = 0x800; // If this bit is set the filename and
17.83 - // comment fields for this file must be
17.84 - // encoded using UTF-8.
17.85 -
17.86 - private ZipConstants64() {}
17.87 -}
18.1 --- a/emul/mini/src/main/java/java/util/zip/ZipInputStream.java Tue Feb 19 15:33:32 2013 +0100
18.2 +++ b/emul/mini/src/main/java/java/util/zip/ZipInputStream.java Tue Feb 19 15:59:27 2013 +0100
18.3 @@ -27,10 +27,6 @@
18.4
18.5 import java.io.InputStream;
18.6 import java.io.IOException;
18.7 -import java.io.EOFException;
18.8 -import java.io.PushbackInputStream;
18.9 -import static java.util.zip.ZipConstants64.*;
18.10 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
18.11
18.12 /**
18.13 * This class implements an input stream filter for reading files in the
18.14 @@ -41,28 +37,7 @@
18.15 */
18.16 public
18.17 class ZipInputStream extends InflaterInputStream implements ZipConstants {
18.18 - private ZipEntry entry;
18.19 - private int flag;
18.20 - private CRC32 crc = new CRC32();
18.21 - private long remaining;
18.22 - private byte[] tmpbuf = new byte[512];
18.23 -
18.24 - private static final int STORED = ZipEntry.STORED;
18.25 - private static final int DEFLATED = ZipEntry.DEFLATED;
18.26 -
18.27 - private boolean closed = false;
18.28 - // this flag is set to true after EOF has reached for
18.29 - // one entry
18.30 - private boolean entryEOF = false;
18.31 -
18.32 - /**
18.33 - * Check to make sure that this stream has not been closed
18.34 - */
18.35 - private void ensureOpen() throws IOException {
18.36 - if (closed) {
18.37 - throw new IOException("Stream closed");
18.38 - }
18.39 - }
18.40 + private final org.apidesign.bck2brwsr.emul.zip.ZipInputStream impl;
18.41
18.42 /**
18.43 * Creates a new ZIP input stream.
18.44 @@ -73,12 +48,8 @@
18.45 * @param in the actual input stream
18.46 */
18.47 public ZipInputStream(InputStream in) {
18.48 -// this(in, "UTF-8");
18.49 - super(new PushbackInputStream(in, 512), new Inflater(true), 512);
18.50 - usesDefaultInflater = true;
18.51 - if(in == null) {
18.52 - throw new NullPointerException("in is null");
18.53 - }
18.54 + super(in);
18.55 + impl = new org.apidesign.bck2brwsr.emul.zip.ZipInputStream(in);
18.56 }
18.57
18.58 /**
18.59 @@ -115,20 +86,7 @@
18.60 * @exception IOException if an I/O error has occurred
18.61 */
18.62 public ZipEntry getNextEntry() throws IOException {
18.63 - ensureOpen();
18.64 - if (entry != null) {
18.65 - closeEntry();
18.66 - }
18.67 - crc.reset();
18.68 - inf.reset();
18.69 - if ((entry = readLOC()) == null) {
18.70 - return null;
18.71 - }
18.72 - if (entry.method == STORED) {
18.73 - remaining = entry.size;
18.74 - }
18.75 - entryEOF = false;
18.76 - return entry;
18.77 + return impl.getNextEntry();
18.78 }
18.79
18.80 /**
18.81 @@ -138,9 +96,7 @@
18.82 * @exception IOException if an I/O error has occurred
18.83 */
18.84 public void closeEntry() throws IOException {
18.85 - ensureOpen();
18.86 - while (read(tmpbuf, 0, tmpbuf.length) != -1) ;
18.87 - entryEOF = true;
18.88 + impl.closeEntry();
18.89 }
18.90
18.91 /**
18.92 @@ -155,12 +111,7 @@
18.93 *
18.94 */
18.95 public int available() throws IOException {
18.96 - ensureOpen();
18.97 - if (entryEOF) {
18.98 - return 0;
18.99 - } else {
18.100 - return 1;
18.101 - }
18.102 + return impl.available();
18.103 }
18.104
18.105 /**
18.106 @@ -181,51 +132,7 @@
18.107 * @exception IOException if an I/O error has occurred
18.108 */
18.109 public int read(byte[] b, int off, int len) throws IOException {
18.110 - ensureOpen();
18.111 - if (off < 0 || len < 0 || off > b.length - len) {
18.112 - throw new IndexOutOfBoundsException();
18.113 - } else if (len == 0) {
18.114 - return 0;
18.115 - }
18.116 -
18.117 - if (entry == null) {
18.118 - return -1;
18.119 - }
18.120 - switch (entry.method) {
18.121 - case DEFLATED:
18.122 - len = super.read(b, off, len);
18.123 - if (len == -1) {
18.124 - readEnd(entry);
18.125 - entryEOF = true;
18.126 - entry = null;
18.127 - } else {
18.128 - crc.update(b, off, len);
18.129 - }
18.130 - return len;
18.131 - case STORED:
18.132 - if (remaining <= 0) {
18.133 - entryEOF = true;
18.134 - entry = null;
18.135 - return -1;
18.136 - }
18.137 - if (len > remaining) {
18.138 - len = (int)remaining;
18.139 - }
18.140 - len = in.read(b, off, len);
18.141 - if (len == -1) {
18.142 - throw new ZipException("unexpected EOF");
18.143 - }
18.144 - crc.update(b, off, len);
18.145 - remaining -= len;
18.146 - if (remaining == 0 && entry.crc != crc.getValue()) {
18.147 - throw new ZipException(
18.148 - "invalid entry CRC (expected 0x" + Long.toHexString(entry.crc) +
18.149 - " but got 0x" + Long.toHexString(crc.getValue()) + ")");
18.150 - }
18.151 - return len;
18.152 - default:
18.153 - throw new ZipException("invalid compression method");
18.154 - }
18.155 + return impl.read(b, off, len);
18.156 }
18.157
18.158 /**
18.159 @@ -237,25 +144,7 @@
18.160 * @exception IllegalArgumentException if n < 0
18.161 */
18.162 public long skip(long n) throws IOException {
18.163 - if (n < 0) {
18.164 - throw new IllegalArgumentException("negative skip length");
18.165 - }
18.166 - ensureOpen();
18.167 - int max = (int)Math.min(n, Integer.MAX_VALUE);
18.168 - int total = 0;
18.169 - while (total < max) {
18.170 - int len = max - total;
18.171 - if (len > tmpbuf.length) {
18.172 - len = tmpbuf.length;
18.173 - }
18.174 - len = read(tmpbuf, 0, len);
18.175 - if (len == -1) {
18.176 - entryEOF = true;
18.177 - break;
18.178 - }
18.179 - total += len;
18.180 - }
18.181 - return total;
18.182 + return impl.skip(n);
18.183 }
18.184
18.185 /**
18.186 @@ -264,89 +153,7 @@
18.187 * @exception IOException if an I/O error has occurred
18.188 */
18.189 public void close() throws IOException {
18.190 - if (!closed) {
18.191 - super.close();
18.192 - closed = true;
18.193 - }
18.194 - }
18.195 -
18.196 - private byte[] b = new byte[256];
18.197 -
18.198 - /*
18.199 - * Reads local file (LOC) header for next entry.
18.200 - */
18.201 - private ZipEntry readLOC() throws IOException {
18.202 - try {
18.203 - readFully(tmpbuf, 0, LOCHDR);
18.204 - } catch (EOFException e) {
18.205 - return null;
18.206 - }
18.207 - if (get32(tmpbuf, 0) != LOCSIG) {
18.208 - return null;
18.209 - }
18.210 - // get flag first, we need check EFS.
18.211 - flag = get16(tmpbuf, LOCFLG);
18.212 - // get the entry name and create the ZipEntry first
18.213 - int len = get16(tmpbuf, LOCNAM);
18.214 - int blen = b.length;
18.215 - if (len > blen) {
18.216 - do
18.217 - blen = blen * 2;
18.218 - while (len > blen);
18.219 - b = new byte[blen];
18.220 - }
18.221 - readFully(b, 0, len);
18.222 - // Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8
18.223 - ZipEntry e = createZipEntry(((flag & EFS) != 0)
18.224 - ? toStringUTF8(b, len)
18.225 - : toString(b, len));
18.226 - // now get the remaining fields for the entry
18.227 - if ((flag & 1) == 1) {
18.228 - throw new ZipException("encrypted ZIP entry not supported");
18.229 - }
18.230 - e.method = get16(tmpbuf, LOCHOW);
18.231 - e.time = get32(tmpbuf, LOCTIM);
18.232 - if ((flag & 8) == 8) {
18.233 - /* "Data Descriptor" present */
18.234 - if (e.method != DEFLATED) {
18.235 - throw new ZipException(
18.236 - "only DEFLATED entries can have EXT descriptor");
18.237 - }
18.238 - } else {
18.239 - e.crc = get32(tmpbuf, LOCCRC);
18.240 - e.csize = get32(tmpbuf, LOCSIZ);
18.241 - e.size = get32(tmpbuf, LOCLEN);
18.242 - }
18.243 - len = get16(tmpbuf, LOCEXT);
18.244 - if (len > 0) {
18.245 - byte[] bb = new byte[len];
18.246 - readFully(bb, 0, len);
18.247 - e.setExtra(bb);
18.248 - // extra fields are in "HeaderID(2)DataSize(2)Data... format
18.249 - if (e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL) {
18.250 - int off = 0;
18.251 - while (off + 4 < len) {
18.252 - int sz = get16(bb, off + 2);
18.253 - if (get16(bb, off) == ZIP64_EXTID) {
18.254 - off += 4;
18.255 - // LOC extra zip64 entry MUST include BOTH original and
18.256 - // compressed file size fields
18.257 - if (sz < 16 || (off + sz) > len ) {
18.258 - // Invalid zip64 extra fields, simply skip. Even it's
18.259 - // rare, it's possible the entry size happens to be
18.260 - // the magic value and it "accidnetly" has some bytes
18.261 - // in extra match the id.
18.262 - return e;
18.263 - }
18.264 - e.size = get64(bb, off);
18.265 - e.csize = get64(bb, off + 8);
18.266 - break;
18.267 - }
18.268 - off += (sz + 4);
18.269 - }
18.270 - }
18.271 - }
18.272 - return e;
18.273 + impl.close();
18.274 }
18.275
18.276 /**
18.277 @@ -360,108 +167,28 @@
18.278 return new ZipEntry(name);
18.279 }
18.280
18.281 - /*
18.282 - * Reads end of deflated entry as well as EXT descriptor if present.
18.283 - */
18.284 - private void readEnd(ZipEntry e) throws IOException {
18.285 - int n = inf.getRemaining();
18.286 - if (n > 0) {
18.287 - ((PushbackInputStream)in).unread(buf, len - n, n);
18.288 - }
18.289 - if ((flag & 8) == 8) {
18.290 - /* "Data Descriptor" present */
18.291 - if (inf.getBytesWritten() > ZIP64_MAGICVAL ||
18.292 - inf.getBytesRead() > ZIP64_MAGICVAL) {
18.293 - // ZIP64 format
18.294 - readFully(tmpbuf, 0, ZIP64_EXTHDR);
18.295 - long sig = get32(tmpbuf, 0);
18.296 - if (sig != EXTSIG) { // no EXTSIG present
18.297 - e.crc = sig;
18.298 - e.csize = get64(tmpbuf, ZIP64_EXTSIZ - ZIP64_EXTCRC);
18.299 - e.size = get64(tmpbuf, ZIP64_EXTLEN - ZIP64_EXTCRC);
18.300 - ((PushbackInputStream)in).unread(
18.301 - tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC - 1, ZIP64_EXTCRC);
18.302 - } else {
18.303 - e.crc = get32(tmpbuf, ZIP64_EXTCRC);
18.304 - e.csize = get64(tmpbuf, ZIP64_EXTSIZ);
18.305 - e.size = get64(tmpbuf, ZIP64_EXTLEN);
18.306 - }
18.307 - } else {
18.308 - readFully(tmpbuf, 0, EXTHDR);
18.309 - long sig = get32(tmpbuf, 0);
18.310 - if (sig != EXTSIG) { // no EXTSIG present
18.311 - e.crc = sig;
18.312 - e.csize = get32(tmpbuf, EXTSIZ - EXTCRC);
18.313 - e.size = get32(tmpbuf, EXTLEN - EXTCRC);
18.314 - ((PushbackInputStream)in).unread(
18.315 - tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC);
18.316 - } else {
18.317 - e.crc = get32(tmpbuf, EXTCRC);
18.318 - e.csize = get32(tmpbuf, EXTSIZ);
18.319 - e.size = get32(tmpbuf, EXTLEN);
18.320 - }
18.321 - }
18.322 - }
18.323 - if (e.size != inf.getBytesWritten()) {
18.324 - throw new ZipException(
18.325 - "invalid entry size (expected " + e.size +
18.326 - " but got " + inf.getBytesWritten() + " bytes)");
18.327 - }
18.328 - if (e.csize != inf.getBytesRead()) {
18.329 - throw new ZipException(
18.330 - "invalid entry compressed size (expected " + e.csize +
18.331 - " but got " + inf.getBytesRead() + " bytes)");
18.332 - }
18.333 - if (e.crc != crc.getValue()) {
18.334 - throw new ZipException(
18.335 - "invalid entry CRC (expected 0x" + Long.toHexString(e.crc) +
18.336 - " but got 0x" + Long.toHexString(crc.getValue()) + ")");
18.337 - }
18.338 + @Override
18.339 + public int read() throws IOException {
18.340 + return impl.read();
18.341 }
18.342
18.343 - /*
18.344 - * Reads bytes, blocking until all bytes are read.
18.345 - */
18.346 - private void readFully(byte[] b, int off, int len) throws IOException {
18.347 - while (len > 0) {
18.348 - int n = in.read(b, off, len);
18.349 - if (n == -1) {
18.350 - throw new EOFException();
18.351 - }
18.352 - off += n;
18.353 - len -= n;
18.354 - }
18.355 + @Override
18.356 + public boolean markSupported() {
18.357 + return impl.markSupported();
18.358 }
18.359
18.360 - /*
18.361 - * Fetches unsigned 16-bit value from byte array at specified offset.
18.362 - * The bytes are assumed to be in Intel (little-endian) byte order.
18.363 - */
18.364 - private static final int get16(byte b[], int off) {
18.365 - return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8);
18.366 + @Override
18.367 + public void mark(int readlimit) {
18.368 + impl.mark(readlimit);
18.369 }
18.370
18.371 - /*
18.372 - * Fetches unsigned 32-bit value from byte array at specified offset.
18.373 - * The bytes are assumed to be in Intel (little-endian) byte order.
18.374 - */
18.375 - private static final long get32(byte b[], int off) {
18.376 - return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL;
18.377 + @Override
18.378 + public void reset() throws IOException {
18.379 + impl.reset();
18.380 }
18.381
18.382 - /*
18.383 - * Fetches signed 64-bit value from byte array at specified offset.
18.384 - * The bytes are assumed to be in Intel (little-endian) byte order.
18.385 - */
18.386 - private static final long get64(byte b[], int off) {
18.387 - return get32(b, off) | (get32(b, off+4) << 32);
18.388 - }
18.389 -
18.390 - private static String toStringUTF8(byte[] arr, int len) {
18.391 - return new String(arr, 0, len);
18.392 - }
18.393 -
18.394 - private static String toString(byte[] b, int len) {
18.395 - return new String(b, 0, len);
18.396 + @Override
18.397 + public int read(byte[] b) throws IOException {
18.398 + return impl.read(b);
18.399 }
18.400 }
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/ManifestInputStream.java Tue Feb 19 15:59:27 2013 +0100
19.3 @@ -0,0 +1,228 @@
19.4 +/*
19.5 + * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
19.7 + *
19.8 + * This code is free software; you can redistribute it and/or modify it
19.9 + * under the terms of the GNU General Public License version 2 only, as
19.10 + * published by the Free Software Foundation. Oracle designates this
19.11 + * particular file as subject to the "Classpath" exception as provided
19.12 + * by Oracle in the LICENSE file that accompanied this code.
19.13 + *
19.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
19.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19.17 + * version 2 for more details (a copy is included in the LICENSE file that
19.18 + * accompanied this code).
19.19 + *
19.20 + * You should have received a copy of the GNU General Public License version
19.21 + * 2 along with this work; if not, write to the Free Software Foundation,
19.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19.23 + *
19.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19.25 + * or visit www.oracle.com if you need additional information or have any
19.26 + * questions.
19.27 + */
19.28 +package org.apidesign.bck2brwsr.emul.lang;
19.29 +
19.30 +import java.io.FilterInputStream;
19.31 +import java.io.IOException;
19.32 +import java.io.InputStream;
19.33 +
19.34 +/*
19.35 + * A fast buffered input stream for parsing manifest files.
19.36 + *
19.37 + * Taken from java.util.jar.Manifest.FastInputStream and modified to be
19.38 + * independent of other Manifest functionality.
19.39 + */
19.40 +public abstract class ManifestInputStream extends FilterInputStream {
19.41 + private byte[] buf;
19.42 + private int count = 0;
19.43 + private int pos = 0;
19.44 +
19.45 + protected ManifestInputStream(InputStream in) {
19.46 + this(in, 8192);
19.47 + }
19.48 +
19.49 + protected ManifestInputStream(InputStream in, int size) {
19.50 + super(in);
19.51 + buf = new byte[size];
19.52 + }
19.53 +
19.54 + public int read() throws IOException {
19.55 + if (pos >= count) {
19.56 + fill();
19.57 + if (pos >= count) {
19.58 + return -1;
19.59 + }
19.60 + }
19.61 + return buf[pos++] & 0xff;
19.62 + }
19.63 +
19.64 + public int read(byte[] b, int off, int len) throws IOException {
19.65 + int avail = count - pos;
19.66 + if (avail <= 0) {
19.67 + if (len >= buf.length) {
19.68 + return in.read(b, off, len);
19.69 + }
19.70 + fill();
19.71 + avail = count - pos;
19.72 + if (avail <= 0) {
19.73 + return -1;
19.74 + }
19.75 + }
19.76 + if (len > avail) {
19.77 + len = avail;
19.78 + }
19.79 + System.arraycopy(buf, pos, b, off, len);
19.80 + pos += len;
19.81 + return len;
19.82 + }
19.83 +
19.84 + /*
19.85 + * Reads 'len' bytes from the input stream, or until an end-of-line
19.86 + * is reached. Returns the number of bytes read.
19.87 + */
19.88 + public int readLine(byte[] b, int off, int len) throws IOException {
19.89 + byte[] tbuf = this.buf;
19.90 + int total = 0;
19.91 + while (total < len) {
19.92 + int avail = count - pos;
19.93 + if (avail <= 0) {
19.94 + fill();
19.95 + avail = count - pos;
19.96 + if (avail <= 0) {
19.97 + return -1;
19.98 + }
19.99 + }
19.100 + int n = len - total;
19.101 + if (n > avail) {
19.102 + n = avail;
19.103 + }
19.104 + int tpos = pos;
19.105 + int maxpos = tpos + n;
19.106 + while (tpos < maxpos && tbuf[tpos++] != '\n') {
19.107 + ;
19.108 + }
19.109 + n = tpos - pos;
19.110 + System.arraycopy(tbuf, pos, b, off, n);
19.111 + off += n;
19.112 + total += n;
19.113 + pos = tpos;
19.114 + if (tbuf[tpos - 1] == '\n') {
19.115 + break;
19.116 + }
19.117 + }
19.118 + return total;
19.119 + }
19.120 +
19.121 + public byte peek() throws IOException {
19.122 + if (pos == count) {
19.123 + fill();
19.124 + }
19.125 + if (pos == count) {
19.126 + return -1; // nothing left in buffer
19.127 + }
19.128 + return buf[pos];
19.129 + }
19.130 +
19.131 + public int readLine(byte[] b) throws IOException {
19.132 + return readLine(b, 0, b.length);
19.133 + }
19.134 +
19.135 + public long skip(long n) throws IOException {
19.136 + if (n <= 0) {
19.137 + return 0;
19.138 + }
19.139 + long avail = count - pos;
19.140 + if (avail <= 0) {
19.141 + return in.skip(n);
19.142 + }
19.143 + if (n > avail) {
19.144 + n = avail;
19.145 + }
19.146 + pos += n;
19.147 + return n;
19.148 + }
19.149 +
19.150 + public int available() throws IOException {
19.151 + return (count - pos) + in.available();
19.152 + }
19.153 +
19.154 + public void close() throws IOException {
19.155 + if (in != null) {
19.156 + in.close();
19.157 + in = null;
19.158 + buf = null;
19.159 + }
19.160 + }
19.161 +
19.162 + private void fill() throws IOException {
19.163 + count = pos = 0;
19.164 + int n = in.read(buf, 0, buf.length);
19.165 + if (n > 0) {
19.166 + count = n;
19.167 + }
19.168 + }
19.169 +
19.170 + protected abstract String putValue(String key, String value);
19.171 +
19.172 + public void readAttributes(byte[] lbuf) throws IOException {
19.173 + ManifestInputStream is = this;
19.174 +
19.175 + String name = null;
19.176 + String value = null;
19.177 + byte[] lastline = null;
19.178 + int len;
19.179 + while ((len = is.readLine(lbuf)) != -1) {
19.180 + boolean lineContinued = false;
19.181 + if (lbuf[--len] != '\n') {
19.182 + throw new IOException("line too long");
19.183 + }
19.184 + if (len > 0 && lbuf[len - 1] == '\r') {
19.185 + --len;
19.186 + }
19.187 + if (len == 0) {
19.188 + break;
19.189 + }
19.190 + int i = 0;
19.191 + if (lbuf[0] == ' ') {
19.192 + if (name == null) {
19.193 + throw new IOException("misplaced continuation line");
19.194 + }
19.195 + lineContinued = true;
19.196 + byte[] buf = new byte[lastline.length + len - 1];
19.197 + System.arraycopy(lastline, 0, buf, 0, lastline.length);
19.198 + System.arraycopy(lbuf, 1, buf, lastline.length, len - 1);
19.199 + if (is.peek() == ' ') {
19.200 + lastline = buf;
19.201 + continue;
19.202 + }
19.203 + value = new String(buf, 0, buf.length, "UTF8");
19.204 + lastline = null;
19.205 + } else {
19.206 + while (lbuf[i++] != ':') {
19.207 + if (i >= len) {
19.208 + throw new IOException("invalid header field");
19.209 + }
19.210 + }
19.211 + if (lbuf[i++] != ' ') {
19.212 + throw new IOException("invalid header field");
19.213 + }
19.214 + name = new String(lbuf, 0, 0, i - 2);
19.215 + if (is.peek() == ' ') {
19.216 + lastline = new byte[len - i];
19.217 + System.arraycopy(lbuf, i, lastline, 0, len - i);
19.218 + continue;
19.219 + }
19.220 + value = new String(lbuf, i, len - i, "UTF8");
19.221 + }
19.222 + try {
19.223 + if ((putValue(name, value) != null) && (!lineContinued)) {
19.224 + throw new IOException("Duplicate name in Manifest: " + name + ".\n" + "Ensure that the manifest does not " + "have duplicate entries, and\n" + "that blank lines separate " + "individual sections in both your\n" + "manifest and in the META-INF/MANIFEST.MF " + "entry in the jar file.");
19.225 + }
19.226 + } catch (IllegalArgumentException e) {
19.227 + throw new IOException("invalid header field name: " + name);
19.228 + }
19.229 + }
19.230 + }
19.231 +}
20.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Tue Feb 19 15:33:32 2013 +0100
20.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Tue Feb 19 15:59:27 2013 +0100
20.3 @@ -17,6 +17,7 @@
20.4 */
20.5 package org.apidesign.bck2brwsr.emul.lang;
20.6
20.7 +import java.lang.reflect.Method;
20.8 import org.apidesign.bck2brwsr.core.JavaScriptBody;
20.9
20.10 /**
20.11 @@ -38,7 +39,15 @@
20.12 " }\n" +
20.13 "}"
20.14 )
20.15 - public static native void arraycopy(Object value, int srcBegin, Object dst, int dstBegin, int count);
20.16 + public static void arraycopy(Object src, int srcBegin, Object dst, int dstBegin, int count) {
20.17 + try {
20.18 + Class<?> system = Class.forName("java.lang.System");
20.19 + Method m = system.getMethod("arraycopy", Object.class, int.class, Object.class, int.class, int.class);
20.20 + m.invoke(null, src, srcBegin, dst, dstBegin, count);
20.21 + } catch (Exception ex) {
20.22 + throw new IllegalStateException(ex);
20.23 + }
20.24 + }
20.25
20.26 @JavaScriptBody(args = { "arr", "expectedSize" }, body =
20.27 "while (expectedSize-- > arr.length) { arr.push(0); }; return arr;"
20.28 @@ -53,5 +62,4 @@
20.29 }
20.30 @JavaScriptBody(args = { "obj" }, body="return vm.java_lang_Object(false).hashCode__I.call(obj);")
20.31 public static native int identityHashCode(Object obj);
20.32 -
20.33 }
21.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/AnnotationImpl.java Tue Feb 19 15:33:32 2013 +0100
21.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/AnnotationImpl.java Tue Feb 19 15:59:27 2013 +0100
21.3 @@ -18,6 +18,8 @@
21.4 package org.apidesign.bck2brwsr.emul.reflect;
21.5
21.6 import java.lang.annotation.Annotation;
21.7 +import java.lang.reflect.Method;
21.8 +import java.lang.reflect.Modifier;
21.9 import org.apidesign.bck2brwsr.core.JavaScriptBody;
21.10
21.11 /**
21.12 @@ -25,39 +27,73 @@
21.13 * @author Jaroslav Tulach <jtulach@netbeans.org>
21.14 */
21.15 public final class AnnotationImpl implements Annotation {
21.16 + private final Class<? extends Annotation> type;
21.17 +
21.18 + public AnnotationImpl(Class<? extends Annotation> type) {
21.19 + this.type = type;
21.20 + }
21.21 +
21.22 public Class<? extends Annotation> annotationType() {
21.23 - return getClass();
21.24 + return type;
21.25 }
21.26
21.27 - @JavaScriptBody(args = { "a", "n", "values" }, body = ""
21.28 - + "function f(v, p) {\n"
21.29 - + " var val = v;\n"
21.30 - + " var prop = p;\n"
21.31 + @JavaScriptBody(args = { "a", "n", "arr", "values" }, body = ""
21.32 + + "function f(val, prop, clazz) {\n"
21.33 + " return function() {\n"
21.34 - + " return val[prop];\n"
21.35 + + " if (clazz == null) return val[prop];\n"
21.36 + + " if (clazz.isArray__Z()) {\n"
21.37 + + " var valarr = val[prop];\n"
21.38 + + " var cmp = clazz.getComponentType__Ljava_lang_Class_2();\n"
21.39 + + " var retarr = vm.java_lang_reflect_Array(false).newInstance__Ljava_lang_Object_2Ljava_lang_Class_2I(cmp, valarr.length);\n"
21.40 + + " for (var i = 0; i < valarr.length; i++) {\n"
21.41 + + " retarr[i] = CLS.prototype.c__Ljava_lang_Object_2Ljava_lang_Class_2Ljava_lang_Object_2(cmp, valarr[i]);\n"
21.42 + + " }\n"
21.43 + + " return retarr;\n"
21.44 + + " }\n"
21.45 + + " return CLS.prototype.c__Ljava_lang_Object_2Ljava_lang_Class_2Ljava_lang_Object_2(clazz, val[prop]);\n"
21.46 + " };\n"
21.47 + "}\n"
21.48 - + "var props = Object.getOwnPropertyNames(values);\n"
21.49 - + "for (var i = 0; i < props.length; i++) {\n"
21.50 - + " var p = props[i];\n"
21.51 - + " a[p] = new f(values, p);\n"
21.52 + + "for (var i = 0; i < arr.length; i += 3) {\n"
21.53 + + " var m = arr[i];\n"
21.54 + + " var p = arr[i + 1];\n"
21.55 + + " var c = arr[i + 2];\n"
21.56 + + " a[m] = f(values, p, c);\n"
21.57 + "}\n"
21.58 + "a['$instOf_' + n] = true;\n"
21.59 + "return a;"
21.60 )
21.61 - private static <T extends Annotation> T create(AnnotationImpl a, String n, Object values) {
21.62 - return null;
21.63 + private static native <T extends Annotation> T create(
21.64 + AnnotationImpl a, String n, Object[] methodsAndProps, Object values
21.65 + );
21.66 +
21.67 + private static Object c(Class<? extends Annotation> a, Object v) {
21.68 + return create(a, v);
21.69 }
21.70 +
21.71 public static <T extends Annotation> T create(Class<T> annoClass, Object values) {
21.72 - return create(new AnnotationImpl(), annoClass.getName().replace('.', '_'), values);
21.73 + return create(new AnnotationImpl(annoClass),
21.74 + annoClass.getName().replace('.', '_'),
21.75 + findProps(annoClass), values
21.76 + );
21.77 }
21.78
21.79 public static Annotation[] create(Object anno) {
21.80 String[] names = findNames(anno);
21.81 Annotation[] ret = new Annotation[names.length];
21.82 for (int i = 0; i < names.length; i++) {
21.83 - String n = names[i].substring(1, names[i].length() - 1).replace('/', '_');
21.84 - ret[i] = create(new AnnotationImpl(), n, findData(anno, names[i]));
21.85 + String annoNameSlash = names[i].substring(1, names[i].length() - 1);
21.86 + Class<? extends Annotation> annoClass;
21.87 + try {
21.88 + annoClass = (Class<? extends Annotation>)Class.forName(annoNameSlash.replace('/', '.'));
21.89 + } catch (ClassNotFoundException ex) {
21.90 + throw new IllegalStateException("Can't find annotation class " + annoNameSlash);
21.91 + }
21.92 + ret[i] = create(
21.93 + new AnnotationImpl(annoClass),
21.94 + annoNameSlash.replace('/', '_'),
21.95 + findProps(annoClass),
21.96 + findData(anno, names[i])
21.97 + );
21.98 }
21.99 return ret;
21.100 }
21.101 @@ -70,12 +106,25 @@
21.102 + "}"
21.103 + "return arr;"
21.104 )
21.105 - private static String[] findNames(Object anno) {
21.106 - throw new UnsupportedOperationException();
21.107 - }
21.108 + private static native String[] findNames(Object anno);
21.109
21.110 @JavaScriptBody(args={ "anno", "p"}, body="return anno[p];")
21.111 - private static Object findData(Object anno, String p) {
21.112 - throw new UnsupportedOperationException();
21.113 + private static native Object findData(Object anno, String p);
21.114 +
21.115 + private static Object[] findProps(Class<?> annoClass) {
21.116 + final Method[] marr = MethodImpl.findMethods(annoClass, Modifier.PUBLIC);
21.117 + Object[] arr = new Object[marr.length * 3];
21.118 + int pos = 0;
21.119 + for (Method m : marr) {
21.120 + arr[pos++] = MethodImpl.toSignature(m);
21.121 + arr[pos++] = m.getName();
21.122 + final Class<?> rt = m.getReturnType();
21.123 + if (rt.isArray()) {
21.124 + arr[pos++] = rt.getComponentType().isAnnotation() ? rt : null;
21.125 + } else {
21.126 + arr[pos++] = rt.isAnnotation() ? rt : null;
21.127 + }
21.128 + }
21.129 + return arr;
21.130 }
21.131 }
22.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java Tue Feb 19 15:33:32 2013 +0100
22.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/reflect/MethodImpl.java Tue Feb 19 15:59:27 2013 +0100
22.3 @@ -17,6 +17,7 @@
22.4 */
22.5 package org.apidesign.bck2brwsr.emul.reflect;
22.6
22.7 +import java.lang.reflect.Array;
22.8 import java.lang.reflect.Method;
22.9 import java.util.Enumeration;
22.10 import org.apidesign.bck2brwsr.core.JavaScriptBody;
22.11 @@ -34,7 +35,7 @@
22.12 throw new IllegalStateException(ex);
22.13 }
22.14 }
22.15 -
22.16 +
22.17 protected abstract Method create(Class<?> declaringClass, String name, Object data, String sig);
22.18
22.19
22.20 @@ -48,8 +49,10 @@
22.21 + "var arr = new Array();\n"
22.22 + "for (m in c) {\n"
22.23 + " if (m.indexOf(prefix) === 0) {\n"
22.24 + + " if (!c[m].cls) continue;\n"
22.25 + " arr.push(m);\n"
22.26 + " arr.push(c[m]);\n"
22.27 + + " arr.push(c[m].cls.$class);\n"
22.28 + " }"
22.29 + "}\n"
22.30 + "return arr;")
22.31 @@ -59,9 +62,10 @@
22.32 public static Method findMethod(
22.33 Class<?> clazz, String name, Class<?>... parameterTypes) {
22.34 Object[] data = findMethodData(clazz, name + "__");
22.35 - BIG: for (int i = 0; i < data.length; i += 2) {
22.36 - String sig = ((String) data[0]).substring(name.length() + 2);
22.37 - Method tmp = INSTANCE.create(clazz, name, data[1], sig);
22.38 + BIG: for (int i = 0; i < data.length; i += 3) {
22.39 + String sig = ((String) data[i]).substring(name.length() + 2);
22.40 + Class<?> cls = (Class<?>) data[i + 2];
22.41 + Method tmp = INSTANCE.create(cls, name, data[i + 1], sig);
22.42 Class<?>[] tmpParms = tmp.getParameterTypes();
22.43 if (parameterTypes.length != tmpParms.length) {
22.44 continue;
22.45 @@ -79,7 +83,7 @@
22.46 public static Method[] findMethods(Class<?> clazz, int mask) {
22.47 Object[] namesAndData = findMethodData(clazz, "");
22.48 int cnt = 0;
22.49 - for (int i = 0; i < namesAndData.length; i += 2) {
22.50 + for (int i = 0; i < namesAndData.length; i += 3) {
22.51 String sig = (String) namesAndData[i];
22.52 Object data = namesAndData[i + 1];
22.53 int middle = sig.indexOf("__");
22.54 @@ -88,7 +92,8 @@
22.55 }
22.56 String name = sig.substring(0, middle);
22.57 sig = sig.substring(middle + 2);
22.58 - final Method m = INSTANCE.create(clazz, name, data, sig);
22.59 + Class<?> cls = (Class<?>) namesAndData[i + 2];
22.60 + final Method m = INSTANCE.create(cls, name, data, sig);
22.61 if ((m.getModifiers() & mask) == 0) {
22.62 continue;
22.63 }
22.64 @@ -100,6 +105,62 @@
22.65 }
22.66 return arr;
22.67 }
22.68 + static String toSignature(Method m) {
22.69 + StringBuilder sb = new StringBuilder();
22.70 + sb.append(m.getName()).append("__");
22.71 + appendType(sb, m.getReturnType());
22.72 + Class<?>[] arr = m.getParameterTypes();
22.73 + for (int i = 0; i < arr.length; i++) {
22.74 + appendType(sb, arr[i]);
22.75 + }
22.76 + return sb.toString();
22.77 + }
22.78 +
22.79 + private static void appendType(StringBuilder sb, Class<?> type) {
22.80 + if (type == Integer.TYPE) {
22.81 + sb.append('I');
22.82 + return;
22.83 + }
22.84 + if (type == Long.TYPE) {
22.85 + sb.append('J');
22.86 + return;
22.87 + }
22.88 + if (type == Double.TYPE) {
22.89 + sb.append('D');
22.90 + return;
22.91 + }
22.92 + if (type == Float.TYPE) {
22.93 + sb.append('F');
22.94 + return;
22.95 + }
22.96 + if (type == Byte.TYPE) {
22.97 + sb.append('B');
22.98 + return;
22.99 + }
22.100 + if (type == Boolean.TYPE) {
22.101 + sb.append('Z');
22.102 + return;
22.103 + }
22.104 + if (type == Short.TYPE) {
22.105 + sb.append('S');
22.106 + return;
22.107 + }
22.108 + if (type == Void.TYPE) {
22.109 + sb.append('V');
22.110 + return;
22.111 + }
22.112 + if (type == Character.TYPE) {
22.113 + sb.append('C');
22.114 + return;
22.115 + }
22.116 + if (type.isArray()) {
22.117 + sb.append("_3");
22.118 + appendType(sb, type.getComponentType());
22.119 + return;
22.120 + }
22.121 + sb.append('L').append(type.getName().replace('.', '_'));
22.122 + sb.append("_2");
22.123 + }
22.124
22.125 public static int signatureElements(String sig) {
22.126 Enumeration<Class> en = signatureParser(sig);
22.127 @@ -141,13 +202,19 @@
22.128 return Character.TYPE;
22.129 case 'L':
22.130 try {
22.131 - int up = sig.indexOf("_2");
22.132 - String type = sig.substring(1, up);
22.133 + int up = sig.indexOf("_2", pos);
22.134 + String type = sig.substring(pos, up);
22.135 pos = up + 2;
22.136 - return Class.forName(type);
22.137 + return Class.forName(type.replace('_', '.'));
22.138 } catch (ClassNotFoundException ex) {
22.139 - // should not happen
22.140 + throw new IllegalStateException(ex);
22.141 }
22.142 + case '_': {
22.143 + char nch = sig.charAt(pos++);
22.144 + assert nch == '3' : "Can't find '3' at " + sig.substring(pos - 1);
22.145 + final Class compType = nextElement();
22.146 + return Array.newInstance(compType, 0).getClass();
22.147 + }
22.148 }
22.149 throw new UnsupportedOperationException(sig + " at " + pos);
22.150 }
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Adler32.java Tue Feb 19 15:59:27 2013 +0100
23.3 @@ -0,0 +1,139 @@
23.4 +/* -*-mode:java; c-basic-offset:2; -*- */
23.5 +/*
23.6 +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved.
23.7 +
23.8 +Redistribution and use in source and binary forms, with or without
23.9 +modification, are permitted provided that the following conditions are met:
23.10 +
23.11 + 1. Redistributions of source code must retain the above copyright notice,
23.12 + this list of conditions and the following disclaimer.
23.13 +
23.14 + 2. Redistributions in binary form must reproduce the above copyright
23.15 + notice, this list of conditions and the following disclaimer in
23.16 + the documentation and/or other materials provided with the distribution.
23.17 +
23.18 + 3. The names of the authors may not be used to endorse or promote products
23.19 + derived from this software without specific prior written permission.
23.20 +
23.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
23.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
23.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
23.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
23.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23.31 + */
23.32 +/*
23.33 + * This program is based on zlib-1.1.3, so all credit should go authors
23.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
23.35 + * and contributors of zlib.
23.36 + */
23.37 +
23.38 +package org.apidesign.bck2brwsr.emul.zip;
23.39 +
23.40 +final class Adler32 implements Checksum {
23.41 +
23.42 + // largest prime smaller than 65536
23.43 + static final private int BASE=65521;
23.44 + // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
23.45 + static final private int NMAX=5552;
23.46 +
23.47 + private long s1=1L;
23.48 + private long s2=0L;
23.49 +
23.50 + public void reset(long init){
23.51 + s1=init&0xffff;
23.52 + s2=(init>>16)&0xffff;
23.53 + }
23.54 +
23.55 + public void reset(){
23.56 + s1=1L;
23.57 + s2=0L;
23.58 + }
23.59 +
23.60 + public long getValue(){
23.61 + return ((s2<<16)|s1);
23.62 + }
23.63 +
23.64 + public void update(byte[] buf, int index, int len){
23.65 +
23.66 + if(len==1){
23.67 + s1+=buf[index++]&0xff; s2+=s1;
23.68 + s1%=BASE;
23.69 + s2%=BASE;
23.70 + return;
23.71 + }
23.72 +
23.73 + int len1 = len/NMAX;
23.74 + int len2 = len%NMAX;
23.75 + while(len1-->0) {
23.76 + int k=NMAX;
23.77 + len-=k;
23.78 + while(k-->0){
23.79 + s1+=buf[index++]&0xff; s2+=s1;
23.80 + }
23.81 + s1%=BASE;
23.82 + s2%=BASE;
23.83 + }
23.84 +
23.85 + int k=len2;
23.86 + len-=k;
23.87 + while(k-->0){
23.88 + s1+=buf[index++]&0xff; s2+=s1;
23.89 + }
23.90 + s1%=BASE;
23.91 + s2%=BASE;
23.92 + }
23.93 +
23.94 + public Adler32 copy(){
23.95 + Adler32 foo = new Adler32();
23.96 + foo.s1 = this.s1;
23.97 + foo.s2 = this.s2;
23.98 + return foo;
23.99 + }
23.100 +
23.101 + // The following logic has come from zlib.1.2.
23.102 + static long combine(long adler1, long adler2, long len2){
23.103 + long BASEL = (long)BASE;
23.104 + long sum1;
23.105 + long sum2;
23.106 + long rem; // unsigned int
23.107 +
23.108 + rem = len2 % BASEL;
23.109 + sum1 = adler1 & 0xffffL;
23.110 + sum2 = rem * sum1;
23.111 + sum2 %= BASEL; // MOD(sum2);
23.112 + sum1 += (adler2 & 0xffffL) + BASEL - 1;
23.113 + sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem;
23.114 + if (sum1 >= BASEL) sum1 -= BASEL;
23.115 + if (sum1 >= BASEL) sum1 -= BASEL;
23.116 + if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1);
23.117 + if (sum2 >= BASEL) sum2 -= BASEL;
23.118 + return sum1 | (sum2 << 16);
23.119 + }
23.120 +
23.121 +/*
23.122 + private java.util.zip.Adler32 adler=new java.util.zip.Adler32();
23.123 + public void update(byte[] buf, int index, int len){
23.124 + if(buf==null) {adler.reset();}
23.125 + else{adler.update(buf, index, len);}
23.126 + }
23.127 + public void reset(){
23.128 + adler.reset();
23.129 + }
23.130 + public void reset(long init){
23.131 + if(init==1L){
23.132 + adler.reset();
23.133 + }
23.134 + else{
23.135 + System.err.println("unsupported operation");
23.136 + }
23.137 + }
23.138 + public long getValue(){
23.139 + return adler.getValue();
23.140 + }
23.141 +*/
23.142 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/CRC32.java Tue Feb 19 15:59:27 2013 +0100
24.3 @@ -0,0 +1,181 @@
24.4 +/* -*-mode:java; c-basic-offset:2; -*- */
24.5 +/*
24.6 +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
24.7 +
24.8 +Redistribution and use in source and binary forms, with or without
24.9 +modification, are permitted provided that the following conditions are met:
24.10 +
24.11 + 1. Redistributions of source code must retain the above copyright notice,
24.12 + this list of conditions and the following disclaimer.
24.13 +
24.14 + 2. Redistributions in binary form must reproduce the above copyright
24.15 + notice, this list of conditions and the following disclaimer in
24.16 + the documentation and/or other materials provided with the distribution.
24.17 +
24.18 + 3. The names of the authors may not be used to endorse or promote products
24.19 + derived from this software without specific prior written permission.
24.20 +
24.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
24.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
24.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
24.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24.31 + */
24.32 +/*
24.33 + * This program is based on zlib-1.1.3, so all credit should go authors
24.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
24.35 + * and contributors of zlib.
24.36 + */
24.37 +
24.38 +package org.apidesign.bck2brwsr.emul.zip;
24.39 +
24.40 +import org.apidesign.bck2brwsr.emul.lang.System;
24.41 +
24.42 +final class CRC32 implements Checksum {
24.43 +
24.44 + /*
24.45 + * The following logic has come from RFC1952.
24.46 + */
24.47 + private int v = 0;
24.48 + private static int[] crc_table = null;
24.49 + static {
24.50 + crc_table = new int[256];
24.51 + for (int n = 0; n < 256; n++) {
24.52 + int c = n;
24.53 + for (int k = 8; --k >= 0; ) {
24.54 + if ((c & 1) != 0)
24.55 + c = 0xedb88320 ^ (c >>> 1);
24.56 + else
24.57 + c = c >>> 1;
24.58 + }
24.59 + crc_table[n] = c;
24.60 + }
24.61 + }
24.62 +
24.63 + public void update (byte[] buf, int index, int len) {
24.64 + int c = ~v;
24.65 + while (--len >= 0)
24.66 + c = crc_table[(c^buf[index++])&0xff]^(c >>> 8);
24.67 + v = ~c;
24.68 + }
24.69 +
24.70 + public void reset(){
24.71 + v = 0;
24.72 + }
24.73 +
24.74 + public void reset(long vv){
24.75 + v = (int)(vv&0xffffffffL);
24.76 + }
24.77 +
24.78 + public long getValue(){
24.79 + return (long)(v&0xffffffffL);
24.80 + }
24.81 +
24.82 + // The following logic has come from zlib.1.2.
24.83 + private static final int GF2_DIM = 32;
24.84 + static long combine(long crc1, long crc2, long len2){
24.85 + long row;
24.86 + long[] even = new long[GF2_DIM];
24.87 + long[] odd = new long[GF2_DIM];
24.88 +
24.89 + // degenerate case (also disallow negative lengths)
24.90 + if (len2 <= 0)
24.91 + return crc1;
24.92 +
24.93 + // put operator for one zero bit in odd
24.94 + odd[0] = 0xedb88320L; // CRC-32 polynomial
24.95 + row = 1;
24.96 + for (int n = 1; n < GF2_DIM; n++) {
24.97 + odd[n] = row;
24.98 + row <<= 1;
24.99 + }
24.100 +
24.101 + // put operator for two zero bits in even
24.102 + gf2_matrix_square(even, odd);
24.103 +
24.104 + // put operator for four zero bits in odd
24.105 + gf2_matrix_square(odd, even);
24.106 +
24.107 + // apply len2 zeros to crc1 (first square will put the operator for one
24.108 + // zero byte, eight zero bits, in even)
24.109 + do {
24.110 + // apply zeros operator for this bit of len2
24.111 + gf2_matrix_square(even, odd);
24.112 + if ((len2 & 1)!=0)
24.113 + crc1 = gf2_matrix_times(even, crc1);
24.114 + len2 >>= 1;
24.115 +
24.116 + // if no more bits set, then done
24.117 + if (len2 == 0)
24.118 + break;
24.119 +
24.120 + // another iteration of the loop with odd and even swapped
24.121 + gf2_matrix_square(odd, even);
24.122 + if ((len2 & 1)!=0)
24.123 + crc1 = gf2_matrix_times(odd, crc1);
24.124 + len2 >>= 1;
24.125 +
24.126 + // if no more bits set, then done
24.127 + } while (len2 != 0);
24.128 +
24.129 + /* return combined crc */
24.130 + crc1 ^= crc2;
24.131 + return crc1;
24.132 + }
24.133 +
24.134 + private static long gf2_matrix_times(long[] mat, long vec){
24.135 + long sum = 0;
24.136 + int index = 0;
24.137 + while (vec!=0) {
24.138 + if ((vec & 1)!=0)
24.139 + sum ^= mat[index];
24.140 + vec >>= 1;
24.141 + index++;
24.142 + }
24.143 + return sum;
24.144 + }
24.145 +
24.146 + static final void gf2_matrix_square(long[] square, long[] mat) {
24.147 + for (int n = 0; n < GF2_DIM; n++)
24.148 + square[n] = gf2_matrix_times(mat, mat[n]);
24.149 + }
24.150 +
24.151 + /*
24.152 + private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32();
24.153 +
24.154 + public void update(byte[] buf, int index, int len){
24.155 + if(buf==null) {crc32.reset();}
24.156 + else{crc32.update(buf, index, len);}
24.157 + }
24.158 + public void reset(){
24.159 + crc32.reset();
24.160 + }
24.161 + public void reset(long init){
24.162 + if(init==0L){
24.163 + crc32.reset();
24.164 + }
24.165 + else{
24.166 + System.err.println("unsupported operation");
24.167 + }
24.168 + }
24.169 + public long getValue(){
24.170 + return crc32.getValue();
24.171 + }
24.172 +*/
24.173 + public CRC32 copy(){
24.174 + CRC32 foo = new CRC32();
24.175 + foo.v = this.v;
24.176 + return foo;
24.177 + }
24.178 +
24.179 + public static int[] getCRC32Table(){
24.180 + int[] tmp = new int[crc_table.length];
24.181 + System.arraycopy(crc_table, 0, tmp, 0, tmp.length);
24.182 + return tmp;
24.183 + }
24.184 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Checksum.java Tue Feb 19 15:59:27 2013 +0100
25.3 @@ -0,0 +1,43 @@
25.4 +/* -*-mode:java; c-basic-offset:2; -*- */
25.5 +/*
25.6 +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
25.7 +
25.8 +Redistribution and use in source and binary forms, with or without
25.9 +modification, are permitted provided that the following conditions are met:
25.10 +
25.11 + 1. Redistributions of source code must retain the above copyright notice,
25.12 + this list of conditions and the following disclaimer.
25.13 +
25.14 + 2. Redistributions in binary form must reproduce the above copyright
25.15 + notice, this list of conditions and the following disclaimer in
25.16 + the documentation and/or other materials provided with the distribution.
25.17 +
25.18 + 3. The names of the authors may not be used to endorse or promote products
25.19 + derived from this software without specific prior written permission.
25.20 +
25.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
25.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
25.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
25.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
25.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
25.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25.31 + */
25.32 +/*
25.33 + * This program is based on zlib-1.1.3, so all credit should go authors
25.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
25.35 + * and contributors of zlib.
25.36 + */
25.37 +
25.38 +package org.apidesign.bck2brwsr.emul.zip;
25.39 +
25.40 +interface Checksum {
25.41 + void update(byte[] buf, int index, int len);
25.42 + void reset();
25.43 + void reset(long init);
25.44 + long getValue();
25.45 + Checksum copy();
25.46 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/FastJar.java Tue Feb 19 15:59:27 2013 +0100
26.3 @@ -0,0 +1,175 @@
26.4 +/*
26.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
26.6 + *
26.7 + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
26.8 + *
26.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
26.10 + * Other names may be trademarks of their respective owners.
26.11 + *
26.12 + * The contents of this file are subject to the terms of either the GNU
26.13 + * General Public License Version 2 only ("GPL") or the Common
26.14 + * Development and Distribution License("CDDL") (collectively, the
26.15 + * "License"). You may not use this file except in compliance with the
26.16 + * License. You can obtain a copy of the License at
26.17 + * http://www.netbeans.org/cddl-gplv2.html
26.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
26.19 + * specific language governing permissions and limitations under the
26.20 + * License. When distributing the software, include this License Header
26.21 + * Notice in each file and include the License file at
26.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
26.23 + * particular file as subject to the "Classpath" exception as provided
26.24 + * by Oracle in the GPL Version 2 section of the License file that
26.25 + * accompanied this code. If applicable, add the following below the
26.26 + * License Header, with the fields enclosed by brackets [] replaced by
26.27 + * your own identifying information:
26.28 + * "Portions Copyrighted [year] [name of copyright owner]"
26.29 + *
26.30 + * Contributor(s):
26.31 + *
26.32 + * Portions Copyrighted 2007 Sun Microsystems, Inc.
26.33 + */
26.34 +package org.apidesign.bck2brwsr.emul.zip;
26.35 +
26.36 +import java.io.ByteArrayInputStream;
26.37 +import java.io.IOException;
26.38 +import java.io.InputStream;
26.39 +import java.util.zip.ZipEntry;
26.40 +import java.util.zip.ZipInputStream;
26.41 +
26.42 +/**
26.43 + *
26.44 + * @author Tomas Zezula
26.45 + */
26.46 +public final class FastJar {
26.47 + private final byte[] arr;
26.48 +
26.49 + public FastJar(byte[] arr) {
26.50 + this.arr = arr;
26.51 + }
26.52 +
26.53 +
26.54 + private static final int GIVE_UP = 1<<16;
26.55 +
26.56 + public static final class Entry {
26.57 +
26.58 + public final String name;
26.59 + final long offset;
26.60 + private final long dosTime;
26.61 +
26.62 + Entry (String name, long offset, long time) {
26.63 + assert name != null;
26.64 + this.name = name;
26.65 + this.offset = offset;
26.66 + this.dosTime = time;
26.67 + }
26.68 +/*
26.69 + public long getTime () {
26.70 + Date d = new Date((int)(((dosTime >> 25) & 0x7f) + 80),
26.71 + (int)(((dosTime >> 21) & 0x0f) - 1),
26.72 + (int)((dosTime >> 16) & 0x1f),
26.73 + (int)((dosTime >> 11) & 0x1f),
26.74 + (int)((dosTime >> 5) & 0x3f),
26.75 + (int)((dosTime << 1) & 0x3e));
26.76 + return d.getTime();
26.77 + }
26.78 + */
26.79 + }
26.80 +
26.81 + public InputStream getInputStream (final Entry e) throws IOException {
26.82 + return getInputStream(arr, e.offset);
26.83 + }
26.84 +
26.85 + private static InputStream getInputStream (byte[] arr, final long offset) throws IOException {
26.86 + ByteArrayInputStream is = new ByteArrayInputStream(arr);
26.87 + is.skip(offset);
26.88 + ZipInputStream in = new ZipInputStream (is);
26.89 + ZipEntry e = in.getNextEntry();
26.90 + if (e != null && e.getCrc() == 0L && e.getMethod() == ZipEntry.STORED) {
26.91 + int cp = arr.length - is.available();
26.92 + return new ByteArrayInputStream(arr, cp, (int)e.getSize());
26.93 + }
26.94 + return in;
26.95 + }
26.96 +
26.97 + public Entry[] list() throws IOException {
26.98 + final int size = arr.length;
26.99 +
26.100 + int at = size - ZipInputStream.ENDHDR;
26.101 +
26.102 + byte[] data = new byte[ZipInputStream.ENDHDR];
26.103 + int giveup = 0;
26.104 +
26.105 + do {
26.106 + org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, at, data, 0, data.length);
26.107 + at--;
26.108 + giveup++;
26.109 + if (giveup > GIVE_UP) {
26.110 + throw new IOException ();
26.111 + }
26.112 + } while (getsig(data) != ZipInputStream.ENDSIG);
26.113 +
26.114 +
26.115 + final long censize = endsiz(data);
26.116 + final long cenoff = endoff(data);
26.117 + at = (int) cenoff;
26.118 +
26.119 + Entry[] result = new Entry[0];
26.120 + int cenread = 0;
26.121 + data = new byte[ZipInputStream.CENHDR];
26.122 + while (cenread < censize) {
26.123 + org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, at, data, 0, data.length);
26.124 + at += data.length;
26.125 + if (getsig(data) != ZipInputStream.CENSIG) {
26.126 + throw new IOException("No central table"); //NOI18N
26.127 + }
26.128 + int cennam = cennam(data);
26.129 + int cenext = cenext(data);
26.130 + int cencom = cencom(data);
26.131 + long lhoff = cenoff(data);
26.132 + long centim = centim(data);
26.133 + String name = new String(arr, at, cennam, "UTF-8");
26.134 + at += cennam;
26.135 + int seekby = cenext+cencom;
26.136 + int cendatalen = ZipInputStream.CENHDR + cennam + seekby;
26.137 + cenread+=cendatalen;
26.138 + result = addEntry(result, new Entry(name,lhoff, centim));
26.139 + at += seekby;
26.140 + }
26.141 + return result;
26.142 + }
26.143 +
26.144 + private Entry[] addEntry(Entry[] result, Entry entry) {
26.145 + Entry[] e = new Entry[result.length + 1];
26.146 + e[result.length] = entry;
26.147 + org.apidesign.bck2brwsr.emul.lang.System.arraycopy(result, 0, e, 0, result.length);
26.148 + return e;
26.149 + }
26.150 +
26.151 + private static final long getsig(final byte[] b) throws IOException {return get32(b,0);}
26.152 + private static final long endsiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.ENDSIZ);}
26.153 + private static final long endoff(final byte[] b) throws IOException {return get32(b,ZipInputStream.ENDOFF);}
26.154 + private static final long cenlen(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENLEN);}
26.155 + private static final long censiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENSIZ);}
26.156 + private static final long centim(final byte[] b) throws IOException {return get32(b,ZipInputStream.CENTIM);}
26.157 + private static final int cennam(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENNAM);}
26.158 + private static final int cenext(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENEXT);}
26.159 + private static final int cencom(final byte[] b) throws IOException {return get16(b,ZipInputStream.CENCOM);}
26.160 + private static final long cenoff (final byte[] b) throws IOException {return get32(b,ZipInputStream.CENOFF);}
26.161 + private static final int lochow(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCHOW);}
26.162 + private static final int locname(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCNAM);}
26.163 + private static final int locext(final byte[] b) throws IOException {return get16(b,ZipInputStream.LOCEXT);}
26.164 + private static final long locsiz(final byte[] b) throws IOException {return get32(b,ZipInputStream.LOCSIZ);}
26.165 +
26.166 + private static final int get16(final byte[] b, int off) throws IOException {
26.167 + final int b1 = b[off];
26.168 + final int b2 = b[off+1];
26.169 + return (b1 & 0xff) | ((b2 & 0xff) << 8);
26.170 + }
26.171 +
26.172 + private static final long get32(final byte[] b, int off) throws IOException {
26.173 + final int s1 = get16(b, off);
26.174 + final int s2 = get16(b, off+2);
26.175 + return s1 | ((long)s2 << 16);
26.176 + }
26.177 +
26.178 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/GZIPHeader.java Tue Feb 19 15:59:27 2013 +0100
27.3 @@ -0,0 +1,215 @@
27.4 +/* -*-mode:java; c-basic-offset:2; -*- */
27.5 +/*
27.6 +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
27.7 +
27.8 +Redistribution and use in source and binary forms, with or without
27.9 +modification, are permitted provided that the following conditions are met:
27.10 +
27.11 + 1. Redistributions of source code must retain the above copyright notice,
27.12 + this list of conditions and the following disclaimer.
27.13 +
27.14 + 2. Redistributions in binary form must reproduce the above copyright
27.15 + notice, this list of conditions and the following disclaimer in
27.16 + the documentation and/or other materials provided with the distribution.
27.17 +
27.18 + 3. The names of the authors may not be used to endorse or promote products
27.19 + derived from this software without specific prior written permission.
27.20 +
27.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
27.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
27.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
27.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
27.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
27.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27.31 + */
27.32 +/*
27.33 + * This program is based on zlib-1.1.3, so all credit should go authors
27.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
27.35 + * and contributors of zlib.
27.36 + */
27.37 +
27.38 +package org.apidesign.bck2brwsr.emul.zip;
27.39 +
27.40 +import org.apidesign.bck2brwsr.emul.lang.System;
27.41 +import java.io.UnsupportedEncodingException;
27.42 +
27.43 +/**
27.44 + * @see "http://www.ietf.org/rfc/rfc1952.txt"
27.45 + */
27.46 +final class GZIPHeader implements Cloneable {
27.47 +
27.48 + public static final byte OS_MSDOS = (byte) 0x00;
27.49 + public static final byte OS_AMIGA = (byte) 0x01;
27.50 + public static final byte OS_VMS = (byte) 0x02;
27.51 + public static final byte OS_UNIX = (byte) 0x03;
27.52 + public static final byte OS_ATARI = (byte) 0x05;
27.53 + public static final byte OS_OS2 = (byte) 0x06;
27.54 + public static final byte OS_MACOS = (byte) 0x07;
27.55 + public static final byte OS_TOPS20 = (byte) 0x0a;
27.56 + public static final byte OS_WIN32 = (byte) 0x0b;
27.57 + public static final byte OS_VMCMS = (byte) 0x04;
27.58 + public static final byte OS_ZSYSTEM = (byte) 0x08;
27.59 + public static final byte OS_CPM = (byte) 0x09;
27.60 + public static final byte OS_QDOS = (byte) 0x0c;
27.61 + public static final byte OS_RISCOS = (byte) 0x0d;
27.62 + public static final byte OS_UNKNOWN = (byte) 0xff;
27.63 +
27.64 + boolean text = false;
27.65 + private boolean fhcrc = false;
27.66 + long time;
27.67 + int xflags;
27.68 + int os = 255;
27.69 + byte[] extra;
27.70 + byte[] name;
27.71 + byte[] comment;
27.72 + int hcrc;
27.73 + long crc;
27.74 + boolean done = false;
27.75 + long mtime = 0;
27.76 +
27.77 + public void setModifiedTime(long mtime) {
27.78 + this.mtime = mtime;
27.79 + }
27.80 +
27.81 + public long getModifiedTime() {
27.82 + return mtime;
27.83 + }
27.84 +
27.85 + public void setOS(int os) {
27.86 + if((0<=os && os <=13) || os==255)
27.87 + this.os=os;
27.88 + else
27.89 + throw new IllegalArgumentException("os: "+os);
27.90 + }
27.91 +
27.92 + public int getOS(){
27.93 + return os;
27.94 + }
27.95 +
27.96 + public void setName(String name) {
27.97 + try{
27.98 + this.name=name.getBytes("ISO-8859-1");
27.99 + }
27.100 + catch(UnsupportedEncodingException e){
27.101 + throw new IllegalArgumentException("name must be in ISO-8859-1 "+name);
27.102 + }
27.103 + }
27.104 +
27.105 + public String getName(){
27.106 + if(name==null) return "";
27.107 + try {
27.108 + return new String(name, "ISO-8859-1");
27.109 + }
27.110 + catch (UnsupportedEncodingException e) {
27.111 + throw new IllegalArgumentException(e.toString());
27.112 + }
27.113 + }
27.114 +
27.115 + public void setComment(String comment) {
27.116 + try{
27.117 + this.comment=comment.getBytes("ISO-8859-1");
27.118 + }
27.119 + catch(UnsupportedEncodingException e){
27.120 + throw new IllegalArgumentException("comment must be in ISO-8859-1 "+name);
27.121 + }
27.122 + }
27.123 +
27.124 + public String getComment(){
27.125 + if(comment==null) return "";
27.126 + try {
27.127 + return new String(comment, "ISO-8859-1");
27.128 + }
27.129 + catch (UnsupportedEncodingException e) {
27.130 + throw new IllegalArgumentException(e.toString());
27.131 + }
27.132 + }
27.133 +
27.134 + public void setCRC(long crc){
27.135 + this.crc = crc;
27.136 + }
27.137 +
27.138 + public long getCRC(){
27.139 + return crc;
27.140 + }
27.141 +/*
27.142 + void put(Deflate d){
27.143 + int flag = 0;
27.144 + if(text){
27.145 + flag |= 1; // FTEXT
27.146 + }
27.147 + if(fhcrc){
27.148 + flag |= 2; // FHCRC
27.149 + }
27.150 + if(extra!=null){
27.151 + flag |= 4; // FEXTRA
27.152 + }
27.153 + if(name!=null){
27.154 + flag |= 8; // FNAME
27.155 + }
27.156 + if(comment!=null){
27.157 + flag |= 16; // FCOMMENT
27.158 + }
27.159 + int xfl = 0;
27.160 + if(d.level == JZlib.Z_BEST_SPEED){
27.161 + xfl |= 4;
27.162 + }
27.163 + else if (d.level == JZlib.Z_BEST_COMPRESSION){
27.164 + xfl |= 2;
27.165 + }
27.166 +
27.167 + d.put_short((short)0x8b1f); // ID1 ID2
27.168 + d.put_byte((byte)8); // CM(Compression Method)
27.169 + d.put_byte((byte)flag);
27.170 + d.put_byte((byte)mtime);
27.171 + d.put_byte((byte)(mtime>>8));
27.172 + d.put_byte((byte)(mtime>>16));
27.173 + d.put_byte((byte)(mtime>>24));
27.174 + d.put_byte((byte)xfl);
27.175 + d.put_byte((byte)os);
27.176 +
27.177 + if(extra!=null){
27.178 + d.put_byte((byte)extra.length);
27.179 + d.put_byte((byte)(extra.length>>8));
27.180 + d.put_byte(extra, 0, extra.length);
27.181 + }
27.182 +
27.183 + if(name!=null){
27.184 + d.put_byte(name, 0, name.length);
27.185 + d.put_byte((byte)0);
27.186 + }
27.187 +
27.188 + if(comment!=null){
27.189 + d.put_byte(comment, 0, comment.length);
27.190 + d.put_byte((byte)0);
27.191 + }
27.192 + }
27.193 +*/
27.194 + @Override
27.195 + public Object clone() throws CloneNotSupportedException {
27.196 + GZIPHeader gheader = (GZIPHeader)super.clone();
27.197 + byte[] tmp;
27.198 + if(gheader.extra!=null){
27.199 + tmp=new byte[gheader.extra.length];
27.200 + System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length);
27.201 + gheader.extra = tmp;
27.202 + }
27.203 +
27.204 + if(gheader.name!=null){
27.205 + tmp=new byte[gheader.name.length];
27.206 + System.arraycopy(gheader.name, 0, tmp, 0, tmp.length);
27.207 + gheader.name = tmp;
27.208 + }
27.209 +
27.210 + if(gheader.comment!=null){
27.211 + tmp=new byte[gheader.comment.length];
27.212 + System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length);
27.213 + gheader.comment = tmp;
27.214 + }
27.215 +
27.216 + return gheader;
27.217 + }
27.218 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfBlocks.java Tue Feb 19 15:59:27 2013 +0100
28.3 @@ -0,0 +1,616 @@
28.4 +/* -*-mode:java; c-basic-offset:2; -*- */
28.5 +/*
28.6 +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
28.7 +
28.8 +Redistribution and use in source and binary forms, with or without
28.9 +modification, are permitted provided that the following conditions are met:
28.10 +
28.11 + 1. Redistributions of source code must retain the above copyright notice,
28.12 + this list of conditions and the following disclaimer.
28.13 +
28.14 + 2. Redistributions in binary form must reproduce the above copyright
28.15 + notice, this list of conditions and the following disclaimer in
28.16 + the documentation and/or other materials provided with the distribution.
28.17 +
28.18 + 3. The names of the authors may not be used to endorse or promote products
28.19 + derived from this software without specific prior written permission.
28.20 +
28.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
28.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
28.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
28.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
28.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
28.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28.31 + */
28.32 +/*
28.33 + * This program is based on zlib-1.1.3, so all credit should go authors
28.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
28.35 + * and contributors of zlib.
28.36 + */
28.37 +
28.38 +package org.apidesign.bck2brwsr.emul.zip;
28.39 +
28.40 +import org.apidesign.bck2brwsr.emul.lang.System;
28.41 +
28.42 +final class InfBlocks{
28.43 + static final private int MANY=1440;
28.44 +
28.45 + // And'ing with mask[n] masks the lower n bits
28.46 + static final private int[] inflate_mask = {
28.47 + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
28.48 + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,
28.49 + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
28.50 + 0x00007fff, 0x0000ffff
28.51 + };
28.52 +
28.53 + // Table for deflate from PKZIP's appnote.txt.
28.54 + static final int[] border = { // Order of the bit length code lengths
28.55 + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
28.56 + };
28.57 +
28.58 + static final private int Z_OK=0;
28.59 + static final private int Z_STREAM_END=1;
28.60 + static final private int Z_NEED_DICT=2;
28.61 + static final private int Z_ERRNO=-1;
28.62 + static final private int Z_STREAM_ERROR=-2;
28.63 + static final private int Z_DATA_ERROR=-3;
28.64 + static final private int Z_MEM_ERROR=-4;
28.65 + static final private int Z_BUF_ERROR=-5;
28.66 + static final private int Z_VERSION_ERROR=-6;
28.67 +
28.68 + static final private int TYPE=0; // get type bits (3, including end bit)
28.69 + static final private int LENS=1; // get lengths for stored
28.70 + static final private int STORED=2;// processing stored block
28.71 + static final private int TABLE=3; // get table lengths
28.72 + static final private int BTREE=4; // get bit lengths tree for a dynamic block
28.73 + static final private int DTREE=5; // get length, distance trees for a dynamic block
28.74 + static final private int CODES=6; // processing fixed or dynamic block
28.75 + static final private int DRY=7; // output remaining window bytes
28.76 + static final private int DONE=8; // finished last block, done
28.77 + static final private int BAD=9; // ot a data error--stuck here
28.78 +
28.79 + int mode; // current inflate_block mode
28.80 +
28.81 + int left; // if STORED, bytes left to copy
28.82 +
28.83 + int table; // table lengths (14 bits)
28.84 + int index; // index into blens (or border)
28.85 + int[] blens; // bit lengths of codes
28.86 + int[] bb=new int[1]; // bit length tree depth
28.87 + int[] tb=new int[1]; // bit length decoding tree
28.88 +
28.89 + int[] bl=new int[1];
28.90 + int[] bd=new int[1];
28.91 +
28.92 + int[][] tl=new int[1][];
28.93 + int[][] td=new int[1][];
28.94 + int[] tli=new int[1]; // tl_index
28.95 + int[] tdi=new int[1]; // td_index
28.96 +
28.97 + private final InfCodes codes; // if CODES, current state
28.98 +
28.99 + int last; // true if this block is the last block
28.100 +
28.101 + // mode independent information
28.102 + int bitk; // bits in bit buffer
28.103 + int bitb; // bit buffer
28.104 + int[] hufts; // single malloc for tree space
28.105 + byte[] window; // sliding window
28.106 + int end; // one byte after sliding window
28.107 + int read; // window read pointer
28.108 + int write; // window write pointer
28.109 + private boolean check;
28.110 +
28.111 + private final InfTree inftree=new InfTree();
28.112 +
28.113 + private final ZStream z;
28.114 +
28.115 + InfBlocks(ZStream z, int w){
28.116 + this.z=z;
28.117 + this.codes=new InfCodes(this.z, this);
28.118 + hufts=new int[MANY*3];
28.119 + window=new byte[w];
28.120 + end=w;
28.121 + this.check = (z.istate.wrap==0) ? false : true;
28.122 + mode = TYPE;
28.123 + reset();
28.124 + }
28.125 +
28.126 + void reset(){
28.127 + if(mode==BTREE || mode==DTREE){
28.128 + }
28.129 + if(mode==CODES){
28.130 + codes.free(z);
28.131 + }
28.132 + mode=TYPE;
28.133 + bitk=0;
28.134 + bitb=0;
28.135 + read=write=0;
28.136 + if(check){
28.137 + z.adler.reset();
28.138 + }
28.139 + }
28.140 +
28.141 + int proc(int r){
28.142 + int t; // temporary storage
28.143 + int b; // bit buffer
28.144 + int k; // bits in bit buffer
28.145 + int p; // input data pointer
28.146 + int n; // bytes available there
28.147 + int q; // output window write pointer
28.148 + int m; // bytes to end of window or read pointer
28.149 +
28.150 + // copy input/output information to locals (UPDATE macro restores)
28.151 + {p=z.next_in_index;n=z.avail_in;b=bitb;k=bitk;}
28.152 + {q=write;m=(int)(q<read?read-q-1:end-q);}
28.153 +
28.154 + // process input based on current state
28.155 + while(true){
28.156 + switch (mode){
28.157 + case TYPE:
28.158 +
28.159 + while(k<(3)){
28.160 + if(n!=0){
28.161 + r=Z_OK;
28.162 + }
28.163 + else{
28.164 + bitb=b; bitk=k;
28.165 + z.avail_in=n;
28.166 + z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.167 + write=q;
28.168 + return inflate_flush(r);
28.169 + };
28.170 + n--;
28.171 + b|=(z.next_in[p++]&0xff)<<k;
28.172 + k+=8;
28.173 + }
28.174 + t = (int)(b & 7);
28.175 + last = t & 1;
28.176 +
28.177 + switch (t >>> 1){
28.178 + case 0: // stored
28.179 + {b>>>=(3);k-=(3);}
28.180 + t = k & 7; // go to byte boundary
28.181 +
28.182 + {b>>>=(t);k-=(t);}
28.183 + mode = LENS; // get length of stored block
28.184 + break;
28.185 + case 1: // fixed
28.186 + InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
28.187 + codes.init(bl[0], bd[0], tl[0], 0, td[0], 0);
28.188 +
28.189 + {b>>>=(3);k-=(3);}
28.190 +
28.191 + mode = CODES;
28.192 + break;
28.193 + case 2: // dynamic
28.194 +
28.195 + {b>>>=(3);k-=(3);}
28.196 +
28.197 + mode = TABLE;
28.198 + break;
28.199 + case 3: // illegal
28.200 +
28.201 + {b>>>=(3);k-=(3);}
28.202 + mode = BAD;
28.203 + z.msg = "invalid block type";
28.204 + r = Z_DATA_ERROR;
28.205 +
28.206 + bitb=b; bitk=k;
28.207 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.208 + write=q;
28.209 + return inflate_flush(r);
28.210 + }
28.211 + break;
28.212 + case LENS:
28.213 +
28.214 + while(k<(32)){
28.215 + if(n!=0){
28.216 + r=Z_OK;
28.217 + }
28.218 + else{
28.219 + bitb=b; bitk=k;
28.220 + z.avail_in=n;
28.221 + z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.222 + write=q;
28.223 + return inflate_flush(r);
28.224 + };
28.225 + n--;
28.226 + b|=(z.next_in[p++]&0xff)<<k;
28.227 + k+=8;
28.228 + }
28.229 +
28.230 + if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)){
28.231 + mode = BAD;
28.232 + z.msg = "invalid stored block lengths";
28.233 + r = Z_DATA_ERROR;
28.234 +
28.235 + bitb=b; bitk=k;
28.236 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.237 + write=q;
28.238 + return inflate_flush(r);
28.239 + }
28.240 + left = (b & 0xffff);
28.241 + b = k = 0; // dump bits
28.242 + mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE);
28.243 + break;
28.244 + case STORED:
28.245 + if (n == 0){
28.246 + bitb=b; bitk=k;
28.247 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.248 + write=q;
28.249 + return inflate_flush(r);
28.250 + }
28.251 +
28.252 + if(m==0){
28.253 + if(q==end&&read!=0){
28.254 + q=0; m=(int)(q<read?read-q-1:end-q);
28.255 + }
28.256 + if(m==0){
28.257 + write=q;
28.258 + r=inflate_flush(r);
28.259 + q=write;m=(int)(q<read?read-q-1:end-q);
28.260 + if(q==end&&read!=0){
28.261 + q=0; m=(int)(q<read?read-q-1:end-q);
28.262 + }
28.263 + if(m==0){
28.264 + bitb=b; bitk=k;
28.265 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.266 + write=q;
28.267 + return inflate_flush(r);
28.268 + }
28.269 + }
28.270 + }
28.271 + r=Z_OK;
28.272 +
28.273 + t = left;
28.274 + if(t>n) t = n;
28.275 + if(t>m) t = m;
28.276 + System.arraycopy(z.next_in, p, window, q, t);
28.277 + p += t; n -= t;
28.278 + q += t; m -= t;
28.279 + if ((left -= t) != 0)
28.280 + break;
28.281 + mode = last!=0 ? DRY : TYPE;
28.282 + break;
28.283 + case TABLE:
28.284 +
28.285 + while(k<(14)){
28.286 + if(n!=0){
28.287 + r=Z_OK;
28.288 + }
28.289 + else{
28.290 + bitb=b; bitk=k;
28.291 + z.avail_in=n;
28.292 + z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.293 + write=q;
28.294 + return inflate_flush(r);
28.295 + };
28.296 + n--;
28.297 + b|=(z.next_in[p++]&0xff)<<k;
28.298 + k+=8;
28.299 + }
28.300 +
28.301 + table = t = (b & 0x3fff);
28.302 + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
28.303 + {
28.304 + mode = BAD;
28.305 + z.msg = "too many length or distance symbols";
28.306 + r = Z_DATA_ERROR;
28.307 +
28.308 + bitb=b; bitk=k;
28.309 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.310 + write=q;
28.311 + return inflate_flush(r);
28.312 + }
28.313 + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
28.314 + if(blens==null || blens.length<t){
28.315 + blens=new int[t];
28.316 + }
28.317 + else{
28.318 + for(int i=0; i<t; i++){blens[i]=0;}
28.319 + }
28.320 +
28.321 + {b>>>=(14);k-=(14);}
28.322 +
28.323 + index = 0;
28.324 + mode = BTREE;
28.325 + case BTREE:
28.326 + while (index < 4 + (table >>> 10)){
28.327 + while(k<(3)){
28.328 + if(n!=0){
28.329 + r=Z_OK;
28.330 + }
28.331 + else{
28.332 + bitb=b; bitk=k;
28.333 + z.avail_in=n;
28.334 + z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.335 + write=q;
28.336 + return inflate_flush(r);
28.337 + };
28.338 + n--;
28.339 + b|=(z.next_in[p++]&0xff)<<k;
28.340 + k+=8;
28.341 + }
28.342 +
28.343 + blens[border[index++]] = b&7;
28.344 +
28.345 + {b>>>=(3);k-=(3);}
28.346 + }
28.347 +
28.348 + while(index < 19){
28.349 + blens[border[index++]] = 0;
28.350 + }
28.351 +
28.352 + bb[0] = 7;
28.353 + t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z);
28.354 + if (t != Z_OK){
28.355 + r = t;
28.356 + if (r == Z_DATA_ERROR){
28.357 + blens=null;
28.358 + mode = BAD;
28.359 + }
28.360 +
28.361 + bitb=b; bitk=k;
28.362 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.363 + write=q;
28.364 + return inflate_flush(r);
28.365 + }
28.366 +
28.367 + index = 0;
28.368 + mode = DTREE;
28.369 + case DTREE:
28.370 + while (true){
28.371 + t = table;
28.372 + if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){
28.373 + break;
28.374 + }
28.375 +
28.376 + int[] h;
28.377 + int i, j, c;
28.378 +
28.379 + t = bb[0];
28.380 +
28.381 + while(k<(t)){
28.382 + if(n!=0){
28.383 + r=Z_OK;
28.384 + }
28.385 + else{
28.386 + bitb=b; bitk=k;
28.387 + z.avail_in=n;
28.388 + z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.389 + write=q;
28.390 + return inflate_flush(r);
28.391 + };
28.392 + n--;
28.393 + b|=(z.next_in[p++]&0xff)<<k;
28.394 + k+=8;
28.395 + }
28.396 +
28.397 + if(tb[0]==-1){
28.398 + //System.err.println("null...");
28.399 + }
28.400 +
28.401 + t=hufts[(tb[0]+(b&inflate_mask[t]))*3+1];
28.402 + c=hufts[(tb[0]+(b&inflate_mask[t]))*3+2];
28.403 +
28.404 + if (c < 16){
28.405 + b>>>=(t);k-=(t);
28.406 + blens[index++] = c;
28.407 + }
28.408 + else { // c == 16..18
28.409 + i = c == 18 ? 7 : c - 14;
28.410 + j = c == 18 ? 11 : 3;
28.411 +
28.412 + while(k<(t+i)){
28.413 + if(n!=0){
28.414 + r=Z_OK;
28.415 + }
28.416 + else{
28.417 + bitb=b; bitk=k;
28.418 + z.avail_in=n;
28.419 + z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.420 + write=q;
28.421 + return inflate_flush(r);
28.422 + };
28.423 + n--;
28.424 + b|=(z.next_in[p++]&0xff)<<k;
28.425 + k+=8;
28.426 + }
28.427 +
28.428 + b>>>=(t);k-=(t);
28.429 +
28.430 + j += (b & inflate_mask[i]);
28.431 +
28.432 + b>>>=(i);k-=(i);
28.433 +
28.434 + i = index;
28.435 + t = table;
28.436 + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
28.437 + (c == 16 && i < 1)){
28.438 + blens=null;
28.439 + mode = BAD;
28.440 + z.msg = "invalid bit length repeat";
28.441 + r = Z_DATA_ERROR;
28.442 +
28.443 + bitb=b; bitk=k;
28.444 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.445 + write=q;
28.446 + return inflate_flush(r);
28.447 + }
28.448 +
28.449 + c = c == 16 ? blens[i-1] : 0;
28.450 + do{
28.451 + blens[i++] = c;
28.452 + }
28.453 + while (--j!=0);
28.454 + index = i;
28.455 + }
28.456 + }
28.457 +
28.458 + tb[0]=-1;
28.459 + {
28.460 + bl[0] = 9; // must be <= 9 for lookahead assumptions
28.461 + bd[0] = 6; // must be <= 9 for lookahead assumptions
28.462 + t = table;
28.463 + t = inftree.inflate_trees_dynamic(257 + (t & 0x1f),
28.464 + 1 + ((t >> 5) & 0x1f),
28.465 + blens, bl, bd, tli, tdi, hufts, z);
28.466 +
28.467 + if (t != Z_OK){
28.468 + if (t == Z_DATA_ERROR){
28.469 + blens=null;
28.470 + mode = BAD;
28.471 + }
28.472 + r = t;
28.473 +
28.474 + bitb=b; bitk=k;
28.475 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.476 + write=q;
28.477 + return inflate_flush(r);
28.478 + }
28.479 + codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]);
28.480 + }
28.481 + mode = CODES;
28.482 + case CODES:
28.483 + bitb=b; bitk=k;
28.484 + z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.485 + write=q;
28.486 +
28.487 + if ((r = codes.proc(r)) != Z_STREAM_END){
28.488 + return inflate_flush(r);
28.489 + }
28.490 + r = Z_OK;
28.491 + codes.free(z);
28.492 +
28.493 + p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk;
28.494 + q=write;m=(int)(q<read?read-q-1:end-q);
28.495 +
28.496 + if (last==0){
28.497 + mode = TYPE;
28.498 + break;
28.499 + }
28.500 + mode = DRY;
28.501 + case DRY:
28.502 + write=q;
28.503 + r=inflate_flush(r);
28.504 + q=write; m=(int)(q<read?read-q-1:end-q);
28.505 + if (read != write){
28.506 + bitb=b; bitk=k;
28.507 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.508 + write=q;
28.509 + return inflate_flush(r);
28.510 + }
28.511 + mode = DONE;
28.512 + case DONE:
28.513 + r = Z_STREAM_END;
28.514 +
28.515 + bitb=b; bitk=k;
28.516 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.517 + write=q;
28.518 + return inflate_flush(r);
28.519 + case BAD:
28.520 + r = Z_DATA_ERROR;
28.521 +
28.522 + bitb=b; bitk=k;
28.523 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.524 + write=q;
28.525 + return inflate_flush(r);
28.526 +
28.527 + default:
28.528 + r = Z_STREAM_ERROR;
28.529 +
28.530 + bitb=b; bitk=k;
28.531 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
28.532 + write=q;
28.533 + return inflate_flush(r);
28.534 + }
28.535 + }
28.536 + }
28.537 +
28.538 + void free(){
28.539 + reset();
28.540 + window=null;
28.541 + hufts=null;
28.542 + //ZFREE(z, s);
28.543 + }
28.544 +
28.545 + void set_dictionary(byte[] d, int start, int n){
28.546 + System.arraycopy(d, start, window, 0, n);
28.547 + read = write = n;
28.548 + }
28.549 +
28.550 + // Returns true if inflate is currently at the end of a block generated
28.551 + // by Z_SYNC_FLUSH or Z_FULL_FLUSH.
28.552 + int sync_point(){
28.553 + return mode == LENS ? 1 : 0;
28.554 + }
28.555 +
28.556 + // copy as much as possible from the sliding window to the output area
28.557 + int inflate_flush(int r){
28.558 + int n;
28.559 + int p;
28.560 + int q;
28.561 +
28.562 + // local copies of source and destination pointers
28.563 + p = z.next_out_index;
28.564 + q = read;
28.565 +
28.566 + // compute number of bytes to copy as far as end of window
28.567 + n = (int)((q <= write ? write : end) - q);
28.568 + if(n > z.avail_out) n = z.avail_out;
28.569 + if(n!=0 && r == Z_BUF_ERROR) r = Z_OK;
28.570 +
28.571 + // update counters
28.572 + z.avail_out -= n;
28.573 + z.total_out += n;
28.574 +
28.575 + // update check information
28.576 + if(check && n>0){
28.577 + z.adler.update(window, q, n);
28.578 + }
28.579 +
28.580 + // copy as far as end of window
28.581 + System.arraycopy(window, q, z.next_out, p, n);
28.582 + p += n;
28.583 + q += n;
28.584 +
28.585 + // see if more to copy at beginning of window
28.586 + if (q == end){
28.587 + // wrap pointers
28.588 + q = 0;
28.589 + if (write == end)
28.590 + write = 0;
28.591 +
28.592 + // compute bytes to copy
28.593 + n = write - q;
28.594 + if (n > z.avail_out) n = z.avail_out;
28.595 + if (n!=0 && r == Z_BUF_ERROR) r = Z_OK;
28.596 +
28.597 + // update counters
28.598 + z.avail_out -= n;
28.599 + z.total_out += n;
28.600 +
28.601 + // update check information
28.602 + if(check && n>0){
28.603 + z.adler.update(window, q, n);
28.604 + }
28.605 +
28.606 + // copy
28.607 + System.arraycopy(window, q, z.next_out, p, n);
28.608 + p += n;
28.609 + q += n;
28.610 + }
28.611 +
28.612 + // update pointers
28.613 + z.next_out_index = p;
28.614 + read = q;
28.615 +
28.616 + // done
28.617 + return r;
28.618 + }
28.619 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfCodes.java Tue Feb 19 15:59:27 2013 +0100
29.3 @@ -0,0 +1,612 @@
29.4 +/* -*-mode:java; c-basic-offset:2; -*- */
29.5 +/*
29.6 +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
29.7 +
29.8 +Redistribution and use in source and binary forms, with or without
29.9 +modification, are permitted provided that the following conditions are met:
29.10 +
29.11 + 1. Redistributions of source code must retain the above copyright notice,
29.12 + this list of conditions and the following disclaimer.
29.13 +
29.14 + 2. Redistributions in binary form must reproduce the above copyright
29.15 + notice, this list of conditions and the following disclaimer in
29.16 + the documentation and/or other materials provided with the distribution.
29.17 +
29.18 + 3. The names of the authors may not be used to endorse or promote products
29.19 + derived from this software without specific prior written permission.
29.20 +
29.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
29.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
29.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
29.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
29.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29.31 + */
29.32 +/*
29.33 + * This program is based on zlib-1.1.3, so all credit should go authors
29.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
29.35 + * and contributors of zlib.
29.36 + */
29.37 +
29.38 +package org.apidesign.bck2brwsr.emul.zip;
29.39 +
29.40 +import org.apidesign.bck2brwsr.emul.lang.System;
29.41 +
29.42 +final class InfCodes{
29.43 +
29.44 + static final private int[] inflate_mask = {
29.45 + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
29.46 + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff,
29.47 + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff,
29.48 + 0x00007fff, 0x0000ffff
29.49 + };
29.50 +
29.51 + static final private int Z_OK=0;
29.52 + static final private int Z_STREAM_END=1;
29.53 + static final private int Z_NEED_DICT=2;
29.54 + static final private int Z_ERRNO=-1;
29.55 + static final private int Z_STREAM_ERROR=-2;
29.56 + static final private int Z_DATA_ERROR=-3;
29.57 + static final private int Z_MEM_ERROR=-4;
29.58 + static final private int Z_BUF_ERROR=-5;
29.59 + static final private int Z_VERSION_ERROR=-6;
29.60 +
29.61 + // waiting for "i:"=input,
29.62 + // "o:"=output,
29.63 + // "x:"=nothing
29.64 + static final private int START=0; // x: set up for LEN
29.65 + static final private int LEN=1; // i: get length/literal/eob next
29.66 + static final private int LENEXT=2; // i: getting length extra (have base)
29.67 + static final private int DIST=3; // i: get distance next
29.68 + static final private int DISTEXT=4;// i: getting distance extra
29.69 + static final private int COPY=5; // o: copying bytes in window, waiting for space
29.70 + static final private int LIT=6; // o: got literal, waiting for output space
29.71 + static final private int WASH=7; // o: got eob, possibly still output waiting
29.72 + static final private int END=8; // x: got eob and all data flushed
29.73 + static final private int BADCODE=9;// x: got error
29.74 +
29.75 + int mode; // current inflate_codes mode
29.76 +
29.77 + // mode dependent information
29.78 + int len;
29.79 +
29.80 + int[] tree; // pointer into tree
29.81 + int tree_index=0;
29.82 + int need; // bits needed
29.83 +
29.84 + int lit;
29.85 +
29.86 + // if EXT or COPY, where and how much
29.87 + int get; // bits to get for extra
29.88 + int dist; // distance back to copy from
29.89 +
29.90 + byte lbits; // ltree bits decoded per branch
29.91 + byte dbits; // dtree bits decoder per branch
29.92 + int[] ltree; // literal/length/eob tree
29.93 + int ltree_index; // literal/length/eob tree
29.94 + int[] dtree; // distance tree
29.95 + int dtree_index; // distance tree
29.96 +
29.97 + private final ZStream z;
29.98 + private final InfBlocks s;
29.99 + InfCodes(ZStream z, InfBlocks s){
29.100 + this.z=z;
29.101 + this.s=s;
29.102 + }
29.103 +
29.104 + void init(int bl, int bd,
29.105 + int[] tl, int tl_index,
29.106 + int[] td, int td_index){
29.107 + mode=START;
29.108 + lbits=(byte)bl;
29.109 + dbits=(byte)bd;
29.110 + ltree=tl;
29.111 + ltree_index=tl_index;
29.112 + dtree = td;
29.113 + dtree_index=td_index;
29.114 + tree=null;
29.115 + }
29.116 +
29.117 + int proc(int r){
29.118 + int j; // temporary storage
29.119 + int[] t; // temporary pointer
29.120 + int tindex; // temporary pointer
29.121 + int e; // extra bits or operation
29.122 + int b=0; // bit buffer
29.123 + int k=0; // bits in bit buffer
29.124 + int p=0; // input data pointer
29.125 + int n; // bytes available there
29.126 + int q; // output window write pointer
29.127 + int m; // bytes to end of window or read pointer
29.128 + int f; // pointer to copy strings from
29.129 +
29.130 + // copy input/output information to locals (UPDATE macro restores)
29.131 + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk;
29.132 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
29.133 +
29.134 + // process input and output based on current state
29.135 + while (true){
29.136 + switch (mode){
29.137 + // waiting for "i:"=input, "o:"=output, "x:"=nothing
29.138 + case START: // x: set up for LEN
29.139 + if (m >= 258 && n >= 10){
29.140 +
29.141 + s.bitb=b;s.bitk=k;
29.142 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.143 + s.write=q;
29.144 + r = inflate_fast(lbits, dbits,
29.145 + ltree, ltree_index,
29.146 + dtree, dtree_index,
29.147 + s, z);
29.148 +
29.149 + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk;
29.150 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
29.151 +
29.152 + if (r != Z_OK){
29.153 + mode = r == Z_STREAM_END ? WASH : BADCODE;
29.154 + break;
29.155 + }
29.156 + }
29.157 + need = lbits;
29.158 + tree = ltree;
29.159 + tree_index=ltree_index;
29.160 +
29.161 + mode = LEN;
29.162 + case LEN: // i: get length/literal/eob next
29.163 + j = need;
29.164 +
29.165 + while(k<(j)){
29.166 + if(n!=0)r=Z_OK;
29.167 + else{
29.168 +
29.169 + s.bitb=b;s.bitk=k;
29.170 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.171 + s.write=q;
29.172 + return s.inflate_flush(r);
29.173 + }
29.174 + n--;
29.175 + b|=(z.next_in[p++]&0xff)<<k;
29.176 + k+=8;
29.177 + }
29.178 +
29.179 + tindex=(tree_index+(b&inflate_mask[j]))*3;
29.180 +
29.181 + b>>>=(tree[tindex+1]);
29.182 + k-=(tree[tindex+1]);
29.183 +
29.184 + e=tree[tindex];
29.185 +
29.186 + if(e == 0){ // literal
29.187 + lit = tree[tindex+2];
29.188 + mode = LIT;
29.189 + break;
29.190 + }
29.191 + if((e & 16)!=0 ){ // length
29.192 + get = e & 15;
29.193 + len = tree[tindex+2];
29.194 + mode = LENEXT;
29.195 + break;
29.196 + }
29.197 + if ((e & 64) == 0){ // next table
29.198 + need = e;
29.199 + tree_index = tindex/3+tree[tindex+2];
29.200 + break;
29.201 + }
29.202 + if ((e & 32)!=0){ // end of block
29.203 + mode = WASH;
29.204 + break;
29.205 + }
29.206 + mode = BADCODE; // invalid code
29.207 + z.msg = "invalid literal/length code";
29.208 + r = Z_DATA_ERROR;
29.209 +
29.210 + s.bitb=b;s.bitk=k;
29.211 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.212 + s.write=q;
29.213 + return s.inflate_flush(r);
29.214 +
29.215 + case LENEXT: // i: getting length extra (have base)
29.216 + j = get;
29.217 +
29.218 + while(k<(j)){
29.219 + if(n!=0)r=Z_OK;
29.220 + else{
29.221 +
29.222 + s.bitb=b;s.bitk=k;
29.223 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.224 + s.write=q;
29.225 + return s.inflate_flush(r);
29.226 + }
29.227 + n--; b|=(z.next_in[p++]&0xff)<<k;
29.228 + k+=8;
29.229 + }
29.230 +
29.231 + len += (b & inflate_mask[j]);
29.232 +
29.233 + b>>=j;
29.234 + k-=j;
29.235 +
29.236 + need = dbits;
29.237 + tree = dtree;
29.238 + tree_index=dtree_index;
29.239 + mode = DIST;
29.240 + case DIST: // i: get distance next
29.241 + j = need;
29.242 +
29.243 + while(k<(j)){
29.244 + if(n!=0)r=Z_OK;
29.245 + else{
29.246 +
29.247 + s.bitb=b;s.bitk=k;
29.248 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.249 + s.write=q;
29.250 + return s.inflate_flush(r);
29.251 + }
29.252 + n--; b|=(z.next_in[p++]&0xff)<<k;
29.253 + k+=8;
29.254 + }
29.255 +
29.256 + tindex=(tree_index+(b & inflate_mask[j]))*3;
29.257 +
29.258 + b>>=tree[tindex+1];
29.259 + k-=tree[tindex+1];
29.260 +
29.261 + e = (tree[tindex]);
29.262 + if((e & 16)!=0){ // distance
29.263 + get = e & 15;
29.264 + dist = tree[tindex+2];
29.265 + mode = DISTEXT;
29.266 + break;
29.267 + }
29.268 + if ((e & 64) == 0){ // next table
29.269 + need = e;
29.270 + tree_index = tindex/3 + tree[tindex+2];
29.271 + break;
29.272 + }
29.273 + mode = BADCODE; // invalid code
29.274 + z.msg = "invalid distance code";
29.275 + r = Z_DATA_ERROR;
29.276 +
29.277 + s.bitb=b;s.bitk=k;
29.278 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.279 + s.write=q;
29.280 + return s.inflate_flush(r);
29.281 +
29.282 + case DISTEXT: // i: getting distance extra
29.283 + j = get;
29.284 +
29.285 + while(k<(j)){
29.286 + if(n!=0)r=Z_OK;
29.287 + else{
29.288 +
29.289 + s.bitb=b;s.bitk=k;
29.290 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.291 + s.write=q;
29.292 + return s.inflate_flush(r);
29.293 + }
29.294 + n--; b|=(z.next_in[p++]&0xff)<<k;
29.295 + k+=8;
29.296 + }
29.297 +
29.298 + dist += (b & inflate_mask[j]);
29.299 +
29.300 + b>>=j;
29.301 + k-=j;
29.302 +
29.303 + mode = COPY;
29.304 + case COPY: // o: copying bytes in window, waiting for space
29.305 + f = q - dist;
29.306 + while(f < 0){ // modulo window size-"while" instead
29.307 + f += s.end; // of "if" handles invalid distances
29.308 + }
29.309 + while (len!=0){
29.310 +
29.311 + if(m==0){
29.312 + if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
29.313 + if(m==0){
29.314 + s.write=q; r=s.inflate_flush(r);
29.315 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
29.316 +
29.317 + if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
29.318 +
29.319 + if(m==0){
29.320 + s.bitb=b;s.bitk=k;
29.321 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.322 + s.write=q;
29.323 + return s.inflate_flush(r);
29.324 + }
29.325 + }
29.326 + }
29.327 +
29.328 + s.window[q++]=s.window[f++]; m--;
29.329 +
29.330 + if (f == s.end)
29.331 + f = 0;
29.332 + len--;
29.333 + }
29.334 + mode = START;
29.335 + break;
29.336 + case LIT: // o: got literal, waiting for output space
29.337 + if(m==0){
29.338 + if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
29.339 + if(m==0){
29.340 + s.write=q; r=s.inflate_flush(r);
29.341 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
29.342 +
29.343 + if(q==s.end&&s.read!=0){q=0;m=q<s.read?s.read-q-1:s.end-q;}
29.344 + if(m==0){
29.345 + s.bitb=b;s.bitk=k;
29.346 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.347 + s.write=q;
29.348 + return s.inflate_flush(r);
29.349 + }
29.350 + }
29.351 + }
29.352 + r=Z_OK;
29.353 +
29.354 + s.window[q++]=(byte)lit; m--;
29.355 +
29.356 + mode = START;
29.357 + break;
29.358 + case WASH: // o: got eob, possibly more output
29.359 + if (k > 7){ // return unused byte, if any
29.360 + k -= 8;
29.361 + n++;
29.362 + p--; // can always return one
29.363 + }
29.364 +
29.365 + s.write=q; r=s.inflate_flush(r);
29.366 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
29.367 +
29.368 + if (s.read != s.write){
29.369 + s.bitb=b;s.bitk=k;
29.370 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.371 + s.write=q;
29.372 + return s.inflate_flush(r);
29.373 + }
29.374 + mode = END;
29.375 + case END:
29.376 + r = Z_STREAM_END;
29.377 + s.bitb=b;s.bitk=k;
29.378 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.379 + s.write=q;
29.380 + return s.inflate_flush(r);
29.381 +
29.382 + case BADCODE: // x: got error
29.383 +
29.384 + r = Z_DATA_ERROR;
29.385 +
29.386 + s.bitb=b;s.bitk=k;
29.387 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.388 + s.write=q;
29.389 + return s.inflate_flush(r);
29.390 +
29.391 + default:
29.392 + r = Z_STREAM_ERROR;
29.393 +
29.394 + s.bitb=b;s.bitk=k;
29.395 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.396 + s.write=q;
29.397 + return s.inflate_flush(r);
29.398 + }
29.399 + }
29.400 + }
29.401 +
29.402 + void free(ZStream z){
29.403 + // ZFREE(z, c);
29.404 + }
29.405 +
29.406 + // Called with number of bytes left to write in window at least 258
29.407 + // (the maximum string length) and number of input bytes available
29.408 + // at least ten. The ten bytes are six bytes for the longest length/
29.409 + // distance pair plus four bytes for overloading the bit buffer.
29.410 +
29.411 + int inflate_fast(int bl, int bd,
29.412 + int[] tl, int tl_index,
29.413 + int[] td, int td_index,
29.414 + InfBlocks s, ZStream z){
29.415 + int t; // temporary pointer
29.416 + int[] tp; // temporary pointer
29.417 + int tp_index; // temporary pointer
29.418 + int e; // extra bits or operation
29.419 + int b; // bit buffer
29.420 + int k; // bits in bit buffer
29.421 + int p; // input data pointer
29.422 + int n; // bytes available there
29.423 + int q; // output window write pointer
29.424 + int m; // bytes to end of window or read pointer
29.425 + int ml; // mask for literal/length tree
29.426 + int md; // mask for distance tree
29.427 + int c; // bytes to copy
29.428 + int d; // distance back to copy from
29.429 + int r; // copy source pointer
29.430 +
29.431 + int tp_index_t_3; // (tp_index+t)*3
29.432 +
29.433 + // load input, output, bit values
29.434 + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk;
29.435 + q=s.write;m=q<s.read?s.read-q-1:s.end-q;
29.436 +
29.437 + // initialize masks
29.438 + ml = inflate_mask[bl];
29.439 + md = inflate_mask[bd];
29.440 +
29.441 + // do until not enough input or output space for fast loop
29.442 + do { // assume called with m >= 258 && n >= 10
29.443 + // get literal/length code
29.444 + while(k<(20)){ // max bits for literal/length code
29.445 + n--;
29.446 + b|=(z.next_in[p++]&0xff)<<k;k+=8;
29.447 + }
29.448 +
29.449 + t= b&ml;
29.450 + tp=tl;
29.451 + tp_index=tl_index;
29.452 + tp_index_t_3=(tp_index+t)*3;
29.453 + if ((e = tp[tp_index_t_3]) == 0){
29.454 + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
29.455 +
29.456 + s.window[q++] = (byte)tp[tp_index_t_3+2];
29.457 + m--;
29.458 + continue;
29.459 + }
29.460 + do {
29.461 +
29.462 + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
29.463 +
29.464 + if((e&16)!=0){
29.465 + e &= 15;
29.466 + c = tp[tp_index_t_3+2] + ((int)b & inflate_mask[e]);
29.467 +
29.468 + b>>=e; k-=e;
29.469 +
29.470 + // decode distance base of block to copy
29.471 + while(k<(15)){ // max bits for distance code
29.472 + n--;
29.473 + b|=(z.next_in[p++]&0xff)<<k;k+=8;
29.474 + }
29.475 +
29.476 + t= b&md;
29.477 + tp=td;
29.478 + tp_index=td_index;
29.479 + tp_index_t_3=(tp_index+t)*3;
29.480 + e = tp[tp_index_t_3];
29.481 +
29.482 + do {
29.483 +
29.484 + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
29.485 +
29.486 + if((e&16)!=0){
29.487 + // get extra bits to add to distance base
29.488 + e &= 15;
29.489 + while(k<(e)){ // get extra bits (up to 13)
29.490 + n--;
29.491 + b|=(z.next_in[p++]&0xff)<<k;k+=8;
29.492 + }
29.493 +
29.494 + d = tp[tp_index_t_3+2] + (b&inflate_mask[e]);
29.495 +
29.496 + b>>=(e); k-=(e);
29.497 +
29.498 + // do the copy
29.499 + m -= c;
29.500 + if (q >= d){ // offset before dest
29.501 + // just copy
29.502 + r=q-d;
29.503 + if(q-r>0 && 2>(q-r)){
29.504 + s.window[q++]=s.window[r++]; // minimum count is three,
29.505 + s.window[q++]=s.window[r++]; // so unroll loop a little
29.506 + c-=2;
29.507 + }
29.508 + else{
29.509 + System.arraycopy(s.window, r, s.window, q, 2);
29.510 + q+=2; r+=2; c-=2;
29.511 + }
29.512 + }
29.513 + else{ // else offset after destination
29.514 + r=q-d;
29.515 + do{
29.516 + r+=s.end; // force pointer in window
29.517 + }while(r<0); // covers invalid distances
29.518 + e=s.end-r;
29.519 + if(c>e){ // if source crosses,
29.520 + c-=e; // wrapped copy
29.521 + if(q-r>0 && e>(q-r)){
29.522 + do{s.window[q++] = s.window[r++];}
29.523 + while(--e!=0);
29.524 + }
29.525 + else{
29.526 + System.arraycopy(s.window, r, s.window, q, e);
29.527 + q+=e; r+=e; e=0;
29.528 + }
29.529 + r = 0; // copy rest from start of window
29.530 + }
29.531 +
29.532 + }
29.533 +
29.534 + // copy all or what's left
29.535 + if(q-r>0 && c>(q-r)){
29.536 + do{s.window[q++] = s.window[r++];}
29.537 + while(--c!=0);
29.538 + }
29.539 + else{
29.540 + System.arraycopy(s.window, r, s.window, q, c);
29.541 + q+=c; r+=c; c=0;
29.542 + }
29.543 + break;
29.544 + }
29.545 + else if((e&64)==0){
29.546 + t+=tp[tp_index_t_3+2];
29.547 + t+=(b&inflate_mask[e]);
29.548 + tp_index_t_3=(tp_index+t)*3;
29.549 + e=tp[tp_index_t_3];
29.550 + }
29.551 + else{
29.552 + z.msg = "invalid distance code";
29.553 +
29.554 + c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
29.555 +
29.556 + s.bitb=b;s.bitk=k;
29.557 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.558 + s.write=q;
29.559 +
29.560 + return Z_DATA_ERROR;
29.561 + }
29.562 + }
29.563 + while(true);
29.564 + break;
29.565 + }
29.566 +
29.567 + if((e&64)==0){
29.568 + t+=tp[tp_index_t_3+2];
29.569 + t+=(b&inflate_mask[e]);
29.570 + tp_index_t_3=(tp_index+t)*3;
29.571 + if((e=tp[tp_index_t_3])==0){
29.572 +
29.573 + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]);
29.574 +
29.575 + s.window[q++]=(byte)tp[tp_index_t_3+2];
29.576 + m--;
29.577 + break;
29.578 + }
29.579 + }
29.580 + else if((e&32)!=0){
29.581 +
29.582 + c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
29.583 +
29.584 + s.bitb=b;s.bitk=k;
29.585 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.586 + s.write=q;
29.587 +
29.588 + return Z_STREAM_END;
29.589 + }
29.590 + else{
29.591 + z.msg="invalid literal/length code";
29.592 +
29.593 + c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
29.594 +
29.595 + s.bitb=b;s.bitk=k;
29.596 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.597 + s.write=q;
29.598 +
29.599 + return Z_DATA_ERROR;
29.600 + }
29.601 + }
29.602 + while(true);
29.603 + }
29.604 + while(m>=258 && n>= 10);
29.605 +
29.606 + // not enough input or output--restore pointers and return
29.607 + c=z.avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;
29.608 +
29.609 + s.bitb=b;s.bitk=k;
29.610 + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p;
29.611 + s.write=q;
29.612 +
29.613 + return Z_OK;
29.614 + }
29.615 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/InfTree.java Tue Feb 19 15:59:27 2013 +0100
30.3 @@ -0,0 +1,520 @@
30.4 +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
30.5 +/*
30.6 +Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
30.7 +
30.8 +Redistribution and use in source and binary forms, with or without
30.9 +modification, are permitted provided that the following conditions are met:
30.10 +
30.11 + 1. Redistributions of source code must retain the above copyright notice,
30.12 + this list of conditions and the following disclaimer.
30.13 +
30.14 + 2. Redistributions in binary form must reproduce the above copyright
30.15 + notice, this list of conditions and the following disclaimer in
30.16 + the documentation and/or other materials provided with the distribution.
30.17 +
30.18 + 3. The names of the authors may not be used to endorse or promote products
30.19 + derived from this software without specific prior written permission.
30.20 +
30.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
30.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
30.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
30.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
30.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
30.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30.31 + */
30.32 +/*
30.33 + * This program is based on zlib-1.1.3, so all credit should go authors
30.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
30.35 + * and contributors of zlib.
30.36 + */
30.37 +
30.38 +package org.apidesign.bck2brwsr.emul.zip;
30.39 +
30.40 +import org.apidesign.bck2brwsr.emul.lang.System;
30.41 +
30.42 +final class InfTree{
30.43 +
30.44 + static final private int MANY=1440;
30.45 +
30.46 + static final private int Z_OK=0;
30.47 + static final private int Z_STREAM_END=1;
30.48 + static final private int Z_NEED_DICT=2;
30.49 + static final private int Z_ERRNO=-1;
30.50 + static final private int Z_STREAM_ERROR=-2;
30.51 + static final private int Z_DATA_ERROR=-3;
30.52 + static final private int Z_MEM_ERROR=-4;
30.53 + static final private int Z_BUF_ERROR=-5;
30.54 + static final private int Z_VERSION_ERROR=-6;
30.55 +
30.56 + static final int fixed_bl = 9;
30.57 + static final int fixed_bd = 5;
30.58 +
30.59 + static final int[] fixed_tl = {
30.60 + 96,7,256, 0,8,80, 0,8,16, 84,8,115,
30.61 + 82,7,31, 0,8,112, 0,8,48, 0,9,192,
30.62 + 80,7,10, 0,8,96, 0,8,32, 0,9,160,
30.63 + 0,8,0, 0,8,128, 0,8,64, 0,9,224,
30.64 + 80,7,6, 0,8,88, 0,8,24, 0,9,144,
30.65 + 83,7,59, 0,8,120, 0,8,56, 0,9,208,
30.66 + 81,7,17, 0,8,104, 0,8,40, 0,9,176,
30.67 + 0,8,8, 0,8,136, 0,8,72, 0,9,240,
30.68 + 80,7,4, 0,8,84, 0,8,20, 85,8,227,
30.69 + 83,7,43, 0,8,116, 0,8,52, 0,9,200,
30.70 + 81,7,13, 0,8,100, 0,8,36, 0,9,168,
30.71 + 0,8,4, 0,8,132, 0,8,68, 0,9,232,
30.72 + 80,7,8, 0,8,92, 0,8,28, 0,9,152,
30.73 + 84,7,83, 0,8,124, 0,8,60, 0,9,216,
30.74 + 82,7,23, 0,8,108, 0,8,44, 0,9,184,
30.75 + 0,8,12, 0,8,140, 0,8,76, 0,9,248,
30.76 + 80,7,3, 0,8,82, 0,8,18, 85,8,163,
30.77 + 83,7,35, 0,8,114, 0,8,50, 0,9,196,
30.78 + 81,7,11, 0,8,98, 0,8,34, 0,9,164,
30.79 + 0,8,2, 0,8,130, 0,8,66, 0,9,228,
30.80 + 80,7,7, 0,8,90, 0,8,26, 0,9,148,
30.81 + 84,7,67, 0,8,122, 0,8,58, 0,9,212,
30.82 + 82,7,19, 0,8,106, 0,8,42, 0,9,180,
30.83 + 0,8,10, 0,8,138, 0,8,74, 0,9,244,
30.84 + 80,7,5, 0,8,86, 0,8,22, 192,8,0,
30.85 + 83,7,51, 0,8,118, 0,8,54, 0,9,204,
30.86 + 81,7,15, 0,8,102, 0,8,38, 0,9,172,
30.87 + 0,8,6, 0,8,134, 0,8,70, 0,9,236,
30.88 + 80,7,9, 0,8,94, 0,8,30, 0,9,156,
30.89 + 84,7,99, 0,8,126, 0,8,62, 0,9,220,
30.90 + 82,7,27, 0,8,110, 0,8,46, 0,9,188,
30.91 + 0,8,14, 0,8,142, 0,8,78, 0,9,252,
30.92 + 96,7,256, 0,8,81, 0,8,17, 85,8,131,
30.93 + 82,7,31, 0,8,113, 0,8,49, 0,9,194,
30.94 + 80,7,10, 0,8,97, 0,8,33, 0,9,162,
30.95 + 0,8,1, 0,8,129, 0,8,65, 0,9,226,
30.96 + 80,7,6, 0,8,89, 0,8,25, 0,9,146,
30.97 + 83,7,59, 0,8,121, 0,8,57, 0,9,210,
30.98 + 81,7,17, 0,8,105, 0,8,41, 0,9,178,
30.99 + 0,8,9, 0,8,137, 0,8,73, 0,9,242,
30.100 + 80,7,4, 0,8,85, 0,8,21, 80,8,258,
30.101 + 83,7,43, 0,8,117, 0,8,53, 0,9,202,
30.102 + 81,7,13, 0,8,101, 0,8,37, 0,9,170,
30.103 + 0,8,5, 0,8,133, 0,8,69, 0,9,234,
30.104 + 80,7,8, 0,8,93, 0,8,29, 0,9,154,
30.105 + 84,7,83, 0,8,125, 0,8,61, 0,9,218,
30.106 + 82,7,23, 0,8,109, 0,8,45, 0,9,186,
30.107 + 0,8,13, 0,8,141, 0,8,77, 0,9,250,
30.108 + 80,7,3, 0,8,83, 0,8,19, 85,8,195,
30.109 + 83,7,35, 0,8,115, 0,8,51, 0,9,198,
30.110 + 81,7,11, 0,8,99, 0,8,35, 0,9,166,
30.111 + 0,8,3, 0,8,131, 0,8,67, 0,9,230,
30.112 + 80,7,7, 0,8,91, 0,8,27, 0,9,150,
30.113 + 84,7,67, 0,8,123, 0,8,59, 0,9,214,
30.114 + 82,7,19, 0,8,107, 0,8,43, 0,9,182,
30.115 + 0,8,11, 0,8,139, 0,8,75, 0,9,246,
30.116 + 80,7,5, 0,8,87, 0,8,23, 192,8,0,
30.117 + 83,7,51, 0,8,119, 0,8,55, 0,9,206,
30.118 + 81,7,15, 0,8,103, 0,8,39, 0,9,174,
30.119 + 0,8,7, 0,8,135, 0,8,71, 0,9,238,
30.120 + 80,7,9, 0,8,95, 0,8,31, 0,9,158,
30.121 + 84,7,99, 0,8,127, 0,8,63, 0,9,222,
30.122 + 82,7,27, 0,8,111, 0,8,47, 0,9,190,
30.123 + 0,8,15, 0,8,143, 0,8,79, 0,9,254,
30.124 + 96,7,256, 0,8,80, 0,8,16, 84,8,115,
30.125 + 82,7,31, 0,8,112, 0,8,48, 0,9,193,
30.126 +
30.127 + 80,7,10, 0,8,96, 0,8,32, 0,9,161,
30.128 + 0,8,0, 0,8,128, 0,8,64, 0,9,225,
30.129 + 80,7,6, 0,8,88, 0,8,24, 0,9,145,
30.130 + 83,7,59, 0,8,120, 0,8,56, 0,9,209,
30.131 + 81,7,17, 0,8,104, 0,8,40, 0,9,177,
30.132 + 0,8,8, 0,8,136, 0,8,72, 0,9,241,
30.133 + 80,7,4, 0,8,84, 0,8,20, 85,8,227,
30.134 + 83,7,43, 0,8,116, 0,8,52, 0,9,201,
30.135 + 81,7,13, 0,8,100, 0,8,36, 0,9,169,
30.136 + 0,8,4, 0,8,132, 0,8,68, 0,9,233,
30.137 + 80,7,8, 0,8,92, 0,8,28, 0,9,153,
30.138 + 84,7,83, 0,8,124, 0,8,60, 0,9,217,
30.139 + 82,7,23, 0,8,108, 0,8,44, 0,9,185,
30.140 + 0,8,12, 0,8,140, 0,8,76, 0,9,249,
30.141 + 80,7,3, 0,8,82, 0,8,18, 85,8,163,
30.142 + 83,7,35, 0,8,114, 0,8,50, 0,9,197,
30.143 + 81,7,11, 0,8,98, 0,8,34, 0,9,165,
30.144 + 0,8,2, 0,8,130, 0,8,66, 0,9,229,
30.145 + 80,7,7, 0,8,90, 0,8,26, 0,9,149,
30.146 + 84,7,67, 0,8,122, 0,8,58, 0,9,213,
30.147 + 82,7,19, 0,8,106, 0,8,42, 0,9,181,
30.148 + 0,8,10, 0,8,138, 0,8,74, 0,9,245,
30.149 + 80,7,5, 0,8,86, 0,8,22, 192,8,0,
30.150 + 83,7,51, 0,8,118, 0,8,54, 0,9,205,
30.151 + 81,7,15, 0,8,102, 0,8,38, 0,9,173,
30.152 + 0,8,6, 0,8,134, 0,8,70, 0,9,237,
30.153 + 80,7,9, 0,8,94, 0,8,30, 0,9,157,
30.154 + 84,7,99, 0,8,126, 0,8,62, 0,9,221,
30.155 + 82,7,27, 0,8,110, 0,8,46, 0,9,189,
30.156 + 0,8,14, 0,8,142, 0,8,78, 0,9,253,
30.157 + 96,7,256, 0,8,81, 0,8,17, 85,8,131,
30.158 + 82,7,31, 0,8,113, 0,8,49, 0,9,195,
30.159 + 80,7,10, 0,8,97, 0,8,33, 0,9,163,
30.160 + 0,8,1, 0,8,129, 0,8,65, 0,9,227,
30.161 + 80,7,6, 0,8,89, 0,8,25, 0,9,147,
30.162 + 83,7,59, 0,8,121, 0,8,57, 0,9,211,
30.163 + 81,7,17, 0,8,105, 0,8,41, 0,9,179,
30.164 + 0,8,9, 0,8,137, 0,8,73, 0,9,243,
30.165 + 80,7,4, 0,8,85, 0,8,21, 80,8,258,
30.166 + 83,7,43, 0,8,117, 0,8,53, 0,9,203,
30.167 + 81,7,13, 0,8,101, 0,8,37, 0,9,171,
30.168 + 0,8,5, 0,8,133, 0,8,69, 0,9,235,
30.169 + 80,7,8, 0,8,93, 0,8,29, 0,9,155,
30.170 + 84,7,83, 0,8,125, 0,8,61, 0,9,219,
30.171 + 82,7,23, 0,8,109, 0,8,45, 0,9,187,
30.172 + 0,8,13, 0,8,141, 0,8,77, 0,9,251,
30.173 + 80,7,3, 0,8,83, 0,8,19, 85,8,195,
30.174 + 83,7,35, 0,8,115, 0,8,51, 0,9,199,
30.175 + 81,7,11, 0,8,99, 0,8,35, 0,9,167,
30.176 + 0,8,3, 0,8,131, 0,8,67, 0,9,231,
30.177 + 80,7,7, 0,8,91, 0,8,27, 0,9,151,
30.178 + 84,7,67, 0,8,123, 0,8,59, 0,9,215,
30.179 + 82,7,19, 0,8,107, 0,8,43, 0,9,183,
30.180 + 0,8,11, 0,8,139, 0,8,75, 0,9,247,
30.181 + 80,7,5, 0,8,87, 0,8,23, 192,8,0,
30.182 + 83,7,51, 0,8,119, 0,8,55, 0,9,207,
30.183 + 81,7,15, 0,8,103, 0,8,39, 0,9,175,
30.184 + 0,8,7, 0,8,135, 0,8,71, 0,9,239,
30.185 + 80,7,9, 0,8,95, 0,8,31, 0,9,159,
30.186 + 84,7,99, 0,8,127, 0,8,63, 0,9,223,
30.187 + 82,7,27, 0,8,111, 0,8,47, 0,9,191,
30.188 + 0,8,15, 0,8,143, 0,8,79, 0,9,255
30.189 + };
30.190 + static final int[] fixed_td = {
30.191 + 80,5,1, 87,5,257, 83,5,17, 91,5,4097,
30.192 + 81,5,5, 89,5,1025, 85,5,65, 93,5,16385,
30.193 + 80,5,3, 88,5,513, 84,5,33, 92,5,8193,
30.194 + 82,5,9, 90,5,2049, 86,5,129, 192,5,24577,
30.195 + 80,5,2, 87,5,385, 83,5,25, 91,5,6145,
30.196 + 81,5,7, 89,5,1537, 85,5,97, 93,5,24577,
30.197 + 80,5,4, 88,5,769, 84,5,49, 92,5,12289,
30.198 + 82,5,13, 90,5,3073, 86,5,193, 192,5,24577
30.199 + };
30.200 +
30.201 + // Tables for deflate from PKZIP's appnote.txt.
30.202 + static final int[] cplens = { // Copy lengths for literal codes 257..285
30.203 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
30.204 + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
30.205 + };
30.206 +
30.207 + // see note #13 above about 258
30.208 + static final int[] cplext = { // Extra bits for literal codes 257..285
30.209 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
30.210 + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid
30.211 + };
30.212 +
30.213 + static final int[] cpdist = { // Copy offsets for distance codes 0..29
30.214 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
30.215 + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
30.216 + 8193, 12289, 16385, 24577
30.217 + };
30.218 +
30.219 + static final int[] cpdext = { // Extra bits for distance codes
30.220 + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
30.221 + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
30.222 + 12, 12, 13, 13};
30.223 +
30.224 + // If BMAX needs to be larger than 16, then h and x[] should be uLong.
30.225 + static final int BMAX=15; // maximum bit length of any code
30.226 +
30.227 + int[] hn = null; // hufts used in space
30.228 + int[] v = null; // work area for huft_build
30.229 + int[] c = null; // bit length count table
30.230 + int[] r = null; // table entry for structure assignment
30.231 + int[] u = null; // table stack
30.232 + int[] x = null; // bit offsets, then code stack
30.233 +
30.234 + private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX)
30.235 + int bindex,
30.236 + int n, // number of codes (assumed <= 288)
30.237 + int s, // number of simple-valued codes (0..s-1)
30.238 + int[] d, // list of base values for non-simple codes
30.239 + int[] e, // list of extra bits for non-simple codes
30.240 + int[] t, // result: starting table
30.241 + int[] m, // maximum lookup bits, returns actual
30.242 + int[] hp,// space for trees
30.243 + int[] hn,// hufts used in space
30.244 + int[] v // working area: values in order of bit length
30.245 + ){
30.246 + // Given a list of code lengths and a maximum table size, make a set of
30.247 + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
30.248 + // if the given code set is incomplete (the tables are still built in this
30.249 + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
30.250 + // lengths), or Z_MEM_ERROR if not enough memory.
30.251 +
30.252 + int a; // counter for codes of length k
30.253 + int f; // i repeats in table every f entries
30.254 + int g; // maximum code length
30.255 + int h; // table level
30.256 + int i; // counter, current code
30.257 + int j; // counter
30.258 + int k; // number of bits in current code
30.259 + int l; // bits per table (returned in m)
30.260 + int mask; // (1 << w) - 1, to avoid cc -O bug on HP
30.261 + int p; // pointer into c[], b[], or v[]
30.262 + int q; // points to current table
30.263 + int w; // bits before this table == (l * h)
30.264 + int xp; // pointer into x
30.265 + int y; // number of dummy codes added
30.266 + int z; // number of entries in current table
30.267 +
30.268 + // Generate counts for each bit length
30.269 +
30.270 + p = 0; i = n;
30.271 + do {
30.272 + c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX
30.273 + }while(i!=0);
30.274 +
30.275 + if(c[0] == n){ // null input--all zero length codes
30.276 + t[0] = -1;
30.277 + m[0] = 0;
30.278 + return Z_OK;
30.279 + }
30.280 +
30.281 + // Find minimum and maximum length, bound *m by those
30.282 + l = m[0];
30.283 + for (j = 1; j <= BMAX; j++)
30.284 + if(c[j]!=0) break;
30.285 + k = j; // minimum code length
30.286 + if(l < j){
30.287 + l = j;
30.288 + }
30.289 + for (i = BMAX; i!=0; i--){
30.290 + if(c[i]!=0) break;
30.291 + }
30.292 + g = i; // maximum code length
30.293 + if(l > i){
30.294 + l = i;
30.295 + }
30.296 + m[0] = l;
30.297 +
30.298 + // Adjust last length count to fill out codes, if needed
30.299 + for (y = 1 << j; j < i; j++, y <<= 1){
30.300 + if ((y -= c[j]) < 0){
30.301 + return Z_DATA_ERROR;
30.302 + }
30.303 + }
30.304 + if ((y -= c[i]) < 0){
30.305 + return Z_DATA_ERROR;
30.306 + }
30.307 + c[i] += y;
30.308 +
30.309 + // Generate starting offsets into the value table for each length
30.310 + x[1] = j = 0;
30.311 + p = 1; xp = 2;
30.312 + while (--i!=0) { // note that i == g from above
30.313 + x[xp] = (j += c[p]);
30.314 + xp++;
30.315 + p++;
30.316 + }
30.317 +
30.318 + // Make a table of values in order of bit lengths
30.319 + i = 0; p = 0;
30.320 + do {
30.321 + if ((j = b[bindex+p]) != 0){
30.322 + v[x[j]++] = i;
30.323 + }
30.324 + p++;
30.325 + }
30.326 + while (++i < n);
30.327 + n = x[g]; // set n to length of v
30.328 +
30.329 + // Generate the Huffman codes and for each, make the table entries
30.330 + x[0] = i = 0; // first Huffman code is zero
30.331 + p = 0; // grab values in bit order
30.332 + h = -1; // no tables yet--level -1
30.333 + w = -l; // bits decoded == (l * h)
30.334 + u[0] = 0; // just to keep compilers happy
30.335 + q = 0; // ditto
30.336 + z = 0; // ditto
30.337 +
30.338 + // go through the bit lengths (k already is bits in shortest code)
30.339 + for (; k <= g; k++){
30.340 + a = c[k];
30.341 + while (a--!=0){
30.342 + // here i is the Huffman code of length k bits for value *p
30.343 + // make tables up to required level
30.344 + while (k > w + l){
30.345 + h++;
30.346 + w += l; // previous table always l bits
30.347 + // compute minimum size table less than or equal to l bits
30.348 + z = g - w;
30.349 + z = (z > l) ? l : z; // table size upper limit
30.350 + if((f=1<<(j=k-w))>a+1){ // try a k-w bit table
30.351 + // too few codes for k-w bit table
30.352 + f -= a + 1; // deduct codes from patterns left
30.353 + xp = k;
30.354 + if(j < z){
30.355 + while (++j < z){ // try smaller tables up to z bits
30.356 + if((f <<= 1) <= c[++xp])
30.357 + break; // enough codes to use up j bits
30.358 + f -= c[xp]; // else deduct codes from patterns
30.359 + }
30.360 + }
30.361 + }
30.362 + z = 1 << j; // table entries for j-bit table
30.363 +
30.364 + // allocate new table
30.365 + if (hn[0] + z > MANY){ // (note: doesn't matter for fixed)
30.366 + return Z_DATA_ERROR; // overflow of MANY
30.367 + }
30.368 + u[h] = q = /*hp+*/ hn[0]; // DEBUG
30.369 + hn[0] += z;
30.370 +
30.371 + // connect to last table, if there is one
30.372 + if(h!=0){
30.373 + x[h]=i; // save pattern for backing up
30.374 + r[0]=(byte)j; // bits in this table
30.375 + r[1]=(byte)l; // bits to dump before this table
30.376 + j=i>>>(w - l);
30.377 + r[2] = (int)(q - u[h-1] - j); // offset to this table
30.378 + System.arraycopy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table
30.379 + }
30.380 + else{
30.381 + t[0] = q; // first table is returned result
30.382 + }
30.383 + }
30.384 +
30.385 + // set up table entry in r
30.386 + r[1] = (byte)(k - w);
30.387 + if (p >= n){
30.388 + r[0] = 128 + 64; // out of values--invalid code
30.389 + }
30.390 + else if (v[p] < s){
30.391 + r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block
30.392 + r[2] = v[p++]; // simple code is just the value
30.393 + }
30.394 + else{
30.395 + r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists
30.396 + r[2]=d[v[p++] - s];
30.397 + }
30.398 +
30.399 + // fill code-like entries with r
30.400 + f=1<<(k-w);
30.401 + for (j=i>>>w;j<z;j+=f){
30.402 + System.arraycopy(r, 0, hp, (q+j)*3, 3);
30.403 + }
30.404 +
30.405 + // backwards increment the k-bit code i
30.406 + for (j = 1 << (k - 1); (i & j)!=0; j >>>= 1){
30.407 + i ^= j;
30.408 + }
30.409 + i ^= j;
30.410 +
30.411 + // backup over finished tables
30.412 + mask = (1 << w) - 1; // needed on HP, cc -O bug
30.413 + while ((i & mask) != x[h]){
30.414 + h--; // don't need to update q
30.415 + w -= l;
30.416 + mask = (1 << w) - 1;
30.417 + }
30.418 + }
30.419 + }
30.420 + // Return Z_BUF_ERROR if we were given an incomplete table
30.421 + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
30.422 + }
30.423 +
30.424 + int inflate_trees_bits(int[] c, // 19 code lengths
30.425 + int[] bb, // bits tree desired/actual depth
30.426 + int[] tb, // bits tree result
30.427 + int[] hp, // space for trees
30.428 + ZStream z // for messages
30.429 + ){
30.430 + int result;
30.431 + initWorkArea(19);
30.432 + hn[0]=0;
30.433 + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
30.434 +
30.435 + if(result == Z_DATA_ERROR){
30.436 + z.msg = "oversubscribed dynamic bit lengths tree";
30.437 + }
30.438 + else if(result == Z_BUF_ERROR || bb[0] == 0){
30.439 + z.msg = "incomplete dynamic bit lengths tree";
30.440 + result = Z_DATA_ERROR;
30.441 + }
30.442 + return result;
30.443 + }
30.444 +
30.445 + int inflate_trees_dynamic(int nl, // number of literal/length codes
30.446 + int nd, // number of distance codes
30.447 + int[] c, // that many (total) code lengths
30.448 + int[] bl, // literal desired/actual bit depth
30.449 + int[] bd, // distance desired/actual bit depth
30.450 + int[] tl, // literal/length tree result
30.451 + int[] td, // distance tree result
30.452 + int[] hp, // space for trees
30.453 + ZStream z // for messages
30.454 + ){
30.455 + int result;
30.456 +
30.457 + // build literal/length tree
30.458 + initWorkArea(288);
30.459 + hn[0]=0;
30.460 + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
30.461 + if (result != Z_OK || bl[0] == 0){
30.462 + if(result == Z_DATA_ERROR){
30.463 + z.msg = "oversubscribed literal/length tree";
30.464 + }
30.465 + else if (result != Z_MEM_ERROR){
30.466 + z.msg = "incomplete literal/length tree";
30.467 + result = Z_DATA_ERROR;
30.468 + }
30.469 + return result;
30.470 + }
30.471 +
30.472 + // build distance tree
30.473 + initWorkArea(288);
30.474 + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
30.475 +
30.476 + if (result != Z_OK || (bd[0] == 0 && nl > 257)){
30.477 + if (result == Z_DATA_ERROR){
30.478 + z.msg = "oversubscribed distance tree";
30.479 + }
30.480 + else if (result == Z_BUF_ERROR) {
30.481 + z.msg = "incomplete distance tree";
30.482 + result = Z_DATA_ERROR;
30.483 + }
30.484 + else if (result != Z_MEM_ERROR){
30.485 + z.msg = "empty distance tree with lengths";
30.486 + result = Z_DATA_ERROR;
30.487 + }
30.488 + return result;
30.489 + }
30.490 +
30.491 + return Z_OK;
30.492 + }
30.493 +
30.494 + static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth
30.495 + int[] bd, //distance desired/actual bit depth
30.496 + int[][] tl,//literal/length tree result
30.497 + int[][] td,//distance tree result
30.498 + ZStream z //for memory allocation
30.499 + ){
30.500 + bl[0]=fixed_bl;
30.501 + bd[0]=fixed_bd;
30.502 + tl[0]=fixed_tl;
30.503 + td[0]=fixed_td;
30.504 + return Z_OK;
30.505 + }
30.506 +
30.507 + private void initWorkArea(int vsize){
30.508 + if(hn==null){
30.509 + hn=new int[1];
30.510 + v=new int[vsize];
30.511 + c=new int[BMAX+1];
30.512 + r=new int[3];
30.513 + u=new int[BMAX];
30.514 + x=new int[BMAX+1];
30.515 + }
30.516 + if(v.length<vsize){ v=new int[vsize]; }
30.517 + for(int i=0; i<vsize; i++){v[i]=0;}
30.518 + for(int i=0; i<BMAX+1; i++){c[i]=0;}
30.519 + for(int i=0; i<3; i++){r[i]=0;}
30.520 + System.arraycopy(c, 0, u, 0, BMAX);
30.521 + System.arraycopy(c, 0, x, 0, BMAX+1);
30.522 + }
30.523 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Inflate.java Tue Feb 19 15:59:27 2013 +0100
31.3 @@ -0,0 +1,727 @@
31.4 +/* -*-mode:java; c-basic-offset:2; -*- */
31.5 +/*
31.6 +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved.
31.7 +
31.8 +Redistribution and use in source and binary forms, with or without
31.9 +modification, are permitted provided that the following conditions are met:
31.10 +
31.11 + 1. Redistributions of source code must retain the above copyright notice,
31.12 + this list of conditions and the following disclaimer.
31.13 +
31.14 + 2. Redistributions in binary form must reproduce the above copyright
31.15 + notice, this list of conditions and the following disclaimer in
31.16 + the documentation and/or other materials provided with the distribution.
31.17 +
31.18 + 3. The names of the authors may not be used to endorse or promote products
31.19 + derived from this software without specific prior written permission.
31.20 +
31.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
31.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
31.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
31.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
31.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
31.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31.31 + */
31.32 +/*
31.33 + * This program is based on zlib-1.1.3, so all credit should go authors
31.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
31.35 + * and contributors of zlib.
31.36 + */
31.37 +
31.38 +package org.apidesign.bck2brwsr.emul.zip;
31.39 +
31.40 +import org.apidesign.bck2brwsr.emul.lang.System;
31.41 +
31.42 +final class Inflate{
31.43 +
31.44 + static final private int MAX_WBITS=15; // 32K LZ77 window
31.45 +
31.46 + // preset dictionary flag in zlib header
31.47 + static final private int PRESET_DICT=0x20;
31.48 +
31.49 + static final int Z_NO_FLUSH=0;
31.50 + static final int Z_PARTIAL_FLUSH=1;
31.51 + static final int Z_SYNC_FLUSH=2;
31.52 + static final int Z_FULL_FLUSH=3;
31.53 + static final int Z_FINISH=4;
31.54 +
31.55 + static final private int Z_DEFLATED=8;
31.56 +
31.57 + static final private int Z_OK=0;
31.58 + static final private int Z_STREAM_END=1;
31.59 + static final private int Z_NEED_DICT=2;
31.60 + static final private int Z_ERRNO=-1;
31.61 + static final private int Z_STREAM_ERROR=-2;
31.62 + static final private int Z_DATA_ERROR=-3;
31.63 + static final private int Z_MEM_ERROR=-4;
31.64 + static final private int Z_BUF_ERROR=-5;
31.65 + static final private int Z_VERSION_ERROR=-6;
31.66 +
31.67 + static final private int METHOD=0; // waiting for method byte
31.68 + static final private int FLAG=1; // waiting for flag byte
31.69 + static final private int DICT4=2; // four dictionary check bytes to go
31.70 + static final private int DICT3=3; // three dictionary check bytes to go
31.71 + static final private int DICT2=4; // two dictionary check bytes to go
31.72 + static final private int DICT1=5; // one dictionary check byte to go
31.73 + static final int DICT0=6; // waiting for inflateSetDictionary
31.74 + static final private int BLOCKS=7; // decompressing blocks
31.75 + static final private int CHECK4=8; // four check bytes to go
31.76 + static final private int CHECK3=9; // three check bytes to go
31.77 + static final private int CHECK2=10; // two check bytes to go
31.78 + static final private int CHECK1=11; // one check byte to go
31.79 + static final private int DONE=12; // finished check, done
31.80 + static final private int BAD=13; // got an error--stay here
31.81 +
31.82 + static final private int HEAD=14;
31.83 + static final private int LENGTH=15;
31.84 + static final private int TIME=16;
31.85 + static final private int OS=17;
31.86 + static final private int EXLEN=18;
31.87 + static final private int EXTRA=19;
31.88 + static final private int NAME=20;
31.89 + static final private int COMMENT=21;
31.90 + static final private int HCRC=22;
31.91 + static final private int FLAGS=23;
31.92 +
31.93 + int mode; // current inflate mode
31.94 +
31.95 + // mode dependent information
31.96 + int method; // if FLAGS, method byte
31.97 +
31.98 + // if CHECK, check values to compare
31.99 + long was = -1; // computed check value
31.100 + long need; // stream check value
31.101 +
31.102 + // if BAD, inflateSync's marker bytes count
31.103 + int marker;
31.104 +
31.105 + // mode independent information
31.106 + int wrap; // flag for no wrapper
31.107 + int wbits; // log2(window size) (8..15, defaults to 15)
31.108 +
31.109 + InfBlocks blocks; // current inflate_blocks state
31.110 +
31.111 + private final ZStream z;
31.112 +
31.113 + private int flags;
31.114 +
31.115 + private int need_bytes = -1;
31.116 + private byte[] crcbuf=new byte[4];
31.117 +
31.118 + GZIPHeader gheader = null;
31.119 +
31.120 + int inflateReset(){
31.121 + if(z == null) return Z_STREAM_ERROR;
31.122 +
31.123 + z.total_in = z.total_out = 0;
31.124 + z.msg = null;
31.125 + this.mode = HEAD;
31.126 + this.need_bytes = -1;
31.127 + this.blocks.reset();
31.128 + return Z_OK;
31.129 + }
31.130 +
31.131 + int inflateEnd(){
31.132 + if(blocks != null){
31.133 + blocks.free();
31.134 + }
31.135 + return Z_OK;
31.136 + }
31.137 +
31.138 + Inflate(ZStream z){
31.139 + this.z=z;
31.140 + }
31.141 +
31.142 + int inflateInit(int w){
31.143 + z.msg = null;
31.144 + blocks = null;
31.145 +
31.146 + // handle undocumented wrap option (no zlib header or check)
31.147 + wrap = 0;
31.148 + if(w < 0){
31.149 + w = - w;
31.150 + }
31.151 + else {
31.152 + wrap = (w >> 4) + 1;
31.153 + if(w < 48)
31.154 + w &= 15;
31.155 + }
31.156 +
31.157 + if(w<8 ||w>15){
31.158 + inflateEnd();
31.159 + return Z_STREAM_ERROR;
31.160 + }
31.161 + if(blocks != null && wbits != w){
31.162 + blocks.free();
31.163 + blocks=null;
31.164 + }
31.165 +
31.166 + // set window size
31.167 + wbits=w;
31.168 +
31.169 + this.blocks=new InfBlocks(z, 1<<w);
31.170 +
31.171 + // reset state
31.172 + inflateReset();
31.173 +
31.174 + return Z_OK;
31.175 + }
31.176 +
31.177 + int inflate(int f){
31.178 + int hold = 0;
31.179 +
31.180 + int r;
31.181 + int b;
31.182 +
31.183 + if(z == null || z.next_in == null){
31.184 + if(f == Z_FINISH && this.mode==HEAD)
31.185 + return Z_OK;
31.186 + return Z_STREAM_ERROR;
31.187 + }
31.188 +
31.189 + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
31.190 + r = Z_BUF_ERROR;
31.191 + while (true){
31.192 +
31.193 + switch (this.mode){
31.194 + case HEAD:
31.195 + if(wrap==0){
31.196 + this.mode = BLOCKS;
31.197 + break;
31.198 + }
31.199 +
31.200 + try { r=readBytes(2, r, f); }
31.201 + catch(Return e){ return e.r; }
31.202 +
31.203 + if((wrap&2)!=0 && this.need == 0x8b1fL) { // gzip header
31.204 + z.adler=new CRC32();
31.205 + checksum(2, this.need);
31.206 +
31.207 + if(gheader==null)
31.208 + gheader=new GZIPHeader();
31.209 +
31.210 + this.mode = FLAGS;
31.211 + break;
31.212 + }
31.213 +
31.214 + flags = 0;
31.215 +
31.216 + this.method = ((int)this.need)&0xff;
31.217 + b=((int)(this.need>>8))&0xff;
31.218 +
31.219 + if((wrap&1)==0 || // check if zlib header allowed
31.220 + (((this.method << 8)+b) % 31)!=0){
31.221 + this.mode = BAD;
31.222 + z.msg = "incorrect header check";
31.223 + // since zlib 1.2, it is allowted to inflateSync for this case.
31.224 + /*
31.225 + this.marker = 5; // can't try inflateSync
31.226 + */
31.227 + break;
31.228 + }
31.229 +
31.230 + if((this.method&0xf)!=Z_DEFLATED){
31.231 + this.mode = BAD;
31.232 + z.msg="unknown compression method";
31.233 + // since zlib 1.2, it is allowted to inflateSync for this case.
31.234 + /*
31.235 + this.marker = 5; // can't try inflateSync
31.236 + */
31.237 + break;
31.238 + }
31.239 +
31.240 + if((this.method>>4)+8>this.wbits){
31.241 + this.mode = BAD;
31.242 + z.msg="invalid window size";
31.243 + // since zlib 1.2, it is allowted to inflateSync for this case.
31.244 + /*
31.245 + this.marker = 5; // can't try inflateSync
31.246 + */
31.247 + break;
31.248 + }
31.249 +
31.250 + z.adler=new Adler32();
31.251 +
31.252 + if((b&PRESET_DICT)==0){
31.253 + this.mode = BLOCKS;
31.254 + break;
31.255 + }
31.256 + this.mode = DICT4;
31.257 + case DICT4:
31.258 +
31.259 + if(z.avail_in==0)return r;r=f;
31.260 +
31.261 + z.avail_in--; z.total_in++;
31.262 + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
31.263 + this.mode=DICT3;
31.264 + case DICT3:
31.265 +
31.266 + if(z.avail_in==0)return r;r=f;
31.267 +
31.268 + z.avail_in--; z.total_in++;
31.269 + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
31.270 + this.mode=DICT2;
31.271 + case DICT2:
31.272 +
31.273 + if(z.avail_in==0)return r;r=f;
31.274 +
31.275 + z.avail_in--; z.total_in++;
31.276 + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
31.277 + this.mode=DICT1;
31.278 + case DICT1:
31.279 +
31.280 + if(z.avail_in==0)return r;r=f;
31.281 +
31.282 + z.avail_in--; z.total_in++;
31.283 + this.need += (z.next_in[z.next_in_index++]&0xffL);
31.284 + z.adler.reset(this.need);
31.285 + this.mode = DICT0;
31.286 + return Z_NEED_DICT;
31.287 + case DICT0:
31.288 + this.mode = BAD;
31.289 + z.msg = "need dictionary";
31.290 + this.marker = 0; // can try inflateSync
31.291 + return Z_STREAM_ERROR;
31.292 + case BLOCKS:
31.293 + r = this.blocks.proc(r);
31.294 + if(r == Z_DATA_ERROR){
31.295 + this.mode = BAD;
31.296 + this.marker = 0; // can try inflateSync
31.297 + break;
31.298 + }
31.299 + if(r == Z_OK){
31.300 + r = f;
31.301 + }
31.302 + if(r != Z_STREAM_END){
31.303 + return r;
31.304 + }
31.305 + r = f;
31.306 + this.was=z.adler.getValue();
31.307 + this.blocks.reset();
31.308 + if(this.wrap==0){
31.309 + this.mode=DONE;
31.310 + break;
31.311 + }
31.312 + this.mode=CHECK4;
31.313 + case CHECK4:
31.314 +
31.315 + if(z.avail_in==0)return r;r=f;
31.316 +
31.317 + z.avail_in--; z.total_in++;
31.318 + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L;
31.319 + this.mode=CHECK3;
31.320 + case CHECK3:
31.321 +
31.322 + if(z.avail_in==0)return r;r=f;
31.323 +
31.324 + z.avail_in--; z.total_in++;
31.325 + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L;
31.326 + this.mode = CHECK2;
31.327 + case CHECK2:
31.328 +
31.329 + if(z.avail_in==0)return r;r=f;
31.330 +
31.331 + z.avail_in--; z.total_in++;
31.332 + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L;
31.333 + this.mode = CHECK1;
31.334 + case CHECK1:
31.335 +
31.336 + if(z.avail_in==0)return r;r=f;
31.337 +
31.338 + z.avail_in--; z.total_in++;
31.339 + this.need+=(z.next_in[z.next_in_index++]&0xffL);
31.340 +
31.341 + if(flags!=0){ // gzip
31.342 + this.need = ((this.need&0xff000000)>>24 |
31.343 + (this.need&0x00ff0000)>>8 |
31.344 + (this.need&0x0000ff00)<<8 |
31.345 + (this.need&0x0000ffff)<<24)&0xffffffffL;
31.346 + }
31.347 +
31.348 + if(((int)(this.was)) != ((int)(this.need))){
31.349 + z.msg = "incorrect data check";
31.350 + // chack is delayed
31.351 + /*
31.352 + this.mode = BAD;
31.353 + this.marker = 5; // can't try inflateSync
31.354 + break;
31.355 + */
31.356 + }
31.357 + else if(flags!=0 && gheader!=null){
31.358 + gheader.crc = this.need;
31.359 + }
31.360 +
31.361 + this.mode = LENGTH;
31.362 + case LENGTH:
31.363 + if (wrap!=0 && flags!=0) {
31.364 +
31.365 + try { r=readBytes(4, r, f); }
31.366 + catch(Return e){ return e.r; }
31.367 +
31.368 + if(z.msg!=null && z.msg.equals("incorrect data check")){
31.369 + this.mode = BAD;
31.370 + this.marker = 5; // can't try inflateSync
31.371 + break;
31.372 + }
31.373 +
31.374 + if (this.need != (z.total_out & 0xffffffffL)) {
31.375 + z.msg = "incorrect length check";
31.376 + this.mode = BAD;
31.377 + break;
31.378 + }
31.379 + z.msg = null;
31.380 + }
31.381 + else {
31.382 + if(z.msg!=null && z.msg.equals("incorrect data check")){
31.383 + this.mode = BAD;
31.384 + this.marker = 5; // can't try inflateSync
31.385 + break;
31.386 + }
31.387 + }
31.388 +
31.389 + this.mode = DONE;
31.390 + case DONE:
31.391 + return Z_STREAM_END;
31.392 + case BAD:
31.393 + return Z_DATA_ERROR;
31.394 +
31.395 + case FLAGS:
31.396 +
31.397 + try { r=readBytes(2, r, f); }
31.398 + catch(Return e){ return e.r; }
31.399 +
31.400 + flags = ((int)this.need)&0xffff;
31.401 +
31.402 + if ((flags & 0xff) != Z_DEFLATED) {
31.403 + z.msg = "unknown compression method";
31.404 + this.mode = BAD;
31.405 + break;
31.406 + }
31.407 + if ((flags & 0xe000)!=0) {
31.408 + z.msg = "unknown header flags set";
31.409 + this.mode = BAD;
31.410 + break;
31.411 + }
31.412 +
31.413 + if ((flags & 0x0200)!=0){
31.414 + checksum(2, this.need);
31.415 + }
31.416 +
31.417 + this.mode = TIME;
31.418 +
31.419 + case TIME:
31.420 + try { r=readBytes(4, r, f); }
31.421 + catch(Return e){ return e.r; }
31.422 + if(gheader!=null)
31.423 + gheader.time = this.need;
31.424 + if ((flags & 0x0200)!=0){
31.425 + checksum(4, this.need);
31.426 + }
31.427 + this.mode = OS;
31.428 + case OS:
31.429 + try { r=readBytes(2, r, f); }
31.430 + catch(Return e){ return e.r; }
31.431 + if(gheader!=null){
31.432 + gheader.xflags = ((int)this.need)&0xff;
31.433 + gheader.os = (((int)this.need)>>8)&0xff;
31.434 + }
31.435 + if ((flags & 0x0200)!=0){
31.436 + checksum(2, this.need);
31.437 + }
31.438 + this.mode = EXLEN;
31.439 + case EXLEN:
31.440 + if ((flags & 0x0400)!=0) {
31.441 + try { r=readBytes(2, r, f); }
31.442 + catch(Return e){ return e.r; }
31.443 + if(gheader!=null){
31.444 + gheader.extra = new byte[((int)this.need)&0xffff];
31.445 + }
31.446 + if ((flags & 0x0200)!=0){
31.447 + checksum(2, this.need);
31.448 + }
31.449 + }
31.450 + else if(gheader!=null){
31.451 + gheader.extra=null;
31.452 + }
31.453 + this.mode = EXTRA;
31.454 +
31.455 + case EXTRA:
31.456 + if ((flags & 0x0400)!=0) {
31.457 + try {
31.458 + r=readBytes(r, f);
31.459 + if(gheader!=null){
31.460 + byte[] foo = tmp_array;
31.461 + tmp_array=null;
31.462 + if(foo.length == gheader.extra.length){
31.463 + System.arraycopy(foo, 0, gheader.extra, 0, foo.length);
31.464 + }
31.465 + else{
31.466 + z.msg = "bad extra field length";
31.467 + this.mode = BAD;
31.468 + break;
31.469 + }
31.470 + }
31.471 + }
31.472 + catch(Return e){ return e.r; }
31.473 + }
31.474 + else if(gheader!=null){
31.475 + gheader.extra=null;
31.476 + }
31.477 + this.mode = NAME;
31.478 + case NAME:
31.479 + if ((flags & 0x0800)!=0) {
31.480 + try {
31.481 + r=readString(r, f);
31.482 + if(gheader!=null){
31.483 + gheader.name=tmp_array;
31.484 + }
31.485 + tmp_array=null;
31.486 + }
31.487 + catch(Return e){ return e.r; }
31.488 + }
31.489 + else if(gheader!=null){
31.490 + gheader.name=null;
31.491 + }
31.492 + this.mode = COMMENT;
31.493 + case COMMENT:
31.494 + if ((flags & 0x1000)!=0) {
31.495 + try {
31.496 + r=readString(r, f);
31.497 + if(gheader!=null){
31.498 + gheader.comment=tmp_array;
31.499 + }
31.500 + tmp_array=null;
31.501 + }
31.502 + catch(Return e){ return e.r; }
31.503 + }
31.504 + else if(gheader!=null){
31.505 + gheader.comment=null;
31.506 + }
31.507 + this.mode = HCRC;
31.508 + case HCRC:
31.509 + if ((flags & 0x0200)!=0) {
31.510 + try { r=readBytes(2, r, f); }
31.511 + catch(Return e){ return e.r; }
31.512 + if(gheader!=null){
31.513 + gheader.hcrc=(int)(this.need&0xffff);
31.514 + }
31.515 + if(this.need != (z.adler.getValue()&0xffffL)){
31.516 + this.mode = BAD;
31.517 + z.msg = "header crc mismatch";
31.518 + this.marker = 5; // can't try inflateSync
31.519 + break;
31.520 + }
31.521 + }
31.522 + z.adler = new CRC32();
31.523 +
31.524 + this.mode = BLOCKS;
31.525 + break;
31.526 + default:
31.527 + return Z_STREAM_ERROR;
31.528 + }
31.529 + }
31.530 + }
31.531 +
31.532 + int inflateSetDictionary(byte[] dictionary, int dictLength){
31.533 + if(z==null || (this.mode != DICT0 && this.wrap != 0)){
31.534 + return Z_STREAM_ERROR;
31.535 + }
31.536 +
31.537 + int index=0;
31.538 + int length = dictLength;
31.539 +
31.540 + if(this.mode==DICT0){
31.541 + long adler_need=z.adler.getValue();
31.542 + z.adler.reset();
31.543 + z.adler.update(dictionary, 0, dictLength);
31.544 + if(z.adler.getValue()!=adler_need){
31.545 + return Z_DATA_ERROR;
31.546 + }
31.547 + }
31.548 +
31.549 + z.adler.reset();
31.550 +
31.551 + if(length >= (1<<this.wbits)){
31.552 + length = (1<<this.wbits)-1;
31.553 + index=dictLength - length;
31.554 + }
31.555 + this.blocks.set_dictionary(dictionary, index, length);
31.556 + this.mode = BLOCKS;
31.557 + return Z_OK;
31.558 + }
31.559 +
31.560 + static private byte[] mark = {(byte)0, (byte)0, (byte)0xff, (byte)0xff};
31.561 +
31.562 + int inflateSync(){
31.563 + int n; // number of bytes to look at
31.564 + int p; // pointer to bytes
31.565 + int m; // number of marker bytes found in a row
31.566 + long r, w; // temporaries to save total_in and total_out
31.567 +
31.568 + // set up
31.569 + if(z == null)
31.570 + return Z_STREAM_ERROR;
31.571 + if(this.mode != BAD){
31.572 + this.mode = BAD;
31.573 + this.marker = 0;
31.574 + }
31.575 + if((n=z.avail_in)==0)
31.576 + return Z_BUF_ERROR;
31.577 +
31.578 + p=z.next_in_index;
31.579 + m=this.marker;
31.580 + // search
31.581 + while (n!=0 && m < 4){
31.582 + if(z.next_in[p] == mark[m]){
31.583 + m++;
31.584 + }
31.585 + else if(z.next_in[p]!=0){
31.586 + m = 0;
31.587 + }
31.588 + else{
31.589 + m = 4 - m;
31.590 + }
31.591 + p++; n--;
31.592 + }
31.593 +
31.594 + // restore
31.595 + z.total_in += p-z.next_in_index;
31.596 + z.next_in_index = p;
31.597 + z.avail_in = n;
31.598 + this.marker = m;
31.599 +
31.600 + // return no joy or set up to restart on a new block
31.601 + if(m != 4){
31.602 + return Z_DATA_ERROR;
31.603 + }
31.604 + r=z.total_in; w=z.total_out;
31.605 + inflateReset();
31.606 + z.total_in=r; z.total_out = w;
31.607 + this.mode = BLOCKS;
31.608 +
31.609 + return Z_OK;
31.610 + }
31.611 +
31.612 + // Returns true if inflate is currently at the end of a block generated
31.613 + // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
31.614 + // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
31.615 + // but removes the length bytes of the resulting empty stored block. When
31.616 + // decompressing, PPP checks that at the end of input packet, inflate is
31.617 + // waiting for these length bytes.
31.618 + int inflateSyncPoint(){
31.619 + if(z == null || this.blocks == null)
31.620 + return Z_STREAM_ERROR;
31.621 + return this.blocks.sync_point();
31.622 + }
31.623 +
31.624 + private int readBytes(int n, int r, int f) throws Return{
31.625 + if(need_bytes == -1){
31.626 + need_bytes=n;
31.627 + this.need=0;
31.628 + }
31.629 + while(need_bytes>0){
31.630 + if(z.avail_in==0){ throw new Return(r); }; r=f;
31.631 + z.avail_in--; z.total_in++;
31.632 + this.need = this.need |
31.633 + ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8));
31.634 + need_bytes--;
31.635 + }
31.636 + if(n==2){
31.637 + this.need&=0xffffL;
31.638 + }
31.639 + else if(n==4) {
31.640 + this.need&=0xffffffffL;
31.641 + }
31.642 + need_bytes=-1;
31.643 + return r;
31.644 + }
31.645 + class Return extends Exception{
31.646 + int r;
31.647 + Return(int r){this.r=r; }
31.648 + }
31.649 +
31.650 + private byte[] tmp_array;
31.651 + private int readString(int r, int f) throws Return{
31.652 + int b=0;
31.653 + byte[] arr = new byte[4092];
31.654 + int at = 0;
31.655 + do {
31.656 + if(z.avail_in==0){ throw new Return(r); }; r=f;
31.657 + z.avail_in--; z.total_in++;
31.658 + b = z.next_in[z.next_in_index];
31.659 + if(b!=0) arr = append(arr, z.next_in[z.next_in_index], at++);
31.660 + z.adler.update(z.next_in, z.next_in_index, 1);
31.661 + z.next_in_index++;
31.662 + }while(b!=0);
31.663 +
31.664 + tmp_array = copy(arr, at);
31.665 +
31.666 + return r;
31.667 + }
31.668 +
31.669 + private int readBytes(int r, int f) throws Return{
31.670 + int b=0;
31.671 + byte[] arr = new byte[4092];
31.672 + int at = 0;
31.673 + while(this.need>0){
31.674 + if(z.avail_in==0){ throw new Return(r); }; r=f;
31.675 + z.avail_in--; z.total_in++;
31.676 + b = z.next_in[z.next_in_index];
31.677 + arr = append(arr, z.next_in[z.next_in_index], at++);
31.678 + z.adler.update(z.next_in, z.next_in_index, 1);
31.679 + z.next_in_index++;
31.680 + this.need--;
31.681 + }
31.682 +
31.683 + tmp_array = copy(arr, at);
31.684 +
31.685 + return r;
31.686 + }
31.687 +
31.688 + private static byte[] copy(byte[] arr, int len) {
31.689 + byte[] ret = new byte[len];
31.690 + org.apidesign.bck2brwsr.emul.lang.System.arraycopy(arr, 0, ret, 0, len);
31.691 + return ret;
31.692 + }
31.693 + private static byte[] append(byte[] arr, byte b, int index) {
31.694 + arr[index] = b;
31.695 + return arr;
31.696 + }
31.697 +
31.698 + private void checksum(int n, long v){
31.699 + for(int i=0; i<n; i++){
31.700 + crcbuf[i]=(byte)(v&0xff);
31.701 + v>>=8;
31.702 + }
31.703 + z.adler.update(crcbuf, 0, n);
31.704 + }
31.705 +
31.706 + public GZIPHeader getGZIPHeader(){
31.707 + return gheader;
31.708 + }
31.709 +
31.710 + boolean inParsingHeader(){
31.711 + switch(mode){
31.712 + case HEAD:
31.713 + case DICT4:
31.714 + case DICT3:
31.715 + case DICT2:
31.716 + case DICT1:
31.717 + case FLAGS:
31.718 + case TIME:
31.719 + case OS:
31.720 + case EXLEN:
31.721 + case EXTRA:
31.722 + case NAME:
31.723 + case COMMENT:
31.724 + case HCRC:
31.725 + return true;
31.726 + default:
31.727 + return false;
31.728 + }
31.729 + }
31.730 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Inflater.java Tue Feb 19 15:59:27 2013 +0100
32.3 @@ -0,0 +1,338 @@
32.4 +/*
32.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
32.7 + *
32.8 + * This code is free software; you can redistribute it and/or modify it
32.9 + * under the terms of the GNU General Public License version 2 only, as
32.10 + * published by the Free Software Foundation. Oracle designates this
32.11 + * particular file as subject to the "Classpath" exception as provided
32.12 + * by Oracle in the LICENSE file that accompanied this code.
32.13 + *
32.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
32.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32.17 + * version 2 for more details (a copy is included in the LICENSE file that
32.18 + * accompanied this code).
32.19 + *
32.20 + * You should have received a copy of the GNU General Public License version
32.21 + * 2 along with this work; if not, write to the Free Software Foundation,
32.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
32.23 + *
32.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
32.25 + * or visit www.oracle.com if you need additional information or have any
32.26 + * questions.
32.27 + */
32.28 +
32.29 +package org.apidesign.bck2brwsr.emul.zip;
32.30 +
32.31 +import java.util.zip.*;
32.32 +import java.io.IOException;
32.33 +
32.34 +/**
32.35 + * This class provides support for general purpose decompression using the
32.36 + * popular ZLIB compression library. The ZLIB compression library was
32.37 + * initially developed as part of the PNG graphics standard and is not
32.38 + * protected by patents. It is fully described in the specifications at
32.39 + * the <a href="package-summary.html#package_description">java.util.zip
32.40 + * package description</a>.
32.41 + *
32.42 + * <p>The following code fragment demonstrates a trivial compression
32.43 + * and decompression of a string using <tt>Deflater</tt> and
32.44 + * <tt>Inflater</tt>.
32.45 + *
32.46 + * <blockquote><pre>
32.47 + * try {
32.48 + * // Encode a String into bytes
32.49 + * String inputString = "blahblahblah\u20AC\u20AC";
32.50 + * byte[] input = inputString.getBytes("UTF-8");
32.51 + *
32.52 + * // Compress the bytes
32.53 + * byte[] output = new byte[100];
32.54 + * Deflater compresser = new Deflater();
32.55 + * compresser.setInput(input);
32.56 + * compresser.finish();
32.57 + * int compressedDataLength = compresser.deflate(output);
32.58 + *
32.59 + * // Decompress the bytes
32.60 + * Inflater decompresser = new Inflater();
32.61 + * decompresser.setInput(output, 0, compressedDataLength);
32.62 + * byte[] result = new byte[100];
32.63 + * int resultLength = decompresser.inflate(result);
32.64 + * decompresser.end();
32.65 + *
32.66 + * // Decode the bytes into a String
32.67 + * String outputString = new String(result, 0, resultLength, "UTF-8");
32.68 + * } catch(java.io.UnsupportedEncodingException ex) {
32.69 + * // handle
32.70 + * } catch (java.util.zip.DataFormatException ex) {
32.71 + * // handle
32.72 + * }
32.73 + * </pre></blockquote>
32.74 + *
32.75 + * @see Deflater
32.76 + * @author David Connelly
32.77 + *
32.78 + */
32.79 +public
32.80 +class Inflater extends java.util.zip.Inflater {
32.81 + private final boolean nowrap;
32.82 + private JzLibInflater impl;
32.83 +
32.84 + /**
32.85 + * Creates a new decompressor. If the parameter 'nowrap' is true then
32.86 + * the ZLIB header and checksum fields will not be used. This provides
32.87 + * compatibility with the compression format used by both GZIP and PKZIP.
32.88 + * <p>
32.89 + * Note: When using the 'nowrap' option it is also necessary to provide
32.90 + * an extra "dummy" byte as input. This is required by the ZLIB native
32.91 + * library in order to support certain optimizations.
32.92 + *
32.93 + * @param nowrap if true then support GZIP compatible compression
32.94 + */
32.95 + public Inflater(boolean nowrap) {
32.96 + this.nowrap = nowrap;
32.97 + reset();
32.98 + }
32.99 +
32.100 + /**
32.101 + * Creates a new decompressor.
32.102 + */
32.103 + public Inflater() {
32.104 + this(false);
32.105 + }
32.106 +
32.107 + /**
32.108 + * Sets input data for decompression. Should be called whenever
32.109 + * needsInput() returns true indicating that more input data is
32.110 + * required.
32.111 + * @param b the input data bytes
32.112 + * @param off the start offset of the input data
32.113 + * @param len the length of the input data
32.114 + * @see Inflater#needsInput
32.115 + */
32.116 + public void setInput(byte[] b, int off, int len) {
32.117 + if (b == null) {
32.118 + throw new NullPointerException();
32.119 + }
32.120 + if (off < 0 || len < 0 || off > b.length - len) {
32.121 + throw new ArrayIndexOutOfBoundsException();
32.122 + }
32.123 + impl.setInput(b, off, len, false);
32.124 + }
32.125 +
32.126 + /**
32.127 + * Sets input data for decompression. Should be called whenever
32.128 + * needsInput() returns true indicating that more input data is
32.129 + * required.
32.130 + * @param b the input data bytes
32.131 + * @see Inflater#needsInput
32.132 + */
32.133 + public void setInput(byte[] b) {
32.134 + setInput(b, 0, b.length);
32.135 + }
32.136 +
32.137 + /**
32.138 + * Sets the preset dictionary to the given array of bytes. Should be
32.139 + * called when inflate() returns 0 and needsDictionary() returns true
32.140 + * indicating that a preset dictionary is required. The method getAdler()
32.141 + * can be used to get the Adler-32 value of the dictionary needed.
32.142 + * @param b the dictionary data bytes
32.143 + * @param off the start offset of the data
32.144 + * @param len the length of the data
32.145 + * @see Inflater#needsDictionary
32.146 + * @see Inflater#getAdler
32.147 + */
32.148 + public void setDictionary(byte[] b, int off, int len) {
32.149 + if (b == null) {
32.150 + throw new NullPointerException();
32.151 + }
32.152 + if (off < 0 || len < 0 || off > b.length - len) {
32.153 + throw new ArrayIndexOutOfBoundsException();
32.154 + }
32.155 + byte[] arr;
32.156 + if (off == 0) {
32.157 + arr = b;
32.158 + } else {
32.159 + arr = new byte[len];
32.160 + org.apidesign.bck2brwsr.emul.lang.System.arraycopy(b, off, arr, 0, len);
32.161 + }
32.162 + impl.setDictionary(arr, len);
32.163 + }
32.164 +
32.165 + /**
32.166 + * Sets the preset dictionary to the given array of bytes. Should be
32.167 + * called when inflate() returns 0 and needsDictionary() returns true
32.168 + * indicating that a preset dictionary is required. The method getAdler()
32.169 + * can be used to get the Adler-32 value of the dictionary needed.
32.170 + * @param b the dictionary data bytes
32.171 + * @see Inflater#needsDictionary
32.172 + * @see Inflater#getAdler
32.173 + */
32.174 + public void setDictionary(byte[] b) {
32.175 + impl.setDictionary(b, b.length);
32.176 + }
32.177 +
32.178 + /**
32.179 + * Returns the total number of bytes remaining in the input buffer.
32.180 + * This can be used to find out what bytes still remain in the input
32.181 + * buffer after decompression has finished.
32.182 + * @return the total number of bytes remaining in the input buffer
32.183 + */
32.184 + public int getRemaining() {
32.185 + return impl.getAvailIn();
32.186 + }
32.187 +
32.188 + /**
32.189 + * Returns true if no data remains in the input buffer. This can
32.190 + * be used to determine if #setInput should be called in order
32.191 + * to provide more input.
32.192 + * @return true if no data remains in the input buffer
32.193 + */
32.194 + public boolean needsInput() {
32.195 + return getRemaining() <= 0;
32.196 + }
32.197 +
32.198 + /**
32.199 + * Returns true if a preset dictionary is needed for decompression.
32.200 + * @return true if a preset dictionary is needed for decompression
32.201 + * @see Inflater#setDictionary
32.202 + */
32.203 + public boolean needsDictionary() {
32.204 + return impl.needDict();
32.205 + }
32.206 +
32.207 + /**
32.208 + * Returns true if the end of the compressed data stream has been
32.209 + * reached.
32.210 + * @return true if the end of the compressed data stream has been
32.211 + * reached
32.212 + */
32.213 + public boolean finished() {
32.214 + return impl.finished();
32.215 + }
32.216 +
32.217 + /**
32.218 + * Uncompresses bytes into specified buffer. Returns actual number
32.219 + * of bytes uncompressed. A return value of 0 indicates that
32.220 + * needsInput() or needsDictionary() should be called in order to
32.221 + * determine if more input data or a preset dictionary is required.
32.222 + * In the latter case, getAdler() can be used to get the Adler-32
32.223 + * value of the dictionary required.
32.224 + * @param b the buffer for the uncompressed data
32.225 + * @param off the start offset of the data
32.226 + * @param len the maximum number of uncompressed bytes
32.227 + * @return the actual number of uncompressed bytes
32.228 + * @exception DataFormatException if the compressed data format is invalid
32.229 + * @see Inflater#needsInput
32.230 + * @see Inflater#needsDictionary
32.231 + */
32.232 + public int inflate(byte[] b, int off, int len)
32.233 + throws DataFormatException
32.234 + {
32.235 + if (b == null) {
32.236 + throw new NullPointerException();
32.237 + }
32.238 + if (off < 0 || len < 0 || off > b.length - len) {
32.239 + throw new ArrayIndexOutOfBoundsException();
32.240 + }
32.241 + impl.setOutput(b, off, len);
32.242 + int err = impl.inflate(JzLibInflater.Z_NO_FLUSH);
32.243 + return impl.next_out_index - off;
32.244 + }
32.245 +
32.246 + /**
32.247 + * Uncompresses bytes into specified buffer. Returns actual number
32.248 + * of bytes uncompressed. A return value of 0 indicates that
32.249 + * needsInput() or needsDictionary() should be called in order to
32.250 + * determine if more input data or a preset dictionary is required.
32.251 + * In the latter case, getAdler() can be used to get the Adler-32
32.252 + * value of the dictionary required.
32.253 + * @param b the buffer for the uncompressed data
32.254 + * @return the actual number of uncompressed bytes
32.255 + * @exception DataFormatException if the compressed data format is invalid
32.256 + * @see Inflater#needsInput
32.257 + * @see Inflater#needsDictionary
32.258 + */
32.259 + public int inflate(byte[] b) throws DataFormatException {
32.260 + return inflate(b, 0, b.length);
32.261 + }
32.262 +
32.263 + /**
32.264 + * Returns the ADLER-32 value of the uncompressed data.
32.265 + * @return the ADLER-32 value of the uncompressed data
32.266 + */
32.267 + public int getAdler() {
32.268 + return (int) impl.getAdler();
32.269 + }
32.270 +
32.271 + /**
32.272 + * Returns the total number of compressed bytes input so far.
32.273 + *
32.274 + * <p>Since the number of bytes may be greater than
32.275 + * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now
32.276 + * the preferred means of obtaining this information.</p>
32.277 + *
32.278 + * @return the total number of compressed bytes input so far
32.279 + */
32.280 + public int getTotalIn() {
32.281 + return (int) getBytesRead();
32.282 + }
32.283 +
32.284 + /**
32.285 + * Returns the total number of compressed bytes input so far.</p>
32.286 + *
32.287 + * @return the total (non-negative) number of compressed bytes input so far
32.288 + * @since 1.5
32.289 + */
32.290 + public long getBytesRead() {
32.291 + return impl.total_in;
32.292 + }
32.293 +
32.294 + /**
32.295 + * Returns the total number of uncompressed bytes output so far.
32.296 + *
32.297 + * <p>Since the number of bytes may be greater than
32.298 + * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now
32.299 + * the preferred means of obtaining this information.</p>
32.300 + *
32.301 + * @return the total number of uncompressed bytes output so far
32.302 + */
32.303 + public int getTotalOut() {
32.304 + return (int) getBytesWritten();
32.305 + }
32.306 +
32.307 + /**
32.308 + * Returns the total number of uncompressed bytes output so far.</p>
32.309 + *
32.310 + * @return the total (non-negative) number of uncompressed bytes output so far
32.311 + * @since 1.5
32.312 + */
32.313 + public long getBytesWritten() {
32.314 + return impl.total_out;
32.315 + }
32.316 +
32.317 + /**
32.318 + * Resets inflater so that a new set of input data can be processed.
32.319 + */
32.320 + public void reset() {
32.321 + impl = new JzLibInflater(15, nowrap);
32.322 + }
32.323 +
32.324 + /**
32.325 + * Closes the decompressor and discards any unprocessed input.
32.326 + * This method should be called when the decompressor is no longer
32.327 + * being used, but will also be called automatically by the finalize()
32.328 + * method. Once this method is called, the behavior of the Inflater
32.329 + * object is undefined.
32.330 + */
32.331 + public void end() {
32.332 + impl.end();
32.333 + }
32.334 +
32.335 + /**
32.336 + * Closes the decompressor when garbage is collected.
32.337 + */
32.338 + protected void finalize() {
32.339 + end();
32.340 + }
32.341 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/JzLibInflater.java Tue Feb 19 15:59:27 2013 +0100
33.3 @@ -0,0 +1,137 @@
33.4 +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
33.5 +/*
33.6 +Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
33.7 +
33.8 +Redistribution and use in source and binary forms, with or without
33.9 +modification, are permitted provided that the following conditions are met:
33.10 +
33.11 + 1. Redistributions of source code must retain the above copyright notice,
33.12 + this list of conditions and the following disclaimer.
33.13 +
33.14 + 2. Redistributions in binary form must reproduce the above copyright
33.15 + notice, this list of conditions and the following disclaimer in
33.16 + the documentation and/or other materials provided with the distribution.
33.17 +
33.18 + 3. The names of the authors may not be used to endorse or promote products
33.19 + derived from this software without specific prior written permission.
33.20 +
33.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
33.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
33.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
33.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
33.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
33.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
33.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33.31 + */
33.32 +/*
33.33 + * This program is based on zlib-1.1.3, so all credit should go authors
33.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
33.35 + * and contributors of zlib.
33.36 + */
33.37 +
33.38 +package org.apidesign.bck2brwsr.emul.zip;
33.39 +
33.40 +final class JzLibInflater extends ZStream{
33.41 +
33.42 + static final private int MAX_WBITS=15; // 32K LZ77 window
33.43 + static final private int DEF_WBITS=MAX_WBITS;
33.44 +
33.45 + public static final int Z_NO_FLUSH=0;
33.46 + static final private int Z_PARTIAL_FLUSH=1;
33.47 + static final private int Z_SYNC_FLUSH=2;
33.48 + static final private int Z_FULL_FLUSH=3;
33.49 + static final private int Z_FINISH=4;
33.50 +
33.51 + static final private int MAX_MEM_LEVEL=9;
33.52 +
33.53 + static final private int Z_OK=0;
33.54 + static final private int Z_STREAM_END=1;
33.55 + static final private int Z_NEED_DICT=2;
33.56 + static final private int Z_ERRNO=-1;
33.57 + static final private int Z_STREAM_ERROR=-2;
33.58 + static final private int Z_DATA_ERROR=-3;
33.59 + static final private int Z_MEM_ERROR=-4;
33.60 + static final private int Z_BUF_ERROR=-5;
33.61 + static final private int Z_VERSION_ERROR=-6;
33.62 +
33.63 + public JzLibInflater() {
33.64 + super();
33.65 + init();
33.66 + }
33.67 +
33.68 + public JzLibInflater(int w) {
33.69 + this(w, false);
33.70 + }
33.71 +
33.72 + public JzLibInflater(int w, boolean nowrap) {
33.73 + super();
33.74 + int ret = init(w, nowrap);
33.75 + if(ret!=Z_OK)
33.76 + throw new IllegalStateException(ret+": "+msg);
33.77 + }
33.78 +
33.79 + private boolean finished = false;
33.80 +
33.81 + public int init(){
33.82 + return init(DEF_WBITS);
33.83 + }
33.84 +
33.85 + public int init(boolean nowrap){
33.86 + return init(DEF_WBITS, nowrap);
33.87 + }
33.88 +
33.89 + public int init(int w){
33.90 + return init(w, false);
33.91 + }
33.92 +
33.93 + public int init(int w, boolean nowrap){
33.94 + finished = false;
33.95 + istate=new Inflate(this);
33.96 + return istate.inflateInit(nowrap?-w:w);
33.97 + }
33.98 +
33.99 + public int inflate(int f){
33.100 + if(istate==null) return Z_STREAM_ERROR;
33.101 + int ret = istate.inflate(f);
33.102 + if(ret == Z_STREAM_END)
33.103 + finished = true;
33.104 + return ret;
33.105 + }
33.106 +
33.107 + public int end(){
33.108 + finished = true;
33.109 + if(istate==null) return Z_STREAM_ERROR;
33.110 + int ret=istate.inflateEnd();
33.111 +// istate = null;
33.112 + return ret;
33.113 + }
33.114 +
33.115 + public int sync(){
33.116 + if(istate == null)
33.117 + return Z_STREAM_ERROR;
33.118 + return istate.inflateSync();
33.119 + }
33.120 +
33.121 + public int syncPoint(){
33.122 + if(istate == null)
33.123 + return Z_STREAM_ERROR;
33.124 + return istate.inflateSyncPoint();
33.125 + }
33.126 +
33.127 + public int setDictionary(byte[] dictionary, int dictLength){
33.128 + if(istate == null)
33.129 + return Z_STREAM_ERROR;
33.130 + return istate.inflateSetDictionary(dictionary, dictLength);
33.131 + }
33.132 +
33.133 + public boolean finished(){
33.134 + return istate.mode==12 /*DONE*/;
33.135 + }
33.136 +
33.137 + public boolean needDict() {
33.138 + return istate == null ? false : istate.mode == Inflate.DICT0;
33.139 + }
33.140 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZStream.java Tue Feb 19 15:59:27 2013 +0100
34.3 @@ -0,0 +1,253 @@
34.4 +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
34.5 +/*
34.6 +Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved.
34.7 +
34.8 +Redistribution and use in source and binary forms, with or without
34.9 +modification, are permitted provided that the following conditions are met:
34.10 +
34.11 + 1. Redistributions of source code must retain the above copyright notice,
34.12 + this list of conditions and the following disclaimer.
34.13 +
34.14 + 2. Redistributions in binary form must reproduce the above copyright
34.15 + notice, this list of conditions and the following disclaimer in
34.16 + the documentation and/or other materials provided with the distribution.
34.17 +
34.18 + 3. The names of the authors may not be used to endorse or promote products
34.19 + derived from this software without specific prior written permission.
34.20 +
34.21 +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
34.22 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34.23 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
34.24 +INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
34.25 +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34.26 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
34.27 +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34.28 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34.29 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
34.30 +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34.31 + */
34.32 +/*
34.33 + * This program is based on zlib-1.1.3, so all credit should go authors
34.34 + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
34.35 + * and contributors of zlib.
34.36 + */
34.37 +
34.38 +package org.apidesign.bck2brwsr.emul.zip;
34.39 +
34.40 +import org.apidesign.bck2brwsr.emul.lang.System;
34.41 +
34.42 +/**
34.43 + * ZStream
34.44 + *
34.45 + * @deprecated Not for public use in the future.
34.46 + */
34.47 +@Deprecated
34.48 +class ZStream{
34.49 +
34.50 + static final private int MAX_WBITS=15; // 32K LZ77 window
34.51 + static final private int DEF_WBITS=MAX_WBITS;
34.52 +
34.53 + static final private int Z_NO_FLUSH=0;
34.54 + static final private int Z_PARTIAL_FLUSH=1;
34.55 + static final private int Z_SYNC_FLUSH=2;
34.56 + static final private int Z_FULL_FLUSH=3;
34.57 + static final private int Z_FINISH=4;
34.58 +
34.59 + static final private int MAX_MEM_LEVEL=9;
34.60 +
34.61 + static final private int Z_OK=0;
34.62 + static final private int Z_STREAM_END=1;
34.63 + static final private int Z_NEED_DICT=2;
34.64 + static final private int Z_ERRNO=-1;
34.65 + static final private int Z_STREAM_ERROR=-2;
34.66 + static final private int Z_DATA_ERROR=-3;
34.67 + static final private int Z_MEM_ERROR=-4;
34.68 + static final private int Z_BUF_ERROR=-5;
34.69 + static final private int Z_VERSION_ERROR=-6;
34.70 +
34.71 + public byte[] next_in; // next input byte
34.72 + public int next_in_index;
34.73 + public int avail_in; // number of bytes available at next_in
34.74 + public long total_in; // total nb of input bytes read so far
34.75 +
34.76 + public byte[] next_out; // next output byte should be put there
34.77 + public int next_out_index;
34.78 + public int avail_out; // remaining free space at next_out
34.79 + public long total_out; // total nb of bytes output so far
34.80 +
34.81 + public String msg;
34.82 +
34.83 + Inflate istate;
34.84 +
34.85 + int data_type; // best guess about the data type: ascii or binary
34.86 +
34.87 + Checksum adler;
34.88 +
34.89 + public ZStream(){
34.90 + this(new Adler32());
34.91 + }
34.92 +
34.93 + public ZStream(Checksum adler){
34.94 + this.adler=adler;
34.95 + }
34.96 +
34.97 + public int inflateInit(){
34.98 + return inflateInit(DEF_WBITS);
34.99 + }
34.100 + public int inflateInit(boolean nowrap){
34.101 + return inflateInit(DEF_WBITS, nowrap);
34.102 + }
34.103 + public int inflateInit(int w){
34.104 + return inflateInit(w, false);
34.105 + }
34.106 +
34.107 + public int inflateInit(int w, boolean nowrap){
34.108 + istate=new Inflate(this);
34.109 + return istate.inflateInit(nowrap?-w:w);
34.110 + }
34.111 +
34.112 + public int inflate(int f){
34.113 + if(istate==null) return Z_STREAM_ERROR;
34.114 + return istate.inflate(f);
34.115 + }
34.116 + public int inflateEnd(){
34.117 + if(istate==null) return Z_STREAM_ERROR;
34.118 + int ret=istate.inflateEnd();
34.119 +// istate = null;
34.120 + return ret;
34.121 + }
34.122 +
34.123 + public int inflateSync(){
34.124 + if(istate == null)
34.125 + return Z_STREAM_ERROR;
34.126 + return istate.inflateSync();
34.127 + }
34.128 + public int inflateSyncPoint(){
34.129 + if(istate == null)
34.130 + return Z_STREAM_ERROR;
34.131 + return istate.inflateSyncPoint();
34.132 + }
34.133 + public int inflateSetDictionary(byte[] dictionary, int dictLength){
34.134 + if(istate == null)
34.135 + return Z_STREAM_ERROR;
34.136 + return istate.inflateSetDictionary(dictionary, dictLength);
34.137 + }
34.138 + public boolean inflateFinished(){
34.139 + return istate.mode==12 /*DONE*/;
34.140 + }
34.141 +
34.142 +
34.143 + public long getAdler(){
34.144 + return adler.getValue();
34.145 + }
34.146 +
34.147 + public void free(){
34.148 + next_in=null;
34.149 + next_out=null;
34.150 + msg=null;
34.151 + }
34.152 +
34.153 + public void setOutput(byte[] buf){
34.154 + setOutput(buf, 0, buf.length);
34.155 + }
34.156 +
34.157 + public void setOutput(byte[] buf, int off, int len){
34.158 + next_out = buf;
34.159 + next_out_index = off;
34.160 + avail_out = len;
34.161 + }
34.162 +
34.163 + public void setInput(byte[] buf){
34.164 + setInput(buf, 0, buf.length, false);
34.165 + }
34.166 +
34.167 + public void setInput(byte[] buf, boolean append){
34.168 + setInput(buf, 0, buf.length, append);
34.169 + }
34.170 +
34.171 + public void setInput(byte[] buf, int off, int len, boolean append){
34.172 + if(len<=0 && append && next_in!=null) return;
34.173 +
34.174 + if(avail_in>0 && append){
34.175 + byte[] tmp = new byte[avail_in+len];
34.176 + System.arraycopy(next_in, next_in_index, tmp, 0, avail_in);
34.177 + System.arraycopy(buf, off, tmp, avail_in, len);
34.178 + next_in=tmp;
34.179 + next_in_index=0;
34.180 + avail_in+=len;
34.181 + }
34.182 + else{
34.183 + next_in=buf;
34.184 + next_in_index=off;
34.185 + avail_in=len;
34.186 + }
34.187 + }
34.188 +
34.189 + public byte[] getNextIn(){
34.190 + return next_in;
34.191 + }
34.192 +
34.193 + public void setNextIn(byte[] next_in){
34.194 + this.next_in = next_in;
34.195 + }
34.196 +
34.197 + public int getNextInIndex(){
34.198 + return next_in_index;
34.199 + }
34.200 +
34.201 + public void setNextInIndex(int next_in_index){
34.202 + this.next_in_index = next_in_index;
34.203 + }
34.204 +
34.205 + public int getAvailIn(){
34.206 + return avail_in;
34.207 + }
34.208 +
34.209 + public void setAvailIn(int avail_in){
34.210 + this.avail_in = avail_in;
34.211 + }
34.212 +
34.213 + public byte[] getNextOut(){
34.214 + return next_out;
34.215 + }
34.216 +
34.217 + public void setNextOut(byte[] next_out){
34.218 + this.next_out = next_out;
34.219 + }
34.220 +
34.221 + public int getNextOutIndex(){
34.222 + return next_out_index;
34.223 + }
34.224 +
34.225 + public void setNextOutIndex(int next_out_index){
34.226 + this.next_out_index = next_out_index;
34.227 + }
34.228 +
34.229 + public int getAvailOut(){
34.230 + return avail_out;
34.231 +
34.232 + }
34.233 +
34.234 + public void setAvailOut(int avail_out){
34.235 + this.avail_out = avail_out;
34.236 + }
34.237 +
34.238 + public long getTotalOut(){
34.239 + return total_out;
34.240 + }
34.241 +
34.242 + public long getTotalIn(){
34.243 + return total_in;
34.244 + }
34.245 +
34.246 + public String getMessage(){
34.247 + return msg;
34.248 + }
34.249 +
34.250 + /**
34.251 + * Those methods are expected to be override by Inflater and Deflater.
34.252 + * In the future, they will become abstract methods.
34.253 + */
34.254 + public int end(){ return Z_OK; }
34.255 + public boolean finished(){ return false; }
34.256 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZipConstants64.java Tue Feb 19 15:59:27 2013 +0100
35.3 @@ -0,0 +1,84 @@
35.4 +/*
35.5 + * Copyright (c) 1995, 1996, Oracle and/or its affiliates. All rights reserved.
35.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
35.7 + *
35.8 + * This code is free software; you can redistribute it and/or modify it
35.9 + * under the terms of the GNU General Public License version 2 only, as
35.10 + * published by the Free Software Foundation. Oracle designates this
35.11 + * particular file as subject to the "Classpath" exception as provided
35.12 + * by Oracle in the LICENSE file that accompanied this code.
35.13 + *
35.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
35.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
35.17 + * version 2 for more details (a copy is included in the LICENSE file that
35.18 + * accompanied this code).
35.19 + *
35.20 + * You should have received a copy of the GNU General Public License version
35.21 + * 2 along with this work; if not, write to the Free Software Foundation,
35.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
35.23 + *
35.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
35.25 + * or visit www.oracle.com if you need additional information or have any
35.26 + * questions.
35.27 + */
35.28 +
35.29 +package org.apidesign.bck2brwsr.emul.zip;
35.30 +
35.31 +/*
35.32 + * This class defines the constants that are used by the classes
35.33 + * which manipulate Zip64 files.
35.34 + */
35.35 +
35.36 +public class ZipConstants64 {
35.37 +
35.38 + /*
35.39 + * ZIP64 constants
35.40 + */
35.41 + static final long ZIP64_ENDSIG = 0x06064b50L; // "PK\006\006"
35.42 + static final long ZIP64_LOCSIG = 0x07064b50L; // "PK\006\007"
35.43 + static final int ZIP64_ENDHDR = 56; // ZIP64 end header size
35.44 + static final int ZIP64_LOCHDR = 20; // ZIP64 end loc header size
35.45 + static final int ZIP64_EXTHDR = 24; // EXT header size
35.46 + static final int ZIP64_EXTID = 0x0001; // Extra field Zip64 header ID
35.47 +
35.48 + static final int ZIP64_MAGICCOUNT = 0xFFFF;
35.49 + static final long ZIP64_MAGICVAL = 0xFFFFFFFFL;
35.50 +
35.51 + /*
35.52 + * Zip64 End of central directory (END) header field offsets
35.53 + */
35.54 + static final int ZIP64_ENDLEN = 4; // size of zip64 end of central dir
35.55 + static final int ZIP64_ENDVEM = 12; // version made by
35.56 + static final int ZIP64_ENDVER = 14; // version needed to extract
35.57 + static final int ZIP64_ENDNMD = 16; // number of this disk
35.58 + static final int ZIP64_ENDDSK = 20; // disk number of start
35.59 + static final int ZIP64_ENDTOD = 24; // total number of entries on this disk
35.60 + static final int ZIP64_ENDTOT = 32; // total number of entries
35.61 + static final int ZIP64_ENDSIZ = 40; // central directory size in bytes
35.62 + static final int ZIP64_ENDOFF = 48; // offset of first CEN header
35.63 + static final int ZIP64_ENDEXT = 56; // zip64 extensible data sector
35.64 +
35.65 + /*
35.66 + * Zip64 End of central directory locator field offsets
35.67 + */
35.68 + static final int ZIP64_LOCDSK = 4; // disk number start
35.69 + static final int ZIP64_LOCOFF = 8; // offset of zip64 end
35.70 + static final int ZIP64_LOCTOT = 16; // total number of disks
35.71 +
35.72 + /*
35.73 + * Zip64 Extra local (EXT) header field offsets
35.74 + */
35.75 + static final int ZIP64_EXTCRC = 4; // uncompressed file crc-32 value
35.76 + static final int ZIP64_EXTSIZ = 8; // compressed size, 8-byte
35.77 + static final int ZIP64_EXTLEN = 16; // uncompressed size, 8-byte
35.78 +
35.79 + /*
35.80 + * Language encoding flag EFS
35.81 + */
35.82 + static final int EFS = 0x800; // If this bit is set the filename and
35.83 + // comment fields for this file must be
35.84 + // encoded using UTF-8.
35.85 +
35.86 + private ZipConstants64() {}
35.87 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/ZipInputStream.java Tue Feb 19 15:59:27 2013 +0100
36.3 @@ -0,0 +1,468 @@
36.4 +/*
36.5 + * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
36.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
36.7 + *
36.8 + * This code is free software; you can redistribute it and/or modify it
36.9 + * under the terms of the GNU General Public License version 2 only, as
36.10 + * published by the Free Software Foundation. Oracle designates this
36.11 + * particular file as subject to the "Classpath" exception as provided
36.12 + * by Oracle in the LICENSE file that accompanied this code.
36.13 + *
36.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
36.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36.17 + * version 2 for more details (a copy is included in the LICENSE file that
36.18 + * accompanied this code).
36.19 + *
36.20 + * You should have received a copy of the GNU General Public License version
36.21 + * 2 along with this work; if not, write to the Free Software Foundation,
36.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
36.23 + *
36.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
36.25 + * or visit www.oracle.com if you need additional information or have any
36.26 + * questions.
36.27 + */
36.28 +
36.29 +package org.apidesign.bck2brwsr.emul.zip;
36.30 +
36.31 +import java.util.zip.*;
36.32 +import java.io.InputStream;
36.33 +import java.io.IOException;
36.34 +import java.io.EOFException;
36.35 +import java.io.PushbackInputStream;
36.36 +import static org.apidesign.bck2brwsr.emul.zip.ZipConstants64.*;
36.37 +import static java.util.zip.ZipInputStream.*;
36.38 +
36.39 +/**
36.40 + * This class implements an input stream filter for reading files in the
36.41 + * ZIP file format. Includes support for both compressed and uncompressed
36.42 + * entries.
36.43 + *
36.44 + * @author David Connelly
36.45 + */
36.46 +public
36.47 +class ZipInputStream extends InflaterInputStream {
36.48 + private ZipEntry entry;
36.49 + private int flag;
36.50 + private CRC32 crc = new CRC32();
36.51 + private long remaining;
36.52 + private byte[] tmpbuf = new byte[512];
36.53 +
36.54 + private static final int STORED = ZipEntry.STORED;
36.55 + private static final int DEFLATED = ZipEntry.DEFLATED;
36.56 +
36.57 + private boolean closed = false;
36.58 + // this flag is set to true after EOF has reached for
36.59 + // one entry
36.60 + private boolean entryEOF = false;
36.61 +
36.62 + /**
36.63 + * Check to make sure that this stream has not been closed
36.64 + */
36.65 + private void ensureOpen() throws IOException {
36.66 + if (closed) {
36.67 + throw new IOException("Stream closed");
36.68 + }
36.69 + }
36.70 +
36.71 + /**
36.72 + * Creates a new ZIP input stream.
36.73 + *
36.74 + * <p>The UTF-8 {@link java.nio.charset.Charset charset} is used to
36.75 + * decode the entry names.
36.76 + *
36.77 + * @param in the actual input stream
36.78 + */
36.79 + public ZipInputStream(InputStream in) {
36.80 +// this(in, "UTF-8");
36.81 + super(new PushbackInputStream(in, 512), new Inflater(true), 512);
36.82 + //usesDefaultInflater = true;
36.83 + if(in == null) {
36.84 + throw new NullPointerException("in is null");
36.85 + }
36.86 + }
36.87 +
36.88 + /**
36.89 + * Creates a new ZIP input stream.
36.90 + *
36.91 + * @param in the actual input stream
36.92 + *
36.93 + * @param charset
36.94 + * The {@linkplain java.nio.charset.Charset charset} to be
36.95 + * used to decode the ZIP entry name (ignored if the
36.96 + * <a href="package-summary.html#lang_encoding"> language
36.97 + * encoding bit</a> of the ZIP entry's general purpose bit
36.98 + * flag is set).
36.99 + *
36.100 + * @since 1.7
36.101 + *
36.102 + public ZipInputStream(InputStream in, Charset charset) {
36.103 + super(new PushbackInputStream(in, 512), new Inflater(true), 512);
36.104 + usesDefaultInflater = true;
36.105 + if(in == null) {
36.106 + throw new NullPointerException("in is null");
36.107 + }
36.108 + if (charset == null)
36.109 + throw new NullPointerException("charset is null");
36.110 + this.zc = ZipCoder.get(charset);
36.111 + }
36.112 + */
36.113 +
36.114 + /**
36.115 + * Reads the next ZIP file entry and positions the stream at the
36.116 + * beginning of the entry data.
36.117 + * @return the next ZIP file entry, or null if there are no more entries
36.118 + * @exception ZipException if a ZIP file error has occurred
36.119 + * @exception IOException if an I/O error has occurred
36.120 + */
36.121 + public ZipEntry getNextEntry() throws IOException {
36.122 + ensureOpen();
36.123 + if (entry != null) {
36.124 + closeEntry();
36.125 + }
36.126 + crc.reset();
36.127 + inf.reset();
36.128 + if ((entry = readLOC()) == null) {
36.129 + return null;
36.130 + }
36.131 + if (entry.getMethod() == STORED) {
36.132 + remaining = entry.getSize();
36.133 + }
36.134 + entryEOF = false;
36.135 + return entry;
36.136 + }
36.137 +
36.138 + /**
36.139 + * Closes the current ZIP entry and positions the stream for reading the
36.140 + * next entry.
36.141 + * @exception ZipException if a ZIP file error has occurred
36.142 + * @exception IOException if an I/O error has occurred
36.143 + */
36.144 + public void closeEntry() throws IOException {
36.145 + ensureOpen();
36.146 + while (read(tmpbuf, 0, tmpbuf.length) != -1) ;
36.147 + entryEOF = true;
36.148 + }
36.149 +
36.150 + /**
36.151 + * Returns 0 after EOF has reached for the current entry data,
36.152 + * otherwise always return 1.
36.153 + * <p>
36.154 + * Programs should not count on this method to return the actual number
36.155 + * of bytes that could be read without blocking.
36.156 + *
36.157 + * @return 1 before EOF and 0 after EOF has reached for current entry.
36.158 + * @exception IOException if an I/O error occurs.
36.159 + *
36.160 + */
36.161 + public int available() throws IOException {
36.162 + ensureOpen();
36.163 + if (entryEOF) {
36.164 + return 0;
36.165 + } else {
36.166 + return 1;
36.167 + }
36.168 + }
36.169 +
36.170 + /**
36.171 + * Reads from the current ZIP entry into an array of bytes.
36.172 + * If <code>len</code> is not zero, the method
36.173 + * blocks until some input is available; otherwise, no
36.174 + * bytes are read and <code>0</code> is returned.
36.175 + * @param b the buffer into which the data is read
36.176 + * @param off the start offset in the destination array <code>b</code>
36.177 + * @param len the maximum number of bytes read
36.178 + * @return the actual number of bytes read, or -1 if the end of the
36.179 + * entry is reached
36.180 + * @exception NullPointerException if <code>b</code> is <code>null</code>.
36.181 + * @exception IndexOutOfBoundsException if <code>off</code> is negative,
36.182 + * <code>len</code> is negative, or <code>len</code> is greater than
36.183 + * <code>b.length - off</code>
36.184 + * @exception ZipException if a ZIP file error has occurred
36.185 + * @exception IOException if an I/O error has occurred
36.186 + */
36.187 + public int read(byte[] b, int off, int len) throws IOException {
36.188 + ensureOpen();
36.189 + if (off < 0 || len < 0 || off > b.length - len) {
36.190 + throw new IndexOutOfBoundsException();
36.191 + } else if (len == 0) {
36.192 + return 0;
36.193 + }
36.194 +
36.195 + if (entry == null) {
36.196 + return -1;
36.197 + }
36.198 + switch (entry.getMethod()) {
36.199 + case DEFLATED:
36.200 + len = super.read(b, off, len);
36.201 + if (len == -1) {
36.202 + readEnd(entry);
36.203 + entryEOF = true;
36.204 + entry = null;
36.205 + } else {
36.206 + crc.update(b, off, len);
36.207 + }
36.208 + return len;
36.209 + case STORED:
36.210 + if (remaining <= 0) {
36.211 + entryEOF = true;
36.212 + entry = null;
36.213 + return -1;
36.214 + }
36.215 + if (len > remaining) {
36.216 + len = (int)remaining;
36.217 + }
36.218 + len = in.read(b, off, len);
36.219 + if (len == -1) {
36.220 + throw new ZipException("unexpected EOF");
36.221 + }
36.222 + crc.update(b, off, len);
36.223 + remaining -= len;
36.224 + if (remaining == 0 && entry.getCrc() != crc.getValue()) {
36.225 + throw new ZipException(
36.226 + "invalid entry CRC (expected 0x" + Long.toHexString(entry.getCrc()) +
36.227 + " but got 0x" + Long.toHexString(crc.getValue()) + ")");
36.228 + }
36.229 + return len;
36.230 + default:
36.231 + throw new ZipException("invalid compression method");
36.232 + }
36.233 + }
36.234 +
36.235 + /**
36.236 + * Skips specified number of bytes in the current ZIP entry.
36.237 + * @param n the number of bytes to skip
36.238 + * @return the actual number of bytes skipped
36.239 + * @exception ZipException if a ZIP file error has occurred
36.240 + * @exception IOException if an I/O error has occurred
36.241 + * @exception IllegalArgumentException if n < 0
36.242 + */
36.243 + public long skip(long n) throws IOException {
36.244 + if (n < 0) {
36.245 + throw new IllegalArgumentException("negative skip length");
36.246 + }
36.247 + ensureOpen();
36.248 + int max = (int)Math.min(n, Integer.MAX_VALUE);
36.249 + int total = 0;
36.250 + while (total < max) {
36.251 + int len = max - total;
36.252 + if (len > tmpbuf.length) {
36.253 + len = tmpbuf.length;
36.254 + }
36.255 + len = read(tmpbuf, 0, len);
36.256 + if (len == -1) {
36.257 + entryEOF = true;
36.258 + break;
36.259 + }
36.260 + total += len;
36.261 + }
36.262 + return total;
36.263 + }
36.264 +
36.265 + /**
36.266 + * Closes this input stream and releases any system resources associated
36.267 + * with the stream.
36.268 + * @exception IOException if an I/O error has occurred
36.269 + */
36.270 + public void close() throws IOException {
36.271 + if (!closed) {
36.272 + super.close();
36.273 + closed = true;
36.274 + }
36.275 + }
36.276 +
36.277 + private byte[] b = new byte[256];
36.278 +
36.279 + /*
36.280 + * Reads local file (LOC) header for next entry.
36.281 + */
36.282 + private ZipEntry readLOC() throws IOException {
36.283 + try {
36.284 + readFully(tmpbuf, 0, LOCHDR);
36.285 + } catch (EOFException e) {
36.286 + return null;
36.287 + }
36.288 + if (get32(tmpbuf, 0) != LOCSIG) {
36.289 + return null;
36.290 + }
36.291 + // get flag first, we need check EFS.
36.292 + flag = get16(tmpbuf, LOCFLG);
36.293 + // get the entry name and create the ZipEntry first
36.294 + int len = get16(tmpbuf, LOCNAM);
36.295 + int blen = b.length;
36.296 + if (len > blen) {
36.297 + do
36.298 + blen = blen * 2;
36.299 + while (len > blen);
36.300 + b = new byte[blen];
36.301 + }
36.302 + readFully(b, 0, len);
36.303 + // Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8
36.304 + ZipEntry e = createZipEntry(((flag & EFS) != 0)
36.305 + ? toStringUTF8(b, len)
36.306 + : toString(b, len));
36.307 + // now get the remaining fields for the entry
36.308 + if ((flag & 1) == 1) {
36.309 + throw new ZipException("encrypted ZIP entry not supported");
36.310 + }
36.311 + e.setMethod(get16(tmpbuf, LOCHOW));
36.312 + e.setTime(get32(tmpbuf, LOCTIM));
36.313 + if ((flag & 8) == 8) {
36.314 + /* "Data Descriptor" present */
36.315 + if (e.getMethod() != DEFLATED) {
36.316 + throw new ZipException(
36.317 + "only DEFLATED entries can have EXT descriptor");
36.318 + }
36.319 + } else {
36.320 + e.setCrc(get32(tmpbuf, LOCCRC));
36.321 + e.setCompressedSize(get32(tmpbuf, LOCSIZ));
36.322 + e.setSize(get32(tmpbuf, LOCLEN));
36.323 + }
36.324 + len = get16(tmpbuf, LOCEXT);
36.325 + if (len > 0) {
36.326 + byte[] bb = new byte[len];
36.327 + readFully(bb, 0, len);
36.328 + e.setExtra(bb);
36.329 + // extra fields are in "HeaderID(2)DataSize(2)Data... format
36.330 + if (e.getCompressedSize() == ZIP64_MAGICVAL || e.getCompressedSize() == ZIP64_MAGICVAL) {
36.331 + int off = 0;
36.332 + while (off + 4 < len) {
36.333 + int sz = get16(bb, off + 2);
36.334 + if (get16(bb, off) == ZIP64_EXTID) {
36.335 + off += 4;
36.336 + // LOC extra zip64 entry MUST include BOTH original and
36.337 + // compressed file size fields
36.338 + if (sz < 16 || (off + sz) > len ) {
36.339 + // Invalid zip64 extra fields, simply skip. Even it's
36.340 + // rare, it's possible the entry size happens to be
36.341 + // the magic value and it "accidnetly" has some bytes
36.342 + // in extra match the id.
36.343 + return e;
36.344 + }
36.345 + e.setSize(get64(bb, off));
36.346 + e.setCompressedSize(get64(bb, off + 8));
36.347 + break;
36.348 + }
36.349 + off += (sz + 4);
36.350 + }
36.351 + }
36.352 + }
36.353 + return e;
36.354 + }
36.355 +
36.356 + /**
36.357 + * Creates a new <code>ZipEntry</code> object for the specified
36.358 + * entry name.
36.359 + *
36.360 + * @param name the ZIP file entry name
36.361 + * @return the ZipEntry just created
36.362 + */
36.363 + protected ZipEntry createZipEntry(String name) {
36.364 + return new ZipEntry(name);
36.365 + }
36.366 +
36.367 + /*
36.368 + * Reads end of deflated entry as well as EXT descriptor if present.
36.369 + */
36.370 + private void readEnd(ZipEntry e) throws IOException {
36.371 + int n = inf.getRemaining();
36.372 + if (n > 0) {
36.373 + ((PushbackInputStream)in).unread(buf, len - n, n);
36.374 + }
36.375 + if ((flag & 8) == 8) {
36.376 + /* "Data Descriptor" present */
36.377 + if (inf.getBytesWritten() > ZIP64_MAGICVAL ||
36.378 + inf.getBytesRead() > ZIP64_MAGICVAL) {
36.379 + // ZIP64 format
36.380 + readFully(tmpbuf, 0, ZIP64_EXTHDR);
36.381 + long sig = get32(tmpbuf, 0);
36.382 + if (sig != EXTSIG) { // no EXTSIG present
36.383 + e.setCrc(sig);
36.384 + e.setCompressedSize(get64(tmpbuf, ZIP64_EXTSIZ - ZIP64_EXTCRC));
36.385 + e.setSize(get64(tmpbuf, ZIP64_EXTLEN - ZIP64_EXTCRC));
36.386 + ((PushbackInputStream)in).unread(
36.387 + tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC - 1, ZIP64_EXTCRC);
36.388 + } else {
36.389 + e.setCrc(get32(tmpbuf, ZIP64_EXTCRC));
36.390 + e.setCompressedSize(get64(tmpbuf, ZIP64_EXTSIZ));
36.391 + e.setSize(get64(tmpbuf, ZIP64_EXTLEN));
36.392 + }
36.393 + } else {
36.394 + readFully(tmpbuf, 0, EXTHDR);
36.395 + long sig = get32(tmpbuf, 0);
36.396 + if (sig != EXTSIG) { // no EXTSIG present
36.397 + e.setCrc(sig);
36.398 + e.setCompressedSize(get32(tmpbuf, EXTSIZ - EXTCRC));
36.399 + e.setSize(get32(tmpbuf, EXTLEN - EXTCRC));
36.400 + ((PushbackInputStream)in).unread(
36.401 + tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC);
36.402 + } else {
36.403 + e.setCrc(get32(tmpbuf, EXTCRC));
36.404 + e.setCompressedSize(get32(tmpbuf, EXTSIZ));
36.405 + e.setSize(get32(tmpbuf, EXTLEN));
36.406 + }
36.407 + }
36.408 + }
36.409 + if (e.getSize() != inf.getBytesWritten()) {
36.410 + throw new ZipException(
36.411 + "invalid entry size (expected " + e.getSize() +
36.412 + " but got " + inf.getBytesWritten() + " bytes)");
36.413 + }
36.414 + if (e.getCompressedSize() != inf.getBytesRead()) {
36.415 + throw new ZipException(
36.416 + "invalid entry compressed size (expected " + e.getCompressedSize() +
36.417 + " but got " + inf.getBytesRead() + " bytes)");
36.418 + }
36.419 + if (e.getCrc() != crc.getValue()) {
36.420 + throw new ZipException(
36.421 + "invalid entry CRC (expected 0x" + Long.toHexString(e.getCrc()) +
36.422 + " but got 0x" + Long.toHexString(crc.getValue()) + ")");
36.423 + }
36.424 + }
36.425 +
36.426 + /*
36.427 + * Reads bytes, blocking until all bytes are read.
36.428 + */
36.429 + private void readFully(byte[] b, int off, int len) throws IOException {
36.430 + while (len > 0) {
36.431 + int n = in.read(b, off, len);
36.432 + if (n == -1) {
36.433 + throw new EOFException();
36.434 + }
36.435 + off += n;
36.436 + len -= n;
36.437 + }
36.438 + }
36.439 +
36.440 + /*
36.441 + * Fetches unsigned 16-bit value from byte array at specified offset.
36.442 + * The bytes are assumed to be in Intel (little-endian) byte order.
36.443 + */
36.444 + private static final int get16(byte b[], int off) {
36.445 + return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8);
36.446 + }
36.447 +
36.448 + /*
36.449 + * Fetches unsigned 32-bit value from byte array at specified offset.
36.450 + * The bytes are assumed to be in Intel (little-endian) byte order.
36.451 + */
36.452 + private static final long get32(byte b[], int off) {
36.453 + return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL;
36.454 + }
36.455 +
36.456 + /*
36.457 + * Fetches signed 64-bit value from byte array at specified offset.
36.458 + * The bytes are assumed to be in Intel (little-endian) byte order.
36.459 + */
36.460 + private static final long get64(byte b[], int off) {
36.461 + return get32(b, off) | (get32(b, off+4) << 32);
36.462 + }
36.463 +
36.464 + private static String toStringUTF8(byte[] arr, int len) {
36.465 + return new String(arr, 0, len);
36.466 + }
36.467 +
36.468 + private static String toString(byte[] b, int len) {
36.469 + return new String(b, 0, len);
36.470 + }
36.471 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/emul/mini/src/test/java/org/apidesign/bck2brwsr/emul/reflect/MethodImplTest.java Tue Feb 19 15:59:27 2013 +0100
37.3 @@ -0,0 +1,49 @@
37.4 +/**
37.5 + * Back 2 Browser Bytecode Translator
37.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
37.7 + *
37.8 + * This program is free software: you can redistribute it and/or modify
37.9 + * it under the terms of the GNU General Public License as published by
37.10 + * the Free Software Foundation, version 2 of the License.
37.11 + *
37.12 + * This program is distributed in the hope that it will be useful,
37.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
37.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37.15 + * GNU General Public License for more details.
37.16 + *
37.17 + * You should have received a copy of the GNU General Public License
37.18 + * along with this program. Look for COPYING file in the top folder.
37.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
37.20 + */
37.21 +package org.apidesign.bck2brwsr.emul.reflect;
37.22 +
37.23 +import java.lang.reflect.Method;
37.24 +import java.util.Enumeration;
37.25 +import org.testng.annotations.Test;
37.26 +
37.27 +/**
37.28 + *
37.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
37.30 + */
37.31 +public class MethodImplTest {
37.32 +
37.33 + public MethodImplTest() {
37.34 + }
37.35 +
37.36 + public static String[] arr(String... arr) {
37.37 + return arr;
37.38 + }
37.39 +
37.40 + @Test
37.41 + public void testSignatureForMethodWithAnArray() throws NoSuchMethodException {
37.42 + Method m = MethodImplTest.class.getMethod("arr", String[].class);
37.43 + String sig = MethodImpl.toSignature(m);
37.44 + int sep = sig.indexOf("__");
37.45 + assert sep > 0 : "Separator found " + sig;
37.46 +
37.47 + Enumeration<Class> en = MethodImpl.signatureParser(sig.substring(sep + 2));
37.48 +
37.49 + assert en.nextElement() == m.getReturnType() : "Return type is the same";
37.50 + assert en.nextElement() == m.getParameterTypes()[0] : "1st param type is the same";
37.51 + }
37.52 +}
37.53 \ No newline at end of file
38.1 --- a/javap/src/main/java/org/apidesign/javap/AnnotationParser.java Tue Feb 19 15:33:32 2013 +0100
38.2 +++ b/javap/src/main/java/org/apidesign/javap/AnnotationParser.java Tue Feb 19 15:59:27 2013 +0100
38.3 @@ -35,22 +35,37 @@
38.4 */
38.5 public class AnnotationParser {
38.6 private final boolean textual;
38.7 + private final boolean iterateArray;
38.8
38.9 - protected AnnotationParser(boolean textual) {
38.10 + protected AnnotationParser(boolean textual, boolean iterateArray) {
38.11 this.textual = textual;
38.12 + this.iterateArray = iterateArray;
38.13 }
38.14
38.15 - protected void visitAnnotationStart(String type) throws IOException {
38.16 + protected void visitAnnotationStart(String type, boolean top) throws IOException {
38.17 }
38.18
38.19 - protected void visitAnnotationEnd(String type) throws IOException {
38.20 + protected void visitAnnotationEnd(String type, boolean top) throws IOException {
38.21 }
38.22 +
38.23 + protected void visitValueStart(String attrName, char type) throws IOException {
38.24 + }
38.25 +
38.26 + protected void visitValueEnd(String attrName, char type) throws IOException {
38.27 + }
38.28 +
38.29
38.30 protected void visitAttr(
38.31 String annoType, String attr, String attrType, String value
38.32 ) throws IOException {
38.33 }
38.34
38.35 + protected void visitEnumAttr(
38.36 + String annoType, String attr, String attrType, String value
38.37 + ) throws IOException {
38.38 + visitAttr(annoType, attr, attrType, value);
38.39 + }
38.40 +
38.41 /** Initialize the parsing with constant pool from <code>cd</code>.
38.42 *
38.43 * @param attr the attribute defining annotations
38.44 @@ -70,30 +85,32 @@
38.45 private void read(DataInputStream dis, ClassData cd) throws IOException {
38.46 int cnt = dis.readUnsignedShort();
38.47 for (int i = 0; i < cnt; i++) {
38.48 - readAnno(dis, cd);
38.49 + readAnno(dis, cd, true);
38.50 }
38.51 }
38.52
38.53 - private void readAnno(DataInputStream dis, ClassData cd) throws IOException {
38.54 + private void readAnno(DataInputStream dis, ClassData cd, boolean top) throws IOException {
38.55 int type = dis.readUnsignedShort();
38.56 String typeName = cd.StringValue(type);
38.57 - visitAnnotationStart(typeName);
38.58 + visitAnnotationStart(typeName, top);
38.59 int cnt = dis.readUnsignedShort();
38.60 for (int i = 0; i < cnt; i++) {
38.61 String attrName = cd.StringValue(dis.readUnsignedShort());
38.62 readValue(dis, cd, typeName, attrName);
38.63 }
38.64 - visitAnnotationEnd(typeName);
38.65 + visitAnnotationEnd(typeName, top);
38.66 if (cnt == 0) {
38.67 visitAttr(typeName, null, null, null);
38.68 }
38.69 }
38.70
38.71 - private void readValue(DataInputStream dis, ClassData cd, String typeName, String attrName)
38.72 - throws IOException {
38.73 + private void readValue(
38.74 + DataInputStream dis, ClassData cd, String typeName, String attrName
38.75 + ) throws IOException {
38.76 char type = (char)dis.readByte();
38.77 + visitValueStart(attrName, type);
38.78 if (type == '@') {
38.79 - readAnno(dis, cd);
38.80 + readAnno(dis, cd, false);
38.81 } else if ("CFJZsSIDB".indexOf(type) >= 0) { // NOI18N
38.82 int primitive = dis.readUnsignedShort();
38.83 String val = cd.stringValue(primitive, textual);
38.84 @@ -112,13 +129,17 @@
38.85 } else if (type == '[') {
38.86 int cnt = dis.readUnsignedShort();
38.87 for (int i = 0; i < cnt; i++) {
38.88 - readValue(dis, cd, typeName, attrName);
38.89 + readValue(dis, cd, typeName, iterateArray ? attrName : null);
38.90 }
38.91 } else if (type == 'e') {
38.92 int enumT = dis.readUnsignedShort();
38.93 + String attrType = cd.stringValue(enumT, textual);
38.94 int enumN = dis.readUnsignedShort();
38.95 + String val = cd.stringValue(enumN, textual);
38.96 + visitEnumAttr(typeName, attrName, attrType, val);
38.97 } else {
38.98 throw new IOException("Unknown type " + type);
38.99 }
38.100 + visitValueEnd(attrName, type);
38.101 }
38.102 }
39.1 --- a/javaquery/api/pom.xml Tue Feb 19 15:33:32 2013 +0100
39.2 +++ b/javaquery/api/pom.xml Tue Feb 19 15:59:27 2013 +0100
39.3 @@ -47,21 +47,16 @@
39.4 </dependency>
39.5 <dependency>
39.6 <groupId>org.apidesign.bck2brwsr</groupId>
39.7 - <artifactId>core</artifactId>
39.8 - <version>0.3-SNAPSHOT</version>
39.9 + <artifactId>emul</artifactId>
39.10 + <version>${project.version}</version>
39.11 + <classifier>rt</classifier>
39.12 <type>jar</type>
39.13 - </dependency>
39.14 - <dependency>
39.15 - <groupId>org.apidesign.bck2brwsr</groupId>
39.16 - <artifactId>emul.mini</artifactId>
39.17 - <version>0.3-SNAPSHOT</version>
39.18 - <type>jar</type>
39.19 - <scope>runtime</scope>
39.20 + <scope>compile</scope>
39.21 </dependency>
39.22 <dependency>
39.23 <groupId>org.apidesign.bck2brwsr</groupId>
39.24 <artifactId>vm4brwsr</artifactId>
39.25 - <version>0.3-SNAPSHOT</version>
39.26 + <version>${project.version}</version>
39.27 <type>jar</type>
39.28 <scope>test</scope>
39.29 </dependency>
40.1 --- a/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java Tue Feb 19 15:33:32 2013 +0100
40.2 +++ b/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java Tue Feb 19 15:59:27 2013 +0100
40.3 @@ -128,6 +128,8 @@
40.4 sb = new StringBuilder();
40.5 }
40.6 Bck2Brwsr.generate(sb, ProcessPageTest.class.getClassLoader(), names);
40.7 + sb.append("var vm = this.bck2brwsr();\n");
40.8 +
40.9 ScriptEngineManager sem = new ScriptEngineManager();
40.10 ScriptEngine js = sem.getEngineByExtension("js");
40.11 try {
41.1 --- a/javaquery/demo-calculator-dynamic/pom.xml Tue Feb 19 15:33:32 2013 +0100
41.2 +++ b/javaquery/demo-calculator-dynamic/pom.xml Tue Feb 19 15:59:27 2013 +0100
41.3 @@ -40,22 +40,54 @@
41.4 <target>1.7</target>
41.5 </configuration>
41.6 </plugin>
41.7 - <plugin>
41.8 + <plugin>
41.9 + <groupId>org.apache.maven.plugins</groupId>
41.10 + <artifactId>maven-jar-plugin</artifactId>
41.11 + <version>2.4</version>
41.12 + <configuration>
41.13 + <archive>
41.14 + <manifest>
41.15 + <addClasspath>true</addClasspath>
41.16 + <classpathPrefix>lib/</classpathPrefix>
41.17 + </manifest>
41.18 + </archive>
41.19 + </configuration>
41.20 + </plugin>
41.21 + <plugin>
41.22 <groupId>org.apache.maven.plugins</groupId>
41.23 <artifactId>maven-deploy-plugin</artifactId>
41.24 <version>2.7</version>
41.25 <configuration>
41.26 <skip>true</skip>
41.27 </configuration>
41.28 - </plugin>
41.29 + </plugin>
41.30 + <plugin>
41.31 + <artifactId>maven-assembly-plugin</artifactId>
41.32 + <version>2.4</version>
41.33 + <executions>
41.34 + <execution>
41.35 + <id>distro-assembly</id>
41.36 + <phase>package</phase>
41.37 + <goals>
41.38 + <goal>single</goal>
41.39 + </goals>
41.40 + <configuration>
41.41 + <descriptors>
41.42 + <descriptor>src/main/assembly/bck2brwsr.xml</descriptor>
41.43 + </descriptors>
41.44 + </configuration>
41.45 + </execution>
41.46 + </executions>
41.47 + </plugin>
41.48 </plugins>
41.49 </build>
41.50
41.51 <dependencies>
41.52 <dependency>
41.53 <groupId>org.apidesign.bck2brwsr</groupId>
41.54 - <artifactId>emul.mini</artifactId>
41.55 + <artifactId>emul</artifactId>
41.56 <version>0.3-SNAPSHOT</version>
41.57 + <classifier>rt</classifier>
41.58 </dependency>
41.59 <dependency>
41.60 <groupId>org.apidesign.bck2brwsr</groupId>
41.61 @@ -68,5 +100,13 @@
41.62 <version>6.5.2</version>
41.63 <scope>test</scope>
41.64 </dependency>
41.65 + <dependency>
41.66 + <groupId>org.apidesign.bck2brwsr</groupId>
41.67 + <artifactId>vm4brwsr</artifactId>
41.68 + <classifier>js</classifier>
41.69 + <type>zip</type>
41.70 + <version>0.3-SNAPSHOT</version>
41.71 + <scope>provided</scope>
41.72 + </dependency>
41.73 </dependencies>
41.74 </project>
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/javaquery/demo-calculator-dynamic/src/main/assembly/bck2brwsr.xml Tue Feb 19 15:59:27 2013 +0100
42.3 @@ -0,0 +1,62 @@
42.4 +<?xml version="1.0"?>
42.5 +<!--
42.6 +
42.7 + Back 2 Browser Bytecode Translator
42.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
42.9 +
42.10 + This program is free software: you can redistribute it and/or modify
42.11 + it under the terms of the GNU General Public License as published by
42.12 + the Free Software Foundation, version 2 of the License.
42.13 +
42.14 + This program is distributed in the hope that it will be useful,
42.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
42.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42.17 + GNU General Public License for more details.
42.18 +
42.19 + You should have received a copy of the GNU General Public License
42.20 + along with this program. Look for COPYING file in the top folder.
42.21 + If not, see http://opensource.org/licenses/GPL-2.0.
42.22 +
42.23 +-->
42.24 +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
42.25 + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
42.26 +
42.27 + <id>bck2brwsr</id>
42.28 + <formats>
42.29 + <format>zip</format>
42.30 + <format>dir</format>
42.31 + </formats>
42.32 + <baseDirectory>public_html</baseDirectory>
42.33 + <dependencySets>
42.34 + <dependencySet>
42.35 + <useProjectArtifact>false</useProjectArtifact>
42.36 + <scope>runtime</scope>
42.37 + <outputDirectory>lib</outputDirectory>
42.38 + <includes>
42.39 + <include>*:jar</include>
42.40 + <include>*:rt</include>
42.41 + </includes>
42.42 + </dependencySet>
42.43 + <dependencySet>
42.44 + <useProjectArtifact>false</useProjectArtifact>
42.45 + <scope>provided</scope>
42.46 + <includes>
42.47 + <include>*:js</include>
42.48 + </includes>
42.49 + <unpack>true</unpack>
42.50 + <outputDirectory>/</outputDirectory>
42.51 + </dependencySet>
42.52 + </dependencySets>
42.53 + <files>
42.54 + <file>
42.55 + <source>${project.build.directory}/${project.build.finalName}.jar</source>
42.56 + <outputDirectory>/</outputDirectory>
42.57 + </file>
42.58 + <file>
42.59 + <source>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/calc/Calculator.xhtml</source>
42.60 + <outputDirectory>/</outputDirectory>
42.61 + <destName>index.xhtml</destName>
42.62 + </file>
42.63 + </files>
42.64 +
42.65 +</assembly>
42.66 \ No newline at end of file
43.1 --- a/javaquery/demo-calculator-dynamic/src/main/resources/org/apidesign/bck2brwsr/demo/calc/Calculator.xhtml Tue Feb 19 15:33:32 2013 +0100
43.2 +++ b/javaquery/demo-calculator-dynamic/src/main/resources/org/apidesign/bck2brwsr/demo/calc/Calculator.xhtml Tue Feb 19 15:59:27 2013 +0100
43.3 @@ -78,9 +78,9 @@
43.4 </table>
43.5 <div data-bind="text: displayPreview"></div>
43.6
43.7 - <script src="/bck2brwsr.js"></script>
43.8 - <script src="/vm.js"></script>
43.9 + <script src="bck2brwsr.js"></script>
43.10 <script type="text/javascript">
43.11 + var vm = bck2brwsr('demo.calculator-0.3-SNAPSHOT.jar');
43.12 vm.loadClass('org.apidesign.bck2brwsr.demo.calc.Calc');
43.13 </script>
43.14
44.1 --- a/javaquery/demo-calculator/nbactions.xml Tue Feb 19 15:33:32 2013 +0100
44.2 +++ b/javaquery/demo-calculator/nbactions.xml Tue Feb 19 15:59:27 2013 +0100
44.3 @@ -22,8 +22,11 @@
44.4 <action>
44.5 <actionName>run</actionName>
44.6 <goals>
44.7 - <goal>process-classes</goal>
44.8 + <goal>package</goal>
44.9 <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
44.10 </goals>
44.11 + <properties>
44.12 + <skipTests>true</skipTests>
44.13 + </properties>
44.14 </action>
44.15 - </actions>
44.16 +</actions>
45.1 --- a/javaquery/demo-calculator/pom.xml Tue Feb 19 15:33:32 2013 +0100
45.2 +++ b/javaquery/demo-calculator/pom.xml Tue Feb 19 15:59:27 2013 +0100
45.3 @@ -23,7 +23,6 @@
45.4 <executions>
45.5 <execution>
45.6 <goals>
45.7 - <goal>j2js</goal>
45.8 <goal>brwsr</goal>
45.9 </goals>
45.10 </execution>
45.11 @@ -43,6 +42,19 @@
45.12 </configuration>
45.13 </plugin>
45.14 <plugin>
45.15 + <groupId>org.apache.maven.plugins</groupId>
45.16 + <artifactId>maven-jar-plugin</artifactId>
45.17 + <version>2.4</version>
45.18 + <configuration>
45.19 + <archive>
45.20 + <manifest>
45.21 + <addClasspath>true</addClasspath>
45.22 + <classpathPrefix>lib/</classpathPrefix>
45.23 + </manifest>
45.24 + </archive>
45.25 + </configuration>
45.26 + </plugin>
45.27 + <plugin>
45.28 <artifactId>maven-assembly-plugin</artifactId>
45.29 <version>2.4</version>
45.30 <executions>
45.31 @@ -74,13 +86,22 @@
45.32 <dependencies>
45.33 <dependency>
45.34 <groupId>org.apidesign.bck2brwsr</groupId>
45.35 - <artifactId>emul.mini</artifactId>
45.36 + <artifactId>emul</artifactId>
45.37 <version>0.3-SNAPSHOT</version>
45.38 + <classifier>rt</classifier>
45.39 </dependency>
45.40 <dependency>
45.41 <groupId>org.apidesign.bck2brwsr</groupId>
45.42 <artifactId>javaquery.api</artifactId>
45.43 <version>0.3-SNAPSHOT</version>
45.44 </dependency>
45.45 + <dependency>
45.46 + <groupId>org.apidesign.bck2brwsr</groupId>
45.47 + <artifactId>vm4brwsr</artifactId>
45.48 + <classifier>js</classifier>
45.49 + <type>zip</type>
45.50 + <version>0.3-SNAPSHOT</version>
45.51 + <scope>provided</scope>
45.52 + </dependency>
45.53 </dependencies>
45.54 </project>
46.1 --- a/javaquery/demo-calculator/src/main/assembly/bck2brwsr.xml Tue Feb 19 15:33:32 2013 +0100
46.2 +++ b/javaquery/demo-calculator/src/main/assembly/bck2brwsr.xml Tue Feb 19 15:59:27 2013 +0100
46.3 @@ -32,6 +32,19 @@
46.4 <useProjectArtifact>false</useProjectArtifact>
46.5 <scope>runtime</scope>
46.6 <outputDirectory>lib</outputDirectory>
46.7 + <includes>
46.8 + <include>*:jar</include>
46.9 + <include>*:rt</include>
46.10 + </includes>
46.11 + </dependencySet>
46.12 + <dependencySet>
46.13 + <useProjectArtifact>false</useProjectArtifact>
46.14 + <scope>provided</scope>
46.15 + <includes>
46.16 + <include>*:js</include>
46.17 + </includes>
46.18 + <unpack>true</unpack>
46.19 + <outputDirectory>/</outputDirectory>
46.20 </dependencySet>
46.21 </dependencySets>
46.22 <files>
46.23 @@ -44,11 +57,6 @@
46.24 <outputDirectory>/</outputDirectory>
46.25 <destName>index.xhtml</destName>
46.26 </file>
46.27 - <file>
46.28 - <source>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/calc/staticcompilation/bootjava.js</source>
46.29 - <outputDirectory>/</outputDirectory>
46.30 - <destName>bck2brwsr.js</destName>
46.31 - </file>
46.32 </files>
46.33
46.34 </assembly>
46.35 \ No newline at end of file
47.1 --- a/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml Tue Feb 19 15:33:32 2013 +0100
47.2 +++ b/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml Tue Feb 19 15:59:27 2013 +0100
47.3 @@ -78,5 +78,9 @@
47.4 </table>
47.5 <div data-bind="text: displayPreview"></div>
47.6 <script src="bck2brwsr.js"/>
47.7 + <script>
47.8 + var vm = bck2brwsr('demo.static.calculator-0.3-SNAPSHOT.jar');
47.9 + vm.loadClass('org.apidesign.bck2brwsr.demo.calc.staticcompilation.Calc');
47.10 + </script>
47.11 </body>
47.12 </html>
48.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Tue Feb 19 15:33:32 2013 +0100
48.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Tue Feb 19 15:59:27 2013 +0100
48.3 @@ -39,6 +39,7 @@
48.4 import java.util.concurrent.TimeUnit;
48.5 import java.util.logging.Level;
48.6 import java.util.logging.Logger;
48.7 +import org.apidesign.bck2brwsr.launcher.InvocationContext.Resource;
48.8 import org.apidesign.vm4brwsr.Bck2Brwsr;
48.9 import org.glassfish.grizzly.PortRange;
48.10 import org.glassfish.grizzly.http.server.HttpHandler;
48.11 @@ -47,6 +48,7 @@
48.12 import org.glassfish.grizzly.http.server.Request;
48.13 import org.glassfish.grizzly.http.server.Response;
48.14 import org.glassfish.grizzly.http.server.ServerConfiguration;
48.15 +import org.glassfish.grizzly.http.util.HttpStatus;
48.16
48.17 /**
48.18 * Lightweight server to launch Bck2Brwsr applications and tests.
48.19 @@ -94,9 +96,12 @@
48.20 startpage = "/" + startpage;
48.21 }
48.22 HttpServer s = initServer(".", true);
48.23 + int last = startpage.lastIndexOf('/');
48.24 + String simpleName = startpage.substring(last);
48.25 + s.getServerConfiguration().addHttpHandler(new Page(resources, startpage), simpleName);
48.26 s.getServerConfiguration().addHttpHandler(new Page(resources, null), "/");
48.27 try {
48.28 - launchServerAndBrwsr(s, startpage);
48.29 + launchServerAndBrwsr(s, simpleName);
48.30 } catch (URISyntaxException | InterruptedException ex) {
48.31 throw new IOException(ex);
48.32 }
48.33 @@ -138,7 +143,7 @@
48.34
48.35 final ServerConfiguration conf = s.getServerConfiguration();
48.36 if (addClasses) {
48.37 - conf.addHttpHandler(new VM(resources), "/vm.js");
48.38 + conf.addHttpHandler(new VM(resources), "/bck2brwsr.js");
48.39 conf.addHttpHandler(new Classes(resources), "/classes/");
48.40 }
48.41 return s;
48.42 @@ -152,11 +157,13 @@
48.43 class DynamicResourceHandler extends HttpHandler {
48.44 private final InvocationContext ic;
48.45 public DynamicResourceHandler(InvocationContext ic) {
48.46 - if (ic == null || ic.httpPath == null) {
48.47 + if (ic == null || ic.resources.isEmpty()) {
48.48 throw new NullPointerException();
48.49 }
48.50 this.ic = ic;
48.51 - conf.addHttpHandler(this, ic.httpPath);
48.52 + for (Resource r : ic.resources) {
48.53 + conf.addHttpHandler(this, r.httpPath);
48.54 + }
48.55 }
48.56
48.57 public void close() {
48.58 @@ -165,10 +172,12 @@
48.59
48.60 @Override
48.61 public void service(Request request, Response response) throws Exception {
48.62 - if (ic.httpPath.equals(request.getRequestURI())) {
48.63 - LOG.log(Level.INFO, "Serving HttpResource for {0}", request.getRequestURI());
48.64 - response.setContentType(ic.httpType);
48.65 - copyStream(ic.httpContent, response.getOutputStream(), null);
48.66 + for (Resource r : ic.resources) {
48.67 + if (r.httpPath.equals(request.getRequestURI())) {
48.68 + LOG.log(Level.INFO, "Serving HttpResource for {0}", request.getRequestURI());
48.69 + response.setContentType(r.httpType);
48.70 + copyStream(r.httpContent, response.getOutputStream(), null);
48.71 + }
48.72 }
48.73 }
48.74 }
48.75 @@ -186,10 +195,26 @@
48.76 String id = request.getParameter("request");
48.77 String value = request.getParameter("result");
48.78
48.79 +
48.80 + InvocationContext mi = null;
48.81 + int caseNmbr = -1;
48.82 +
48.83 if (id != null && value != null) {
48.84 LOG.log(Level.INFO, "Received result for case {0} = {1}", new Object[]{id, value});
48.85 value = decodeURL(value);
48.86 - cases.get(Integer.parseInt(id)).result(value, null);
48.87 + int indx = Integer.parseInt(id);
48.88 + cases.get(indx).result(value, null);
48.89 + if (++indx < cases.size()) {
48.90 + mi = cases.get(indx);
48.91 + LOG.log(Level.INFO, "Re-executing case {0}", indx);
48.92 + caseNmbr = indx;
48.93 + }
48.94 + } else {
48.95 + if (!cases.isEmpty()) {
48.96 + LOG.info("Re-executing test cases");
48.97 + mi = cases.get(0);
48.98 + caseNmbr = 0;
48.99 + }
48.100 }
48.101
48.102 if (prev != null) {
48.103 @@ -197,7 +222,10 @@
48.104 prev = null;
48.105 }
48.106
48.107 - InvocationContext mi = methods.take();
48.108 + if (mi == null) {
48.109 + mi = methods.take();
48.110 + caseNmbr = cnt++;
48.111 + }
48.112 if (mi == END) {
48.113 response.getWriter().write("");
48.114 wait.countDown();
48.115 @@ -206,18 +234,18 @@
48.116 return;
48.117 }
48.118
48.119 - if (mi.httpPath != null) {
48.120 + if (!mi.resources.isEmpty()) {
48.121 prev = new DynamicResourceHandler(mi);
48.122 }
48.123
48.124 cases.add(mi);
48.125 final String cn = mi.clazz.getName();
48.126 final String mn = mi.methodName;
48.127 - LOG.log(Level.INFO, "Request for {0} case. Sending {1}.{2}", new Object[]{cnt, cn, mn});
48.128 + LOG.log(Level.INFO, "Request for {0} case. Sending {1}.{2}", new Object[]{caseNmbr, cn, mn});
48.129 response.getWriter().write("{"
48.130 + "className: '" + cn + "', "
48.131 + "methodName: '" + mn + "', "
48.132 - + "request: " + cnt
48.133 + + "request: " + caseNmbr
48.134 );
48.135 if (mi.html != null) {
48.136 response.getWriter().write(", html: '");
48.137 @@ -225,7 +253,6 @@
48.138 response.getWriter().write("'");
48.139 }
48.140 response.getWriter().write("}");
48.141 - cnt++;
48.142 }
48.143 }, "/data");
48.144
48.145 @@ -427,9 +454,9 @@
48.146 String r = resource;
48.147 if (r == null) {
48.148 r = request.getHttpHandlerPath();
48.149 - if (r.startsWith("/")) {
48.150 - r = r.substring(1);
48.151 - }
48.152 + }
48.153 + if (r.startsWith("/")) {
48.154 + r = r.substring(1);
48.155 }
48.156 String[] replace = {};
48.157 if (r.endsWith(".html")) {
48.158 @@ -460,14 +487,22 @@
48.159 StringBuilder sb = new StringBuilder();
48.160 Bck2Brwsr.generate(sb, loader);
48.161 sb.append(
48.162 - "function ldCls(res) {\n"
48.163 - + " var request = new XMLHttpRequest();\n"
48.164 - + " request.open('GET', '/classes/' + res, false);\n"
48.165 - + " request.send();\n"
48.166 - + " var arr = eval('(' + request.responseText + ')');\n"
48.167 - + " return arr;\n"
48.168 - + "}\n"
48.169 - + "var vm = new bck2brwsr(ldCls);\n"
48.170 + "(function WrapperVM(global) {"
48.171 + + " function ldCls(res) {\n"
48.172 + + " var request = new XMLHttpRequest();\n"
48.173 + + " request.open('GET', '/classes/' + res, false);\n"
48.174 + + " request.send();\n"
48.175 + + " if (request.status !== 200) return null;\n"
48.176 + + " var arr = eval('(' + request.responseText + ')');\n"
48.177 + + " return arr;\n"
48.178 + + " }\n"
48.179 + + " var prevvm = global.bck2brwsr;\n"
48.180 + + " global.bck2brwsr = function() {\n"
48.181 + + " var args = Array.prototype.slice.apply(arguments);\n"
48.182 + + " args.unshift(ldCls);\n"
48.183 + + " return prevvm.apply(null, args);\n"
48.184 + + " };\n"
48.185 + + "})(this);\n"
48.186 );
48.187 this.bck2brwsr = sb.toString();
48.188 }
48.189 @@ -515,6 +550,7 @@
48.190 }
48.191 w.append("\n]");
48.192 } catch (IOException ex) {
48.193 + response.setStatus(HttpStatus.NOT_FOUND_404);
48.194 response.setError();
48.195 response.setDetailMessage(ex.getMessage());
48.196 }
49.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/InvocationContext.java Tue Feb 19 15:33:32 2013 +0100
49.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/InvocationContext.java Tue Feb 19 15:59:27 2013 +0100
49.3 @@ -19,6 +19,8 @@
49.4
49.5 import java.io.IOException;
49.6 import java.io.InputStream;
49.7 +import java.util.ArrayList;
49.8 +import java.util.List;
49.9 import java.util.concurrent.CountDownLatch;
49.10 import java.util.concurrent.TimeUnit;
49.11
49.12 @@ -34,9 +36,7 @@
49.13 private String result;
49.14 private Throwable exception;
49.15 String html;
49.16 - InputStream httpContent;
49.17 - String httpType;
49.18 - String httpPath;
49.19 + final List<Resource> resources = new ArrayList<>();
49.20
49.21 InvocationContext(Launcher launcher, Class<?> clazz, String methodName) {
49.22 this.launcher = launcher;
49.23 @@ -55,13 +55,11 @@
49.24 /** HTTP resource to be available during execution. An invocation may
49.25 * perform an HTTP query and obtain a resource relative to the page.
49.26 */
49.27 - public void setHttpResource(String relativePath, String mimeType, InputStream content) {
49.28 + public void addHttpResource(String relativePath, String mimeType, InputStream content) {
49.29 if (relativePath == null || mimeType == null || content == null) {
49.30 throw new NullPointerException();
49.31 }
49.32 - this.httpPath = relativePath;
49.33 - this.httpType = mimeType;
49.34 - this.httpContent = content;
49.35 + resources.add(new Resource(content, mimeType, relativePath));
49.36 }
49.37
49.38 /** Invokes the associated method.
49.39 @@ -97,5 +95,16 @@
49.40 wait.countDown();
49.41 }
49.42
49.43 -
49.44 +
49.45 + static final class Resource {
49.46 + final InputStream httpContent;
49.47 + final String httpType;
49.48 + final String httpPath;
49.49 +
49.50 + Resource(InputStream httpContent, String httpType, String httpPath) {
49.51 + this.httpContent = httpContent;
49.52 + this.httpType = httpType;
49.53 + this.httpPath = httpPath;
49.54 + }
49.55 + }
49.56 }
50.1 --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java Tue Feb 19 15:33:32 2013 +0100
50.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/impl/Console.java Tue Feb 19 15:59:27 2013 +0100
50.3 @@ -125,7 +125,7 @@
50.4 loadText(u, this, arr);
50.5
50.6 } catch (Exception ex) {
50.7 - log(ex.getMessage());
50.8 + log(ex.getClass().getName() + ":" + ex.getMessage());
50.9 }
50.10 }
50.11 }
51.1 --- a/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml Tue Feb 19 15:33:32 2013 +0100
51.2 +++ b/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml Tue Feb 19 15:59:27 2013 +0100
51.3 @@ -24,7 +24,10 @@
51.4 <title>Bck2Brwsr Harness</title>
51.5 </head>
51.6 <body>
51.7 - <script src="/vm.js"></script>
51.8 + <script src="/bck2brwsr.js"></script>
51.9 + <script>
51.10 + var vm = bck2brwsr();
51.11 + </script>
51.12
51.13 <h1>Bck2Brwsr Execution Harness</h1>
51.14
52.1 --- a/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Bck2BrswrMojo.java Tue Feb 19 15:33:32 2013 +0100
52.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
52.3 @@ -1,122 +0,0 @@
52.4 -/**
52.5 - * Back 2 Browser Bytecode Translator
52.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
52.7 - *
52.8 - * This program is free software: you can redistribute it and/or modify
52.9 - * it under the terms of the GNU General Public License as published by
52.10 - * the Free Software Foundation, version 2 of the License.
52.11 - *
52.12 - * This program is distributed in the hope that it will be useful,
52.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
52.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52.15 - * GNU General Public License for more details.
52.16 - *
52.17 - * You should have received a copy of the GNU General Public License
52.18 - * along with this program. Look for COPYING file in the top folder.
52.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
52.20 - */
52.21 -package org.apidesign.bck2brwsr.mojo;
52.22 -
52.23 -import org.apache.maven.plugin.AbstractMojo;
52.24 -
52.25 -import java.io.File;
52.26 -import java.io.FileWriter;
52.27 -import java.io.IOException;
52.28 -import java.net.MalformedURLException;
52.29 -import java.net.URL;
52.30 -import java.net.URLClassLoader;
52.31 -import java.util.ArrayList;
52.32 -import java.util.Collection;
52.33 -import java.util.List;
52.34 -import org.apache.maven.artifact.Artifact;
52.35 -import org.apache.maven.plugin.MojoExecutionException;
52.36 -import org.apache.maven.plugins.annotations.LifecyclePhase;
52.37 -import org.apache.maven.plugins.annotations.Mojo;
52.38 -import org.apache.maven.plugins.annotations.Parameter;
52.39 -import org.apache.maven.project.MavenProject;
52.40 -import org.apidesign.vm4brwsr.Bck2Brwsr;
52.41 -
52.42 -/** Compiles classes into JavaScript. */
52.43 -@Mojo(name="j2js", defaultPhase=LifecyclePhase.PROCESS_CLASSES)
52.44 -public class Bck2BrswrMojo extends AbstractMojo {
52.45 - public Bck2BrswrMojo() {
52.46 - }
52.47 - /** Root of the class files */
52.48 - @Parameter(defaultValue="${project.build.directory}/classes")
52.49 - private File classes;
52.50 - /** File to generate. Defaults bootjava.js in the first non-empty
52.51 - package under the classes directory */
52.52 - @Parameter
52.53 - private File javascript;
52.54 -
52.55 - @Parameter(defaultValue="${project}")
52.56 - private MavenProject prj;
52.57 -
52.58 -
52.59 -
52.60 - @Override
52.61 - public void execute() throws MojoExecutionException {
52.62 - if (!classes.isDirectory()) {
52.63 - throw new MojoExecutionException("Can't find " + classes);
52.64 - }
52.65 -
52.66 - if (javascript == null) {
52.67 - javascript = new File(findNonEmptyFolder(classes), "bootjava.js");
52.68 - }
52.69 -
52.70 - List<String> arr = new ArrayList<String>();
52.71 - long newest = collectAllClasses("", classes, arr);
52.72 -
52.73 - if (javascript.lastModified() > newest) {
52.74 - return;
52.75 - }
52.76 -
52.77 - try {
52.78 - URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
52.79 - FileWriter w = new FileWriter(javascript);
52.80 - Bck2Brwsr.generate(w, url, arr.toArray(new String[0]));
52.81 - w.close();
52.82 - } catch (IOException ex) {
52.83 - throw new MojoExecutionException("Can't compile", ex);
52.84 - }
52.85 - }
52.86 -
52.87 - private static File findNonEmptyFolder(File dir) throws MojoExecutionException {
52.88 - if (!dir.isDirectory()) {
52.89 - throw new MojoExecutionException("Not a directory " + dir);
52.90 - }
52.91 - File[] arr = dir.listFiles();
52.92 - if (arr.length == 1 && arr[0].isDirectory()) {
52.93 - return findNonEmptyFolder(arr[0]);
52.94 - }
52.95 - return dir;
52.96 - }
52.97 -
52.98 - private static long collectAllClasses(String prefix, File toCheck, List<String> arr) {
52.99 - File[] files = toCheck.listFiles();
52.100 - if (files != null) {
52.101 - long newest = 0L;
52.102 - for (File f : files) {
52.103 - long lastModified = collectAllClasses(prefix + f.getName() + "/", f, arr);
52.104 - if (newest < lastModified) {
52.105 - newest = lastModified;
52.106 - }
52.107 - }
52.108 - return newest;
52.109 - } else if (toCheck.getName().endsWith(".class")) {
52.110 - arr.add(prefix.substring(0, prefix.length() - 7));
52.111 - return toCheck.lastModified();
52.112 - } else {
52.113 - return 0L;
52.114 - }
52.115 - }
52.116 -
52.117 - private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
52.118 - List<URL> arr = new ArrayList<URL>();
52.119 - arr.add(root.toURI().toURL());
52.120 - for (Artifact a : deps) {
52.121 - arr.add(a.getFile().toURI().toURL());
52.122 - }
52.123 - return new URLClassLoader(arr.toArray(new URL[0]), Bck2BrswrMojo.class.getClassLoader());
52.124 - }
52.125 -}
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
53.2 +++ b/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java Tue Feb 19 15:59:27 2013 +0100
53.3 @@ -0,0 +1,122 @@
53.4 +/**
53.5 + * Back 2 Browser Bytecode Translator
53.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
53.7 + *
53.8 + * This program is free software: you can redistribute it and/or modify
53.9 + * it under the terms of the GNU General Public License as published by
53.10 + * the Free Software Foundation, version 2 of the License.
53.11 + *
53.12 + * This program is distributed in the hope that it will be useful,
53.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
53.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53.15 + * GNU General Public License for more details.
53.16 + *
53.17 + * You should have received a copy of the GNU General Public License
53.18 + * along with this program. Look for COPYING file in the top folder.
53.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
53.20 + */
53.21 +package org.apidesign.bck2brwsr.mojo;
53.22 +
53.23 +import org.apache.maven.plugin.AbstractMojo;
53.24 +
53.25 +import java.io.File;
53.26 +import java.io.FileWriter;
53.27 +import java.io.IOException;
53.28 +import java.net.MalformedURLException;
53.29 +import java.net.URL;
53.30 +import java.net.URLClassLoader;
53.31 +import java.util.ArrayList;
53.32 +import java.util.Collection;
53.33 +import java.util.List;
53.34 +import org.apache.maven.artifact.Artifact;
53.35 +import org.apache.maven.plugin.MojoExecutionException;
53.36 +import org.apache.maven.plugins.annotations.LifecyclePhase;
53.37 +import org.apache.maven.plugins.annotations.Mojo;
53.38 +import org.apache.maven.plugins.annotations.Parameter;
53.39 +import org.apache.maven.project.MavenProject;
53.40 +import org.apidesign.vm4brwsr.Bck2Brwsr;
53.41 +
53.42 +/** Compiles classes into JavaScript. */
53.43 +@Mojo(name="j2js", defaultPhase=LifecyclePhase.PROCESS_CLASSES)
53.44 +public class Java2JavaScript extends AbstractMojo {
53.45 + public Java2JavaScript() {
53.46 + }
53.47 + /** Root of the class files */
53.48 + @Parameter(defaultValue="${project.build.directory}/classes")
53.49 + private File classes;
53.50 + /** File to generate. Defaults bootjava.js in the first non-empty
53.51 + package under the classes directory */
53.52 + @Parameter
53.53 + private File javascript;
53.54 +
53.55 + @Parameter(defaultValue="${project}")
53.56 + private MavenProject prj;
53.57 +
53.58 +
53.59 +
53.60 + @Override
53.61 + public void execute() throws MojoExecutionException {
53.62 + if (!classes.isDirectory()) {
53.63 + throw new MojoExecutionException("Can't find " + classes);
53.64 + }
53.65 +
53.66 + if (javascript == null) {
53.67 + javascript = new File(findNonEmptyFolder(classes), "bootjava.js");
53.68 + }
53.69 +
53.70 + List<String> arr = new ArrayList<String>();
53.71 + long newest = collectAllClasses("", classes, arr);
53.72 +
53.73 + if (javascript.lastModified() > newest) {
53.74 + return;
53.75 + }
53.76 +
53.77 + try {
53.78 + URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
53.79 + FileWriter w = new FileWriter(javascript);
53.80 + Bck2Brwsr.generate(w, url, arr.toArray(new String[0]));
53.81 + w.close();
53.82 + } catch (IOException ex) {
53.83 + throw new MojoExecutionException("Can't compile", ex);
53.84 + }
53.85 + }
53.86 +
53.87 + private static File findNonEmptyFolder(File dir) throws MojoExecutionException {
53.88 + if (!dir.isDirectory()) {
53.89 + throw new MojoExecutionException("Not a directory " + dir);
53.90 + }
53.91 + File[] arr = dir.listFiles();
53.92 + if (arr.length == 1 && arr[0].isDirectory()) {
53.93 + return findNonEmptyFolder(arr[0]);
53.94 + }
53.95 + return dir;
53.96 + }
53.97 +
53.98 + private static long collectAllClasses(String prefix, File toCheck, List<String> arr) {
53.99 + File[] files = toCheck.listFiles();
53.100 + if (files != null) {
53.101 + long newest = 0L;
53.102 + for (File f : files) {
53.103 + long lastModified = collectAllClasses(prefix + f.getName() + "/", f, arr);
53.104 + if (newest < lastModified) {
53.105 + newest = lastModified;
53.106 + }
53.107 + }
53.108 + return newest;
53.109 + } else if (toCheck.getName().endsWith(".class")) {
53.110 + arr.add(prefix.substring(0, prefix.length() - 7));
53.111 + return toCheck.lastModified();
53.112 + } else {
53.113 + return 0L;
53.114 + }
53.115 + }
53.116 +
53.117 + private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
53.118 + List<URL> arr = new ArrayList<URL>();
53.119 + arr.add(root.toURI().toURL());
53.120 + for (Artifact a : deps) {
53.121 + arr.add(a.getFile().toURI().toURL());
53.122 + }
53.123 + return new URLClassLoader(arr.toArray(new URL[0]), Java2JavaScript.class.getClassLoader());
53.124 + }
53.125 +}
54.1 --- a/mojo/src/main/resources/META-INF/maven/archetype-metadata.xml Tue Feb 19 15:33:32 2013 +0100
54.2 +++ b/mojo/src/main/resources/META-INF/maven/archetype-metadata.xml Tue Feb 19 15:59:27 2013 +0100
54.3 @@ -30,6 +30,7 @@
54.4 <directory>src/main/resources</directory>
54.5 <includes>
54.6 <include>**/*.xhtml</include>
54.7 + <include>**/*.html</include>
54.8 </includes>
54.9 </fileSet>
54.10 <fileSet filtered="true" packaged="true">
54.11 @@ -44,5 +45,11 @@
54.12 <include>nbactions.xml</include>
54.13 </includes>
54.14 </fileSet>
54.15 + <fileSet filtered="true" packaged="false">
54.16 + <directory></directory>
54.17 + <includes>
54.18 + <include>bck2brwsr-assembly.xml</include>
54.19 + </includes>
54.20 + </fileSet>
54.21 </fileSets>
54.22 </archetype-descriptor>
54.23 \ No newline at end of file
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
55.2 +++ b/mojo/src/main/resources/archetype-resources/bck2brwsr-assembly.xml Tue Feb 19 15:59:27 2013 +0100
55.3 @@ -0,0 +1,61 @@
55.4 +<?xml version="1.0"?>
55.5 +<!--
55.6 +
55.7 + Back 2 Browser Bytecode Translator
55.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
55.9 +
55.10 + This program is free software: you can redistribute it and/or modify
55.11 + it under the terms of the GNU General Public License as published by
55.12 + the Free Software Foundation, version 2 of the License.
55.13 +
55.14 + This program is distributed in the hope that it will be useful,
55.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
55.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55.17 + GNU General Public License for more details.
55.18 +
55.19 + You should have received a copy of the GNU General Public License
55.20 + along with this program. Look for COPYING file in the top folder.
55.21 + If not, see http://opensource.org/licenses/GPL-2.0.
55.22 +
55.23 +-->
55.24 +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
55.25 + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
55.26 +
55.27 + <id>bck2brwsr</id>
55.28 + <formats>
55.29 + <format>zip</format>
55.30 + </formats>
55.31 + <baseDirectory>public_html</baseDirectory>
55.32 + <dependencySets>
55.33 + <dependencySet>
55.34 + <useProjectArtifact>false</useProjectArtifact>
55.35 + <scope>runtime</scope>
55.36 + <outputDirectory>lib</outputDirectory>
55.37 + <includes>
55.38 + <include>*:jar</include>
55.39 + <include>*:rt</include>
55.40 + </includes>
55.41 + </dependencySet>
55.42 + <dependencySet>
55.43 + <useProjectArtifact>false</useProjectArtifact>
55.44 + <scope>provided</scope>
55.45 + <includes>
55.46 + <include>*:js</include>
55.47 + </includes>
55.48 + <unpack>true</unpack>
55.49 + <outputDirectory>/</outputDirectory>
55.50 + </dependencySet>
55.51 + </dependencySets>
55.52 + <files>
55.53 + <file>
55.54 + <source>${project.build.directory}/${project.build.finalName}.jar</source>
55.55 + <outputDirectory>/</outputDirectory>
55.56 + </file>
55.57 + <file>
55.58 + <source>${project.build.directory}/classes/${package.replace('.','/')}/index.html</source>
55.59 + <outputDirectory>/</outputDirectory>
55.60 + <destName>index.html</destName>
55.61 + </file>
55.62 + </files>
55.63 +
55.64 +</assembly>
55.65 \ No newline at end of file
56.1 --- a/mojo/src/main/resources/archetype-resources/pom.xml Tue Feb 19 15:33:32 2013 +0100
56.2 +++ b/mojo/src/main/resources/archetype-resources/pom.xml Tue Feb 19 15:59:27 2013 +0100
56.3 @@ -53,7 +53,7 @@
56.4 </execution>
56.5 </executions>
56.6 <configuration>
56.7 - <startpage>${package.replace('.','/')}/index.xhtml</startpage>
56.8 + <startpage>${package.replace('.','/')}/index.html</startpage>
56.9 </configuration>
56.10 </plugin>
56.11 <plugin>
56.12 @@ -65,14 +65,46 @@
56.13 <target>1.7</target>
56.14 </configuration>
56.15 </plugin>
56.16 + <plugin>
56.17 + <groupId>org.apache.maven.plugins</groupId>
56.18 + <artifactId>maven-jar-plugin</artifactId>
56.19 + <version>2.4</version>
56.20 + <configuration>
56.21 + <archive>
56.22 + <manifest>
56.23 + <addClasspath>true</addClasspath>
56.24 + <classpathPrefix>lib/</classpathPrefix>
56.25 + </manifest>
56.26 + </archive>
56.27 + </configuration>
56.28 + </plugin>
56.29 + <plugin>
56.30 + <artifactId>maven-assembly-plugin</artifactId>
56.31 + <version>2.4</version>
56.32 + <executions>
56.33 + <execution>
56.34 + <id>distro-assembly</id>
56.35 + <phase>package</phase>
56.36 + <goals>
56.37 + <goal>single</goal>
56.38 + </goals>
56.39 + <configuration>
56.40 + <descriptors>
56.41 + <descriptor>bck2brwsr-assembly.xml</descriptor>
56.42 + </descriptors>
56.43 + </configuration>
56.44 + </execution>
56.45 + </executions>
56.46 + </plugin>
56.47 </plugins>
56.48 </build>
56.49
56.50 <dependencies>
56.51 <dependency>
56.52 <groupId>org.apidesign.bck2brwsr</groupId>
56.53 - <artifactId>emul.mini</artifactId>
56.54 + <artifactId>emul</artifactId>
56.55 <version>0.3-SNAPSHOT</version>
56.56 + <classifier>rt</classifier>
56.57 </dependency>
56.58 <dependency>
56.59 <groupId>org.apidesign.bck2brwsr</groupId>
56.60 @@ -87,6 +119,14 @@
56.61 </dependency>
56.62 <dependency>
56.63 <groupId>org.apidesign.bck2brwsr</groupId>
56.64 + <artifactId>vm4brwsr</artifactId>
56.65 + <classifier>js</classifier>
56.66 + <type>zip</type>
56.67 + <version>0.3-SNAPSHOT</version>
56.68 + <scope>provided</scope>
56.69 + </dependency>
56.70 + <dependency>
56.71 + <groupId>org.apidesign.bck2brwsr</groupId>
56.72 <artifactId>vmtest</artifactId>
56.73 <version>0.3-SNAPSHOT</version>
56.74 <scope>test</scope>
57.1 --- a/mojo/src/main/resources/archetype-resources/src/main/java/App.java Tue Feb 19 15:33:32 2013 +0100
57.2 +++ b/mojo/src/main/resources/archetype-resources/src/main/java/App.java Tue Feb 19 15:59:27 2013 +0100
57.3 @@ -9,7 +9,7 @@
57.4 /** Edit the index.xhtml file. Use 'id' to name certain HTML elements.
57.5 * Use this class to define behavior of the elements.
57.6 */
57.7 -@Page(xhtml="index.xhtml", className="Index", properties={
57.8 +@Page(xhtml="index.html", className="Index", properties={
57.9 @Property(name="name", type=String.class)
57.10 })
57.11 public class App {
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
58.2 +++ b/mojo/src/main/resources/archetype-resources/src/main/resources/index.html Tue Feb 19 15:59:27 2013 +0100
58.3 @@ -0,0 +1,22 @@
58.4 +<?xml version="1.0" encoding="UTF-8"?>
58.5 +<!DOCTYPE html>
58.6 +<html xmlns="http://www.w3.org/1999/xhtml">
58.7 + <head>
58.8 + <title>Bck2Brwsr's Hello World</title>
58.9 + </head>
58.10 + <body>
58.11 + <h1 data-bind="text: helloMessage">Loading Bck2Brwsr's Hello World...</h1>
58.12 + Your name: <input id='input' data-bind="value: name, valueUpdate: 'afterkeydown'"></input>
58.13 + <button id="hello">Say Hello!</button>
58.14 + <p>
58.15 + <canvas id="canvas" width="300" height="50">
58.16 + </canvas>
58.17 + </p>
58.18 +
58.19 + <script src="bck2brwsr.js"></script>
58.20 + <script type="text/javascript">
58.21 + var vm = bck2brwsr('${artifactId}-${version}.jar');
58.22 + vm.loadClass('${package}.App');
58.23 + </script>
58.24 + </body>
58.25 +</html>
59.1 --- a/mojo/src/main/resources/archetype-resources/src/main/resources/index.xhtml Tue Feb 19 15:33:32 2013 +0100
59.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
59.3 @@ -1,22 +0,0 @@
59.4 -<?xml version="1.0" encoding="UTF-8"?>
59.5 -<!DOCTYPE html>
59.6 -<html xmlns="http://www.w3.org/1999/xhtml">
59.7 - <head>
59.8 - <title>Bck2Brwsr's Hello World</title>
59.9 - </head>
59.10 - <body>
59.11 - <h1 data-bind="text: helloMessage">Loading Bck2Brwsr's Hello World...</h1>
59.12 - Your name: <input id='input' data-bind="value: name, valueUpdate: 'afterkeydown'"></input>
59.13 - <button id="hello">Say Hello!</button>
59.14 - <p>
59.15 - <canvas id="canvas" width="300" height="50">
59.16 - </canvas>
59.17 - </p>
59.18 -
59.19 - <script src="/bck2brwsr.js"></script>
59.20 - <script src="/vm.js"></script>
59.21 - <script type="text/javascript">
59.22 - vm.loadClass('${package}.App');
59.23 - </script>
59.24 - </body>
59.25 -</html>
60.1 --- a/pom.xml Tue Feb 19 15:33:32 2013 +0100
60.2 +++ b/pom.xml Tue Feb 19 15:59:27 2013 +0100
60.3 @@ -93,6 +93,15 @@
60.4 </configuration>
60.5 </plugin>
60.6 </plugins>
60.7 + <pluginManagement>
60.8 + <plugins>
60.9 + <plugin>
60.10 + <groupId>org.apache.maven.plugins</groupId>
60.11 + <artifactId>maven-surefire-plugin</artifactId>
60.12 + <version>2.13</version>
60.13 + </plugin>
60.14 + </plugins>
60.15 + </pluginManagement>
60.16 </build>
60.17 <dependencyManagement>
60.18 <dependencies>
61.1 --- a/vm/pom.xml Tue Feb 19 15:33:32 2013 +0100
61.2 +++ b/vm/pom.xml Tue Feb 19 15:59:27 2013 +0100
61.3 @@ -12,7 +12,7 @@
61.4 <version>0.3-SNAPSHOT</version>
61.5 <packaging>jar</packaging>
61.6
61.7 - <name>Java VM for Browser</name>
61.8 + <name>Virtual Machine for Browser</name>
61.9 <url>http://bck2brwsr.apidesign.org</url>
61.10
61.11 <properties>
61.12 @@ -68,6 +68,45 @@
61.13 <target>1.7</target>
61.14 </configuration>
61.15 </plugin>
61.16 + <plugin>
61.17 + <groupId>org.codehaus.mojo</groupId>
61.18 + <artifactId>exec-maven-plugin</artifactId>
61.19 + <version>1.2.1</version>
61.20 + <executions>
61.21 + <execution>
61.22 + <id>generate-js</id>
61.23 + <phase>process-classes</phase>
61.24 + <goals>
61.25 + <goal>java</goal>
61.26 + </goals>
61.27 + </execution>
61.28 + </executions>
61.29 + <configuration>
61.30 + <mainClass>org.apidesign.vm4brwsr.Main</mainClass>
61.31 + <arguments>
61.32 + <argument>${project.build.directory}/bck2brwsr.js</argument>
61.33 + <argument>org/apidesign/vm4brwsr/Bck2Brwsr</argument>
61.34 + </arguments>
61.35 + </configuration>
61.36 + </plugin>
61.37 + <plugin>
61.38 + <artifactId>maven-assembly-plugin</artifactId>
61.39 + <version>2.4</version>
61.40 + <executions>
61.41 + <execution>
61.42 + <id>js</id>
61.43 + <phase>package</phase>
61.44 + <goals>
61.45 + <goal>single</goal>
61.46 + </goals>
61.47 + <configuration>
61.48 + <descriptors>
61.49 + <descriptor>src/main/assembly/bck2brwsr.xml</descriptor>
61.50 + </descriptors>
61.51 + </configuration>
61.52 + </execution>
61.53 + </executions>
61.54 + </plugin>
61.55 </plugins>
61.56 </build>
61.57 <dependencies>
61.58 @@ -85,19 +124,20 @@
61.59 <dependency>
61.60 <groupId>${project.groupId}</groupId>
61.61 <artifactId>core</artifactId>
61.62 - <version>0.3-SNAPSHOT</version>
61.63 + <version>${project.version}</version>
61.64 <type>jar</type>
61.65 </dependency>
61.66 <dependency>
61.67 <groupId>${project.groupId}</groupId>
61.68 <artifactId>emul.mini</artifactId>
61.69 - <version>0.3-SNAPSHOT</version>
61.70 - <scope>test</scope>
61.71 + <version>${project.version}</version>
61.72 + <scope>compile</scope>
61.73 </dependency>
61.74 <dependency>
61.75 <groupId>${project.groupId}</groupId>
61.76 <artifactId>javap</artifactId>
61.77 - <version>0.3-SNAPSHOT</version>
61.78 + <version>${project.version}</version>
61.79 + <scope>compile</scope>
61.80 </dependency>
61.81 </dependencies>
61.82 </project>
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
62.2 +++ b/vm/src/main/assembly/bck2brwsr.xml Tue Feb 19 15:59:27 2013 +0100
62.3 @@ -0,0 +1,36 @@
62.4 +<?xml version="1.0"?>
62.5 +<!--
62.6 +
62.7 + Back 2 Browser Bytecode Translator
62.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
62.9 +
62.10 + This program is free software: you can redistribute it and/or modify
62.11 + it under the terms of the GNU General Public License as published by
62.12 + the Free Software Foundation, version 2 of the License.
62.13 +
62.14 + This program is distributed in the hope that it will be useful,
62.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
62.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
62.17 + GNU General Public License for more details.
62.18 +
62.19 + You should have received a copy of the GNU General Public License
62.20 + along with this program. Look for COPYING file in the top folder.
62.21 + If not, see http://opensource.org/licenses/GPL-2.0.
62.22 +
62.23 +-->
62.24 +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
62.25 + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
62.26 +
62.27 + <id>js</id>
62.28 + <formats>
62.29 + <format>zip</format>
62.30 + </formats>
62.31 + <baseDirectory>/</baseDirectory>
62.32 + <files>
62.33 + <file>
62.34 + <source>${project.build.directory}/bck2brwsr.js</source>
62.35 + <outputDirectory>/</outputDirectory>
62.36 + </file>
62.37 + </files>
62.38 +
62.39 +</assembly>
62.40 \ No newline at end of file
63.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Tue Feb 19 15:33:32 2013 +0100
63.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Tue Feb 19 15:59:27 2013 +0100
63.3 @@ -40,6 +40,16 @@
63.4 * In this scenario, when a request for an unknown class is made, the loader
63.5 * function is asked for its byte code and the system dynamically transforms
63.6 * it to JavaScript.
63.7 + * <p>
63.8 + * Instead of a loader function, one can also provide a URL to a JAR file.
63.9 + * The <code>bck2brwsr</code> system will do its best to download the file
63.10 + * and provide loader function for it automatically.
63.11 + * <p>
63.12 + * One can provide as many loader functions and JAR URL references as necessary.
63.13 + * Then the initialization code would look like:<pre>
63.14 + * var vm = bck2brwsr(url1, url2, fnctn1, url3, functn2);
63.15 + * </pre>
63.16 + * The provided URLs and loader functions will be consulted one by one.
63.17 *
63.18 * @author Jaroslav Tulach <jtulach@netbeans.org>
63.19 */
64.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Feb 19 15:33:32 2013 +0100
64.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Feb 19 15:59:27 2013 +0100
64.3 @@ -113,7 +113,7 @@
64.4 final String className = className(jc);
64.5 out.append("\n\n").append(assignClass(className));
64.6 out.append("function CLS() {");
64.7 - out.append("\n if (!CLS.prototype.$instOf_").append(className).append(") {");
64.8 + out.append("\n if (!CLS.$class) {");
64.9 if (proto == null) {
64.10 String sc = jc.getSuperClassName(); // with _
64.11 out.append("\n var pp = ").
64.12 @@ -175,12 +175,14 @@
64.13 out.append("\n };");
64.14 }
64.15 out.append(prefix).append(mn).append(".access = " + m.getAccess()).append(";");
64.16 + out.append(prefix).append(mn).append(".cls = CLS;");
64.17 }
64.18 out.append("\n c.constructor = CLS;");
64.19 out.append("\n c.$instOf_").append(className).append(" = true;");
64.20 for (String superInterface : jc.getSuperInterfaces()) {
64.21 out.append("\n c.$instOf_").append(superInterface.replace('/', '_')).append(" = true;");
64.22 }
64.23 + out.append("\n CLS.$class = 'temp';");
64.24 out.append("\n CLS.$class = ");
64.25 out.append(accessClass("java_lang_Class(true);"));
64.26 out.append("\n CLS.$class.jvmName = '").append(jc.getClassName()).append("';");
64.27 @@ -1620,7 +1622,7 @@
64.28 final String jvmType = "Lorg/apidesign/bck2brwsr/core/JavaScriptBody;";
64.29 class P extends AnnotationParser {
64.30 public P() {
64.31 - super(false);
64.32 + super(false, true);
64.33 }
64.34
64.35 int cnt;
64.36 @@ -1676,7 +1678,7 @@
64.37 final String[] values = new String[attrNames.length];
64.38 final boolean[] found = { false };
64.39 final String jvmType = "L" + className.replace('.', '/') + ";";
64.40 - AnnotationParser ap = new AnnotationParser(false) {
64.41 + AnnotationParser ap = new AnnotationParser(false, true) {
64.42 @Override
64.43 protected void visitAttr(String type, String attr, String at, String value) {
64.44 if (type.equals(jvmType)) {
64.45 @@ -1713,35 +1715,71 @@
64.46 return " = null;";
64.47 }
64.48
64.49 - private static void generateAnno(ClassData cd, final Appendable out, byte[] data) throws IOException {
64.50 - AnnotationParser ap = new AnnotationParser(true) {
64.51 - int anno;
64.52 - int cnt;
64.53 + private void generateAnno(ClassData cd, final Appendable out, byte[] data) throws IOException {
64.54 + AnnotationParser ap = new AnnotationParser(true, false) {
64.55 + int[] cnt = new int[32];
64.56 + int depth;
64.57
64.58 @Override
64.59 - protected void visitAnnotationStart(String type) throws IOException {
64.60 - if (anno++ > 0) {
64.61 + protected void visitAnnotationStart(String attrType, boolean top) throws IOException {
64.62 + final String slashType = attrType.substring(1, attrType.length() - 1);
64.63 + requireReference(slashType);
64.64 +
64.65 + if (cnt[depth]++ > 0) {
64.66 out.append(",");
64.67 }
64.68 - out.append('"').append(type).append("\" : {\n");
64.69 - cnt = 0;
64.70 + if (top) {
64.71 + out.append('"').append(attrType).append("\" : ");
64.72 + }
64.73 + out.append("{\n");
64.74 + cnt[++depth] = 0;
64.75 }
64.76
64.77 @Override
64.78 - protected void visitAnnotationEnd(String type) throws IOException {
64.79 + protected void visitAnnotationEnd(String type, boolean top) throws IOException {
64.80 out.append("\n}\n");
64.81 + depth--;
64.82 + }
64.83 +
64.84 + @Override
64.85 + protected void visitValueStart(String attrName, char type) throws IOException {
64.86 + if (cnt[depth]++ > 0) {
64.87 + out.append(",\n");
64.88 + }
64.89 + cnt[++depth] = 0;
64.90 + if (attrName != null) {
64.91 + out.append(attrName).append(" : ");
64.92 + }
64.93 + if (type == '[') {
64.94 + out.append("[");
64.95 + }
64.96 + }
64.97 +
64.98 + @Override
64.99 + protected void visitValueEnd(String attrName, char type) throws IOException {
64.100 + if (type == '[') {
64.101 + out.append("]");
64.102 + }
64.103 + depth--;
64.104 }
64.105
64.106 @Override
64.107 protected void visitAttr(String type, String attr, String attrType, String value)
64.108 throws IOException {
64.109 - if (attr == null) {
64.110 + if (attr == null && value == null) {
64.111 return;
64.112 }
64.113 - if (cnt++ > 0) {
64.114 - out.append(",\n");
64.115 - }
64.116 - out.append(attr).append("__").append(attrType).append(" : ").append(value);
64.117 + out.append(value);
64.118 + }
64.119 +
64.120 + @Override
64.121 + protected void visitEnumAttr(String type, String attr, String attrType, String value)
64.122 + throws IOException {
64.123 + final String slashType = attrType.substring(1, attrType.length() - 1);
64.124 + requireReference(slashType);
64.125 +
64.126 + out.append(accessClass(slashType.replace('/', '_')))
64.127 + .append("(false).constructor.").append(value);
64.128 }
64.129 };
64.130 ap.parse(data, cd);
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
65.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ParseMan.java Tue Feb 19 15:59:27 2013 +0100
65.3 @@ -0,0 +1,57 @@
65.4 +/**
65.5 + * Back 2 Browser Bytecode Translator
65.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
65.7 + *
65.8 + * This program is free software: you can redistribute it and/or modify
65.9 + * it under the terms of the GNU General Public License as published by
65.10 + * the Free Software Foundation, version 2 of the License.
65.11 + *
65.12 + * This program is distributed in the hope that it will be useful,
65.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
65.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
65.15 + * GNU General Public License for more details.
65.16 + *
65.17 + * You should have received a copy of the GNU General Public License
65.18 + * along with this program. Look for COPYING file in the top folder.
65.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
65.20 + */
65.21 +package org.apidesign.vm4brwsr;
65.22 +
65.23 +import java.io.IOException;
65.24 +import java.io.InputStream;
65.25 +import org.apidesign.bck2brwsr.emul.lang.ManifestInputStream;
65.26 +
65.27 +/**
65.28 + *
65.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
65.30 + */
65.31 +final class ParseMan extends ManifestInputStream {
65.32 + private String cp;
65.33 + private String mc;
65.34 +
65.35 + public ParseMan(InputStream is) throws IOException {
65.36 + super(is);
65.37 + readAttributes(new byte[512]);
65.38 + }
65.39 +
65.40 + @Override
65.41 + protected String putValue(String key, String value) {
65.42 + if ("Class-Path".equals(key)) {
65.43 + cp = value;
65.44 + }
65.45 + if ("Main-Class".equals(key)) {
65.46 + mc = value;
65.47 + }
65.48 + return null;
65.49 + }
65.50 +
65.51 + String getMainClass() {
65.52 + return mc;
65.53 + }
65.54 +
65.55 + @Override
65.56 + public String toString() {
65.57 + return cp;
65.58 + }
65.59 +
65.60 +}
66.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Tue Feb 19 15:33:32 2013 +0100
66.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Tue Feb 19 15:59:27 2013 +0100
66.3 @@ -31,8 +31,12 @@
66.4
66.5 static {
66.6 // uses VMLazy to load dynamic classes
66.7 - VMLazy.init();
66.8 - Zips.init();
66.9 + boolean assertsOn = false;
66.10 + assert assertsOn = true;
66.11 + if (assertsOn) {
66.12 + VMLazy.init();
66.13 + Zips.init();
66.14 + }
66.15 }
66.16
66.17 @Override
66.18 @@ -44,8 +48,7 @@
66.19 new VM(out).doCompile(l, names);
66.20 }
66.21 protected void doCompile(Bck2Brwsr.Resources l, StringArray names) throws IOException {
66.22 - out.append("(function VM(global) {");
66.23 - out.append("\n var vm = {};");
66.24 + out.append("(function VM(global) {var fillInVMSkeleton = function(vm) {");
66.25 StringArray processed = new StringArray();
66.26 StringArray initCode = new StringArray();
66.27 for (String baseClass : names.toArray()) {
66.28 @@ -113,31 +116,31 @@
66.29 }
66.30 }
66.31 out.append(
66.32 - " global.bck2brwsr = function() {\n"
66.33 - + " var args = arguments;\n"
66.34 + " return vm;\n"
66.35 + + " };\n"
66.36 + + " global.bck2brwsr = function() {\n"
66.37 + + " var args = Array.prototype.slice.apply(arguments);\n"
66.38 + + " var vm = fillInVMSkeleton({});\n"
66.39 + " var loader = {};\n"
66.40 + " loader.vm = vm;\n"
66.41 - + " if (args.length == 1 && typeof args[0] !== 'function') {;\n"
66.42 - + " var classpath = args[0];\n"
66.43 - + " args[0] = function(name) {\n"
66.44 - + " return vm.org_apidesign_vm4brwsr_Zips(false).loadFromCp___3B_3Ljava_lang_Object_2Ljava_lang_String_2(classpath, name);\n"
66.45 - + " };\n"
66.46 - + " };\n"
66.47 + " loader.loadClass = function(name) {\n"
66.48 + " var attr = name.replace__Ljava_lang_String_2CC('.','_');\n"
66.49 + " var fn = vm[attr];\n"
66.50 + " if (fn) return fn(false);\n"
66.51 - + " if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
66.52 + " return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
66.53 + " load__Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
66.54 + " }\n"
66.55 - + " if (args[0]) {\n"
66.56 - + " vm.loadClass = loader.loadClass;\n"
66.57 - + " vm.loadBytes = function(name) {\n"
66.58 - + " if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
66.59 - + " return args[0](name);\n"
66.60 - + " }\n"
66.61 + + " if (vm.loadClass) {\n"
66.62 + + " throw 'Cannot initialize the bck2brwsr VM twice!';\n"
66.63 + " }\n"
66.64 + + " vm.loadClass = loader.loadClass;\n"
66.65 + + " vm.loadBytes = function(name) {\n"
66.66 + + " return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
66.67 + + " loadBytes___3BLjava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
66.68 + + " }\n"
66.69 + + " vm.java_lang_reflect_Array(false);\n"
66.70 + + " vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
66.71 + + " loadBytes___3BLjava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, null, args);\n"
66.72 + " return loader;\n"
66.73 + " };\n");
66.74 out.append("}(this));");
67.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Tue Feb 19 15:33:32 2013 +0100
67.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Tue Feb 19 15:59:27 2013 +0100
67.3 @@ -20,6 +20,7 @@
67.4 import java.io.ByteArrayInputStream;
67.5 import java.io.IOException;
67.6 import java.io.InputStream;
67.7 +import java.lang.reflect.Array;
67.8 import org.apidesign.bck2brwsr.core.JavaScriptBody;
67.9
67.10 /**
67.11 @@ -38,23 +39,19 @@
67.12 static void init() {
67.13 }
67.14
67.15 - @JavaScriptBody(args={"l", "res", "args" }, body = ""
67.16 - + "\ntry {"
67.17 - + "\n return args[0](res.toString());"
67.18 - + "\n} catch (x) {"
67.19 - + "\n throw Object.getOwnPropertyNames(l.vm).toString() + x.toString();"
67.20 - + "\n}")
67.21 - private static native byte[] read(Object l, String res, Object[] args);
67.22 -
67.23 static Object load(Object loader, String name, Object[] arguments)
67.24 throws IOException, ClassNotFoundException {
67.25 return new VMLazy(loader, arguments).load(name, false);
67.26 }
67.27
67.28 + static byte[] loadBytes(Object loader, String name, Object[] arguments) throws Exception {
67.29 + return Zips.loadFromCp(arguments, name);
67.30 + }
67.31 +
67.32 private Object load(String name, boolean instance)
67.33 throws IOException, ClassNotFoundException {
67.34 String res = name.replace('.', '/') + ".class";
67.35 - byte[] arr = read(loader, res, args);
67.36 + byte[] arr = Zips.loadFromCp(args, res);
67.37 if (arr == null) {
67.38 throw new ClassNotFoundException(name);
67.39 }
68.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/Zips.java Tue Feb 19 15:33:32 2013 +0100
68.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Zips.java Tue Feb 19 15:59:27 2013 +0100
68.3 @@ -17,81 +17,171 @@
68.4 */
68.5 package org.apidesign.vm4brwsr;
68.6
68.7 +import java.io.ByteArrayInputStream;
68.8 import java.io.IOException;
68.9 +import java.io.InputStream;
68.10 import java.net.URL;
68.11 -import java.util.zip.ZipEntry;
68.12 -import java.util.zip.ZipInputStream;
68.13 import org.apidesign.bck2brwsr.core.JavaScriptBody;
68.14 +import org.apidesign.bck2brwsr.emul.zip.FastJar;
68.15
68.16 /** Conversion from classpath to load function.
68.17 *
68.18 * @author Jaroslav Tulach <jtulach@netbeans.org>
68.19 */
68.20 final class Zips {
68.21 - private Zips() {
68.22 + private final FastJar fj;
68.23 +
68.24 + private Zips(String path, byte[] zipData) throws IOException {
68.25 + long bef = timeNow();
68.26 + fj = new FastJar(zipData);
68.27 + for (FastJar.Entry e : fj.list()) {
68.28 + putRes(e.name, e);
68.29 + }
68.30 + log("Iterating thru " + path + " took " + (timeNow() - bef) + "ms");
68.31 }
68.32
68.33 public static void init() {
68.34 }
68.35 + @JavaScriptBody(args = { "arr" }, body = "return arr.length;")
68.36 + private static native int length(Object arr);
68.37 + @JavaScriptBody(args = { "arr", "index" }, body = "return arr[index];")
68.38 + private static native Object at(Object arr, int index);
68.39 + @JavaScriptBody(args = { "arr", "index", "value" }, body = "arr[index] = value; return value;")
68.40 + private static native Object set(Object arr, int index, Object value);
68.41
68.42 - public static byte[] loadFromCp(Object[] classpath, String res) {
68.43 - for (int i = 0; i < classpath.length; i++) {
68.44 - Object c = classpath[i];
68.45 + public static byte[] loadFromCp(Object classpath, String res)
68.46 + throws IOException, ClassNotFoundException {
68.47 + for (int i = 0; i < length(classpath); i++) {
68.48 + Object c = at(classpath, i);
68.49 if (c instanceof String) {
68.50 try {
68.51 - c = classpath[i] = toZip((String)c);
68.52 + String url = (String)c;
68.53 + final Zips z = toZip(url);
68.54 + c = set(classpath, i, z);
68.55 + final byte[] man = z.findRes("META-INF/MANIFEST.MF");
68.56 + if (man != null) {
68.57 + String mainClass = processClassPathAttr(man, url, classpath);
68.58 +// if (mainClass != null) {
68.59 +// Class.forName(mainClass);
68.60 +// }
68.61 + }
68.62 } catch (IOException ex) {
68.63 - classpath[i] = ex;
68.64 + set(classpath, i, ex);
68.65 + log("Cannot load " + c + " - " + ex.getClass().getName() + ":" + ex.getMessage());
68.66 }
68.67 }
68.68 - if (c instanceof Zips) {
68.69 - Object checkRes = ((Zips)c).findRes(res);
68.70 - if (checkRes instanceof byte[]) {
68.71 - return (byte[])checkRes;
68.72 + if (res != null) {
68.73 + byte[] checkRes;
68.74 + if (c instanceof Zips) {
68.75 + checkRes = ((Zips)c).findRes(res);
68.76 + } else {
68.77 + checkRes = callFunction(c, res);
68.78 + }
68.79 + if (checkRes != null) {
68.80 + return checkRes;
68.81 }
68.82 }
68.83 }
68.84 return null;
68.85 }
68.86 +
68.87 + @JavaScriptBody(args = { "fn", "res" }, body =
68.88 + "if (typeof fn === 'function') return fn(res);\n"
68.89 + + "return null;"
68.90 + )
68.91 + private static native byte[] callFunction(Object fn, String res);
68.92 +
68.93 + @JavaScriptBody(args = { "msg" }, body = "console.log(msg.toString());")
68.94 + private static native void log(String msg);
68.95 +
68.96 + private byte[] findRes(String res) throws IOException {
68.97 + Object arr = findResImpl(res);
68.98 + if (arr instanceof FastJar.Entry) {
68.99 + long bef = timeNow();
68.100 + InputStream zip = fj.getInputStream((FastJar.Entry)arr);
68.101 + arr = readFully(new byte[512], zip);
68.102 + putRes(res, arr);
68.103 + log("Reading " + res + " took " + (timeNow() - bef) + "ms");
68.104 + }
68.105 + return (byte[]) arr;
68.106 + }
68.107
68.108 @JavaScriptBody(args = { "res" }, body = "var r = this[res]; return r ? r : null;")
68.109 - private native byte[] findRes(String res);
68.110 + private native Object findResImpl(String res);
68.111
68.112 @JavaScriptBody(args = { "res", "arr" }, body = "this[res] = arr;")
68.113 - private native void putRes(String res, byte[] arr);
68.114 + private native void putRes(String res, Object arr);
68.115
68.116 private static Zips toZip(String path) throws IOException {
68.117 URL u = new URL(path);
68.118 - ZipInputStream zip = new ZipInputStream(u.openStream());
68.119 - Zips z = new Zips();
68.120 - for (;;) {
68.121 - ZipEntry entry = zip.getNextEntry();
68.122 - if (entry == null) {
68.123 - break;
68.124 - }
68.125 - byte[] arr = new byte[4096];
68.126 - int offset = 0;
68.127 - for (;;) {
68.128 - int len = zip.read(arr, offset, arr.length - offset);
68.129 - if (len == -1) {
68.130 - break;
68.131 - }
68.132 - offset += len;
68.133 - if (offset == arr.length) {
68.134 - enlargeArray(arr, arr.length + 4096);
68.135 + byte[] zipData = (byte[]) u.getContent(new Class[] { byte[].class });
68.136 + return new Zips(path, zipData);
68.137 + }
68.138 +
68.139 + private static String processClassPathAttr(final byte[] man, String url, Object classpath) throws IOException {
68.140 + try (ParseMan is = new ParseMan(new ByteArrayInputStream(man))) {
68.141 + String cp = is.toString();
68.142 + if (cp != null) {
68.143 + cp = cp.trim();
68.144 + for (int p = 0; p < cp.length();) {
68.145 + int n = cp.indexOf(' ', p);
68.146 + if (n == -1) {
68.147 + n = cp.length();
68.148 + }
68.149 + String el = cp.substring(p, n);
68.150 + URL u = new URL(new URL(url), el);
68.151 + classpath = addToArray(classpath, u.toString());
68.152 + p = n + 1;
68.153 }
68.154 }
68.155 - sliceArray(arr, offset);
68.156 - z.putRes(entry.getName(), arr);
68.157 + return is.getMainClass();
68.158 }
68.159 - return z;
68.160 }
68.161
68.162 + private static Object addToArray(Object arr, String value) {
68.163 + final int last = length(arr);
68.164 + Object ret = enlargeArray(arr, last + 1);
68.165 + set(ret, last, value);
68.166 + return ret;
68.167 + }
68.168 +
68.169 + @JavaScriptBody(args = { "arr", "len" }, body = "while (arr.length < len) arr.push(null); return arr;")
68.170 + private static native Object enlargeArray(Object arr, int len);
68.171 @JavaScriptBody(args = { "arr", "len" }, body = "while (arr.length < len) arr.push(0);")
68.172 - private static native void enlargeArray(byte[] arr, int len);
68.173 + private static native void enlargeBytes(byte[] arr, int len);
68.174
68.175 @JavaScriptBody(args = { "arr", "len" }, body = "arr.splice(len, arr.length - len);")
68.176 private static native void sliceArray(byte[] arr, int len);
68.177 +
68.178 + private static Object readFully(byte[] arr, InputStream zip) throws IOException {
68.179 + int offset = 0;
68.180 + for (;;) {
68.181 + int len = zip.read(arr, offset, arr.length - offset);
68.182 + if (len == -1) {
68.183 + break;
68.184 + }
68.185 + offset += len;
68.186 + if (offset == arr.length) {
68.187 + enlargeBytes(arr, arr.length + 4096);
68.188 + }
68.189 + }
68.190 + sliceArray(arr, offset);
68.191 + return arr;
68.192 + }
68.193 +
68.194 + private static long timeNow() {
68.195 + double time = m();
68.196 + if (time >= 0) {
68.197 + return (long)time;
68.198 + }
68.199 + return org.apidesign.bck2brwsr.emul.lang.System.currentTimeMillis();
68.200 + }
68.201 + @JavaScriptBody(args = {}, body =
68.202 + "if (typeof window.performance === 'undefined') return -1;\n"
68.203 + + "if (typeof window.performance.now === 'undefined') return -1;\n"
68.204 + + "return window.performance.now();"
68.205 + )
68.206 + private static native double m();
68.207
68.208
68.209 }
69.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java Tue Feb 19 15:33:32 2013 +0100
69.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java Tue Feb 19 15:59:27 2013 +0100
69.3 @@ -17,7 +17,6 @@
69.4 */
69.5 package org.apidesign.vm4brwsr;
69.6
69.7 -import javax.script.Invocable;
69.8 import static org.testng.Assert.*;
69.9 import org.testng.annotations.BeforeClass;
69.10 import org.testng.annotations.Test;
69.11 @@ -76,18 +75,13 @@
69.12 assertExec("Returns 'false'", Array.class, "instanceOfArray__ZLjava_lang_Object_2", Double.valueOf(0), "non-array");
69.13 }
69.14
69.15 - private static CharSequence codeSeq;
69.16 - private static Invocable code;
69.17 + private static TestVM code;
69.18
69.19 @BeforeClass
69.20 public void compileTheCode() throws Exception {
69.21 - StringBuilder sb = new StringBuilder();
69.22 - code = StaticMethodTest.compileClass(sb,
69.23 - "org/apidesign/vm4brwsr/Array"
69.24 - );
69.25 - codeSeq = sb;
69.26 + code = TestVM.compileClass("org/apidesign/vm4brwsr/Array");
69.27 }
69.28 private static void assertExec(String msg, Class clazz, String method, Object expRes, Object... args) throws Exception {
69.29 - StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args);
69.30 + code.assertExec(msg, clazz, method, expRes, args);
69.31 }
69.32 }
70.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Tue Feb 19 15:33:32 2013 +0100
70.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java Tue Feb 19 15:59:27 2013 +0100
70.3 @@ -17,7 +17,6 @@
70.4 */
70.5 package org.apidesign.vm4brwsr;
70.6
70.7 -import javax.script.Invocable;
70.8 import org.testng.annotations.Test;
70.9 import static org.testng.Assert.*;
70.10 import org.testng.annotations.BeforeClass;
70.11 @@ -87,12 +86,27 @@
70.12 @Test public void jsAnnotation() throws Exception {
70.13 assertExec("Check class annotation", Classes.class, "getMarker__I", Double.valueOf(10));
70.14 }
70.15 + @Test public void jsArrayAnnotation() throws Exception {
70.16 + assertExec("Check array annotation", Classes.class, "getMarkerNicknames__Ljava_lang_String_2", Classes.getMarkerNicknames());
70.17 + }
70.18 + @Test public void jsEnumAnnotation() throws Exception {
70.19 + assertExec("Check enum annotation", Classes.class, "getMarkerE__Ljava_lang_String_2", Classes.getMarkerE());
70.20 + }
70.21 + @Test public void jsRetentionAnnotation() throws Exception {
70.22 + assertExec("Check enum annotation", Classes.class, "getRetention__Ljava_lang_String_2", Classes.getRetention());
70.23 + }
70.24 @Test public void jsStringAnnotation() throws Exception {
70.25 assertExec("Check class annotation", Classes.class, "getNamer__Ljava_lang_String_2Z", "my text", true);
70.26 }
70.27 @Test public void jsStringAnnotationFromArray() throws Exception {
70.28 assertExec("Check class annotation", Classes.class, "getNamer__Ljava_lang_String_2Z", "my text", false);
70.29 }
70.30 + @Test public void jsInnerAnnotation() throws Exception {
70.31 + assertExec("Check inner annotation", Classes.class, "getInnerNamer__I", Double.valueOf(Classes.getInnerNamer()));
70.32 + }
70.33 + @Test public void jsInnerAnnotationFromArray() throws Exception {
70.34 + assertExec("Check inner annotation", Classes.class, "getInnerNamers__I", Double.valueOf(Classes.getInnerNamers()));
70.35 + }
70.36 @Test public void javaInvokeMethod() throws Exception {
70.37 assertEquals(Classes.reflectiveMethodCall(true, "name"), "java.io.IOException", "Calls the name() method via reflection");
70.38 }
70.39 @@ -102,6 +116,14 @@
70.40 "java.io.IOException", true, "name"
70.41 );
70.42 }
70.43 +
70.44 + @Test public void jsMethodDeclaredInObject() throws Exception {
70.45 + assertExec("Defined in Object", Classes.class,
70.46 + "objectName__Ljava_lang_String_2",
70.47 + "java.lang.Object"
70.48 + );
70.49 + }
70.50 +
70.51 @Test public void jsInvokeParamMethod() throws Exception {
70.52 assertExec("sums two numbers via reflection", Classes.class,
70.53 "reflectiveSum__III", Double.valueOf(5), 2, 3
70.54 @@ -149,14 +171,12 @@
70.55 0.0, "java.lang.String"
70.56 );
70.57 }
70.58 - /*
70.59 @Test public void isInterface() throws Exception {
70.60 assertExec("Calls Class.isInterface", Classes.class,
70.61 "isInterface__ZLjava_lang_String_2",
70.62 1.0, "java.lang.Runnable"
70.63 );
70.64 }
70.65 - */
70.66 @Test public void integerType() throws Exception {
70.67 assertExec("Computes the type", Classes.class,
70.68 "intType__Ljava_lang_String_2",
70.69 @@ -164,22 +184,17 @@
70.70 );
70.71 }
70.72
70.73 - private static CharSequence codeSeq;
70.74 - private static Invocable code;
70.75 + private static TestVM code;
70.76
70.77 @BeforeClass
70.78 public void compileTheCode() throws Exception {
70.79 - if (codeSeq == null) {
70.80 - StringBuilder sb = new StringBuilder();
70.81 - code = StaticMethodTest.compileClass(sb, "org/apidesign/vm4brwsr/Classes");
70.82 - codeSeq = sb;
70.83 - }
70.84 + code = TestVM.compileClass("org/apidesign/vm4brwsr/Classes");
70.85 }
70.86
70.87 private void assertExec(
70.88 String msg, Class clazz, String method, Object expRes, Object... args
70.89 ) throws Exception {
70.90 - StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args);
70.91 + code.assertExec(msg, clazz, method, expRes, args);
70.92 }
70.93 @Test public void isClassAssignable() throws Exception {
70.94 assertExec("isAssignable works on subclasses", Classes.class,
71.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Tue Feb 19 15:33:32 2013 +0100
71.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java Tue Feb 19 15:59:27 2013 +0100
71.3 @@ -19,6 +19,8 @@
71.4
71.5 import java.io.IOException;
71.6 import java.lang.annotation.Annotation;
71.7 +import java.lang.annotation.Retention;
71.8 +import java.lang.annotation.RetentionPolicy;
71.9 import java.lang.reflect.Method;
71.10 import java.net.MalformedURLException;
71.11 import org.apidesign.bck2brwsr.core.JavaScriptBody;
71.12 @@ -27,8 +29,11 @@
71.13 *
71.14 * @author Jaroslav Tulach <jtulach@netbeans.org>
71.15 */
71.16 -@ClassesMarker(number = 10)
71.17 -@ClassesNamer(name = "my text")
71.18 +@ClassesMarker(number = 10, nicknames = { "Ten", "Deset" }, count = ClassesMarker.E.TWO, subs = {
71.19 + @ClassesMarker.Anno(Integer.SIZE),
71.20 + @ClassesMarker.Anno(Integer.MIN_VALUE)
71.21 +})
71.22 +@ClassesNamer(name = "my text", anno = @ClassesMarker.Anno(333))
71.23 public class Classes {
71.24 public static String nameOfIO() {
71.25 return nameFor(IOException.class);
71.26 @@ -38,6 +43,8 @@
71.27 return c.getName();
71.28 }
71.29
71.30 + private static final Class<?> PRELOAD = Runnable.class;
71.31 +
71.32 public static boolean isInterface(String s) throws ClassNotFoundException {
71.33 return Class.forName(s).isInterface();
71.34 }
71.35 @@ -55,7 +62,7 @@
71.36 return new IOException().getClass().getName().toString();
71.37 }
71.38
71.39 - @ClassesMarker(number = 1)
71.40 + @ClassesMarker(number = 1, nicknames = { "One", "Jedna" } )
71.41 public static String name() {
71.42 return IOException.class.getName().toString();
71.43 }
71.44 @@ -65,6 +72,11 @@
71.45 public static String canonicalName() {
71.46 return IOException.class.getCanonicalName();
71.47 }
71.48 +
71.49 + public static String objectName() throws NoSuchMethodException {
71.50 + return IOException.class.getMethod("wait").getDeclaringClass().getName();
71.51 + }
71.52 +
71.53 public static boolean newInstance() throws Exception {
71.54 IOException ioe = IOException.class.newInstance();
71.55 if (ioe instanceof IOException) {
71.56 @@ -85,8 +97,45 @@
71.57 return -2;
71.58 }
71.59 ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class);
71.60 + assert cm instanceof Object : "Is object " + cm;
71.61 + assert cm instanceof Annotation : "Is annotation " + cm;
71.62 + assert !((Object)cm instanceof Class) : "Is not Class " + cm;
71.63 return cm == null ? -1 : cm.number();
71.64 }
71.65 + public static String getMarkerNicknames() {
71.66 + ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class);
71.67 + if (cm == null) {
71.68 + return null;
71.69 + }
71.70 +
71.71 + final Object[] arr = cm.nicknames();
71.72 + assert arr instanceof Object[] : "Instance of Object array: " + arr;
71.73 + assert arr instanceof String[] : "Instance of String array: " + arr;
71.74 + assert !(arr instanceof Integer[]) : "Not instance of Integer array: " + arr;
71.75 +
71.76 + StringBuilder sb = new StringBuilder();
71.77 + for (String s : cm.nicknames()) {
71.78 + sb.append(s).append("\n");
71.79 + }
71.80 + return sb.toString().toString();
71.81 + }
71.82 + @Retention(RetentionPolicy.CLASS)
71.83 + @interface Ann {
71.84 + }
71.85 +
71.86 + public static String getRetention() throws Exception {
71.87 + Retention r = Ann.class.getAnnotation(Retention.class);
71.88 + assert r != null : "Annotation is present";
71.89 + assert r.value() == RetentionPolicy.CLASS : "Policy value is OK: " + r.value();
71.90 + return r.annotationType().getName();
71.91 + }
71.92 + public static String getMarkerE() {
71.93 + ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class);
71.94 + if (cm == null) {
71.95 + return null;
71.96 + }
71.97 + return cm.count().name();
71.98 + }
71.99 public static String getNamer(boolean direct) {
71.100 if (direct) {
71.101 ClassesNamer cm = Classes.class.getAnnotation(ClassesNamer.class);
71.102 @@ -99,6 +148,20 @@
71.103 }
71.104 return null;
71.105 }
71.106 + public static int getInnerNamer() {
71.107 + ClassesNamer cm = Classes.class.getAnnotation(ClassesNamer.class);
71.108 + assert cm != null : "ClassesNamer is present";
71.109 + return cm.anno().value();
71.110 + }
71.111 + public static int getInnerNamers() {
71.112 + ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class);
71.113 + assert cm != null : "ClassesNamer is present";
71.114 + int sum = 0;
71.115 + for (ClassesMarker.Anno anno : cm.subs()) {
71.116 + sum += anno.value();
71.117 + }
71.118 + return sum;
71.119 + }
71.120
71.121 public static String intType() {
71.122 return Integer.TYPE.getName();
72.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassesMarker.java Tue Feb 19 15:33:32 2013 +0100
72.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassesMarker.java Tue Feb 19 15:59:27 2013 +0100
72.3 @@ -27,4 +27,16 @@
72.4 @Retention(RetentionPolicy.RUNTIME)
72.5 public @interface ClassesMarker {
72.6 int number();
72.7 + String[] nicknames();
72.8 + E count() default E.ONE;
72.9 +
72.10 + enum E {
72.11 + ONE, TWO;
72.12 + }
72.13 +
72.14 + Anno[] subs() default {};
72.15 +
72.16 + public @interface Anno {
72.17 + int value();
72.18 + }
72.19 }
73.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassesNamer.java Tue Feb 19 15:33:32 2013 +0100
73.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassesNamer.java Tue Feb 19 15:59:27 2013 +0100
73.3 @@ -27,4 +27,5 @@
73.4 @Retention(RetentionPolicy.RUNTIME)
73.5 public @interface ClassesNamer {
73.6 String name();
73.7 + ClassesMarker.Anno anno();
73.8 }
74.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java Tue Feb 19 15:33:32 2013 +0100
74.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java Tue Feb 19 15:59:27 2013 +0100
74.3 @@ -17,7 +17,6 @@
74.4 */
74.5 package org.apidesign.vm4brwsr;
74.6
74.7 -import javax.script.Invocable;
74.8 import javax.script.ScriptException;
74.9 import static org.testng.Assert.*;
74.10 import org.testng.annotations.BeforeClass;
74.11 @@ -81,8 +80,7 @@
74.12 }
74.13
74.14 @Test public void testThreeCalls() throws Exception {
74.15 - Object vm = code.invokeFunction("bck2brwsr");
74.16 - Object clazz = code.invokeMethod(vm, "loadClass", Exceptions.class.getName());
74.17 + Object clazz = code.loadClass("loadClass", Exceptions.class.getName());
74.18
74.19 String method = "readCounter__ILjava_lang_String_2";
74.20
74.21 @@ -104,18 +102,13 @@
74.22 }
74.23 }
74.24
74.25 - private static CharSequence codeSeq;
74.26 - private static Invocable code;
74.27 + private static TestVM code;
74.28
74.29 @BeforeClass
74.30 public void compileTheCode() throws Exception {
74.31 - StringBuilder sb = new StringBuilder();
74.32 - code = StaticMethodTest.compileClass(sb,
74.33 - "org/apidesign/vm4brwsr/Exceptions"
74.34 - );
74.35 - codeSeq = sb;
74.36 + code = TestVM.compileClass("org/apidesign/vm4brwsr/Exceptions");
74.37 }
74.38 private static void assertExec(String msg, Class clazz, String method, Object expRes, Object... args) throws Exception {
74.39 - StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args);
74.40 + code.assertExec(msg, clazz, method, expRes, args);
74.41 }
74.42 }
75.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java Tue Feb 19 15:33:32 2013 +0100
75.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java Tue Feb 19 15:59:27 2013 +0100
75.3 @@ -17,7 +17,6 @@
75.4 */
75.5 package org.apidesign.vm4brwsr;
75.6
75.7 -import javax.script.Invocable;
75.8 import org.testng.annotations.Test;
75.9 import org.testng.annotations.BeforeClass;
75.10
75.11 @@ -151,22 +150,17 @@
75.12 return "org/apidesign/vm4brwsr/Instance";
75.13 }
75.14
75.15 - private static CharSequence codeSeq;
75.16 - private static Invocable code;
75.17 + private static TestVM code;
75.18
75.19 @BeforeClass
75.20 public void compileTheCode() throws Exception {
75.21 - if (codeSeq == null) {
75.22 - StringBuilder sb = new StringBuilder();
75.23 - code = StaticMethodTest.compileClass(sb, startCompilationWith());
75.24 - codeSeq = sb;
75.25 - }
75.26 + code = TestVM.compileClass(startCompilationWith());
75.27 }
75.28
75.29 private void assertExec(
75.30 String msg, Class clazz, String method, Object expRes, Object... args
75.31 ) throws Exception {
75.32 - StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args);
75.33 + code.assertExec(msg, clazz, method, expRes, args);
75.34 }
75.35
75.36 }
76.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java Tue Feb 19 15:33:32 2013 +0100
76.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java Tue Feb 19 15:59:27 2013 +0100
76.3 @@ -17,8 +17,6 @@
76.4 */
76.5 package org.apidesign.vm4brwsr;
76.6
76.7 -import javax.script.Invocable;
76.8 -import javax.script.ScriptException;
76.9 import static org.testng.Assert.*;
76.10 import org.testng.annotations.BeforeClass;
76.11 import org.testng.annotations.Test;
76.12 @@ -144,22 +142,17 @@
76.13 );
76.14 }
76.15
76.16 - private static CharSequence codeSeq;
76.17 - private static Invocable code;
76.18 + private static TestVM code;
76.19
76.20 @BeforeClass
76.21 public void compileTheCode() throws Exception {
76.22 - if (codeSeq == null) {
76.23 - StringBuilder sb = new StringBuilder();
76.24 - code = StaticMethodTest.compileClass(sb, "org/apidesign/vm4brwsr/Numbers");
76.25 - codeSeq = sb;
76.26 - }
76.27 + code = TestVM.compileClass("org/apidesign/vm4brwsr/Numbers");
76.28 }
76.29
76.30 private static void assertExec(
76.31 String msg, Class<?> clazz, String method, Object expRes, Object... args) throws Exception
76.32 {
76.33 - Object ret = TestUtils.execCode(code, codeSeq, msg, clazz, method, expRes, args);
76.34 + Object ret = code.execCode(msg, clazz, method, expRes, args);
76.35 if (ret == null) {
76.36 return;
76.37 }
76.38 @@ -167,10 +160,10 @@
76.39 double expD = ((Double)expRes).doubleValue();
76.40 double retD = ((Double)ret).doubleValue();
76.41 assertEquals(retD, expD, 0.000004, msg + " "
76.42 - + StaticMethodTest.dumpJS(codeSeq));
76.43 + + code.toString());
76.44 return;
76.45 }
76.46 - assertEquals(ret, expRes, msg + " " + StaticMethodTest.dumpJS(codeSeq));
76.47 + assertEquals(ret, expRes, msg + " " + code.toString());
76.48 }
76.49
76.50 }
77.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java Tue Feb 19 15:33:32 2013 +0100
77.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java Tue Feb 19 15:59:27 2013 +0100
77.3 @@ -17,16 +17,6 @@
77.4 */
77.5 package org.apidesign.vm4brwsr;
77.6
77.7 -import java.io.File;
77.8 -import java.io.FileWriter;
77.9 -import java.io.IOException;
77.10 -import java.io.InputStream;
77.11 -import java.net.URL;
77.12 -import java.util.Enumeration;
77.13 -import javax.script.Invocable;
77.14 -import javax.script.ScriptEngine;
77.15 -import javax.script.ScriptEngineManager;
77.16 -import javax.script.ScriptException;
77.17 import static org.testng.Assert.*;
77.18 import org.testng.annotations.BeforeClass;
77.19 import org.testng.annotations.Test;
77.20 @@ -331,88 +321,18 @@
77.21 );
77.22 }
77.23
77.24 - private static CharSequence codeSeq;
77.25 - private static Invocable code;
77.26 + private static TestVM code;
77.27
77.28 @BeforeClass
77.29 public void compileTheCode() throws Exception {
77.30 StringBuilder sb = new StringBuilder();
77.31 - code = compileClass(sb, "org/apidesign/vm4brwsr/StaticMethod");
77.32 - codeSeq = sb;
77.33 - }
77.34 -
77.35 -
77.36 - private static void assertExec(
77.37 - String msg, Class clazz, String method,
77.38 - Object expRes, Object... args
77.39 - ) throws Exception {
77.40 - assertExec(code, codeSeq, msg, clazz, method, expRes, args);
77.41 - }
77.42 - static void assertExec(
77.43 - Invocable toRun, CharSequence theCode,
77.44 - String msg, Class clazz, String method,
77.45 - Object expRes, Object... args
77.46 - ) throws Exception {
77.47 - Object ret = TestUtils.execCode(toRun, theCode, msg, clazz, method, expRes, args);
77.48 - if (ret == null) {
77.49 - return;
77.50 - }
77.51 - if (expRes != null && expRes.equals(ret)) {
77.52 - return;
77.53 - }
77.54 - assertEquals(ret, expRes, msg + "was: " + ret + "\n" + dumpJS(theCode));
77.55 -
77.56 + code = TestVM.compileClass(sb, "org/apidesign/vm4brwsr/StaticMethod");
77.57 }
77.58
77.59 - static Invocable compileClass(StringBuilder sb, String... names) throws ScriptException, IOException {
77.60 - return compileClass(sb, null, names);
77.61 - }
77.62 - static Invocable compileClass(
77.63 - StringBuilder sb, ScriptEngine[] eng, String... names
77.64 - ) throws ScriptException, IOException {
77.65 - if (sb == null) {
77.66 - sb = new StringBuilder();
77.67 - }
77.68 - Bck2Brwsr.generate(sb, new EmulationResources(), names);
77.69 - ScriptEngineManager sem = new ScriptEngineManager();
77.70 - ScriptEngine js = sem.getEngineByExtension("js");
77.71 - if (eng != null) {
77.72 - eng[0] = js;
77.73 - }
77.74 - try {
77.75 - Object res = js.eval(sb.toString());
77.76 - assertTrue(js instanceof Invocable, "It is invocable object: " + res);
77.77 - return (Invocable)js;
77.78 - } catch (Exception ex) {
77.79 - if (sb.length() > 2000) {
77.80 - sb = dumpJS(sb);
77.81 - }
77.82 - fail("Could not evaluate:\n" + sb, ex);
77.83 - return null;
77.84 - }
77.85 - }
77.86 - static StringBuilder dumpJS(CharSequence sb) throws IOException {
77.87 - File f = File.createTempFile("execution", ".js");
77.88 - FileWriter w = new FileWriter(f);
77.89 - w.append(sb);
77.90 - w.close();
77.91 - return new StringBuilder(f.getPath());
77.92 - }
77.93 - private static class EmulationResources implements Bck2Brwsr.Resources {
77.94 - @Override
77.95 - public InputStream get(String name) throws IOException {
77.96 - Enumeration<URL> en = StaticMethodTest.class.getClassLoader().getResources(name);
77.97 - URL u = null;
77.98 - while (en.hasMoreElements()) {
77.99 - u = en.nextElement();
77.100 - }
77.101 - if (u == null) {
77.102 - throw new IOException("Can't find " + name);
77.103 - }
77.104 - if (u.toExternalForm().contains("rt.jar!")) {
77.105 - throw new IOException("No emulation for " + u);
77.106 - }
77.107 - return u.openStream();
77.108 - }
77.109 + private void assertExec(
77.110 + String msg, Class<?> clazz, String method,
77.111 + Object ret, Object... args
77.112 + ) throws Exception {
77.113 + code.assertExec(msg, clazz, method, ret, args);
77.114 }
77.115 }
78.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StringTest.java Tue Feb 19 15:33:32 2013 +0100
78.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StringTest.java Tue Feb 19 15:59:27 2013 +0100
78.3 @@ -17,7 +17,6 @@
78.4 */
78.5 package org.apidesign.vm4brwsr;
78.6
78.7 -import javax.script.Invocable;
78.8 import org.testng.annotations.Test;
78.9 import static org.testng.Assert.*;
78.10 import org.testng.annotations.BeforeClass;
78.11 @@ -194,23 +193,20 @@
78.12
78.13 }
78.14
78.15 - private static CharSequence codeSeq;
78.16 - private static Invocable code;
78.17 + private static TestVM code;
78.18
78.19 @BeforeClass
78.20 public void compileTheCode() throws Exception {
78.21 - StringBuilder sb = new StringBuilder();
78.22 - code = StaticMethodTest.compileClass(sb,
78.23 + code = TestVM.compileClass(
78.24 "org/apidesign/vm4brwsr/StringSample",
78.25 "java/lang/String"
78.26 );
78.27 - codeSeq = sb;
78.28 }
78.29
78.30 private static void assertExec(String msg,
78.31 Class<?> clazz, String method, Object expRes, Object... args
78.32 ) throws Exception {
78.33 - StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args);
78.34 + code.assertExec(msg, clazz, method, expRes, args);
78.35 }
78.36
78.37 }
79.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/SystemTest.java Tue Feb 19 15:33:32 2013 +0100
79.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/SystemTest.java Tue Feb 19 15:59:27 2013 +0100
79.3 @@ -17,10 +17,8 @@
79.4 */
79.5 package org.apidesign.vm4brwsr;
79.6
79.7 -import javax.script.Invocable;
79.8 import org.testng.annotations.BeforeClass;
79.9 import static org.testng.Assert.*;
79.10 -import org.testng.annotations.BeforeMethod;
79.11 import org.testng.annotations.Test;
79.12
79.13 /**
79.14 @@ -28,10 +26,12 @@
79.15 * @author Jaroslav Tulach <jtulach@netbeans.org>
79.16 */
79.17 public class SystemTest {
79.18 + private static TestVM code;
79.19 +
79.20 @Test public void verifyJSTime() throws Exception {
79.21 long now = System.currentTimeMillis();
79.22
79.23 - Object js = TestUtils.execCode(code, codeSeq, "Get js time",
79.24 + Object js = code.execCode("Get js time",
79.25 org.apidesign.bck2brwsr.emul.lang.System.class, "currentTimeMillis__J",
79.26 null
79.27 );
79.28 @@ -45,14 +45,11 @@
79.29 assertTrue(time <= later, "Upper bound is OK: " + time + " <= " + later);
79.30 }
79.31
79.32 - private static CharSequence codeSeq;
79.33 - private static Invocable code;
79.34
79.35 @BeforeClass
79.36 - public void compileTheCode() throws Exception {
79.37 - StringBuilder sb = new StringBuilder();
79.38 - code = StaticMethodTest.compileClass(sb, "org/apidesign/bck2brwsr/emul/lang/System");
79.39 - codeSeq = sb;
79.40 + public static void compileTheCode() throws Exception {
79.41 + code = TestVM.compileClass(
79.42 + "org/apidesign/bck2brwsr/emul/lang/System");
79.43 }
79.44
79.45 }
80.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/TestUtils.java Tue Feb 19 15:33:32 2013 +0100
80.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
80.3 @@ -1,60 +0,0 @@
80.4 -/**
80.5 - * Back 2 Browser Bytecode Translator
80.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
80.7 - *
80.8 - * This program is free software: you can redistribute it and/or modify
80.9 - * it under the terms of the GNU General Public License as published by
80.10 - * the Free Software Foundation, version 2 of the License.
80.11 - *
80.12 - * This program is distributed in the hope that it will be useful,
80.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
80.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
80.15 - * GNU General Public License for more details.
80.16 - *
80.17 - * You should have received a copy of the GNU General Public License
80.18 - * along with this program. Look for COPYING file in the top folder.
80.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
80.20 - */
80.21 -package org.apidesign.vm4brwsr;
80.22 -
80.23 -import javax.script.Invocable;
80.24 -import javax.script.ScriptException;
80.25 -import static org.testng.Assert.*;
80.26 -
80.27 -class TestUtils {
80.28 -
80.29 - static Object execCode(Invocable code, CharSequence codeSeq,
80.30 - String msg, Class<?> clazz, String method, Object expRes, Object... args)
80.31 - throws Exception
80.32 - {
80.33 - Object ret = null;
80.34 - try {
80.35 - ret = code.invokeFunction("bck2brwsr");
80.36 - ret = code.invokeMethod(ret, "loadClass", clazz.getName());
80.37 - ret = code.invokeMethod(ret, method, args);
80.38 - } catch (ScriptException ex) {
80.39 - fail("Execution failed in " + StaticMethodTest.dumpJS(codeSeq), ex);
80.40 - } catch (NoSuchMethodException ex) {
80.41 - fail("Cannot find method in " + StaticMethodTest.dumpJS(codeSeq), ex);
80.42 - }
80.43 - if (ret == null && expRes == null) {
80.44 - return null;
80.45 - }
80.46 - if (expRes != null && expRes.equals(ret)) {
80.47 - return null;
80.48 - }
80.49 - if (expRes instanceof Number) {
80.50 - // in case of Long it is necessary convert it to number
80.51 - // since the Long is represented by two numbers in JavaScript
80.52 - try {
80.53 - ret = code.invokeMethod(ret, "toFP");
80.54 - ret = code.invokeFunction("Number", ret);
80.55 - } catch (ScriptException ex) {
80.56 - fail("Conversion to number failed in " + StaticMethodTest.dumpJS(codeSeq), ex);
80.57 - } catch (NoSuchMethodException ex) {
80.58 - fail("Cannot find global Number(x) function in " + StaticMethodTest.dumpJS(codeSeq), ex);
80.59 - }
80.60 - }
80.61 - return ret;
80.62 - }
80.63 -}
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
81.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Tue Feb 19 15:59:27 2013 +0100
81.3 @@ -0,0 +1,170 @@
81.4 +/**
81.5 + * Back 2 Browser Bytecode Translator
81.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
81.7 + *
81.8 + * This program is free software: you can redistribute it and/or modify
81.9 + * it under the terms of the GNU General Public License as published by
81.10 + * the Free Software Foundation, version 2 of the License.
81.11 + *
81.12 + * This program is distributed in the hope that it will be useful,
81.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
81.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81.15 + * GNU General Public License for more details.
81.16 + *
81.17 + * You should have received a copy of the GNU General Public License
81.18 + * along with this program. Look for COPYING file in the top folder.
81.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
81.20 + */
81.21 +package org.apidesign.vm4brwsr;
81.22 +
81.23 +import java.io.File;
81.24 +import java.io.FileWriter;
81.25 +import java.io.IOException;
81.26 +import java.io.InputStream;
81.27 +import java.net.URL;
81.28 +import java.util.Enumeration;
81.29 +import javax.script.Invocable;
81.30 +import javax.script.ScriptEngine;
81.31 +import javax.script.ScriptEngineManager;
81.32 +import javax.script.ScriptException;
81.33 +import static org.testng.Assert.*;
81.34 +
81.35 +final class TestVM {
81.36 + private final Invocable code;
81.37 + private final CharSequence codeSeq;
81.38 + private final Object bck2brwsr;
81.39 +
81.40 +
81.41 + private TestVM(Invocable code, CharSequence codeSeq) throws ScriptException, NoSuchMethodException {
81.42 + this.code = code;
81.43 + this.codeSeq = codeSeq;
81.44 + this.bck2brwsr = code.invokeFunction("bck2brwsr");
81.45 + }
81.46 +
81.47 +
81.48 + public Object execCode(
81.49 + String msg, Class<?> clazz, String method,
81.50 + Object expRes, Object... args
81.51 + ) throws Exception {
81.52 + Object ret = null;
81.53 + try {
81.54 + ret = code.invokeMethod(bck2brwsr, "loadClass", clazz.getName());
81.55 + ret = code.invokeMethod(ret, method, args);
81.56 + } catch (ScriptException ex) {
81.57 + fail("Execution failed in " + dumpJS(codeSeq), ex);
81.58 + } catch (NoSuchMethodException ex) {
81.59 + fail("Cannot find method in " + dumpJS(codeSeq), ex);
81.60 + }
81.61 + if (ret == null && expRes == null) {
81.62 + return null;
81.63 + }
81.64 + if (expRes != null && expRes.equals(ret)) {
81.65 + return null;
81.66 + }
81.67 + if (expRes instanceof Number) {
81.68 + // in case of Long it is necessary convert it to number
81.69 + // since the Long is represented by two numbers in JavaScript
81.70 + try {
81.71 + ret = code.invokeMethod(ret, "toFP");
81.72 + ret = code.invokeFunction("Number", ret);
81.73 + } catch (ScriptException ex) {
81.74 + fail("Conversion to number failed in " + dumpJS(codeSeq), ex);
81.75 + } catch (NoSuchMethodException ex) {
81.76 + fail("Cannot find global Number(x) function in " + dumpJS(codeSeq), ex);
81.77 + }
81.78 + }
81.79 + return ret;
81.80 + }
81.81 +
81.82 + void assertExec(
81.83 + String msg, Class clazz, String method, Object expRes, Object... args
81.84 + ) throws Exception {
81.85 + Object ret = execCode(msg, clazz, method, expRes, args);
81.86 + if (ret == null) {
81.87 + return;
81.88 + }
81.89 + if (expRes != null && expRes.equals(ret)) {
81.90 + return;
81.91 + }
81.92 + assertEquals(ret, expRes, msg + "was: " + ret + "\n" + dumpJS(codeSeq));
81.93 + }
81.94 +
81.95 + static TestVM compileClass(String... names) throws ScriptException, IOException {
81.96 + return compileClass(null, names);
81.97 + }
81.98 +
81.99 + static TestVM compileClass(StringBuilder sb, String... names) throws ScriptException, IOException {
81.100 + return compileClass(sb, null, names);
81.101 + }
81.102 +
81.103 + static TestVM compileClass(StringBuilder sb, ScriptEngine[] eng, String... names) throws ScriptException, IOException {
81.104 + if (sb == null) {
81.105 + sb = new StringBuilder();
81.106 + }
81.107 + Bck2Brwsr.generate(sb, new EmulationResources(), names);
81.108 + ScriptEngineManager sem = new ScriptEngineManager();
81.109 + ScriptEngine js = sem.getEngineByExtension("js");
81.110 + if (eng != null) {
81.111 + eng[0] = js;
81.112 + }
81.113 + try {
81.114 + Object res = js.eval(sb.toString());
81.115 + assertTrue(js instanceof Invocable, "It is invocable object: " + res);
81.116 + return new TestVM((Invocable) js, sb);
81.117 + } catch (Exception ex) {
81.118 + if (sb.length() > 2000) {
81.119 + sb = dumpJS(sb);
81.120 + }
81.121 + fail("Could not evaluate:\n" + sb, ex);
81.122 + return null;
81.123 + }
81.124 + }
81.125 +
81.126 + Object loadClass(String loadClass, String name) throws ScriptException, NoSuchMethodException {
81.127 + return code.invokeMethod(bck2brwsr, "loadClass", Exceptions.class.getName());
81.128 + }
81.129 +
81.130 + Object invokeMethod(Object obj, String method, Object... params) throws ScriptException, NoSuchMethodException {
81.131 + return code.invokeMethod(obj, method, params);
81.132 + }
81.133 +
81.134 + Object invokeFunction(String methodName, Object... args) throws ScriptException, NoSuchMethodException {
81.135 + return code.invokeFunction(methodName, args);
81.136 + }
81.137 +
81.138 + static StringBuilder dumpJS(CharSequence sb) throws IOException {
81.139 + File f = File.createTempFile("execution", ".js");
81.140 + FileWriter w = new FileWriter(f);
81.141 + w.append(sb);
81.142 + w.close();
81.143 + return new StringBuilder(f.getPath());
81.144 + }
81.145 +
81.146 + @Override
81.147 + public String toString() {
81.148 + try {
81.149 + return dumpJS(codeSeq).toString();
81.150 + } catch (IOException ex) {
81.151 + return ex.toString();
81.152 + }
81.153 + }
81.154 +
81.155 +
81.156 + private static class EmulationResources implements Bck2Brwsr.Resources {
81.157 + @Override
81.158 + public InputStream get(String name) throws IOException {
81.159 + Enumeration<URL> en = StaticMethodTest.class.getClassLoader().getResources(name);
81.160 + URL u = null;
81.161 + while (en.hasMoreElements()) {
81.162 + u = en.nextElement();
81.163 + }
81.164 + if (u == null) {
81.165 + throw new IOException("Can't find " + name);
81.166 + }
81.167 + if (u.toExternalForm().contains("rt.jar!")) {
81.168 + throw new IOException("No emulation for " + u);
81.169 + }
81.170 + return u.openStream();
81.171 + }
81.172 + }
81.173 +}
82.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java Tue Feb 19 15:33:32 2013 +0100
82.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java Tue Feb 19 15:59:27 2013 +0100
82.3 @@ -17,7 +17,6 @@
82.4 */
82.5 package org.apidesign.vm4brwsr;
82.6
82.7 -import javax.script.Invocable;
82.8 import javax.script.ScriptContext;
82.9 import javax.script.ScriptEngine;
82.10 import javax.script.ScriptException;
82.11 @@ -30,10 +29,7 @@
82.12 * @author Jaroslav Tulach <jtulach@netbeans.org>
82.13 */
82.14 public class VMLazyTest {
82.15 -
82.16 -
82.17 - private static CharSequence codeSeq;
82.18 - private static Invocable code;
82.19 + private static TestVM code;
82.20
82.21 @BeforeClass
82.22 public void compileTheCode() throws Exception {
82.23 @@ -50,11 +46,10 @@
82.24 sb.append("\n}");
82.25
82.26 ScriptEngine[] arr = { null };
82.27 - code = StaticMethodTest.compileClass(sb, arr,
82.28 + code = TestVM.compileClass(sb, arr,
82.29 new String[]{"org/apidesign/vm4brwsr/VM", "org/apidesign/vm4brwsr/StaticMethod"}
82.30 );
82.31 arr[0].getContext().setAttribute("loader", new BytesLoader(), ScriptContext.ENGINE_SCOPE);
82.32 - codeSeq = sb;
82.33 }
82.34
82.35 @Test public void invokeStaticMethod() throws Exception {
82.36 @@ -83,9 +78,9 @@
82.37 try {
82.38 ret = code.invokeFunction(methodName, args);
82.39 } catch (ScriptException ex) {
82.40 - fail("Execution failed in\n" + StaticMethodTest.dumpJS(codeSeq), ex);
82.41 + fail("Execution failed in\n" + code.toString(), ex);
82.42 } catch (NoSuchMethodException ex) {
82.43 - fail("Cannot find method in\n" + StaticMethodTest.dumpJS(codeSeq), ex);
82.44 + fail("Cannot find method in\n" + code.toString(), ex);
82.45 }
82.46 if (ret == null && expRes == null) {
82.47 return;
82.48 @@ -93,6 +88,6 @@
82.49 if (expRes.equals(ret)) {
82.50 return;
82.51 }
82.52 - assertEquals(ret, expRes, msg + "was: " + ret + "\n" + StaticMethodTest.dumpJS(codeSeq));
82.53 + assertEquals(ret, expRes, msg + "was: " + ret + "\n" + code.toString());
82.54 }
82.55 }
83.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMinVMTest.java Tue Feb 19 15:33:32 2013 +0100
83.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/VMinVMTest.java Tue Feb 19 15:59:27 2013 +0100
83.3 @@ -21,7 +21,6 @@
83.4 import java.io.FileWriter;
83.5 import java.io.IOException;
83.6 import static org.testng.Assert.*;
83.7 -import javax.script.Invocable;
83.8 import org.testng.annotations.BeforeClass;
83.9 import org.testng.annotations.Test;
83.10
83.11 @@ -30,9 +29,7 @@
83.12 * @author Jaroslav Tulach <jtulach@netbeans.org>
83.13 */
83.14 public class VMinVMTest {
83.15 -
83.16 - private static CharSequence codeSeq;
83.17 - private static Invocable code;
83.18 + private static TestVM code;
83.19
83.20 @Test public void compareGeneratedCodeForArrayClass() throws Exception {
83.21 compareCode("org/apidesign/vm4brwsr/Array.class");
83.22 @@ -44,11 +41,7 @@
83.23
83.24 @BeforeClass
83.25 public void compileTheCode() throws Exception {
83.26 - StringBuilder sb = new StringBuilder();
83.27 - code = StaticMethodTest.compileClass(sb,
83.28 - "org/apidesign/vm4brwsr/VMinVM"
83.29 - );
83.30 - codeSeq = sb;
83.31 + code = TestVM.compileClass("org/apidesign/vm4brwsr/VMinVM");
83.32 }
83.33
83.34 private void compareCode(final String nm) throws Exception, IOException {
83.35 @@ -73,7 +66,7 @@
83.36 }
83.37 }
83.38 w.append("\n];\n");
83.39 - w.append(codeSeq);
83.40 + w.append(code.toString());
83.41 w.close();
83.42 throw new Exception(ex.getMessage() + " file: " + f, ex);
83.43 }
83.44 @@ -83,11 +76,11 @@
83.45
83.46 if (!ret1.toString().equals(ret)) {
83.47 StringBuilder msg = new StringBuilder("Difference found between ");
83.48 - msg.append(StaticMethodTest.dumpJS(ret1));
83.49 + msg.append(TestVM.dumpJS(ret1));
83.50 msg.append(" ");
83.51 - msg.append(StaticMethodTest.dumpJS((CharSequence) ret));
83.52 + msg.append(TestVM.dumpJS((CharSequence) ret));
83.53 msg.append(" compiled by ");
83.54 - msg.append(StaticMethodTest.dumpJS(codeSeq));
83.55 + msg.append(code.toString());
83.56 fail(msg.toString());
83.57 }
83.58 }
84.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
84.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/Http.java Tue Feb 19 15:59:27 2013 +0100
84.3 @@ -0,0 +1,56 @@
84.4 +/**
84.5 + * Back 2 Browser Bytecode Translator
84.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
84.7 + *
84.8 + * This program is free software: you can redistribute it and/or modify
84.9 + * it under the terms of the GNU General Public License as published by
84.10 + * the Free Software Foundation, version 2 of the License.
84.11 + *
84.12 + * This program is distributed in the hope that it will be useful,
84.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
84.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
84.15 + * GNU General Public License for more details.
84.16 + *
84.17 + * You should have received a copy of the GNU General Public License
84.18 + * along with this program. Look for COPYING file in the top folder.
84.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
84.20 + */
84.21 +package org.apidesign.bck2brwsr.vmtest;
84.22 +
84.23 +import java.lang.annotation.ElementType;
84.24 +import java.lang.annotation.Retention;
84.25 +import java.lang.annotation.RetentionPolicy;
84.26 +import java.lang.annotation.Target;
84.27 +
84.28 +/**
84.29 + * Exposes HTTP page or pages to the running {@link BrwsrTest}, so it can access under
84.30 + * the relative path.
84.31 + *
84.32 + * @author Jaroslav Tulach <jtulach@netbeans.org>
84.33 + */
84.34 +@Retention(RetentionPolicy.RUNTIME)
84.35 +@Target({ElementType.METHOD, ElementType.TYPE})
84.36 +public @interface Http {
84.37 + /** Set of pages to make available */
84.38 + public Resource[] value();
84.39 +
84.40 + /** Exposes an HTTP page to the running {@link BrwsrTest}, so it can access
84.41 + * under the relative path.
84.42 + *
84.43 + * @author Jaroslav Tulach <jtulach@netbeans.org>
84.44 + */
84.45 + @Retention(RetentionPolicy.RUNTIME)
84.46 + @Target({})
84.47 + public @interface Resource {
84.48 + /** path on the server that the test can use to access the exposed resource */
84.49 + String path();
84.50 + /** the content of the HttpResource */
84.51 + String content();
84.52 + /** resource relative to the class that should be used instead of <code>content</code>.
84.53 + * Leave content equal to empty string.
84.54 + */
84.55 + String resource() default "";
84.56 + /** mime type of the resource */
84.57 + String mimeType();
84.58 + }
84.59 +}
85.1 --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/HttpResource.java Tue Feb 19 15:33:32 2013 +0100
85.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
85.3 @@ -1,43 +0,0 @@
85.4 -/**
85.5 - * Back 2 Browser Bytecode Translator
85.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
85.7 - *
85.8 - * This program is free software: you can redistribute it and/or modify
85.9 - * it under the terms of the GNU General Public License as published by
85.10 - * the Free Software Foundation, version 2 of the License.
85.11 - *
85.12 - * This program is distributed in the hope that it will be useful,
85.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
85.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
85.15 - * GNU General Public License for more details.
85.16 - *
85.17 - * You should have received a copy of the GNU General Public License
85.18 - * along with this program. Look for COPYING file in the top folder.
85.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
85.20 - */
85.21 -package org.apidesign.bck2brwsr.vmtest;
85.22 -
85.23 -import java.lang.annotation.ElementType;
85.24 -import java.lang.annotation.Retention;
85.25 -import java.lang.annotation.RetentionPolicy;
85.26 -import java.lang.annotation.Target;
85.27 -
85.28 -/** Exposes an HTTP page to the running {@link BrwsrTest}, so it can access
85.29 - * under the relative path.
85.30 - *
85.31 - * @author Jaroslav Tulach <jtulach@netbeans.org>
85.32 - */
85.33 -@Retention(RetentionPolicy.RUNTIME)
85.34 -@Target({ ElementType.METHOD, ElementType.TYPE})
85.35 -public @interface HttpResource {
85.36 - /** path on the server that the test can use to access the exposed resource */
85.37 - String path();
85.38 - /** the content of the HttpResource */
85.39 - String content();
85.40 - /** resource relative to the class that should be used instead of <code>content</code>.
85.41 - * Leave content equal to empty string.
85.42 - */
85.43 - String resource() default "";
85.44 - /** mime type of the resource */
85.45 - String mimeType();
85.46 -}
86.1 --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java Tue Feb 19 15:33:32 2013 +0100
86.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java Tue Feb 19 15:59:27 2013 +0100
86.3 @@ -28,7 +28,7 @@
86.4 import org.apidesign.bck2brwsr.launcher.Launcher;
86.5 import org.apidesign.bck2brwsr.launcher.InvocationContext;
86.6 import org.apidesign.bck2brwsr.vmtest.HtmlFragment;
86.7 -import org.apidesign.bck2brwsr.vmtest.HttpResource;
86.8 +import org.apidesign.bck2brwsr.vmtest.Http;
86.9 import org.testng.ITest;
86.10 import org.testng.annotations.Test;
86.11
86.12 @@ -42,10 +42,10 @@
86.13 private final String type;
86.14 private final boolean fail;
86.15 private final HtmlFragment html;
86.16 - private final HttpResource http;
86.17 + private final Http.Resource[] http;
86.18 Object value;
86.19
86.20 - Bck2BrwsrCase(Method m, String type, Launcher l, boolean fail, HtmlFragment html, HttpResource http) {
86.21 + Bck2BrwsrCase(Method m, String type, Launcher l, boolean fail, HtmlFragment html, Http.Resource[] http) {
86.22 this.l = l;
86.23 this.m = m;
86.24 this.type = type;
86.25 @@ -62,12 +62,14 @@
86.26 c.setHtmlFragment(html.value());
86.27 }
86.28 if (http != null) {
86.29 - if (!http.content().isEmpty()) {
86.30 - InputStream is = new ByteArrayInputStream(http.content().getBytes("UTF-8"));
86.31 - c.setHttpResource(http.path(), http.mimeType(), is);
86.32 - } else {
86.33 - InputStream is = m.getDeclaringClass().getResourceAsStream(http.resource());
86.34 - c.setHttpResource(http.path(), http.mimeType(), is);
86.35 + for (Http.Resource r : http) {
86.36 + if (!r.content().isEmpty()) {
86.37 + InputStream is = new ByteArrayInputStream(r.content().getBytes("UTF-8"));
86.38 + c.addHttpResource(r.path(), r.mimeType(), is);
86.39 + } else {
86.40 + InputStream is = m.getDeclaringClass().getResourceAsStream(r.resource());
86.41 + c.addHttpResource(r.path(), r.mimeType(), is);
86.42 + }
86.43 }
86.44 }
86.45 String res = c.invoke();
87.1 --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java Tue Feb 19 15:33:32 2013 +0100
87.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java Tue Feb 19 15:59:27 2013 +0100
87.3 @@ -135,9 +135,15 @@
87.4 if (f == null) {
87.5 f = m.getDeclaringClass().getAnnotation(HtmlFragment.class);
87.6 }
87.7 - HttpResource r = m.getAnnotation(HttpResource.class);
87.8 - if (r == null) {
87.9 - r = m.getDeclaringClass().getAnnotation(HttpResource.class);
87.10 + Http.Resource[] r = {};
87.11 + Http h = m.getAnnotation(Http.class);
87.12 + if (h == null) {
87.13 + h = m.getDeclaringClass().getAnnotation(Http.class);
87.14 + if (h != null) {
87.15 + r = h.value();
87.16 + }
87.17 + } else {
87.18 + r = h.value();
87.19 }
87.20 if (brwsr.length == 0) {
87.21 final Launcher s = l.brwsr(null);
88.1 --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/GenerateZipProcessor.java Tue Feb 19 15:33:32 2013 +0100
88.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/GenerateZipProcessor.java Tue Feb 19 15:59:27 2013 +0100
88.3 @@ -25,6 +25,7 @@
88.4 import java.util.jar.JarOutputStream;
88.5 import java.util.jar.Manifest;
88.6 import javax.annotation.processing.AbstractProcessor;
88.7 +import javax.annotation.processing.Filer;
88.8 import javax.annotation.processing.Processor;
88.9 import javax.annotation.processing.RoundEnvironment;
88.10 import javax.annotation.processing.SupportedAnnotationTypes;
88.11 @@ -73,7 +74,8 @@
88.12 }
88.13
88.14 private void generateJar(PackageElement pe, GenerateZip gz, Element e) throws IOException {
88.15 - FileObject res = processingEnv.getFiler().createResource(
88.16 + final Filer filer = processingEnv.getFiler();
88.17 + FileObject res = filer.createResource(
88.18 StandardLocation.CLASS_OUTPUT,
88.19 pe.getQualifiedName().toString(),
88.20 gz.name(), e
88.21 @@ -93,6 +95,7 @@
88.22 jar.write(arr[i + 1].getBytes("UTF-8"));
88.23 jar.closeEntry();
88.24 }
88.25 + jar.close();
88.26 }
88.27 -
88.28 +
88.29 }
89.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java Tue Feb 19 15:33:32 2013 +0100
89.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java Tue Feb 19 15:59:27 2013 +0100
89.3 @@ -47,6 +47,19 @@
89.4 return "Ahoj".equals(null);
89.5 }
89.6
89.7 + @Compare public int highByteLenght() {
89.8 + byte[] arr= { 77,97,110,105,102,101,115,116,45,86,101,114,115,105,111,110 };
89.9 + return new String(arr, 0).length();
89.10 + }
89.11 +
89.12 + @Compare public String highByte() {
89.13 + byte[] arr= { 77,97,110,105,102,101,115,116,45,86,101,114,115,105,111,110 };
89.14 + StringBuilder sb = new StringBuilder();
89.15 + sb.append("pref:");
89.16 + sb.append(new String(arr, 0));
89.17 + return sb.toString();
89.18 + }
89.19 +
89.20 @Compare public static Object compareURLs() throws MalformedURLException {
89.21 return new URL("http://apidesign.org:8080/wiki/").toExternalForm().toString();
89.22 }
90.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/HttpResourceTest.java Tue Feb 19 15:33:32 2013 +0100
90.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/HttpResourceTest.java Tue Feb 19 15:59:27 2013 +0100
90.3 @@ -21,7 +21,7 @@
90.4 import java.net.URL;
90.5 import org.apidesign.bck2brwsr.core.JavaScriptBody;
90.6 import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
90.7 -import org.apidesign.bck2brwsr.vmtest.HttpResource;
90.8 +import org.apidesign.bck2brwsr.vmtest.Http;
90.9 import org.apidesign.bck2brwsr.vmtest.VMTest;
90.10 import org.testng.annotations.Factory;
90.11
90.12 @@ -31,15 +31,21 @@
90.13 */
90.14 public class HttpResourceTest {
90.15
90.16 - @HttpResource(path = "/xhr", content = "Hello Brwsr!", mimeType = "text/plain")
90.17 + @Http({
90.18 + @Http.Resource(path = "/xhr", content = "Hello Brwsr!", mimeType = "text/plain")
90.19 + })
90.20 @BrwsrTest
90.21 +
90.22 +
90.23 public String testReadContentViaXHR() throws Exception {
90.24 String msg = read("/xhr");
90.25 assert "Hello Brwsr!".equals(msg) : "The message was " + msg;
90.26 return msg;
90.27 }
90.28
90.29 - @HttpResource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
90.30 + @Http({
90.31 + @Http.Resource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
90.32 + })
90.33 @BrwsrTest
90.34 public String testReadContentViaURL() throws Exception {
90.35 URL url = new URL("http:/url");
90.36 @@ -47,7 +53,9 @@
90.37 assert "Hello via URL!".equals(msg) : "The message was " + msg;
90.38 return msg;
90.39 }
90.40 - @HttpResource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
90.41 + @Http({
90.42 + @Http.Resource(path = "/url", content = "Hello via URL!", mimeType = "text/plain")
90.43 + })
90.44 @BrwsrTest
90.45 public String testReadContentViaURLWithStringParam() throws Exception {
90.46 URL url = new URL("http:/url");
90.47 @@ -56,7 +64,9 @@
90.48 return msg;
90.49 }
90.50
90.51 - @HttpResource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
90.52 + @Http({
90.53 + @Http.Resource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
90.54 + })
90.55 @BrwsrTest
90.56 public void testReadByte() throws Exception {
90.57 URL url = new URL("http:/bytes");
90.58 @@ -67,7 +77,9 @@
90.59 assert arr[0] == 0xfe : "It is 0xfe: " + Integer.toHexString(arr[0]);
90.60 }
90.61
90.62 - @HttpResource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
90.63 + @Http({
90.64 + @Http.Resource(path = "/bytes", content = "", resource = "0xfe", mimeType = "x-application/binary")
90.65 + })
90.66 @BrwsrTest
90.67 public void testReadByteViaInputStream() throws Exception {
90.68 URL url = new URL("http:/bytes");
91.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Tue Feb 19 15:33:32 2013 +0100
91.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java Tue Feb 19 15:59:27 2013 +0100
91.3 @@ -17,6 +17,8 @@
91.4 */
91.5 package org.apidesign.bck2brwsr.tck;
91.6
91.7 +import java.lang.annotation.Retention;
91.8 +import java.lang.annotation.RetentionPolicy;
91.9 import java.lang.reflect.Method;
91.10 import java.util.Arrays;
91.11 import java.util.Collections;
91.12 @@ -47,6 +49,14 @@
91.13 return long.class.toString();
91.14 }
91.15
91.16 + @Compare public boolean isRunnableInterface() {
91.17 + return Runnable.class.isInterface();
91.18 + }
91.19 +
91.20 + @Compare public String isRunnableHasRunMethod() throws NoSuchMethodException {
91.21 + return Runnable.class.getMethod("run").getName();
91.22 + }
91.23 +
91.24 @Compare public String namesOfMethods() {
91.25 StringBuilder sb = new StringBuilder();
91.26 String[] arr = new String[20];
91.27 @@ -59,6 +69,19 @@
91.28 }
91.29 return sb.toString();
91.30 }
91.31 +
91.32 + @Compare public String namesOfDeclaringClassesOfMethods() {
91.33 + StringBuilder sb = new StringBuilder();
91.34 + String[] arr = new String[20];
91.35 + int i = 0;
91.36 + for (Method m : StaticUse.class.getMethods()) {
91.37 + arr[i++] = m.getName() + "@" + m.getDeclaringClass().getName();
91.38 + }
91.39 + for (String s : sort(arr, i)) {
91.40 + sb.append(s).append("\n");
91.41 + }
91.42 + return sb.toString();
91.43 + }
91.44
91.45 @Compare public String cannotCallNonStaticMethodWithNull() throws Exception {
91.46 StaticUse.class.getMethod("instanceMethod").invoke(null);
91.47 @@ -69,6 +92,26 @@
91.48 return StaticUse.class.getMethod("instanceMethod").getReturnType();
91.49 }
91.50
91.51 + @Retention(RetentionPolicy.RUNTIME)
91.52 + @interface Ann {
91.53 + }
91.54 +
91.55 + @Compare public String annoClass() throws Exception {
91.56 + Retention r = Ann.class.getAnnotation(Retention.class);
91.57 + assert r != null : "Annotation is present";
91.58 + assert r.value() == RetentionPolicy.RUNTIME : "Policy value is OK: " + r.value();
91.59 + return r.annotationType().getName();
91.60 + }
91.61 +
91.62 + @Compare public boolean isAnnotation() {
91.63 + return Ann.class.isAnnotation();
91.64 + }
91.65 + @Compare public boolean isNotAnnotation() {
91.66 + return String.class.isAnnotation();
91.67 + }
91.68 + @Compare public boolean isNotAnnotationEnum() {
91.69 + return E.class.isAnnotation();
91.70 + }
91.71 enum E { A, B };
91.72 @Compare public boolean isEnum() {
91.73 return E.A.getClass().isEnum();
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
92.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipEntryTest.java Tue Feb 19 15:59:27 2013 +0100
92.3 @@ -0,0 +1,67 @@
92.4 +/**
92.5 + * Back 2 Browser Bytecode Translator
92.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
92.7 + *
92.8 + * This program is free software: you can redistribute it and/or modify
92.9 + * it under the terms of the GNU General Public License as published by
92.10 + * the Free Software Foundation, version 2 of the License.
92.11 + *
92.12 + * This program is distributed in the hope that it will be useful,
92.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
92.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
92.15 + * GNU General Public License for more details.
92.16 + *
92.17 + * You should have received a copy of the GNU General Public License
92.18 + * along with this program. Look for COPYING file in the top folder.
92.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
92.20 + */
92.21 +package org.apidesign.bck2brwsr.vmtest.impl;
92.22 +
92.23 +import java.io.ByteArrayInputStream;
92.24 +import java.io.IOException;
92.25 +import java.io.InputStream;
92.26 +import org.apidesign.bck2brwsr.emul.zip.FastJar;
92.27 +import org.testng.annotations.Test;
92.28 +import static org.testng.Assert.*;
92.29 +
92.30 +/**
92.31 + *
92.32 + * @author Jaroslav Tulach <jtulach@netbeans.org>
92.33 + */
92.34 +@GenerateZip(name = "five.zip", contents = {
92.35 + "1.txt", "one",
92.36 + "2.txt", "duo",
92.37 + "3.txt", "three",
92.38 + "4.txt", "four",
92.39 + "5.txt", "five"
92.40 +})
92.41 +public class ZipEntryTest {
92.42 + @Test
92.43 + public void readEntriesEffectively() throws IOException {
92.44 + InputStream is = ZipEntryTest.class.getResourceAsStream("five.zip");
92.45 + byte[] arr = new byte[is.available()];
92.46 + int len = is.read(arr);
92.47 + assertEquals(len, arr.length, "Read fully");
92.48 +
92.49 + FastJar fj = new FastJar(arr);
92.50 + FastJar.Entry[] entrs = fj.list();
92.51 +
92.52 + assertEquals(5, entrs.length, "Five entries");
92.53 +
92.54 + for (int i = 1; i <= 5; i++) {
92.55 + FastJar.Entry en = entrs[i - 1];
92.56 + assertEquals(en.name, i + ".txt");
92.57 +// assertEquals(cis.cnt, 0, "Content of the file should be skipped, not read");
92.58 + }
92.59 +
92.60 + assertContent("three", fj.getInputStream(entrs[3 - 1]), "read OK");
92.61 + assertContent("five", fj.getInputStream(entrs[5 - 1]), "read OK");
92.62 + }
92.63 +
92.64 + private static void assertContent(String exp, InputStream is, String msg) throws IOException {
92.65 + byte[] arr = new byte[512];
92.66 + int len = is.read(arr);
92.67 + String s = new String(arr, 0, len);
92.68 + assertEquals(exp, s, msg);
92.69 + }
92.70 +}
93.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java Tue Feb 19 15:33:32 2013 +0100
93.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/vmtest/impl/ZipFileTest.java Tue Feb 19 15:59:27 2013 +0100
93.3 @@ -25,7 +25,7 @@
93.4 import org.apidesign.bck2brwsr.core.JavaScriptBody;
93.5 import org.apidesign.bck2brwsr.vmtest.BrwsrTest;
93.6 import org.apidesign.bck2brwsr.vmtest.Compare;
93.7 -import org.apidesign.bck2brwsr.vmtest.HttpResource;
93.8 +import org.apidesign.bck2brwsr.vmtest.Http;
93.9 import org.apidesign.bck2brwsr.vmtest.VMTest;
93.10 import org.testng.annotations.Factory;
93.11
93.12 @@ -54,13 +54,15 @@
93.13 }
93.14
93.15 @JavaScriptBody(args = { "res", "path" }, body =
93.16 - "var myvm = new bck2brwsr(path);\n"
93.17 + "var myvm = bck2brwsr.apply(null, path);\n"
93.18 + "var cls = myvm.loadClass('java.lang.String');\n"
93.19 + "return cls.getClass__Ljava_lang_Class_2().getResourceAsStream__Ljava_io_InputStream_2Ljava_lang_String_2(res);\n"
93.20 )
93.21 private static native Object loadVMResource(String res, String...path);
93.22
93.23 - @HttpResource(path = "/readAnEntry.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip")
93.24 + @Http({
93.25 + @Http.Resource(path = "/readAnEntry.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip")
93.26 + })
93.27 @BrwsrTest public void canVmLoadResourceFromZip() throws IOException {
93.28 Object res = loadVMResource("/my/main/file.txt", "/readAnEntry.jar");
93.29 assert res instanceof InputStream : "Got array of bytes: " + res;
93.30 @@ -74,6 +76,28 @@
93.31 assertEquals(ret, "Hello World!", "Can read the bytes");
93.32 }
93.33
93.34 + @GenerateZip(name = "cpattr.zip", contents = {
93.35 + "META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n"
93.36 + + "Created-By: hand\n"
93.37 + + "Class-Path: realJar.jar\n\n\n"
93.38 + })
93.39 + @Http({
93.40 + @Http.Resource(path = "/readComplexEntry.jar", mimeType = "x-application/zip", content = "", resource="cpattr.zip"),
93.41 + @Http.Resource(path = "/realJar.jar", mimeType = "x-application/zip", content = "", resource="readAnEntry.zip"),
93.42 + })
93.43 + @BrwsrTest public void understandsClassPathAttr() throws IOException {
93.44 + Object res = loadVMResource("/my/main/file.txt", "/readComplexEntry.jar");
93.45 + assert res instanceof InputStream : "Got array of bytes: " + res;
93.46 + InputStream is = (InputStream)res;
93.47 +
93.48 + byte[] arr = new byte[4096];
93.49 + int len = is.read(arr);
93.50 +
93.51 + final String ret = new String(arr, 0, len, "UTF-8");
93.52 +
93.53 + assertEquals(ret, "Hello World!", "Can read the bytes from secondary JAR");
93.54 + }
93.55 +
93.56 private static void assertEquals(Object real, Object exp, String msg) {
93.57 assert Objects.equals(exp, real) : msg + " exp: " + exp + " real: " + real;
93.58 }