You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2005/12/01 07:04:00 UTC
svn commit: r350181 [52/198] - in
/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core: ./ depends/
depends/files/ depends/jars/ depends/libs/ depends/libs/linux.IA32/
depends/libs/win.IA32/ depends/oss/ depends/oss/linux.IA32/
depends/oss/win.I...
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarFile.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarFile.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarFile.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarFile.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,358 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.jar;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+
+/**
+ * JarFile is used to read jar entries and their associated data from jar files.
+ *
+ * @see JarInputStream
+ * @see JarEntry
+ */
+public class JarFile extends java.util.zip.ZipFile {
+ public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
+
+ static final String META_DIR = "META-INF/";
+
+ private Manifest manifest;
+
+ private ZipEntry manifestEntry;
+
+ JarVerifier verifier;
+
+ static final class JarFileInputStream extends FilterInputStream {
+ private long count;
+
+ private ZipEntry zipEntry;
+
+ private JarVerifier verifier;
+
+ private JarVerifier.VerifierEntry entry;
+
+ private MessageDigest digest;
+
+ JarFileInputStream(InputStream is, ZipEntry ze, JarVerifier ver) {
+ super(is);
+ if (ver != null) {
+ zipEntry = ze;
+ verifier = ver;
+ count = zipEntry.getSize();
+ entry = verifier.initEntry(ze.getName());
+ if (entry != null)
+ digest = entry.digest;
+ }
+ }
+
+ public int read() throws IOException {
+ int r = super.read();
+ if (entry != null) {
+ if (r != -1) {
+ digest.update((byte) r);
+ count--;
+ }
+ if (r == -1 || count <= 0) {
+ JarVerifier.VerifierEntry temp = entry;
+ entry = null;
+ verifier.verifySignatures(temp, zipEntry);
+ }
+ }
+ return r;
+ }
+
+ public int read(byte[] buf, int off, int nbytes) throws IOException {
+ int r = super.read(buf, off, nbytes);
+ if (entry != null) {
+ if (r != -1) {
+ int size = r;
+ if (count < size)
+ size = (int) count;
+ digest.update(buf, off, size);
+ count -= r;
+ }
+ if (r == -1 || count <= 0) {
+ JarVerifier.VerifierEntry temp = entry;
+ entry = null;
+ verifier.verifySignatures(temp, zipEntry);
+ }
+ }
+ return r;
+ }
+
+ public long skip(long nbytes) throws IOException {
+ long cnt = 0, rem = 0;
+ byte[] buf = new byte[4096];
+ while (cnt < nbytes) {
+ int x = read(buf, 0,
+ (rem = nbytes - cnt) > buf.length ? buf.length
+ : (int) rem);
+ if (x == -1)
+ return cnt;
+ cnt += x;
+ }
+ return cnt;
+ }
+ }
+
+ /**
+ * Create a new JarFile using the contents of file.
+ *
+ * @param file
+ * java.io.File
+ * @exception java.io.IOException
+ * If the file cannot be read.
+ */
+ public JarFile(File file) throws IOException {
+ this(file, true);
+ }
+
+ /**
+ * Create a new JarFile using the contents of file.
+ *
+ * @param file
+ * java.io.File
+ * @param verify
+ * verify a signed jar file
+ * @exception java.io.IOException
+ * If the file cannot be read.
+ */
+ public JarFile(File file, boolean verify) throws IOException {
+ super(file);
+ if (verify)
+ verifier = new JarVerifier(file.getPath());
+ readMetaEntries();
+ }
+
+ /**
+ * Create a new JarFile using the contents of file.
+ *
+ * @param file
+ * java.io.File
+ * @param verify
+ * verify a signed jar file
+ * @param mode
+ * the mode to use, either OPEN_READ or OPEN_READ | OPEN_DELETE
+ * @exception java.io.IOException
+ * If the file cannot be read.
+ */
+ public JarFile(File file, boolean verify, int mode) throws IOException {
+ super(file, mode);
+ if (verify)
+ verifier = new JarVerifier(file.getPath());
+ readMetaEntries();
+ }
+
+ /**
+ * Create a new JarFile from the contents of the file specified by filename.
+ *
+ * @param filename
+ * java.lang.String
+ * @exception java.io.IOException
+ * If fileName cannot be opened for reading.
+ */
+ public JarFile(String filename) throws IOException {
+ this(filename, true);
+
+ }
+
+ /**
+ * Create a new JarFile from the contents of the file specified by filename.
+ *
+ * @param filename
+ * java.lang.String
+ * @param verify
+ * verify a signed jar file
+ * @exception java.io.IOException
+ * If fileName cannot be opened for reading.
+ */
+ public JarFile(String filename, boolean verify) throws IOException {
+ super(filename);
+ if (verify)
+ verifier = new JarVerifier(filename);
+ readMetaEntries();
+ }
+
+ /**
+ * Return an enumeration containing the JarEntrys contained in this JarFile.
+ *
+ * @return java.util.Enumeration
+ * @exception java.lang.IllegalStateException
+ * If this JarFile has been closed.
+ */
+ public Enumeration entries() {
+ class JarFileEnumerator implements Enumeration {
+ Enumeration ze;
+
+ JarFile jf;
+
+ JarFileEnumerator(Enumeration zenum, JarFile jf) {
+ ze = zenum;
+ this.jf = jf;
+ }
+
+ public boolean hasMoreElements() {
+ return ze.hasMoreElements();
+ }
+
+ public Object nextElement() {
+ JarEntry je = new JarEntry((ZipEntry) ze.nextElement());
+ je.parentJar = jf;
+ if (verifier != null)
+ je.certificates = verifier.getCertificates(je.getName());
+ return je;
+ }
+ }
+ return new JarFileEnumerator(super.entries(), this);
+ }
+
+ /**
+ * Return the JarEntry specified by name or null if no such entry exists.
+ *
+ * @param name
+ * the name of the entry in the jar file
+ * @return java.util.jar.JarEntry
+ */
+ public JarEntry getJarEntry(String name) {
+ return (JarEntry) getEntry(name);
+ }
+
+ /**
+ * Returns the Manifest object associated with this JarFile or null if no
+ * manifest entry exists.
+ *
+ * @return java.util.jar.Manifest
+ */
+ public Manifest getManifest() throws IOException {
+ if (manifest != null)
+ return manifest;
+ if (manifestEntry != null) {
+ ByteArrayInputStream is = (ByteArrayInputStream) super
+ .getInputStream(manifestEntry);
+ if (verifier != null) {
+ byte[] buf = new byte[is.available()];
+ is.mark(buf.length);
+ is.read(buf, 0, buf.length);
+ is.reset();
+ verifier.addMetaEntry(manifestEntry.getName(), buf);
+ }
+ try {
+ manifest = new Manifest(is, verifier != null);
+ } finally {
+ is.close();
+ }
+ manifestEntry = null;
+ }
+ return manifest;
+ }
+
+ private void readMetaEntries() throws IOException {
+ ZipEntry[] metaEntries = this.getMetaEntriesImpl(null);
+ int dirLength = META_DIR.length();
+
+ boolean signed = false;
+ if (null != metaEntries) {
+ for (int i = 0; i < metaEntries.length; i++) {
+ ZipEntry entry = metaEntries[i];
+ String entryName = entry.getName();
+ if (manifestEntry == null
+ && manifest == null
+ && entryName.regionMatches(true, dirLength,
+ MANIFEST_NAME, dirLength, MANIFEST_NAME
+ .length()
+ - dirLength)) {
+ manifestEntry = entry;
+ if (verifier == null)
+ break;
+ } else if (verifier != null
+ && entryName.length() > dirLength
+ && (entryName.regionMatches(true,
+ entryName.length() - 3, ".SF", 0, 3)
+ || entryName.regionMatches(true, entryName
+ .length() - 4, ".DSA", 0, 4) || entryName
+ .regionMatches(true, entryName.length() - 4,
+ ".RSA", 0, 4))) {
+ signed = true;
+ if (manifest == null)
+ verifier.setManifest(getManifest());
+ InputStream is = super.getInputStream(entry);
+ byte[] buf = new byte[is.available()];
+ is.read(buf, 0, buf.length);
+ is.close();
+ verifier.addMetaEntry(entryName, buf);
+ }
+ }
+ }
+ if (!signed)
+ verifier = null;
+ }
+
+ /**
+ * Return an InputStream for reading the decompressed contents of ze.
+ *
+ * @param ze
+ * the ZipEntry to read from
+ * @return java.io.InputStream
+ * @exception java.io.IOException
+ * If an error occured while creating the InputStream.
+ */
+ public InputStream getInputStream(ZipEntry ze) throws IOException {
+ if (manifestEntry != null)
+ getManifest();
+ if (verifier != null) {
+ if (verifier.readCertificates()) {
+ verifier.removeMetaEntries();
+ if (manifest != null)
+ manifest.removeChunks();
+ if (!verifier.isSignedJar())
+ verifier = null;
+ }
+ }
+ InputStream in = super.getInputStream(ze);
+ if (in == null)
+ return null;
+ return new JarFileInputStream(in, ze, ze.getSize() >= 0 ? verifier
+ : null);
+ }
+
+ /**
+ * Return the JarEntry specified by name or null if no such entry exists
+ *
+ * @param name
+ * the name of the entry in the jar file
+ * @return java.util.jar.JarEntry
+ */
+ public ZipEntry getEntry(String name) {
+ ZipEntry ze = super.getEntry(name);
+ if (ze == null)
+ return ze;
+ JarEntry je = new JarEntry(ze);
+ je.parentJar = this;
+ if (verifier != null)
+ je.certificates = verifier.getCertificates(je.getName());
+ return je;
+ }
+
+ private native ZipEntry[] getMetaEntriesImpl(byte[] buf);
+
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarInputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarInputStream.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarInputStream.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarInputStream.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,155 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.jar;
+
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class JarInputStream extends ZipInputStream {
+
+ private Manifest manifest;
+
+ private boolean eos = false;
+
+ private JarEntry mEntry;
+
+ private JarEntry jarEntry;
+
+ private boolean isMeta;
+
+ private JarVerifier verifier;
+
+ private OutputStream verStream;
+
+ /**
+ * Constructs a new JarInputStream from stream
+ */
+ public JarInputStream(InputStream stream, boolean verify)
+ throws IOException {
+ super(stream);
+ if (verify)
+ verifier = new JarVerifier("JarInputStream");
+ if ((mEntry = getNextJarEntry()) == null)
+ return;
+ String name = mEntry.getName().toUpperCase();
+ if (name.equals(JarFile.META_DIR)) {
+ mEntry = null; // modifies behavior of getNextJarEntry()
+ closeEntry();
+ mEntry = getNextJarEntry();
+ name = mEntry.getName().toUpperCase();
+ }
+ if (name.equals(JarFile.MANIFEST_NAME)) {
+ mEntry = null;
+ manifest = new Manifest(this, verify);
+ closeEntry();
+ if (verify)
+ verifier.setManifest(manifest);
+ } else {
+ Attributes temp = new Attributes(3);
+ temp.map.put("hidden", null);
+ mEntry.setAttributes(temp);
+ }
+ }
+
+ public JarInputStream(InputStream stream) throws IOException {
+ this(stream, true);
+ }
+
+ /**
+ * Returns the Manifest object associated with this JarInputStream or null
+ * if no manifest entry exists.
+ *
+ * @return java.util.jar.Manifest
+ */
+ public Manifest getManifest() {
+ return manifest;
+ }
+
+ /**
+ * Returns the next JarEntry contained in this stream or null if no more
+ * entries are present.
+ *
+ * @return java.util.jar.JarEntry
+ * @exception java.io.IOException
+ * If an error occurs while reading the entry
+ */
+ public JarEntry getNextJarEntry() throws IOException {
+ return (JarEntry) getNextEntry();
+ }
+
+ public int read(byte[] buffer, int offset, int length) throws IOException {
+ if (mEntry != null)
+ return -1;
+ int r = super.read(buffer, offset, length);
+ if (verStream != null && !eos) {
+ if (r == -1) {
+ eos = true;
+ if (isMeta) {
+ verifier.addMetaEntry(jarEntry.getName(),
+ ((ByteArrayOutputStream) verStream).toByteArray());
+ verifier.readCertificates();
+ } else
+ verifier.verifySignatures(
+ (JarVerifier.VerifierEntry) verStream, jarEntry);
+ } else
+ verStream.write(buffer, offset, r);
+ }
+ return r;
+ }
+
+ /**
+ * Returns the next ZipEntry contained in this stream or null if no more
+ * entries are present.
+ *
+ * @return java.util.zip.ZipEntry
+ * @exception java.io.IOException
+ * If an error occurs while reading the entry
+ */
+ public ZipEntry getNextEntry() throws IOException {
+ eos = false;
+ if (mEntry != null) {
+ jarEntry = mEntry;
+ mEntry = null;
+ jarEntry.setAttributes(null);
+ return jarEntry;
+ }
+ jarEntry = (JarEntry) super.getNextEntry();
+ if (jarEntry == null)
+ return null;
+ if (verifier != null) {
+ isMeta = jarEntry.getName().toUpperCase().startsWith(
+ JarFile.META_DIR);
+ if (isMeta) {
+ verStream = new ByteArrayOutputStream();
+ } else {
+ verStream = verifier.initEntry(jarEntry.getName());
+ }
+ }
+ return jarEntry;
+ }
+
+ protected ZipEntry createZipEntry(String name) {
+ JarEntry entry = new JarEntry(name);
+ if (manifest != null)
+ entry.setAttributes(manifest.getAttributes(name));
+ return entry;
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarOutputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarOutputStream.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarOutputStream.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarOutputStream.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,79 @@
+/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.jar;
+
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * The JarOutputStream is used to output data in JarFile format.
+ */
+public class JarOutputStream extends ZipOutputStream {
+
+ private Manifest manifest;
+
+ /**
+ * Contructs a new JarOuputStream using os as the underlying stream.
+ * Manifest information for the JarFile to be written is obtained from the
+ * parameter Manifest, mf.
+ *
+ * @param os
+ * The OutputStream to write to
+ * @param mf
+ * The Manifest to output for this Jar.
+ * @exception IOException
+ * If an error occurs creating the JarOutputStream
+ */
+ public JarOutputStream(OutputStream os, Manifest mf) throws IOException {
+ super(os);
+ if (mf == null)
+ throw new NullPointerException();
+ manifest = mf;
+ ZipEntry ze = new ZipEntry(JarFile.MANIFEST_NAME);
+ putNextEntry(ze);
+ manifest.write(this);
+ closeEntry();
+ }
+
+ /**
+ * Contructs a new JarOuputStream using os as the underlying stream.
+ *
+ * @param os
+ * The OutputStream to write to
+ * @exception IOException
+ * If an error occurs creating the JarOutputStream
+ */
+ public JarOutputStream(OutputStream os) throws IOException {
+ super(os);
+ }
+
+ /**
+ * Writes the specified entry to the underlying stream. The previous entry
+ * is closed if it is still open.
+ *
+ *
+ * @param ze
+ * The ZipEntry to write
+ * @exception IOException
+ * If an error occurs writing the entry
+ */
+ public void putNextEntry(ZipEntry ze) throws IOException {
+ super.putNextEntry(ze);
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarVerifier.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarVerifier.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarVerifier.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/JarVerifier.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,467 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.jar;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.zip.ZipEntry;
+
+import com.ibm.oti.util.BASE64Decoder;
+import com.ibm.oti.util.JarUtils;
+import com.ibm.oti.util.Msg;
+
+/**
+ * Non-public class used by {@link java.util.jar.JarFile} and
+ * {@link java.util.jar.JarInputStream} to manage the verification of signed
+ * jars. <code>JarFile</code> and <code>JarInputStream</code> objects will
+ * be expected to have a <code>JarVerifier</code> instance member which can be
+ * used to carry out the tasks associated with verifying a signed jar. These
+ * tasks would typically include:
+ * <ul>
+ * <li>verification of all signed signature files
+ * <li>confirmation that all signed data was signed only by the party or
+ * parties specified in the signature block data
+ * <li>verification that the contents of all signature files (i.e.
+ * <code>.SF</code> files) agree with the jar entries information found in the
+ * jar maifest.
+ * </ul>
+ */
+class JarVerifier {
+
+ private String jarName;
+
+ private Manifest man;
+
+ private HashMap metaEntries = new HashMap(5);
+
+ private Hashtable signatures = new Hashtable(5);
+
+ private Hashtable certificates = new Hashtable(5);
+
+ private Hashtable verifiedEntries = new Hashtable();
+
+ /**
+ * TODO Type description
+ */
+ static class VerifierEntry extends OutputStream {
+ /**
+ * Comment for <code>digest</code>
+ */
+ MessageDigest digest;
+
+ /**
+ * Comment for <code>hash</code>
+ */
+ byte[] hash;
+
+ /**
+ * Comment for <code>certificates</code>
+ */
+ java.security.cert.Certificate[] certificates;
+
+ /**
+ * @param digest
+ * @param hash
+ * @param certificates
+ */
+ VerifierEntry(MessageDigest digest, byte[] hash,
+ java.security.cert.Certificate[] certificates) {
+ this.digest = digest;
+ this.hash = hash;
+ this.certificates = certificates;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#write(int)
+ */
+ public void write(int value) {
+ digest.update((byte) value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.OutputStream#write(byte[], int, int)
+ */
+ public void write(byte[] buf, int off, int nbytes) {
+ digest.update(buf, off, nbytes);
+ }
+ }
+
+ /**
+ * Constructs and answers with a new instance of JarVerifier.
+ *
+ * @param name
+ * the name of the jar file being verified.
+ */
+ JarVerifier(String name) {
+ jarName = name;
+ }
+
+ /**
+ * Called for each new jar entry read in from the input stream. This method
+ * constructs and returns a new {@link VerifierEntry} which contains the
+ * certificates used to sign the entry and its hash value as specified in
+ * the jar manifest.
+ *
+ * @param name
+ * the name of an entry in a jar file which is <b>not</b> in the
+ * <code>META-INF</code> directory.
+ * @return a new instance of {@link VerifierEntry} which can be used by
+ * callers as an {@link OutputStream}.
+ */
+ VerifierEntry initEntry(String name) {
+ // If no manifest is present by the time an entry is found,
+ // verification cannot occur. If no signature files have
+ // been found, do not verify.
+ if (man == null || signatures.size() == 0)
+ return null;
+
+ Attributes attributes = man.getAttributes(name);
+ // entry has no digest
+ if (attributes == null)
+ return null;
+
+ Vector certs = new Vector();
+ Iterator it = signatures.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry) it.next();
+ HashMap hm = (HashMap) entry.getValue();
+ if (hm.get(name) != null) {
+ // Found an entry for entry name in .SF file
+ String signatureFile = (String) entry.getKey();
+
+ Vector newCerts = getSignerCertificates(signatureFile,
+ certificates);
+ Iterator iter = newCerts.iterator();
+ while (iter.hasNext()) {
+ certs.add(iter.next());
+ }
+ }
+ }
+
+ // entry is not signed
+ if (certs.size() == 0)
+ return null;
+ Certificate[] certificatesArray = new Certificate[certs.size()];
+ certs.toArray(certificatesArray);
+
+ String algorithms = attributes.getValue("Digest-Algorithms");
+ if (algorithms == null)
+ algorithms = "SHA SHA1";
+ StringTokenizer tokens = new StringTokenizer(algorithms);
+ while (tokens.hasMoreTokens()) {
+ String algorithm = tokens.nextToken();
+ String hash = attributes.getValue(algorithm + "-Digest");
+ if (hash == null)
+ continue;
+ byte[] hashBytes;
+ try {
+ hashBytes = hash.getBytes("ISO8859_1");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e.toString());
+ }
+
+ try {
+ return new VerifierEntry(MessageDigest.getInstance(algorithm),
+ hashBytes, certificatesArray);
+ } catch (NoSuchAlgorithmException e) {
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Add a new meta entry to the internal collection of data held on each jar
+ * entry in the <code>META-INF</code> directory including the manifest
+ * file itself. Files associated with the signing of a jar would also be
+ * added to this collection.
+ *
+ * @param name
+ * the name of the file located in the <code>META-INF</code>
+ * directory.
+ * @param buf
+ * the file bytes for the file called <code>name</code>.
+ * @see #removeMetaEntries()
+ */
+ void addMetaEntry(String name, byte[] buf) {
+ metaEntries.put(name.toUpperCase(), buf);
+ }
+
+ /**
+ * If the associated jar file is signed, check on the validity of all of the
+ * known signatures.
+ *
+ * @return <code>true</code> if the associated jar is signed and an
+ * internal check verifies the validity of the signature(s).
+ * <code>false</code> if the associated jar file has no entries at
+ * all in its <code>META-INF</code> directory. This situation is
+ * indicative of an invalid jar file.
+ * <p>
+ * Will also return true if the jar file is <i>not</i> signed.
+ * </p>
+ * @throws SecurityException
+ * if the jar file is signed and it is determined that a
+ * signature block file contains an invalid signature for the
+ * corresponding signature file.
+ */
+ synchronized boolean readCertificates() {
+ if (metaEntries == null)
+ return false;
+ Iterator it = metaEntries.keySet().iterator();
+ while (it.hasNext()) {
+ String key = (String) it.next();
+ if (key.endsWith(".DSA") || key.endsWith(".RSA")) {
+ verifyCertificate(key);
+ // Check for recursive class load
+ if (metaEntries == null)
+ return false;
+ it.remove();
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @param certFile
+ */
+ private void verifyCertificate(String certFile) {
+ // Found Digital Sig, .SF should already have been read
+ String signatureFile = certFile.substring(0, certFile.lastIndexOf('.'))
+ + ".SF";
+ byte[] sfBytes = (byte[]) metaEntries.get(signatureFile);
+ if (sfBytes == null)
+ return;
+
+ byte[] sBlockBytes = (byte[]) metaEntries.get(certFile);
+ try {
+ Certificate[] signerCertChain = JarUtils.verifySignature(
+ new ByteArrayInputStream(sfBytes),
+ new ByteArrayInputStream(sBlockBytes));
+ if (signerCertChain != null) {
+ this.certificates.put(signatureFile, signerCertChain);
+ }
+ } catch (IOException e) {
+ return;
+ } catch (GeneralSecurityException e) {
+ /* [MSG "K00eb", "{0} failed verification of {1}"] */
+ throw new SecurityException(Msg.getString("K00eb", jarName,
+ signatureFile));
+ }
+
+ // Verify manifest hash in .sf file
+ Attributes attributes = new Attributes();
+ HashMap hm = new HashMap();
+ try {
+ new InitManifest(new ByteArrayInputStream(sfBytes), attributes, hm,
+ null, "Signature-Version");
+ } catch (IOException e) {
+ return;
+ }
+
+ boolean createdBySigntool = false;
+ String createdByValue = attributes.getValue("Created-By");
+ if (createdByValue != null) {
+ createdBySigntool = createdByValue.indexOf("signtool") != -1;
+ }
+ byte[] manifest = (byte[]) metaEntries.get(JarFile.MANIFEST_NAME);
+ if (manifest == null)
+ return;
+ String digestAttribute = createdBySigntool ? "-Digest"
+ : "-Digest-Manifest";
+ if (!verify(attributes, digestAttribute, manifest, false)) {
+ Iterator it = hm.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry entry = (Map.Entry) it.next();
+ byte[] chunk = man.getChunk((String) entry.getKey());
+ if (chunk == null)
+ return;
+ if (!verify((Attributes) entry.getValue(), "-Digest", chunk,
+ createdBySigntool))
+ /* [MSG "K00ec", "{0} has invalid digest for {1} in {2}"] */
+ throw new SecurityException(Msg.getString("K00ec",
+ new Object[] { signatureFile, entry.getKey(),
+ jarName }));
+ }
+ }
+ metaEntries.put(signatureFile, null);
+ signatures.put(signatureFile, hm);
+ }
+
+ /**
+ * Associate this verifier with the specified {@link Manifest} object.
+ *
+ * @param mf
+ * a <code>java.util.jar.Manifest</code> object.
+ */
+ void setManifest(Manifest mf) {
+ man = mf;
+ }
+
+ /**
+ * Verifies that the digests stored in the manifest match the decrypted
+ * digests from the .SF file. This indicates the validity of the signing,
+ * not the integrity of the file, as it's digest must be calculated and
+ * verified when its contents are read.
+ *
+ * @param entry
+ * the {@link VerifierEntry} associated with the specified
+ * <code>zipEntry</code>.
+ * @param zipEntry
+ * an entry in the jar file
+ * @throws SecurityException
+ * if the digest value stored in the manifest does <i>not</i>
+ * agree with the decrypted digest as recovered from the
+ * <code>.SF</code> file.
+ * @see #initEntry(String)
+ */
+ void verifySignatures(VerifierEntry entry, ZipEntry zipEntry) {
+ byte[] digest = entry.digest.digest();
+ if (!MessageDigest.isEqual(digest, BASE64Decoder.decode(entry.hash)))
+ /* [MSG "K00ec", "{0} has invalid digest for {1} in {2}"] */
+ throw new SecurityException(Msg.getString("K00ec", new Object[] {
+ JarFile.MANIFEST_NAME, zipEntry.getName(), jarName }));
+ verifiedEntries.put(zipEntry.getName(), entry.certificates);
+ if (zipEntry instanceof JarEntry)
+ ((JarEntry) zipEntry).certificates = (Certificate[]) entry.certificates
+ .clone();
+ }
+
+ /**
+ * Returns a <code>boolean</code> indication of whether or not the
+ * associated jar file is signed.
+ *
+ * @return <code>true</code> if the jar is signed, <code>false</code>
+ * otherwise.
+ */
+ boolean isSignedJar() {
+ return certificates.size() > 0;
+ }
+
+ /*
+ * @param attributes @param entry @param data @param ignoreSecondEndline
+ * @return
+ */
+ private boolean verify(Attributes attributes, String entry, byte[] data,
+ boolean ignoreSecondEndline) {
+ String algorithms = attributes.getValue("Digest-Algorithms");
+ if (algorithms == null)
+ algorithms = "SHA SHA1";
+ StringTokenizer tokens = new StringTokenizer(algorithms);
+ while (tokens.hasMoreTokens()) {
+ String algorithm = tokens.nextToken();
+ String hash = attributes.getValue(algorithm + entry);
+ if (hash == null)
+ continue;
+
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance(algorithm);
+ } catch (NoSuchAlgorithmException e) {
+ continue;
+ }
+ if (ignoreSecondEndline && data[data.length - 1] == '\n'
+ && data[data.length - 2] == '\n') {
+ md.update(data, 0, data.length - 1);
+ } else {
+ md.update(data, 0, data.length);
+ }
+ byte[] b = md.digest();
+ byte[] hashBytes;
+ try {
+ hashBytes = hash.getBytes("ISO8859_1");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e.toString());
+ }
+ return MessageDigest.isEqual(b, BASE64Decoder.decode(hashBytes));
+ }
+ return false;
+ }
+
+ /**
+ * Returns all of the {@link java.security.cert.Certificate} instances that
+ * were used to verify the signature on the jar entry called
+ * <code>name</code>.
+ *
+ * @param name
+ * the name of a jar entry.
+ * @return an array of {@link java.security.cert.Certificate}.
+ */
+ Certificate[] getCertificates(String name) {
+ Certificate[] verifiedCerts = (Certificate[]) verifiedEntries.get(name);
+ if (verifiedCerts == null) {
+ return null;
+ }
+ return (Certificate[]) verifiedCerts.clone();
+ }
+
+ /**
+ * Remove all entries from the internal collection of data held about each
+ * jar entry in the <code>META-INF</code> directory.
+ *
+ * @see #addMetaEntry(String, byte[])
+ */
+ void removeMetaEntries() {
+ metaEntries = null;
+ }
+
+ /**
+ * Returns a <code>Vector</code> of all of the
+ * {@link java.security.cert.Certificate}s that are associated with the
+ * signing of the named signature file.
+ *
+ * @param signatureFileName
+ * the name of a signature file
+ * @param certificates
+ * a <code>Map</code> of all of the certificate chains
+ * discovered so far while attempting to verify the jar that
+ * contains the signature file <code>signatureFileName</code>.
+ * This object will have been previously set in the course of one
+ * or more calls to
+ * {@link #verifyJarSignatureFile(String, String, String, Map, Map)}
+ * where it was passed in as the last argument.
+ * @return all of the <code>Certificate</code> entries for the signer of
+ * the jar whose actions led to the creation of the named signature
+ * file.
+ */
+ public static Vector getSignerCertificates(String signatureFileName,
+ Map certificates) {
+ Vector result = new Vector();
+ Certificate[] certChain = (Certificate[]) certificates
+ .get(signatureFileName);
+ if (certChain != null) {
+ for (int i = 0; i < certChain.length; i++) {
+ result.add(certChain[i]);
+ }// end for all certificates
+ }// end if at least one cert found
+ return result;
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/Manifest.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/Manifest.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/Manifest.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/jar/Manifest.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,312 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.jar;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.security.AccessController;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.ibm.oti.util.PriviAction;
+
+/**
+ * The Manifest class is used to obtain attribute information for a JarFile and
+ * it's entries.
+ *
+ */
+public class Manifest implements Cloneable {
+ private Attributes mainAttributes = new Attributes();
+
+ private HashMap entryAttributes = new HashMap();
+
+ private HashMap chunks;
+
+ /**
+ * Contructs a new Manifest instance.
+ */
+ public Manifest() {
+ }
+
+ /**
+ * Contructs a new Manifest instance using the attributes obtained from is.
+ *
+ * @param is
+ * InputStream to parse for attributes
+ *
+ * @throws IOException
+ * if an IO error occurs while creating this Manifest
+ *
+ */
+ public Manifest(InputStream is) throws IOException {
+ read(is);
+ }
+
+ Manifest(InputStream is, boolean readChunks) throws IOException {
+ if (readChunks)
+ chunks = new HashMap();
+ read(is);
+ }
+
+ /**
+ * Resets the both the mainAttributes as well as the entry Attributes
+ * associated with this Manifest.
+ */
+ public void clear() {
+ entryAttributes.clear();
+ mainAttributes.clear();
+ }
+
+ /**
+ * Returns the Attributes associated with the parameter entry name
+ *
+ * @param name
+ * The name of the entry to obtain Attributes for.
+ * @return The Attributes for the entry or null if the entry does not exist.
+ */
+ public Attributes getAttributes(String name) {
+ return (Attributes) getEntries().get(name);
+ }
+
+ /**
+ * Returns a Map containing the Attributes for each entry in the Manifest.
+ *
+ * @return A Map of entry attributes
+ */
+ public Map getEntries() {
+ return entryAttributes;
+ }
+
+ /**
+ * Returns the main Attributes of the JarFile.
+ *
+ * @return Main Attributes associated with the source JarFile
+ */
+ public Attributes getMainAttributes() {
+ return mainAttributes;
+ }
+
+ /**
+ * Contructs a new Manifest instance. The new instance will have the same
+ * attributes as those found in the parameter Manifest.
+ *
+ * @param man
+ * Manifest instance to obtain attributes from
+ */
+ public Manifest(Manifest man) {
+ mainAttributes = (Attributes) man.mainAttributes.clone();
+ entryAttributes = (HashMap) man.entryAttributes.clone();
+ }
+
+ /**
+ * Creates a copy of this Manifest. The returned Manifest will equal the
+ * Manifest from which it was cloned.
+ *
+ * @return A copy of the receiver.
+ */
+ public Object clone() {
+ return new Manifest(this);
+ }
+
+ static class WriteManifest {
+ private static final int LIMIT = 70;
+
+ private static byte[] sepBuf = new byte[] { '\r', '\n' };
+
+ private static Attributes.Name nameAttribute = new Attributes.Name(
+ "Name", false);
+
+ byte[] oneByte = new byte[1];
+
+ char[] oneChar = new char[1];
+
+ private Charset charset;
+
+ private byte[] outBuf = new byte[LIMIT];
+
+ OutputStream os;
+
+ /**
+ * Writes out a manifest entry.
+ */
+ private void writeEntry(Attributes.Name name, String value)
+ throws IOException {
+ int offset = 0, limit = LIMIT;
+ byte[] out = (name.toString() + ": ").getBytes("ISO8859_1");
+ if (out.length > limit) {
+ while (out.length - offset >= limit) {
+ int len = out.length - offset;
+ if (len > limit)
+ len = limit;
+ if (offset > 0)
+ os.write(' ');
+ os.write(out, offset, len);
+ os.write(sepBuf);
+ offset += len;
+ limit = LIMIT - 1;
+ }
+ }
+ int size = out.length - offset;
+ System.arraycopy(out, offset, outBuf, 0, size);
+ for (int i = 0; i < value.length(); i++) {
+ oneChar[0] = value.charAt(i);
+ byte[] buf;
+ if (oneChar[0] < 128 || charset == null) {
+ oneByte[0] = (byte) oneChar[0];
+ buf = oneByte;
+ } else
+ buf = charset.encode(CharBuffer.wrap(oneChar, 0, 1)).array();
+ if (size + buf.length > limit) {
+ if (limit != LIMIT)
+ os.write(' ');
+ os.write(outBuf, 0, size);
+ os.write(sepBuf);
+ limit = LIMIT - 1;
+ size = 0;
+ }
+ if (buf.length == 1)
+ outBuf[size] = buf[0];
+ else
+ System.arraycopy(buf, 0, outBuf, size, buf.length);
+ size += buf.length;
+ }
+ if (size > 0) {
+ if (limit != LIMIT)
+ os.write(' ');
+ os.write(outBuf, 0, size);
+ os.write(sepBuf);
+ }
+ }
+
+ /**
+ * Writes out the attribute information of the receiver to the specified
+ * OutputStream
+ *
+ *
+ * @param manifest
+ * the attribute information of the receiver
+ * @param out
+ * The OutputStream to write to.
+ *
+ * @throws IOException
+ * If an error occurs writing the Manifest
+ */
+ void write(Manifest manifest, OutputStream out) throws IOException {
+ os = out;
+ String encoding = (String) AccessController
+ .doPrivileged(new PriviAction("manifest.write.encoding"));
+ if (encoding != null) {
+ if ("".equals(encoding))
+ encoding = "UTF8";
+ charset = Charset.forName(encoding);
+ }
+ String version = manifest.mainAttributes
+ .getValue(Attributes.Name.MANIFEST_VERSION);
+ if (version != null) {
+ writeEntry(Attributes.Name.MANIFEST_VERSION, version);
+ Iterator entries = manifest.mainAttributes.keySet().iterator();
+ while (entries.hasNext()) {
+ Attributes.Name name = (Attributes.Name) entries.next();
+ if (!name.equals(Attributes.Name.MANIFEST_VERSION))
+ writeEntry(name, manifest.mainAttributes.getValue(name));
+ }
+ }
+ os.write(sepBuf);
+ Iterator i = manifest.entryAttributes.keySet().iterator();
+ while (i.hasNext()) {
+ String key = (String) i.next();
+ writeEntry(nameAttribute, key);
+ Attributes attrib = (Attributes) manifest.entryAttributes
+ .get(key);
+ Iterator entries = attrib.keySet().iterator();
+ while (entries.hasNext()) {
+ Attributes.Name name = (Attributes.Name) entries.next();
+ writeEntry(name, attrib.getValue(name));
+ }
+ os.write(sepBuf);
+ }
+ }
+ }
+
+ /**
+ * Writes out the attribute information of the receiver to the specified
+ * OutputStream
+ *
+ * @param os
+ * The OutputStream to write to.
+ *
+ * @throws IOException
+ * If an error occurs writing the Manifest
+ */
+ public void write(OutputStream os) throws IOException {
+ new WriteManifest().write(this, os);
+ }
+
+ /**
+ * Contructs a new Manifest instance obtaining Attribute information from
+ * the paramter InputStream.
+ *
+ * @param is
+ * The InputStream to read from
+ * @throws IOException
+ * If an error occurs reading the Manifest.
+ */
+ public void read(InputStream is) throws IOException {
+ new InitManifest(is, mainAttributes, entryAttributes, chunks, null);
+ }
+
+ /**
+ * Returns the hashCode for this instance.
+ *
+ * @return This Manifest's hashCode
+ */
+ public int hashCode() {
+ return mainAttributes.hashCode() ^ entryAttributes.hashCode();
+ }
+
+ /**
+ * Determines if the receiver is equal to the parameter Object. Two
+ * Manifests are equal if they have identical main Attributes as well as
+ * identical entry Attributes.
+ *
+ * @param o
+ * The Object to compare against.
+ * @return <code>true</code> if the manifests are equal,
+ * <code>false</code> otherwise
+ */
+ public boolean equals(Object o) {
+ if (o == null)
+ return false;
+ if (o.getClass() != this.getClass())
+ return false;
+ if (!mainAttributes.equals(((Manifest) o).mainAttributes))
+ return false;
+ return entryAttributes.equals(((Manifest) o).entryAttributes);
+ }
+
+ byte[] getChunk(String name) {
+ return (byte[]) chunks.get(name);
+ }
+
+ void removeChunks() {
+ chunks = null;
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Adler32.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Adler32.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Adler32.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Adler32.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,85 @@
+/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+
+/**
+ * The Adler32 class is used to compute the Adler32 Checksum from a set of data.
+ */
+public class Adler32 implements java.util.zip.Checksum {
+
+ private long adler = 1;
+
+ /**
+ * Returns the Adler32 checksum for all input received
+ *
+ * @return The checksum for this instance
+ */
+ public long getValue() {
+ return adler;
+ }
+
+ /**
+ * Reset this instance to its initial checksum
+ */
+ public void reset() {
+ adler = 1;
+ }
+
+ /**
+ * Update this Adler32 checksum using val.
+ *
+ * @param i
+ * byte to update checksum with
+ */
+ public void update(int i) {
+ adler = updateByteImpl(i, adler);
+ }
+
+ /**
+ * Update this Adler32 checksum using the contents of buf.
+ *
+ * @param buf
+ * bytes to update checksum with
+ */
+ public void update(byte[] buf) {
+ update(buf, 0, buf.length);
+ }
+
+ /**
+ * Update this Adler32 checksum with the contents of buf, starting from
+ * offset and using nbytes of data.
+ *
+ * @param buf
+ * bufffer to obtain dat from
+ * @param off
+ * offset i buf to conpy from
+ * @param nbytes
+ * number of bytes from buf to use
+ */
+ public void update(byte[] buf, int off, int nbytes) {
+ // avoid int overflow, check null buf
+ if (off <= buf.length && nbytes >= 0 && off >= 0
+ && buf.length - off >= nbytes)
+ adler = updateImpl(buf, off, nbytes, adler);
+ else
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ private native long updateImpl(byte[] buf, int off, int nbytes, long adler1);
+
+ private native long updateByteImpl(int val, long adler1);
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CRC32.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CRC32.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CRC32.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CRC32.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,86 @@
+/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+
+/**
+ * The CRC32 class is used to compute a CRC32 Checksum from a set of data.
+ */
+public class CRC32 implements java.util.zip.Checksum {
+
+ private long crc = 0L;
+
+ long tbytes = 0L;
+
+ /**
+ * Returns the CRC32 Checksum for all input received.
+ *
+ * @return The checksum for this instance
+ */
+ public long getValue() {
+ return crc;
+ }
+
+ /**
+ * Returns the CRC32 checksum to it initial state.
+ */
+ public void reset() {
+ tbytes = crc = 0;
+
+ }
+
+ /**
+ * Updates this Checksum with value val
+ */
+ public void update(int val) {
+ crc = updateByteImpl((byte) val, crc);
+ }
+
+ /**
+ * Updates this Checksum with the bytes contained in buffer buf.
+ *
+ * @param buf
+ * Buffer to update Checksum
+ */
+ public void update(byte[] buf) {
+ update(buf, 0, buf.length);
+ }
+
+ /**
+ * Updates this Checksum with nbytes of data from buffer buf, starting at
+ * offset off.
+ *
+ * @param buf
+ * Buffer to update Checksum
+ * @param off
+ * Offest in buf to obtain data from
+ * @param nbytes
+ * Number of bytes to read from buf
+ */
+ public void update(byte[] buf, int off, int nbytes) {
+ // avoid int overflow, check null buf
+ if (off <= buf.length && nbytes >= 0 && off >= 0
+ && buf.length - off >= nbytes) {
+ tbytes += nbytes;
+ crc = updateImpl(buf, off, nbytes, crc);
+ } else
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ private native long updateImpl(byte[] buf, int off, int nbytes, long crc1);
+
+ private native long updateByteImpl(byte val, long crc1);
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CheckedInputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CheckedInputStream.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CheckedInputStream.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CheckedInputStream.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,106 @@
+/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * The CheckedInputStream class is used to maintain a running Checksum of all
+ * data read from a stream.
+ */
+public class CheckedInputStream extends java.io.FilterInputStream {
+
+ private Checksum check;
+
+ /**
+ * Constructs a new CheckedInputStream on InputStream is. The Checksum will
+ * be calculated using the algorithm implemented by csum.
+ *
+ * @param is
+ * InputStream to calculate checksum from
+ * @param csum
+ * Type of Checksum to calculate
+ */
+ public CheckedInputStream(InputStream is, Checksum csum) {
+ super(is);
+ check = csum;
+ }
+
+ /**
+ * Reads a byte of data from the underlying stream and recomputes the
+ * Checksum with the byte data.
+ *
+ * @return -1 if end of stream, a single byte value otherwise
+ */
+ public int read() throws IOException {
+ int x = in.read();
+ if (x != -1) {
+ check.update(x);
+ }
+ return x;
+ }
+
+ /**
+ * Reads up to nbytes of data from the underlying stream, storing it in buf,
+ * starting at offset off. The Checksum is updated with the bytes read.
+ *
+ * @return Number of bytes read, -1 if end of stream
+ */
+ public int read(byte[] buf, int off, int nbytes) throws IOException {
+ int x = in.read(buf, off, nbytes);
+ if (x != -1)
+ check.update(buf, off, x);
+ return x;
+ }
+
+ /**
+ * Returns the Checksum calculated on the stream thus far.
+ *
+ * @return A java.util.zip.Checksum
+ */
+ public Checksum getChecksum() {
+ return check;
+ }
+
+ /**
+ * Skip upto nbytes of data on the underlying stream. Any skipped bytes are
+ * added to the running Checksum value.
+ *
+ * @param nbytes
+ * long Number of bytes to skip
+ * @return Number of bytes skipped
+ */
+ public long skip(long nbytes) throws IOException {
+ if (nbytes < 1) {
+ return 0;
+ }
+ long skipped = 0;
+ byte[] b = new byte[2048];
+ int x, v;
+ while (skipped != nbytes) {
+ x = in.read(b, 0,
+ (v = (int) (nbytes - skipped)) > b.length ? b.length : v);
+ if (x == -1) {
+ return skipped;
+ }
+ check.update(b, 0, x);
+ skipped += x;
+ }
+ return skipped;
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CheckedOutputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CheckedOutputStream.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CheckedOutputStream.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/CheckedOutputStream.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,86 @@
+/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The CheckedOutputStream class is used to maintain a running Checksum of all
+ * data written to a stream.
+ */
+public class CheckedOutputStream extends java.io.FilterOutputStream {
+
+ private Checksum check;
+
+ /**
+ * Constructs a new CheckedOutputStream on OutputStream os. The Checksum
+ * will be calculated using the algorithm implemented by csum.
+ *
+ * @param os
+ * OutputStream to calculate checksum from
+ * @param cs
+ * Type of Checksum to calculate
+ */
+ public CheckedOutputStream(OutputStream os, Checksum cs) {
+ super(os);
+ check = cs;
+ }
+
+ /**
+ * Returns the Checksum calculated on the stream thus far.
+ *
+ * @return A java.util.zip.Checksum
+ */
+ public Checksum getChecksum() {
+ return check;
+ }
+
+ /**
+ * Writes byte value val to the underlying stream. The Checksum is updated
+ * with val.
+ *
+ * @param val
+ * Value of the byte to write out
+ *
+ * @throws IOException
+ * if an IO error has occured
+ */
+ public void write(int val) throws IOException {
+ out.write(val);
+ check.update(val);
+ }
+
+ /**
+ * Writes nbytes of data from buf starting at offset off to the underlying
+ * stream. The Checksum is updated with the bytes written.
+ *
+ * @param buf
+ * data to write out
+ * @param off
+ * the start offset of the data
+ * @param nbytes
+ * number of bytes to write out
+ *
+ * @throws IOException
+ * if an IO error has occured
+ */
+ public void write(byte[] buf, int off, int nbytes) throws IOException {
+ out.write(buf, off, nbytes);
+ check.update(buf, off, nbytes);
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Checksum.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Checksum.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Checksum.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Checksum.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,27 @@
+/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+
+public interface Checksum {
+ public long getValue();
+
+ public void reset();
+
+ public void update(int val);
+
+ public void update(byte[] buf, int off, int nbytes);
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/DataFormatException.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/DataFormatException.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/DataFormatException.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/DataFormatException.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,43 @@
+/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+
+/**
+ * DataFormatException is used to indicate an error in the format of a
+ * particular data stream.
+ */
+public class DataFormatException extends Exception {
+
+ /**
+ * Constructs a new instance of this class with its walkback filled in.
+ *
+ */
+ public DataFormatException() {
+ super();
+ }
+
+ /**
+ * Constructs a new instance of this class with its walkback and message
+ * filled in.
+ *
+ * @param detailMessage
+ * String The detail message for the exception.
+ */
+ public DataFormatException(String detailMessage) {
+ super(detailMessage);
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Deflater.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Deflater.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Deflater.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/Deflater.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,376 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+
+/**
+ * The Deflater class is used to compress bytes using the DEFLATE compressionn
+ * algorithm. Deflation is performed by the ZLIB compression library.
+ *
+ * @see DeflaterOutputStream
+ * @see Inflater
+ */
+public class Deflater {
+
+ public static final int BEST_COMPRESSION = 9;
+
+ public static final int BEST_SPEED = 1;
+
+ public static final int DEFAULT_COMPRESSION = -1;
+
+ public static final int DEFAULT_STRATEGY = 0;
+
+ public static final int DEFLATED = 8;
+
+ public static final int FILTERED = 1;
+
+ public static final int HUFFMAN_ONLY = 2;
+
+ public static final int NO_COMPRESSION = 0;
+
+ private static final int Z_NO_FLUSH = 0;
+
+ private static final int Z_FINISH = 4;
+
+ private int flushParm = Z_NO_FLUSH;
+
+ private boolean noHeader = false;
+
+ private boolean finished = false;
+
+ int compressLevel = DEFAULT_COMPRESSION;
+
+ int strategy = DEFAULT_STRATEGY;
+
+ long streamHandle = -1;
+
+ byte[] inputBuffer;
+
+ int inRead = 0, inLength = 0;
+
+ // Fill in the JNI id caches
+ private static native void oneTimeInitialization();
+
+ static {
+ oneTimeInitialization();
+ }
+
+ /**
+ * Deflates data into the supplied buffer
+ *
+ * @param buf
+ * buffer to store compressed data
+ *
+ * @return number of bytes of compressed data stored
+ *
+ */
+ public int deflate(byte[] buf) {
+ return deflate(buf, 0, buf.length);
+ }
+
+ /**
+ * Deflates data into the supplied buffer using the region from off to
+ * nbytes - 1.
+ *
+ * @param buf
+ * buffer to store compressed data
+ * @param off
+ * offset inf buf to start storing data
+ * @param nbytes
+ * number of bytes of compressed data to store in buf
+ *
+ * @return number of bytes of compresed data stored
+ *
+ */
+ public synchronized int deflate(byte[] buf, int off, int nbytes) {
+ if (streamHandle == -1)
+ throw new IllegalStateException();
+ // avoid int overflow, check null buf
+ if (off <= buf.length && nbytes >= 0 && off >= 0
+ && buf.length - off >= nbytes)
+ return deflateImpl(buf, off, nbytes, streamHandle, flushParm);
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ private native synchronized int deflateImpl(byte[] buf, int off,
+ int nbytes, long handle, int flushParm1);
+
+ private synchronized native void endImpl(long handle);
+
+ /**
+ * Frees all resources held onto by this Deflater. Any unused input or ouput
+ * is discarded. This is also called from the finalize method.
+ *
+ * @see #finalize
+ */
+ public synchronized void end() {
+ if (streamHandle != -1) {
+ endImpl(streamHandle);
+ inputBuffer = null;
+ streamHandle = -1;
+ }
+ }
+
+ protected void finalize() {
+ end();
+ }
+
+ /**
+ * Indicates to the Deflater that all uncompressed input has been provided
+ * to it.
+ *
+ * @see #finished
+ */
+ public synchronized void finish() {
+ flushParm = Z_FINISH;
+ }
+
+ /**
+ * Returns whether or not all provided data has been successfully
+ * compressed.
+ *
+ * @return true if all data has been compressed, false otherwise
+ */
+ public synchronized boolean finished() {
+ return finished;
+ }
+
+ /**
+ * Returns the Adler32 checksum of uncompressed data currently read. If a
+ * preset dictionary is used getAdler() will return the Adler32 checksum of
+ * the dictionary used.
+ *
+ * @return The Adler32 checksum of uncompressed data or preset dictionary if
+ * used
+ *
+ * @see #setDictionary(byte[])
+ * @see #setDictionary(byte[], int, int)
+ */
+ public synchronized int getAdler() {
+ if (streamHandle == -1)
+ throw new IllegalStateException();
+
+ return getAdlerImpl(streamHandle);
+ }
+
+ private synchronized native int getAdlerImpl(long handle);
+
+ /**
+ * Returns the total number of bytes of input consumed by the deflater.
+ *
+ * @return number of bytes of input read.
+ */
+ public synchronized int getTotalIn() {
+ if (streamHandle == -1)
+ throw new IllegalStateException();
+
+ return getTotalInImpl(streamHandle);
+ }
+
+ private native synchronized int getTotalInImpl(long handle);
+
+ /**
+ * Returns the total number of compressed bytes output nby this Deflater.
+ *
+ * @return number of compressed bytes output.
+ */
+ public synchronized int getTotalOut() {
+ if (streamHandle == -1)
+ throw new IllegalStateException();
+
+ return getTotalOutImpl(streamHandle);
+ }
+
+ private synchronized native int getTotalOutImpl(long handle);
+
+ /**
+ * Indicates whether or not all bytes of uncompressed input have been
+ * consumed by the Deflater. If needsInput() answers true setInput() must be
+ * called before deflation can continue. If all bytes of uncompressed data
+ * have been provided to the Deflater finish() must be called to ensure the
+ * compressed data is output.
+ *
+ * @return True if input is reuired for deflation to continue, false
+ * otherwise
+ * @see #finished()
+ * @see #setInput(byte[])
+ * @see #setInput(byte[], int, int)
+ */
+ public boolean needsInput() {
+ if (inputBuffer == null)
+ return true;
+ return inRead == inLength;
+ }
+
+ /**
+ * Resets the <code>Deflater</code> to accept new input without affecting
+ * any previously made settings for the compression strategy or level. This
+ * operation <i>must</i> be called after <code>finished()</code> returns
+ * <code>true</code> if the <code>Deflater</code> is to be reused.
+ *
+ * @see #finished
+ */
+ public synchronized void reset() {
+ if (streamHandle == -1)
+ throw new NullPointerException();
+
+ flushParm = Z_NO_FLUSH;
+ finished = false;
+ resetImpl(streamHandle);
+ inputBuffer = null;
+ }
+
+ private native synchronized void resetImpl(long handle);
+
+ public void setDictionary(byte[] buf) {
+ setDictionary(buf, 0, buf.length);
+ }
+
+ /**
+ * Sets the dictionary to be used for compression by this Deflater.
+ * setDictionary() can only be called if this Deflater supports the writing
+ * of ZLIB headers. This is the default behaviour but can be overridden
+ * using Deflater(int, boolean).
+ *
+ * @see Deflater#Deflater(int, boolean)
+ */
+ public synchronized void setDictionary(byte[] buf, int off, int nbytes) {
+ if (streamHandle == -1)
+ throw new IllegalStateException();
+ // avoid int overflow, check null buf
+ if (off <= buf.length && nbytes >= 0 && off >= 0
+ && buf.length - off >= nbytes)
+ setDictionaryImpl(buf, off, nbytes, streamHandle);
+ else
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ private native synchronized void setDictionaryImpl(byte[] buf, int off,
+ int nbytes, long handle);
+
+ /**
+ * Sets the input buffer the Deflater will use to extract uncompressed bytes
+ * for later compression.
+ */
+ public void setInput(byte[] buf) {
+ setInput(buf, 0, buf.length);
+ }
+
+ /**
+ * Sets the input buffer the Deflater will use to extract uncompressed bytes
+ * for later compression. Input will be taken from the buffer region
+ * starting at off and ending at nbytes - 1.
+ */
+ public synchronized void setInput(byte[] buf, int off, int nbytes) {
+ if (streamHandle == -1)
+ throw new IllegalStateException();
+ // avoid int overflow, check null buf
+ if (off <= buf.length && nbytes >= 0 && off >= 0
+ && buf.length - off >= nbytes) {
+ inLength = nbytes;
+ inRead = 0;
+ if (inputBuffer == null)
+ setLevelsImpl(compressLevel, strategy, streamHandle);
+ inputBuffer = buf;
+ setInputImpl(buf, off, nbytes, streamHandle);
+ } else
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ private native synchronized void setLevelsImpl(int level, int strategy,
+ long handle);
+
+ private native synchronized void setInputImpl(byte[] buf, int off,
+ int nbytes, long handle);
+
+ /**
+ * Sets the compression level to be used when compressing data. The
+ * compression level must be a value between 0 and 9. This value must be set
+ * prior to calling setInput().
+ *
+ * @param level
+ * compression level to use
+ * @exception IllegalArgumentException
+ * If the compression level is invalid.
+ */
+ public synchronized void setLevel(int level) {
+ if (level < DEFAULT_COMPRESSION || level > BEST_COMPRESSION)
+ throw new IllegalArgumentException();
+ if (inputBuffer != null)
+ throw new IllegalStateException();
+ compressLevel = level;
+ }
+
+ /**
+ * Sets the compression strategy to be used. The strategy must be one of
+ * FILTERED, HUFFMAN_ONLY or DEFAULT_STRATEGY.This value must be set prior
+ * to calling setInput().
+ *
+ * @param strategy
+ * compression strategy to use
+ * @exception IllegalArgumentException
+ * If the strategy specified is not one of FILTERED,
+ * HUFFMAN_ONLY or DEFAULT_STRATEGY.
+ */
+ public synchronized void setStrategy(int strategy) {
+ if (strategy < DEFAULT_STRATEGY || strategy > HUFFMAN_ONLY)
+ throw new IllegalArgumentException();
+ if (inputBuffer != null)
+ throw new IllegalStateException();
+ this.strategy = strategy;
+ }
+
+ /**
+ * Constructs a new Deflater instance with default compression level and
+ * strategy.
+ */
+ public Deflater() {
+ this(DEFAULT_COMPRESSION, false);
+ }
+
+ /**
+ * Constructs a new Deflater instance with compression level level and
+ * default compression strategy. If the noHeader parameter is specified then
+ * no ZLIB header will be written as part of the compressed output. The
+ * compression level specified must be between 0 and 9.
+ *
+ * @param level
+ * the compression level to use
+ * @param noHeader
+ * if true do not write the ZLIB header
+ */
+ public Deflater(int level, boolean noHeader) {
+ if (level < DEFAULT_COMPRESSION || level > BEST_COMPRESSION)
+ throw new IllegalArgumentException();
+ compressLevel = level;
+ this.noHeader = noHeader;
+ streamHandle = createStream(compressLevel, strategy, noHeader);
+ }
+
+ /**
+ * Constructs a new Deflater instance with compression level level and
+ * default compression strategy. THe compression level provided must be
+ * between 0 and 9.
+ *
+ * @param level
+ * the compression level to use
+ */
+ public Deflater(int level) {
+ this(level, false);
+ }
+
+ private native long createStream(int level, int strategy1, boolean noHeader1);
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/DeflaterOutputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/DeflaterOutputStream.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/DeflaterOutputStream.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/DeflaterOutputStream.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,170 @@
+/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.ibm.oti.util.Msg;
+
+/**
+ * The DeflaterOutputStream class implements a stream filter for the writing of
+ * compressed data to a stream. Compression is performed by an instance of
+ * Deflater.
+ */
+public class DeflaterOutputStream extends FilterOutputStream {
+ static final int BUF_SIZE = 512;
+
+ protected byte[] buf;
+
+ protected Deflater def;
+
+ boolean done = false;
+
+ /**
+ * Constructs a new DeflaterOutputStream instance using os as the underlying
+ * stream. The provided Deflater instance will be used to compress data.
+ *
+ * @param os
+ * OutputStream to receive compressed data
+ * @param def
+ * Deflater to perform compression
+ */
+ public DeflaterOutputStream(OutputStream os, Deflater def) {
+ this(os, def, BUF_SIZE);
+ }
+
+ /**
+ * Constructs a new DeflaterOutputStream instance using os as the underlying
+ * stream.
+ *
+ * @param os
+ * OutputStream to receive compressed data
+ */
+ public DeflaterOutputStream(OutputStream os) {
+ this(os, new Deflater());
+ }
+
+ /**
+ * Constructs a new DeflaterOutputStream instance using os as the underlying
+ * stream. The provided Deflater instance will be used to compress data. The
+ * internal buffer for storing compressed data will be of size bsize.
+ *
+ * @param os
+ * OutputStream to receive compressed data
+ * @param def
+ * Deflater to perform compression
+ * @param bsize
+ * size of internal compression buffer
+ */
+ public DeflaterOutputStream(OutputStream os, Deflater def, int bsize) {
+ super(os);
+ if (os == null || def == null)
+ throw new NullPointerException();
+ if (bsize <= 0)
+ throw new IllegalArgumentException();
+ this.def = def;
+ buf = new byte[bsize];
+ }
+
+ /**
+ * Compress the data in the input buffer and write it to the underlying
+ * stream.
+ *
+ * @exception java.io.IOException
+ * If an error occurs during deflation.
+ */
+ protected void deflate() throws IOException {
+ int x = 0;
+ do {
+ x = def.deflate(buf);
+ out.write(buf, 0, x);
+ } while (!def.needsInput());
+ }
+
+ /**
+ * Writes any unwritten compressed data to the underlying stream, the closes
+ * all underlying streams. This stream can no longer be used after close()
+ * has been called.
+ *
+ * @exception java.io.IOException
+ * If an error occurs during close.
+ */
+ public void close() throws IOException {
+ if (!def.finished())
+ finish();
+ def.end();
+ out.close();
+ }
+
+ /**
+ * Write any unwritten data to the underlying stream. Do not close the
+ * stream. This allows subsequent Deflater's to write to the same stream.
+ * This Deflater cannot be used again.
+ *
+ * @exception java.io.IOException
+ * If an error occurs.
+ */
+ public void finish() throws IOException {
+ if (done)
+ return;
+ def.finish();
+ int x = 0;
+ while (!def.finished()) {
+ if (def.needsInput())
+ def.setInput(buf, 0, 0);
+ x = def.deflate(buf);
+ out.write(buf, 0, x);
+ }
+ done = true;
+ }
+
+ public void write(int i) throws IOException {
+ byte[] b = new byte[1];
+ b[0] = (byte) i;
+ write(b, 0, 1);
+ }
+
+ /**
+ * Compress nbytes of data from buf starting at off and write it to the
+ * underlying stream.
+ *
+ * @param buf
+ * Buffer of data to compress
+ * @param off
+ * offset in buffer to extract data from
+ * @param nbytes
+ * Number of bytes of data to compress and write
+ *
+ * @exception java.io.IOException
+ * If an error occurs during writing.
+ */
+ public void write(byte[] buffer, int off, int nbytes) throws IOException {
+ if (done)
+ throw new IOException(Msg.getString("K0007"));
+ // avoid int overflow, check null buf
+ if (off <= buffer.length && nbytes >= 0 && off >= 0
+ && buffer.length - off >= nbytes) {
+ if (!def.needsInput())
+ throw new IOException();
+ def.setInput(buffer, off, nbytes);
+ deflate();
+ } else
+ throw new ArrayIndexOutOfBoundsException();
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/GZIPInputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/GZIPInputStream.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/GZIPInputStream.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/GZIPInputStream.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,189 @@
+/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.ibm.oti.util.Msg;
+
+/**
+ * The GZIPInputStream class is used to read data stored in the GZIP format.
+ */
+public class GZIPInputStream extends java.util.zip.InflaterInputStream {
+ protected CRC32 crc = new CRC32();
+
+ protected boolean eos = false;
+
+ public final static int GZIP_MAGIC = 0x8b1f;
+
+ private static final int FHCRC = 2;
+
+ private static final int FEXTRA = 4;
+
+ private static final int FNAME = 8;
+
+ private static final int FCOMMENT = 16;
+
+ /**
+ * Construct a GZIPInputStream to read from GZIP data from the underlying
+ * stream
+ *
+ * @param is
+ * InputStream to read data from
+ */
+ public GZIPInputStream(InputStream is) throws IOException {
+ this(is, BUF_SIZE);
+ }
+
+ /**
+ * Construct a GZIPInputStream to read from GZIP data from the underlying
+ * stream. Set the internal buffer size to size
+ *
+ * @param is
+ * InputStream to read data from
+ * @param size
+ * Internal read buffer size
+ */
+ public GZIPInputStream(InputStream is, int size) throws IOException {
+ super(is, new Inflater(true), size);
+ byte[] header = new byte[10];
+ readFully(header, 0, header.length);
+ if (getShort(header, 0) != GZIP_MAGIC)
+ throw new IOException(Msg.getString("K0020"));
+ int flags = header[3];
+ boolean hcrc = (flags & FHCRC) != 0;
+ if (hcrc)
+ crc.update(header, 0, header.length);
+ if ((flags & FEXTRA) != 0) {
+ readFully(header, 0, 2);
+ if (hcrc)
+ crc.update(header, 0, 2);
+ int length = getShort(header, 0);
+ while (length > 0) {
+ int max = length > buf.length ? buf.length : length;
+ int result = in.read(buf, 0, max);
+ if (result == -1)
+ throw new EOFException();
+ if (hcrc)
+ crc.update(buf, 0, result);
+ length -= result;
+ }
+ }
+ if ((flags & FNAME) != 0)
+ readZeroTerminated(hcrc);
+ if ((flags & FCOMMENT) != 0)
+ readZeroTerminated(hcrc);
+ if (hcrc) {
+ readFully(header, 0, 2);
+ int crc16 = getShort(header, 0);
+ if ((crc.getValue() & 0xffff) != crc16)
+ throw new IOException(Msg.getString("K0077"));
+ crc.reset();
+ }
+ }
+
+ private long getLong(byte[] buffer, int off) {
+ long l = 0;
+ l |= (buffer[off] & 0xFF);
+ l |= (buffer[off + 1] & 0xFF) << 8;
+ l |= (buffer[off + 2] & 0xFF) << 16;
+ l |= ((long) (buffer[off + 3] & 0xFF)) << 24;
+ return l;
+ }
+
+ private int getShort(byte[] buffer, int off) {
+ return (buffer[off] & 0xFF) | ((buffer[off + 1] & 0xFF) << 8);
+ }
+
+ /**
+ * Reads and decompresses GZIP data from the underlying stream into buf.
+ *
+ * @param buffer
+ * Buffer to receive data
+ * @param off
+ * Offset in buffer to store data
+ * @param nbytes
+ * Number of bytes to read
+ */
+ public int read(byte[] buffer, int off, int nbytes) throws IOException {
+ // avoid int overflow, check null buffer
+ if (off <= buffer.length && nbytes >= 0 && off >= 0
+ && buffer.length - off >= nbytes) {
+ int val = super.read(buffer, off, nbytes);
+ if (val != -1)
+ crc.update(buffer, off, val);
+ else if (!eos) {
+ eos = true;
+ // Get non-compressed bytes read by fill
+ int size = 0;
+ byte[] b = new byte[8];
+ int inB = inf.getTotalIn();
+ if (inB > 0) {
+ int diff = inB % buf.length;
+ if (diff != 0 || len != buf.length) {
+ size = len - diff;
+ if (size > b.length)
+ size = b.length;
+ System.arraycopy(buf, diff, b, 0, size);
+ }
+ }
+ readFully(b, size, b.length - size);
+ if (getLong(b, 0) != crc.getValue())
+ throw new IOException(Msg.getString("K0077"));
+ if ((int) getLong(b, 4) != inf.getTotalOut())
+ throw new IOException(Msg.getString("K00ae"));
+ }
+ return val;
+ }
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ /**
+ * Closes this stream and any underlying streams.
+ */
+ public void close() throws IOException {
+ eos = true;
+ super.close();
+ }
+
+ private void readFully(byte[] buffer, int offset, int length)
+ throws IOException {
+ int result;
+ while (length > 0) {
+ result = in.read(buffer, offset, length);
+ if (result == -1)
+ throw new EOFException();
+ offset += result;
+ length -= result;
+ }
+ }
+
+ private void readZeroTerminated(boolean hcrc) throws IOException {
+ int result;
+ while ((result = in.read()) > 0) {
+ if (hcrc)
+ crc.update(result);
+ }
+ if (result == -1)
+ throw new EOFException();
+ // Add the zero
+ if (hcrc)
+ crc.update(result);
+ }
+}
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/GZIPOutputStream.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/GZIPOutputStream.java?rev=350181&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/GZIPOutputStream.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/ibm_core/java-src/archive/src/java/util/zip/GZIPOutputStream.java Wed Nov 30 21:29:27 2005
@@ -0,0 +1,102 @@
+/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util.zip;
+
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The GZIPOutputStream class is used to write data to a stream in the GZIP
+ * storage format.
+ */
+public class GZIPOutputStream extends DeflaterOutputStream {
+
+ protected CRC32 crc = new CRC32();
+
+ /**
+ * Construct a new GZIPOutputStream to write data in GZIP format to the
+ * underlying stream.
+ *
+ * @param os
+ * OutputStream to write to
+ */
+ public GZIPOutputStream(OutputStream os) throws IOException {
+ this(os, BUF_SIZE);
+ }
+
+ /**
+ * Construct a new GZIPOutputStream to write data in GZIP format to the
+ * underlying stream. Set the internal compression buffer to sise size.
+ *
+ * @param os
+ * OutputStream to write to
+ * @param size
+ * Internal buffer size
+ */
+ public GZIPOutputStream(OutputStream os, int size) throws IOException {
+ super(os, new Deflater(Deflater.DEFAULT_COMPRESSION, true), size);
+ writeShort(GZIPInputStream.GZIP_MAGIC);
+ out.write(Deflater.DEFLATED);
+ out.write(0); // flags
+ writeLong(0); // mod time
+ out.write(0); // extra flags
+ out.write(0); // operating system
+ }
+
+ /**
+ * Indicates to the stream that all data has been written out, and any GZIP
+ * terminal data can now be output.
+ */
+ public void finish() throws IOException {
+ super.finish();
+ writeLong(crc.getValue());
+ writeLong(crc.tbytes);
+ }
+
+ /**
+ * Close this stream and any underlying streams.
+ */
+ public void close() throws IOException {
+ if (!done)
+ finish();
+ super.close();
+ }
+
+ /**
+ * Write up to nbytes of data from buf, starting at offset off, to the
+ * underlying stream in GZIP format.
+ */
+ public void write(byte[] buffer, int off, int nbytes) throws IOException {
+ super.write(buffer, off, nbytes);
+ crc.update(buffer, off, nbytes);
+ }
+
+ private int writeShort(int i) throws IOException {
+ out.write(i & 0xFF);
+ out.write((i >> 8) & 0xFF);
+ return i;
+ }
+
+ private long writeLong(long i) throws IOException {
+ // Write out the long value as an unsigned int
+ out.write((int) (i & 0xFF));
+ out.write((int) (i >> 8) & 0xFF);
+ out.write((int) (i >> 16) & 0xFF);
+ out.write((int) (i >> 24) & 0xFF);
+ return i;
+ }
+}