harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ndbe...@apache.org
Subject svn commit: r446478 [5/11] - in /incubator/harmony/enhanced/classlib/trunk/modules/archive: ./ .settings/ META-INF/ make/ src/main/java/java/util/jar/ src/main/java/java/util/zip/ src/main/java/org/apache/harmony/archive/internal/pack200/ src/main/nati...
Date Fri, 15 Sep 2006 02:40:36 GMT
Modified: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipFile.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipFile.java?view=diff&rev=446478&r1=446477&r2=446478
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipFile.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipFile.java Thu Sep 14 19:40:33 2006
@@ -1,258 +1,258 @@
-/* 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;
-
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-
-import org.apache.harmony.luni.util.Msg;
-import org.apache.harmony.luni.util.Util;
-
-/**
- * ZipFile is used to read zip entries and their associated data from zip files.
- * 
- * @see ZipInputStream
- * @see ZipEntry
- */
-
-public class ZipFile implements ZipConstants {
-
-	private String fileName;
-
-	long descriptor = -1;
-
-	private int size = -1;
-
-	private int mode;
-	static {
-		ntvinit();
-	}
-
-	/**
-	 * Open zip file for read.
-	 */
-	public static final int OPEN_READ = 1;
-
-	/**
-	 * Delete zip file when closed.
-	 */
-	public static final int OPEN_DELETE = 4;
-
-	/**
-	 * Constructs a new ZipFile opened on the specified File.
-	 * 
-	 * @param file
-	 *            the File
-	 */
-	public ZipFile(File file) throws ZipException, IOException {
-		this(file.getPath());
-	}
-
-	/**
-	 * Constructs a new ZipFile opened on the specified File using the specified
-	 * mode.
-	 * 
-	 * @param file
-	 *            the File
-	 * @param mode
-	 *            the mode to use, either OPEN_READ or OPEN_READ | OPEN_DELETE
-	 */
-	public ZipFile(File file, int mode) throws IOException {
-		if (mode == OPEN_READ || mode == (OPEN_READ | OPEN_DELETE)) {
-			fileName = file.getPath();
-			SecurityManager security = System.getSecurityManager();
-			if (security != null) {
-				security.checkRead(fileName);
-				if ((mode & OPEN_DELETE) != 0) {
-					security.checkDelete(fileName);
-				}
-			}
-			this.mode = mode;
-			openZip(fileName);
-		} else
-			throw new IllegalArgumentException();
-	}
-
-	/**
-	 * Constructs a new ZipFile opened on the specified file path name.
-	 * 
-	 * @param filename
-	 *            the file path name
-	 */
-	public ZipFile(String filename) throws IOException {
-		SecurityManager security = System.getSecurityManager();
-		if (security != null) {
-			security.checkRead(filename);
-		}
-		fileName = filename;
-		openZip(fileName);
-	}
-
-	private void openZip(String filename) throws IOException {
-		int result = openZipImpl(Util.getBytes(fileName));
-		if (result != 0) {
-			switch (result) {
-			case 1:
-				throw new ZipException(Msg.getString("K01c3", fileName));
-			case 2:
-				throw new ZipException(Msg.getString("K01c4", fileName));
-			default:
-				throw new OutOfMemoryError();
-			}
-		}
-	}
-
-	protected void finalize() throws IOException {
-		close();
-	}
-
-	/**
-	 * Closes this ZipFile.
-	 */
-	public void close() throws IOException {
-		if (fileName != null) {
-			// Only close initialized instances
-			closeZipImpl();
-			if ((mode & OPEN_DELETE) != 0) {
-				AccessController.doPrivileged(new PrivilegedAction<Object>() {
-					public Object run() {
-						new File(fileName).delete();
-						return null;
-					}
-				});
-			}
-		}
-}
-
-	/**
-	 * Answers all of the zip entries contained in this ZipFile.
-	 * 
-	 * @return an Enumeration of the zip entries
-	 */
-	public Enumeration<? extends ZipEntry> entries() {
-		return new ZFEnum<ZipEntry>();
-	}
-
-	/**
-	 * Gets the zip entry with the specified name from this ZipFile.
-	 * 
-	 * @param entryName
-	 *            the name of the entry in the zip file
-	 * @return a ZipEntry or null if the entry name does not exist in the zip
-	 *         file
-	 */
-	public ZipEntry getEntry(String entryName) {
-		if (entryName != null) {
-			ZipEntry entry = getEntryImpl(descriptor, entryName);
-			return entry;
-		}
-		throw new NullPointerException();
-	}
-
-	/**
-	 * Answers an input stream on the data of the specified ZipEntry.
-	 * 
-	 * @param entry
-	 *            the ZipEntry
-	 * @return an input stream on the ZipEntry data
-	 */
-	public InputStream getInputStream(ZipEntry entry) throws IOException {
-		if(descriptor == -1) {
-			/* the descriptor is set to -1 by native code to indicate the zip was closed */
-			throw new IllegalStateException();
-		}
-		byte[] buf = inflateEntryImpl2(descriptor, entry.getName());
-		if (buf == null) return null;
-		return new ByteArrayInputStream(buf);
-}
-
-	/**
-	 * Gets the file name of this ZipFile.
-	 * 
-	 * @return the file name of this ZipFile
-	 */
-	public String getName() {
-		return fileName;
-	}
-
-	private synchronized native int openZipImpl(byte[] fileName1);
-
-	private synchronized native void closeZipImpl() throws IOException;
-
-	private native ZipEntry getEntryImpl(long descriptor1, String entryName);
-
-	private native byte[] inflateEntryImpl2(long descriptor1, String entryName)
-			throws ZipException;
-
-	/**
-	 * Returns the number of ZipEntries in this ZipFile.
-	 * 
-	 * @return Number of entries in this file
-	 */
-	public int size() {
-		if (size != -1)
-			return size;
-
-		size = 0;
-		Enumeration<?> e = entries();
-		while (e.hasMoreElements()) {
-			size++;
-			e.nextElement();
-		}
-		return size;
-
-	}
-
-	private static native void ntvinit();
-
-	class ZFEnum<T extends ZipEntry> implements Enumeration<T> {
-		private long nextEntryPointer;
-
-		private T current;
-
-		ZFEnum() {
-			nextEntryPointer = resetZip(descriptor);
-			current = getNextEntry(descriptor, nextEntryPointer);
-		}
-
-		private native long resetZip(long descriptor1);
-
-		private native T getNextEntry(long descriptor1, long nextEntryPointer1);
-
-		public boolean hasMoreElements() {
-			if(descriptor == -1) {
-				/* the descriptor is set to -1 by native code to indicate the zip was closed */
-				throw new IllegalStateException();
-			}
-			return current != null;
-		}
-
-		public T nextElement() {
-			if (current == null)
-				throw new NoSuchElementException();
-			T ze = current;
-			current = getNextEntry(descriptor, nextEntryPointer);
-			return ze;
-		}
-	}
-}
+/* 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;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+import org.apache.harmony.luni.util.Msg;
+import org.apache.harmony.luni.util.Util;
+
+/**
+ * ZipFile is used to read zip entries and their associated data from zip files.
+ * 
+ * @see ZipInputStream
+ * @see ZipEntry
+ */
+
+public class ZipFile implements ZipConstants {
+
+	private String fileName;
+
+	long descriptor = -1;
+
+	private int size = -1;
+
+	private int mode;
+	static {
+		ntvinit();
+	}
+
+	/**
+	 * Open zip file for read.
+	 */
+	public static final int OPEN_READ = 1;
+
+	/**
+	 * Delete zip file when closed.
+	 */
+	public static final int OPEN_DELETE = 4;
+
+	/**
+	 * Constructs a new ZipFile opened on the specified File.
+	 * 
+	 * @param file
+	 *            the File
+	 */
+	public ZipFile(File file) throws ZipException, IOException {
+		this(file.getPath());
+	}
+
+	/**
+	 * Constructs a new ZipFile opened on the specified File using the specified
+	 * mode.
+	 * 
+	 * @param file
+	 *            the File
+	 * @param mode
+	 *            the mode to use, either OPEN_READ or OPEN_READ | OPEN_DELETE
+	 */
+	public ZipFile(File file, int mode) throws IOException {
+		if (mode == OPEN_READ || mode == (OPEN_READ | OPEN_DELETE)) {
+			fileName = file.getPath();
+			SecurityManager security = System.getSecurityManager();
+			if (security != null) {
+				security.checkRead(fileName);
+				if ((mode & OPEN_DELETE) != 0) {
+					security.checkDelete(fileName);
+				}
+			}
+			this.mode = mode;
+			openZip(fileName);
+		} else
+			throw new IllegalArgumentException();
+	}
+
+	/**
+	 * Constructs a new ZipFile opened on the specified file path name.
+	 * 
+	 * @param filename
+	 *            the file path name
+	 */
+	public ZipFile(String filename) throws IOException {
+		SecurityManager security = System.getSecurityManager();
+		if (security != null) {
+			security.checkRead(filename);
+		}
+		fileName = filename;
+		openZip(fileName);
+	}
+
+	private void openZip(String filename) throws IOException {
+		int result = openZipImpl(Util.getBytes(fileName));
+		if (result != 0) {
+			switch (result) {
+			case 1:
+				throw new ZipException(Msg.getString("K01c3", fileName));
+			case 2:
+				throw new ZipException(Msg.getString("K01c4", fileName));
+			default:
+				throw new OutOfMemoryError();
+			}
+		}
+	}
+
+	protected void finalize() throws IOException {
+		close();
+	}
+
+	/**
+	 * Closes this ZipFile.
+	 */
+	public void close() throws IOException {
+		if (fileName != null) {
+			// Only close initialized instances
+			closeZipImpl();
+			if ((mode & OPEN_DELETE) != 0) {
+				AccessController.doPrivileged(new PrivilegedAction<Object>() {
+					public Object run() {
+						new File(fileName).delete();
+						return null;
+					}
+				});
+			}
+		}
+}
+
+	/**
+	 * Answers all of the zip entries contained in this ZipFile.
+	 * 
+	 * @return an Enumeration of the zip entries
+	 */
+	public Enumeration<? extends ZipEntry> entries() {
+		return new ZFEnum<ZipEntry>();
+	}
+
+	/**
+	 * Gets the zip entry with the specified name from this ZipFile.
+	 * 
+	 * @param entryName
+	 *            the name of the entry in the zip file
+	 * @return a ZipEntry or null if the entry name does not exist in the zip
+	 *         file
+	 */
+	public ZipEntry getEntry(String entryName) {
+		if (entryName != null) {
+			ZipEntry entry = getEntryImpl(descriptor, entryName);
+			return entry;
+		}
+		throw new NullPointerException();
+	}
+
+	/**
+	 * Answers an input stream on the data of the specified ZipEntry.
+	 * 
+	 * @param entry
+	 *            the ZipEntry
+	 * @return an input stream on the ZipEntry data
+	 */
+	public InputStream getInputStream(ZipEntry entry) throws IOException {
+		if(descriptor == -1) {
+			/* the descriptor is set to -1 by native code to indicate the zip was closed */
+			throw new IllegalStateException();
+		}
+		byte[] buf = inflateEntryImpl2(descriptor, entry.getName());
+		if (buf == null) return null;
+		return new ByteArrayInputStream(buf);
+}
+
+	/**
+	 * Gets the file name of this ZipFile.
+	 * 
+	 * @return the file name of this ZipFile
+	 */
+	public String getName() {
+		return fileName;
+	}
+
+	private synchronized native int openZipImpl(byte[] fileName1);
+
+	private synchronized native void closeZipImpl() throws IOException;
+
+	private native ZipEntry getEntryImpl(long descriptor1, String entryName);
+
+	private native byte[] inflateEntryImpl2(long descriptor1, String entryName)
+			throws ZipException;
+
+	/**
+	 * Returns the number of ZipEntries in this ZipFile.
+	 * 
+	 * @return Number of entries in this file
+	 */
+	public int size() {
+		if (size != -1)
+			return size;
+
+		size = 0;
+		Enumeration<?> e = entries();
+		while (e.hasMoreElements()) {
+			size++;
+			e.nextElement();
+		}
+		return size;
+
+	}
+
+	private static native void ntvinit();
+
+	class ZFEnum<T extends ZipEntry> implements Enumeration<T> {
+		private long nextEntryPointer;
+
+		private T current;
+
+		ZFEnum() {
+			nextEntryPointer = resetZip(descriptor);
+			current = getNextEntry(descriptor, nextEntryPointer);
+		}
+
+		private native long resetZip(long descriptor1);
+
+		private native T getNextEntry(long descriptor1, long nextEntryPointer1);
+
+		public boolean hasMoreElements() {
+			if(descriptor == -1) {
+				/* the descriptor is set to -1 by native code to indicate the zip was closed */
+				throw new IllegalStateException();
+			}
+			return current != null;
+		}
+
+		public T nextElement() {
+			if (current == null)
+				throw new NoSuchElementException();
+			T ze = current;
+			current = getNextEntry(descriptor, nextEntryPointer);
+			return ze;
+		}
+	}
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipFile.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipInputStream.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipInputStream.java?view=diff&rev=446478&r1=446477&r2=446478
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipInputStream.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipInputStream.java Thu Sep 14 19:40:33 2006
@@ -1,335 +1,335 @@
-/* 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;
-
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-
-import org.apache.harmony.luni.util.Msg;
-import org.apache.harmony.luni.util.Util;
-
-/**
- * ZipInputStream is an input stream for reading zip files.
- * 
- * @see ZipEntry
- * @see ZipFile
- */
-public class ZipInputStream extends InflaterInputStream implements ZipConstants {
-	static final int DEFLATED = 8;
-
-	static final int STORED = 0;
-
-	static final int ZIPDataDescriptorFlag = 8;
-
-	static final int ZIPLocalHeaderVersionNeeded = 20;
-
-	private boolean zipClosed = false;
-
-	private boolean entriesEnd = false;
-
-	private boolean hasDD = false;
-
-	private int entryIn = 0;
-
-	private int inRead, lastRead = 0;
-
-	ZipEntry currentEntry;
-
-	private byte[] hdrBuf = new byte[LOCHDR - LOCVER];
-
-	private CRC32 crc = new CRC32();
-
-	private byte[] nameBuf = new byte[256];
-
-	private char[] charBuf = new char[256];
-
-	/**
-	 * Constructs a new ZipInputStream on the specified input stream.
-	 * 
-	 * @param stream
-	 *            the input stream
-	 */
-	public ZipInputStream(InputStream stream) {
-		super(new PushbackInputStream(stream, BUF_SIZE), new Inflater(true));
-		if (stream == null)
-			throw new NullPointerException();
-	}
-
-	/**
-     * Closes this ZipInputStream.
-     */
-    public void close() throws IOException {
-        if (zipClosed != true) {
-            closeEntry(); // Close the current entry
-            zipClosed = true;
-            super.close();
-        }
-    }
-
-	/**
-	 * Closes the current zip entry and positions to read the next entry.
-	 */
-	public void closeEntry() throws IOException {
-		if (zipClosed)
-			throw new IOException(Msg.getString("K0059"));
-		if (currentEntry == null)
-			return;
-		if (currentEntry instanceof java.util.jar.JarEntry) {
-			Attributes temp = ((JarEntry) currentEntry).getAttributes();
-			if (temp != null && temp.containsKey("hidden"))
-				return;
-		}
-		// Ensure all entry bytes are read
-		skip(Long.MAX_VALUE);
-		int inB, out;
-		if (currentEntry.compressionMethod == DEFLATED) {
-			inB = inf.getTotalIn();
-			out = inf.getTotalOut();
-		} else {
-			inB = inRead;
-			out = inRead;
-		}
-		int diff = 0;
-		// Pushback any required bytes
-		if ((diff = entryIn - inB) != 0)
-			((PushbackInputStream) in).unread(buf, len - diff, diff);
-
-		if (hasDD) {
-			in.read(hdrBuf, 0, EXTHDR);
-			if (getLong(hdrBuf, 0) != EXTSIG)
-				throw new ZipException(Msg.getString("K0020"));
-			currentEntry.crc = getLong(hdrBuf, EXTCRC);
-			currentEntry.compressedSize = getLong(hdrBuf, EXTSIZ);
-			currentEntry.size = getLong(hdrBuf, EXTLEN);
-		}
-		if (currentEntry.crc != crc.getValue())
-			throw new ZipException(Msg.getString("K0077"));
-		if (currentEntry.compressedSize != inB || currentEntry.size != out)
-			throw new ZipException(Msg.getString("K00ae"));
-
-		inf.reset();
-		lastRead = inRead = entryIn = len = 0;
-		crc.reset();
-		currentEntry = null;
-	}
-
-	/**
-	 * Reads the next zip entry from this ZipInputStream.
-	 */
-	public ZipEntry getNextEntry() throws IOException {
-		if (currentEntry != null)
-			closeEntry();
-		if (entriesEnd)
-			return null;
-
-		int x = 0, count = 0;
-		while (count != 4) {
-			count += x = in.read(hdrBuf, count, 4 - count);
-			if (x == -1)
-				return null;
-		}
-		long hdr = getLong(hdrBuf, 0);
-		if (hdr == CENSIG) {
-			entriesEnd = true;
-			return null;
-		}
-		if (hdr != LOCSIG)
-			return null;
-
-		// Read the local header
-		count = 0;
-		while (count != (LOCHDR - LOCVER)) {
-			count += x = in.read(hdrBuf, count, (LOCHDR - LOCVER) - count);
-			if (x == -1)
-				throw new EOFException();
-		}
-		int version = getShort(hdrBuf, 0) & 0xff;
-		if (version > ZIPLocalHeaderVersionNeeded)
-			throw new ZipException(Msg.getString("K0008"));
-		int flags = getShort(hdrBuf, LOCFLG - LOCVER);
-		hasDD = ((flags & ZIPDataDescriptorFlag) == ZIPDataDescriptorFlag);
-		int cetime = getShort(hdrBuf, LOCTIM - LOCVER);
-		int cemodDate = getShort(hdrBuf, LOCTIM - LOCVER + 2);
-		int cecompressionMethod = getShort(hdrBuf, LOCHOW - LOCVER);
-		long cecrc = 0, cecompressedSize = 0, cesize = -1;
-		if (!hasDD) {
-			cecrc = getLong(hdrBuf, LOCCRC - LOCVER);
-			cecompressedSize = getLong(hdrBuf, LOCSIZ - LOCVER);
-			cesize = getLong(hdrBuf, LOCLEN - LOCVER);
-		}
-		int flen = getShort(hdrBuf, LOCNAM - LOCVER);
-		if (flen == 0)
-			throw new ZipException(Msg.getString("K000a"));
-		int elen = getShort(hdrBuf, LOCEXT - LOCVER);
-
-		count = 0;
-		if (flen > nameBuf.length) {
-			nameBuf = new byte[flen];
-			charBuf = new char[flen];
-		}
-		while (count != flen) {
-			count += x = in.read(nameBuf, count, flen - count);
-			if (x == -1)
-				throw new EOFException();
-		}
-		currentEntry = createZipEntry(Util.convertUTF8WithBuf(nameBuf, charBuf,
-				0, flen));
-		currentEntry.time = cetime;
-		currentEntry.modDate = cemodDate;
-		currentEntry.setMethod(cecompressionMethod);
-		if (cesize != -1) {
-			currentEntry.setCrc(cecrc);
-			currentEntry.setSize(cesize);
-			currentEntry.setCompressedSize(cecompressedSize);
-		}
-		if (elen > 0) {
-			count = 0;
-			byte[] e = new byte[elen];
-			while (count != elen) {
-				count += x = in.read(e, count, elen - count);
-				if (x == -1)
-					throw new EOFException();
-			}
-			currentEntry.setExtra(e);
-		}
-		return currentEntry;
-	}
-
-	/* Read 4 bytes from the buffer and store it as an int */
-
-	/**
-	 * Reads up to the specified number of uncompressed bytes into the buffer
-	 * starting at the offset.
-	 * 
-	 * @param buffer
-	 *            a byte array
-	 * @param start
-	 *            the starting offset into the buffer
-	 * @param length
-	 *            the number of bytes to read
-	 * @return the number of bytes read
-	 */
-	public int read(byte[] buffer, int start, int length) throws IOException {
-		if (zipClosed)
-			throw new IOException(Msg.getString("K0059"));
-		if (inf.finished() || currentEntry == null)
-			return -1;
-		// avoid int overflow, check null buffer
-		if (start <= buffer.length && length >= 0 && start >= 0
-				&& buffer.length - start >= length) {
-			if (currentEntry.compressionMethod == STORED) {
-				int csize = (int) currentEntry.size;
-				if (inRead >= csize)
-					return -1;
-				if (lastRead >= len) {
-					lastRead = 0;
-					if ((len = in.read(buf)) == -1)
-						return -1;
-					entryIn += len;
-				}
-				int toRead = length > len ? len - lastRead : length;
-				if ((csize - inRead) < toRead)
-					toRead = csize - inRead;
-				System.arraycopy(buf, lastRead, buffer, start, toRead);
-				lastRead += toRead;
-				inRead += toRead;
-				crc.update(buffer, start, toRead);
-				return toRead;
-			}
-			if (inf.needsInput()) {
-				fill();
-				if (len > 0)
-					entryIn += len;
-			}
-			int read = 0;
-			try {
-				read = inf.inflate(buffer, start, length);
-			} catch (DataFormatException e) {
-				throw new ZipException(e.getMessage());
-			}
-			if (read == 0 && inf.finished())
-				return -1;
-			crc.update(buffer, start, read);
-			return read;
-		}
-		throw new ArrayIndexOutOfBoundsException();
-	}
-
-	/**
-	 * Skips up to the specified number of bytes in the current zip entry.
-	 * 
-	 * @param value
-	 *            the number of bytes to skip
-	 * @return the number of bytes skipped
-	 */
-	public long skip(long value) throws IOException {
-		if (value >= 0) {
-			long skipped = 0;
-			byte[] b = new byte[1024];
-			while (skipped != value) {
-				long rem = value - skipped;
-				int x = read(b, 0, (int) (b.length > rem ? rem : b.length));
-				if (x == -1)
-					return skipped;
-				skipped += x;
-			}
-			return skipped;
-		} else
-			throw new IllegalArgumentException();
-}
-
-	/**
-	 * Answers 1 if the EOF has been reached, otherwise returns 0.
-	 * 
-	 * @return 0 after EOF of current entry, 1 otherwise
-	 */
-	public int available() throws IOException {
-		if (zipClosed)
-			throw new IOException(Msg.getString("K0059"));
-		if (currentEntry == null)
-			return 1;
-		if (currentEntry.compressionMethod == STORED) {
-			if (inRead >= currentEntry.size)
-				return 0;
-		} else {
-			if (inf.finished())
-				return 0;
-		}
-		return 1;
-	}
-
-	protected ZipEntry createZipEntry(String name) {
-		return new ZipEntry(name);
-	}
-
-	private int getShort(byte[] buffer, int off) {
-		return (buffer[off] & 0xFF) | ((buffer[off + 1] & 0xFF) << 8);
-	}
-
-	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;
-	}
-}
+/* 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;
+
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+
+import org.apache.harmony.luni.util.Msg;
+import org.apache.harmony.luni.util.Util;
+
+/**
+ * ZipInputStream is an input stream for reading zip files.
+ * 
+ * @see ZipEntry
+ * @see ZipFile
+ */
+public class ZipInputStream extends InflaterInputStream implements ZipConstants {
+	static final int DEFLATED = 8;
+
+	static final int STORED = 0;
+
+	static final int ZIPDataDescriptorFlag = 8;
+
+	static final int ZIPLocalHeaderVersionNeeded = 20;
+
+	private boolean zipClosed = false;
+
+	private boolean entriesEnd = false;
+
+	private boolean hasDD = false;
+
+	private int entryIn = 0;
+
+	private int inRead, lastRead = 0;
+
+	ZipEntry currentEntry;
+
+	private byte[] hdrBuf = new byte[LOCHDR - LOCVER];
+
+	private CRC32 crc = new CRC32();
+
+	private byte[] nameBuf = new byte[256];
+
+	private char[] charBuf = new char[256];
+
+	/**
+	 * Constructs a new ZipInputStream on the specified input stream.
+	 * 
+	 * @param stream
+	 *            the input stream
+	 */
+	public ZipInputStream(InputStream stream) {
+		super(new PushbackInputStream(stream, BUF_SIZE), new Inflater(true));
+		if (stream == null)
+			throw new NullPointerException();
+	}
+
+	/**
+     * Closes this ZipInputStream.
+     */
+    public void close() throws IOException {
+        if (zipClosed != true) {
+            closeEntry(); // Close the current entry
+            zipClosed = true;
+            super.close();
+        }
+    }
+
+	/**
+	 * Closes the current zip entry and positions to read the next entry.
+	 */
+	public void closeEntry() throws IOException {
+		if (zipClosed)
+			throw new IOException(Msg.getString("K0059"));
+		if (currentEntry == null)
+			return;
+		if (currentEntry instanceof java.util.jar.JarEntry) {
+			Attributes temp = ((JarEntry) currentEntry).getAttributes();
+			if (temp != null && temp.containsKey("hidden"))
+				return;
+		}
+		// Ensure all entry bytes are read
+		skip(Long.MAX_VALUE);
+		int inB, out;
+		if (currentEntry.compressionMethod == DEFLATED) {
+			inB = inf.getTotalIn();
+			out = inf.getTotalOut();
+		} else {
+			inB = inRead;
+			out = inRead;
+		}
+		int diff = 0;
+		// Pushback any required bytes
+		if ((diff = entryIn - inB) != 0)
+			((PushbackInputStream) in).unread(buf, len - diff, diff);
+
+		if (hasDD) {
+			in.read(hdrBuf, 0, EXTHDR);
+			if (getLong(hdrBuf, 0) != EXTSIG)
+				throw new ZipException(Msg.getString("K0020"));
+			currentEntry.crc = getLong(hdrBuf, EXTCRC);
+			currentEntry.compressedSize = getLong(hdrBuf, EXTSIZ);
+			currentEntry.size = getLong(hdrBuf, EXTLEN);
+		}
+		if (currentEntry.crc != crc.getValue())
+			throw new ZipException(Msg.getString("K0077"));
+		if (currentEntry.compressedSize != inB || currentEntry.size != out)
+			throw new ZipException(Msg.getString("K00ae"));
+
+		inf.reset();
+		lastRead = inRead = entryIn = len = 0;
+		crc.reset();
+		currentEntry = null;
+	}
+
+	/**
+	 * Reads the next zip entry from this ZipInputStream.
+	 */
+	public ZipEntry getNextEntry() throws IOException {
+		if (currentEntry != null)
+			closeEntry();
+		if (entriesEnd)
+			return null;
+
+		int x = 0, count = 0;
+		while (count != 4) {
+			count += x = in.read(hdrBuf, count, 4 - count);
+			if (x == -1)
+				return null;
+		}
+		long hdr = getLong(hdrBuf, 0);
+		if (hdr == CENSIG) {
+			entriesEnd = true;
+			return null;
+		}
+		if (hdr != LOCSIG)
+			return null;
+
+		// Read the local header
+		count = 0;
+		while (count != (LOCHDR - LOCVER)) {
+			count += x = in.read(hdrBuf, count, (LOCHDR - LOCVER) - count);
+			if (x == -1)
+				throw new EOFException();
+		}
+		int version = getShort(hdrBuf, 0) & 0xff;
+		if (version > ZIPLocalHeaderVersionNeeded)
+			throw new ZipException(Msg.getString("K0008"));
+		int flags = getShort(hdrBuf, LOCFLG - LOCVER);
+		hasDD = ((flags & ZIPDataDescriptorFlag) == ZIPDataDescriptorFlag);
+		int cetime = getShort(hdrBuf, LOCTIM - LOCVER);
+		int cemodDate = getShort(hdrBuf, LOCTIM - LOCVER + 2);
+		int cecompressionMethod = getShort(hdrBuf, LOCHOW - LOCVER);
+		long cecrc = 0, cecompressedSize = 0, cesize = -1;
+		if (!hasDD) {
+			cecrc = getLong(hdrBuf, LOCCRC - LOCVER);
+			cecompressedSize = getLong(hdrBuf, LOCSIZ - LOCVER);
+			cesize = getLong(hdrBuf, LOCLEN - LOCVER);
+		}
+		int flen = getShort(hdrBuf, LOCNAM - LOCVER);
+		if (flen == 0)
+			throw new ZipException(Msg.getString("K000a"));
+		int elen = getShort(hdrBuf, LOCEXT - LOCVER);
+
+		count = 0;
+		if (flen > nameBuf.length) {
+			nameBuf = new byte[flen];
+			charBuf = new char[flen];
+		}
+		while (count != flen) {
+			count += x = in.read(nameBuf, count, flen - count);
+			if (x == -1)
+				throw new EOFException();
+		}
+		currentEntry = createZipEntry(Util.convertUTF8WithBuf(nameBuf, charBuf,
+				0, flen));
+		currentEntry.time = cetime;
+		currentEntry.modDate = cemodDate;
+		currentEntry.setMethod(cecompressionMethod);
+		if (cesize != -1) {
+			currentEntry.setCrc(cecrc);
+			currentEntry.setSize(cesize);
+			currentEntry.setCompressedSize(cecompressedSize);
+		}
+		if (elen > 0) {
+			count = 0;
+			byte[] e = new byte[elen];
+			while (count != elen) {
+				count += x = in.read(e, count, elen - count);
+				if (x == -1)
+					throw new EOFException();
+			}
+			currentEntry.setExtra(e);
+		}
+		return currentEntry;
+	}
+
+	/* Read 4 bytes from the buffer and store it as an int */
+
+	/**
+	 * Reads up to the specified number of uncompressed bytes into the buffer
+	 * starting at the offset.
+	 * 
+	 * @param buffer
+	 *            a byte array
+	 * @param start
+	 *            the starting offset into the buffer
+	 * @param length
+	 *            the number of bytes to read
+	 * @return the number of bytes read
+	 */
+	public int read(byte[] buffer, int start, int length) throws IOException {
+		if (zipClosed)
+			throw new IOException(Msg.getString("K0059"));
+		if (inf.finished() || currentEntry == null)
+			return -1;
+		// avoid int overflow, check null buffer
+		if (start <= buffer.length && length >= 0 && start >= 0
+				&& buffer.length - start >= length) {
+			if (currentEntry.compressionMethod == STORED) {
+				int csize = (int) currentEntry.size;
+				if (inRead >= csize)
+					return -1;
+				if (lastRead >= len) {
+					lastRead = 0;
+					if ((len = in.read(buf)) == -1)
+						return -1;
+					entryIn += len;
+				}
+				int toRead = length > len ? len - lastRead : length;
+				if ((csize - inRead) < toRead)
+					toRead = csize - inRead;
+				System.arraycopy(buf, lastRead, buffer, start, toRead);
+				lastRead += toRead;
+				inRead += toRead;
+				crc.update(buffer, start, toRead);
+				return toRead;
+			}
+			if (inf.needsInput()) {
+				fill();
+				if (len > 0)
+					entryIn += len;
+			}
+			int read = 0;
+			try {
+				read = inf.inflate(buffer, start, length);
+			} catch (DataFormatException e) {
+				throw new ZipException(e.getMessage());
+			}
+			if (read == 0 && inf.finished())
+				return -1;
+			crc.update(buffer, start, read);
+			return read;
+		}
+		throw new ArrayIndexOutOfBoundsException();
+	}
+
+	/**
+	 * Skips up to the specified number of bytes in the current zip entry.
+	 * 
+	 * @param value
+	 *            the number of bytes to skip
+	 * @return the number of bytes skipped
+	 */
+	public long skip(long value) throws IOException {
+		if (value >= 0) {
+			long skipped = 0;
+			byte[] b = new byte[1024];
+			while (skipped != value) {
+				long rem = value - skipped;
+				int x = read(b, 0, (int) (b.length > rem ? rem : b.length));
+				if (x == -1)
+					return skipped;
+				skipped += x;
+			}
+			return skipped;
+		} else
+			throw new IllegalArgumentException();
+}
+
+	/**
+	 * Answers 1 if the EOF has been reached, otherwise returns 0.
+	 * 
+	 * @return 0 after EOF of current entry, 1 otherwise
+	 */
+	public int available() throws IOException {
+		if (zipClosed)
+			throw new IOException(Msg.getString("K0059"));
+		if (currentEntry == null)
+			return 1;
+		if (currentEntry.compressionMethod == STORED) {
+			if (inRead >= currentEntry.size)
+				return 0;
+		} else {
+			if (inf.finished())
+				return 0;
+		}
+		return 1;
+	}
+
+	protected ZipEntry createZipEntry(String name) {
+		return new ZipEntry(name);
+	}
+
+	private int getShort(byte[] buffer, int off) {
+		return (buffer[off] & 0xFF) | ((buffer[off + 1] & 0xFF) << 8);
+	}
+
+	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;
+	}
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipOutputStream.java?view=diff&rev=446478&r1=446477&r2=446478
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipOutputStream.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipOutputStream.java Thu Sep 14 19:40:33 2006
@@ -1,389 +1,389 @@
-/* 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;
-
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Vector;
-
-import org.apache.harmony.luni.util.Msg;
-
-/**
- * ZipOuputStream is used to write ZipEntries to the underlying stream. Output
- * from ZipOutputStream conforms to the ZipFile file format.
- * 
- * @see ZipInputStream
- * @see ZipEntry
- */
-public class ZipOutputStream extends DeflaterOutputStream implements
-		ZipConstants {
-
-	public static final int DEFLATED = 8;
-
-	public static final int STORED = 0;
-
-	static final int ZIPDataDescriptorFlag = 8;
-
-	static final int ZIPLocalHeaderVersionNeeded = 20;
-
-	private String comment;
-
-	private Vector<String> entries = new Vector<String>();
-
-	private int compressMethod = DEFLATED;
-
-	private int compressLevel = Deflater.DEFAULT_COMPRESSION;
-
-	private ByteArrayOutputStream cDir = new ByteArrayOutputStream();
-
-	private ZipEntry currentEntry;
-
-	private CRC32 crc = new CRC32();
-
-	private int offset = 0, curOffset = 0, nameLength;
-
-	private byte[] nameBytes;
-
-	/**
-	 * Constructs a new ZipOutputStream on p1
-	 * 
-	 * @param p1
-	 *            OutputStream The InputStream to output to
-	 */
-	public ZipOutputStream(OutputStream p1) {
-		super(p1, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
-	}
-
-	/**
-	 * Closes the current ZipEntry if any. Closes the underlying output stream.
-	 * If the stream is already closed this method does nothing.
-	 * 
-	 * @exception IOException
-	 *                If an error occurs closing the stream
-	 */
-	public void close() throws IOException {
-		if (out != null) {
-			finish();
-			out.close();
-			out = null;
-		}
-	}
-
-	/**
-	 * Closes the current ZipEntry. Any entry terminal data is written to the
-	 * underlying stream.
-	 * 
-	 * @exception IOException
-	 *                If an error occurs closing the entry
-	 */
-	public void closeEntry() throws IOException {
-		if (cDir == null)
-			throw new IOException(Msg.getString("K0059"));
-		if (currentEntry == null)
-			return;
-		if (currentEntry.getMethod() == DEFLATED) {
-			super.finish();
-		}
-
-		// Verify values for STORED types
-		if (currentEntry.getMethod() == STORED) {
-			if (crc.getValue() != currentEntry.crc)
-				throw new ZipException(Msg.getString("K0077"));
-			if (currentEntry.size != crc.tbytes)
-				throw new ZipException(Msg.getString("K00ae"));
-		}
-		curOffset = LOCHDR;
-
-		// Write the DataDescriptor
-		if (currentEntry.getMethod() != STORED) {
-			curOffset += EXTHDR;
-			writeLong(out, EXTSIG);
-			writeLong(out, currentEntry.crc = crc.getValue());
-			writeLong(out, currentEntry.compressedSize = def.getTotalOut());
-			writeLong(out, currentEntry.size = def.getTotalIn());
-		}
-		// Update the CentralDirectory
-		writeLong(cDir, CENSIG);
-		writeShort(cDir, ZIPLocalHeaderVersionNeeded); // Version created
-		writeShort(cDir, ZIPLocalHeaderVersionNeeded); // Version to extract
-		writeShort(cDir, currentEntry.getMethod() == STORED ? 0
-				: ZIPDataDescriptorFlag);
-		writeShort(cDir, currentEntry.getMethod());
-		writeShort(cDir, currentEntry.time);
-		writeShort(cDir, currentEntry.modDate);
-		writeLong(cDir, crc.getValue());
-		if (currentEntry.getMethod() == DEFLATED) {
-			curOffset += writeLong(cDir, def.getTotalOut());
-			writeLong(cDir, def.getTotalIn());
-		} else {
-			curOffset += writeLong(cDir, crc.tbytes);
-			writeLong(cDir, crc.tbytes);
-		}
-		curOffset += writeShort(cDir, nameLength);
-		if (currentEntry.extra != null)
-			curOffset += writeShort(cDir, currentEntry.extra.length);
-		else
-			writeShort(cDir, 0);
-		String c;
-		if ((c = currentEntry.getComment()) != null)
-			writeShort(cDir, c.length());
-		else
-			writeShort(cDir, 0);
-		writeShort(cDir, 0); // Disk Start
-		writeShort(cDir, 0); // Internal File Attributes
-		writeLong(cDir, 0); // External File Attributes
-		writeLong(cDir, offset);
-		cDir.write(nameBytes);
-		nameBytes = null;
-		if (currentEntry.extra != null)
-			cDir.write(currentEntry.extra);
-		offset += curOffset;
-		if (c != null)
-			cDir.write(c.getBytes());
-		currentEntry = null;
-		crc.reset();
-		def.reset();
-		done = false;
-	}
-
-	/**
-	 * Indicates that all entries have been written to the stream. Any terminal
-	 * ZipFile information is written to the underlying stream.
-	 * 
-	 * @exception IOException
-	 *                If an error occurs while finishing
-	 */
-	public void finish() throws IOException {
-		if (out == null)
-			throw new IOException(Msg.getString("K0059"));
-		if (cDir == null)
-			return;
-		if (entries.size() == 0)
-			throw new ZipException(Msg.getString("K00b6"));
-		if (currentEntry != null)
-			closeEntry();
-		int cdirSize = cDir.size();
-		// Write Central Dir End
-		writeLong(cDir, ENDSIG);
-		writeShort(cDir, 0); // Disk Number
-		writeShort(cDir, 0); // Start Disk
-		writeShort(cDir, entries.size()); // Number of entries
-		writeShort(cDir, entries.size()); // Number of entries
-		writeLong(cDir, cdirSize); // Size of central dir
-		writeLong(cDir, offset); // Offset of central dir
-		if (comment != null) {
-			writeShort(cDir, comment.length());
-			cDir.write(comment.getBytes());
-		} else
-			writeShort(cDir, 0);
-		// Write the central dir
-		out.write(cDir.toByteArray());
-		cDir = null;
-
-	}
-
-	/**
-	 * Writes entry information for ze to the underlying stream. Data associated
-	 * with the entry can then be written using write(). After data is written
-	 * closeEntry() must be called to complete the storing of ze on the
-	 * underlying stream.
-	 * 
-	 * @param ze
-	 *            ZipEntry to store
-	 * @exception IOException
-	 *                If an error occurs storing the entry
-	 * @see #write
-	 */
-	public void putNextEntry(ZipEntry ze) throws java.io.IOException {
-        if (currentEntry != null)
-            closeEntry();
-		if (ze.getMethod() == STORED
-				|| (compressMethod == STORED && ze.getMethod() == -1)) {
-			if (ze.crc == -1)
-				/* [MSG "K0077", "Crc mismatch"] */
-				throw new ZipException(Msg.getString("K0077"));
-			if (ze.size == -1 && ze.compressedSize == -1)
-				/* [MSG "K00ae", "Size mismatch"] */
-				throw new ZipException(Msg.getString("K00ae"));
-			if (ze.size != ze.compressedSize && ze.compressedSize != -1
-					&& ze.size != -1)
-				/* [MSG "K00ae", "Size mismatch"] */
-				throw new ZipException(Msg.getString("K00ae"));
-		}
-		/* [MSG "K0059", "Stream is closed"] */
-		if (cDir == null)
-			throw new IOException(Msg.getString("K0059"));
-		if (entries.contains(ze.name))
-			/* [MSG "K0066", "Entry already exists: {0}"] */
-			throw new ZipException(Msg.getString("K0066", ze.name));
-		nameLength = utf8Count(ze.name);
-		if (nameLength > 0xffff)
-			/* [MSG "K01a7", "Name too long: {0}"] */
-			throw new IllegalArgumentException(Msg.getString("K01a7", ze.name));
-
-		def.setLevel(compressLevel);
-		currentEntry = ze;
-		entries.add(currentEntry.name);
-		if (currentEntry.getMethod() == -1)
-			currentEntry.setMethod(compressMethod);
-		writeLong(out, LOCSIG); // Entry header
-		writeShort(out, ZIPLocalHeaderVersionNeeded); // Extraction version
-		writeShort(out, currentEntry.getMethod() == STORED ? 0
-				: ZIPDataDescriptorFlag);
-		writeShort(out, currentEntry.getMethod());
-		if (currentEntry.getTime() == -1)
-			currentEntry.setTime(System.currentTimeMillis());
-		writeShort(out, currentEntry.time);
-		writeShort(out, currentEntry.modDate);
-
-		if (currentEntry.getMethod() == STORED) {
-			if (currentEntry.size == -1)
-				currentEntry.size = currentEntry.compressedSize;
-			else if (currentEntry.compressedSize == -1)
-				currentEntry.compressedSize = currentEntry.size;
-			writeLong(out, currentEntry.crc);
-			writeLong(out, currentEntry.size);
-			writeLong(out, currentEntry.size);
-		} else {
-			writeLong(out, 0);
-			writeLong(out, 0);
-			writeLong(out, 0);
-		}
-		writeShort(out, nameLength);
-		if (currentEntry.extra != null)
-			writeShort(out, currentEntry.extra.length);
-		else
-			writeShort(out, 0);
-		nameBytes = toUTF8Bytes(currentEntry.name, nameLength);
-		out.write(nameBytes);
-		if (currentEntry.extra != null)
-			out.write(currentEntry.extra);
-	}
-
-	/**
-	 * Sets the ZipFile comment associated with the file being written.
-	 * 
-	 */
-	public void setComment(String comment) {
-		if (comment.length() > 0xFFFF)
-			throw new IllegalArgumentException(Msg.getString("K0068"));
-		this.comment = comment;
-	}
-
-	/**
-	 * Sets the compression level to be used for writing entry data. This level
-	 * may be set on a per entry basis. level must have a value between 0 and
-	 * 10.
-	 * 
-	 */
-	public void setLevel(int level) {
-		if (level < Deflater.DEFAULT_COMPRESSION
-				|| level > Deflater.BEST_COMPRESSION)
-			throw new IllegalArgumentException();
-		compressLevel = level;
-	}
-
-	/**
-	 * Sets the compression method to be used when compressing entry data.
-	 * method must be one of STORED or DEFLATED.
-	 * 
-	 * @param method
-	 *            Compression method to use
-	 */
-	public void setMethod(int method) {
-		if (method != STORED && method != DEFLATED)
-			throw new IllegalArgumentException();
-		compressMethod = method;
-
-	}
-
-	private long writeLong(OutputStream os, long i) throws java.io.IOException {
-		// Write out the long value as an unsigned int
-		os.write((int) (i & 0xFF));
-		os.write((int) (i >> 8) & 0xFF);
-		os.write((int) (i >> 16) & 0xFF);
-		os.write((int) (i >> 24) & 0xFF);
-		return i;
-	}
-
-	private int writeShort(OutputStream os, int i) throws java.io.IOException {
-		os.write(i & 0xFF);
-		os.write((i >> 8) & 0xFF);
-		return i;
-
-	}
-
-	/**
-	 * Writes data for the current entry to the underlying stream.
-	 * 
-	 * @exception IOException
-	 *                If an error occurs writing to the stream
-	 */
-	public void write(byte[] buffer, int off, int nbytes)
-			throws java.io.IOException {
-		// avoid int overflow, check null buf
-		if ((off > buffer.length) || (nbytes < 0) || (off < 0)
-				|| (buffer.length - off < nbytes)) {
-			throw new IndexOutOfBoundsException();
-		}
-
-		if (currentEntry == null) {
-            /* [MSG "K00ab", "No active entry"] */
-            throw new ZipException(Msg.getString("K00ab"));
-        }
-
-		if (currentEntry.getMethod() == STORED)
-			out.write(buffer, off, nbytes);
-		else
-			super.write(buffer, off, nbytes);
-		crc.update(buffer, off, nbytes);
-	}
-
-	static int utf8Count(String value) {
-		int total = 0;
-		for (int i = value.length(); --i >= 0;) {
-			char ch = value.charAt(i);
-			if (ch < 0x80)
-				total++;
-			else if (ch < 0x800)
-				total += 2;
-			else
-				total += 3;
-		}
-		return total;
-	}
-
-	static byte[] toUTF8Bytes(String value, int length) {
-		byte[] result = new byte[length];
-		int pos = result.length;
-		for (int i = value.length(); --i >= 0;) {
-			char ch = value.charAt(i);
-			if (ch < 0x80)
-				result[--pos] = (byte) ch;
-			else if (ch < 0x800) {
-				result[--pos] = (byte) (0x80 | (ch & 0x3f));
-				result[--pos] = (byte) (0xc0 | (ch >> 6));
-			} else {
-				result[--pos] = (byte) (0x80 | (ch & 0x3f));
-				result[--pos] = (byte) (0x80 | ((ch >> 6) & 0x3f));
-				result[--pos] = (byte) (0xe0 | (ch >> 12));
-			}
-		}
-		return result;
-	}
-}
+/* 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;
+
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import org.apache.harmony.luni.util.Msg;
+
+/**
+ * ZipOuputStream is used to write ZipEntries to the underlying stream. Output
+ * from ZipOutputStream conforms to the ZipFile file format.
+ * 
+ * @see ZipInputStream
+ * @see ZipEntry
+ */
+public class ZipOutputStream extends DeflaterOutputStream implements
+		ZipConstants {
+
+	public static final int DEFLATED = 8;
+
+	public static final int STORED = 0;
+
+	static final int ZIPDataDescriptorFlag = 8;
+
+	static final int ZIPLocalHeaderVersionNeeded = 20;
+
+	private String comment;
+
+	private Vector<String> entries = new Vector<String>();
+
+	private int compressMethod = DEFLATED;
+
+	private int compressLevel = Deflater.DEFAULT_COMPRESSION;
+
+	private ByteArrayOutputStream cDir = new ByteArrayOutputStream();
+
+	private ZipEntry currentEntry;
+
+	private CRC32 crc = new CRC32();
+
+	private int offset = 0, curOffset = 0, nameLength;
+
+	private byte[] nameBytes;
+
+	/**
+	 * Constructs a new ZipOutputStream on p1
+	 * 
+	 * @param p1
+	 *            OutputStream The InputStream to output to
+	 */
+	public ZipOutputStream(OutputStream p1) {
+		super(p1, new Deflater(Deflater.DEFAULT_COMPRESSION, true));
+	}
+
+	/**
+	 * Closes the current ZipEntry if any. Closes the underlying output stream.
+	 * If the stream is already closed this method does nothing.
+	 * 
+	 * @exception IOException
+	 *                If an error occurs closing the stream
+	 */
+	public void close() throws IOException {
+		if (out != null) {
+			finish();
+			out.close();
+			out = null;
+		}
+	}
+
+	/**
+	 * Closes the current ZipEntry. Any entry terminal data is written to the
+	 * underlying stream.
+	 * 
+	 * @exception IOException
+	 *                If an error occurs closing the entry
+	 */
+	public void closeEntry() throws IOException {
+		if (cDir == null)
+			throw new IOException(Msg.getString("K0059"));
+		if (currentEntry == null)
+			return;
+		if (currentEntry.getMethod() == DEFLATED) {
+			super.finish();
+		}
+
+		// Verify values for STORED types
+		if (currentEntry.getMethod() == STORED) {
+			if (crc.getValue() != currentEntry.crc)
+				throw new ZipException(Msg.getString("K0077"));
+			if (currentEntry.size != crc.tbytes)
+				throw new ZipException(Msg.getString("K00ae"));
+		}
+		curOffset = LOCHDR;
+
+		// Write the DataDescriptor
+		if (currentEntry.getMethod() != STORED) {
+			curOffset += EXTHDR;
+			writeLong(out, EXTSIG);
+			writeLong(out, currentEntry.crc = crc.getValue());
+			writeLong(out, currentEntry.compressedSize = def.getTotalOut());
+			writeLong(out, currentEntry.size = def.getTotalIn());
+		}
+		// Update the CentralDirectory
+		writeLong(cDir, CENSIG);
+		writeShort(cDir, ZIPLocalHeaderVersionNeeded); // Version created
+		writeShort(cDir, ZIPLocalHeaderVersionNeeded); // Version to extract
+		writeShort(cDir, currentEntry.getMethod() == STORED ? 0
+				: ZIPDataDescriptorFlag);
+		writeShort(cDir, currentEntry.getMethod());
+		writeShort(cDir, currentEntry.time);
+		writeShort(cDir, currentEntry.modDate);
+		writeLong(cDir, crc.getValue());
+		if (currentEntry.getMethod() == DEFLATED) {
+			curOffset += writeLong(cDir, def.getTotalOut());
+			writeLong(cDir, def.getTotalIn());
+		} else {
+			curOffset += writeLong(cDir, crc.tbytes);
+			writeLong(cDir, crc.tbytes);
+		}
+		curOffset += writeShort(cDir, nameLength);
+		if (currentEntry.extra != null)
+			curOffset += writeShort(cDir, currentEntry.extra.length);
+		else
+			writeShort(cDir, 0);
+		String c;
+		if ((c = currentEntry.getComment()) != null)
+			writeShort(cDir, c.length());
+		else
+			writeShort(cDir, 0);
+		writeShort(cDir, 0); // Disk Start
+		writeShort(cDir, 0); // Internal File Attributes
+		writeLong(cDir, 0); // External File Attributes
+		writeLong(cDir, offset);
+		cDir.write(nameBytes);
+		nameBytes = null;
+		if (currentEntry.extra != null)
+			cDir.write(currentEntry.extra);
+		offset += curOffset;
+		if (c != null)
+			cDir.write(c.getBytes());
+		currentEntry = null;
+		crc.reset();
+		def.reset();
+		done = false;
+	}
+
+	/**
+	 * Indicates that all entries have been written to the stream. Any terminal
+	 * ZipFile information is written to the underlying stream.
+	 * 
+	 * @exception IOException
+	 *                If an error occurs while finishing
+	 */
+	public void finish() throws IOException {
+		if (out == null)
+			throw new IOException(Msg.getString("K0059"));
+		if (cDir == null)
+			return;
+		if (entries.size() == 0)
+			throw new ZipException(Msg.getString("K00b6"));
+		if (currentEntry != null)
+			closeEntry();
+		int cdirSize = cDir.size();
+		// Write Central Dir End
+		writeLong(cDir, ENDSIG);
+		writeShort(cDir, 0); // Disk Number
+		writeShort(cDir, 0); // Start Disk
+		writeShort(cDir, entries.size()); // Number of entries
+		writeShort(cDir, entries.size()); // Number of entries
+		writeLong(cDir, cdirSize); // Size of central dir
+		writeLong(cDir, offset); // Offset of central dir
+		if (comment != null) {
+			writeShort(cDir, comment.length());
+			cDir.write(comment.getBytes());
+		} else
+			writeShort(cDir, 0);
+		// Write the central dir
+		out.write(cDir.toByteArray());
+		cDir = null;
+
+	}
+
+	/**
+	 * Writes entry information for ze to the underlying stream. Data associated
+	 * with the entry can then be written using write(). After data is written
+	 * closeEntry() must be called to complete the storing of ze on the
+	 * underlying stream.
+	 * 
+	 * @param ze
+	 *            ZipEntry to store
+	 * @exception IOException
+	 *                If an error occurs storing the entry
+	 * @see #write
+	 */
+	public void putNextEntry(ZipEntry ze) throws java.io.IOException {
+        if (currentEntry != null)
+            closeEntry();
+		if (ze.getMethod() == STORED
+				|| (compressMethod == STORED && ze.getMethod() == -1)) {
+			if (ze.crc == -1)
+				/* [MSG "K0077", "Crc mismatch"] */
+				throw new ZipException(Msg.getString("K0077"));
+			if (ze.size == -1 && ze.compressedSize == -1)
+				/* [MSG "K00ae", "Size mismatch"] */
+				throw new ZipException(Msg.getString("K00ae"));
+			if (ze.size != ze.compressedSize && ze.compressedSize != -1
+					&& ze.size != -1)
+				/* [MSG "K00ae", "Size mismatch"] */
+				throw new ZipException(Msg.getString("K00ae"));
+		}
+		/* [MSG "K0059", "Stream is closed"] */
+		if (cDir == null)
+			throw new IOException(Msg.getString("K0059"));
+		if (entries.contains(ze.name))
+			/* [MSG "K0066", "Entry already exists: {0}"] */
+			throw new ZipException(Msg.getString("K0066", ze.name));
+		nameLength = utf8Count(ze.name);
+		if (nameLength > 0xffff)
+			/* [MSG "K01a7", "Name too long: {0}"] */
+			throw new IllegalArgumentException(Msg.getString("K01a7", ze.name));
+
+		def.setLevel(compressLevel);
+		currentEntry = ze;
+		entries.add(currentEntry.name);
+		if (currentEntry.getMethod() == -1)
+			currentEntry.setMethod(compressMethod);
+		writeLong(out, LOCSIG); // Entry header
+		writeShort(out, ZIPLocalHeaderVersionNeeded); // Extraction version
+		writeShort(out, currentEntry.getMethod() == STORED ? 0
+				: ZIPDataDescriptorFlag);
+		writeShort(out, currentEntry.getMethod());
+		if (currentEntry.getTime() == -1)
+			currentEntry.setTime(System.currentTimeMillis());
+		writeShort(out, currentEntry.time);
+		writeShort(out, currentEntry.modDate);
+
+		if (currentEntry.getMethod() == STORED) {
+			if (currentEntry.size == -1)
+				currentEntry.size = currentEntry.compressedSize;
+			else if (currentEntry.compressedSize == -1)
+				currentEntry.compressedSize = currentEntry.size;
+			writeLong(out, currentEntry.crc);
+			writeLong(out, currentEntry.size);
+			writeLong(out, currentEntry.size);
+		} else {
+			writeLong(out, 0);
+			writeLong(out, 0);
+			writeLong(out, 0);
+		}
+		writeShort(out, nameLength);
+		if (currentEntry.extra != null)
+			writeShort(out, currentEntry.extra.length);
+		else
+			writeShort(out, 0);
+		nameBytes = toUTF8Bytes(currentEntry.name, nameLength);
+		out.write(nameBytes);
+		if (currentEntry.extra != null)
+			out.write(currentEntry.extra);
+	}
+
+	/**
+	 * Sets the ZipFile comment associated with the file being written.
+	 * 
+	 */
+	public void setComment(String comment) {
+		if (comment.length() > 0xFFFF)
+			throw new IllegalArgumentException(Msg.getString("K0068"));
+		this.comment = comment;
+	}
+
+	/**
+	 * Sets the compression level to be used for writing entry data. This level
+	 * may be set on a per entry basis. level must have a value between 0 and
+	 * 10.
+	 * 
+	 */
+	public void setLevel(int level) {
+		if (level < Deflater.DEFAULT_COMPRESSION
+				|| level > Deflater.BEST_COMPRESSION)
+			throw new IllegalArgumentException();
+		compressLevel = level;
+	}
+
+	/**
+	 * Sets the compression method to be used when compressing entry data.
+	 * method must be one of STORED or DEFLATED.
+	 * 
+	 * @param method
+	 *            Compression method to use
+	 */
+	public void setMethod(int method) {
+		if (method != STORED && method != DEFLATED)
+			throw new IllegalArgumentException();
+		compressMethod = method;
+
+	}
+
+	private long writeLong(OutputStream os, long i) throws java.io.IOException {
+		// Write out the long value as an unsigned int
+		os.write((int) (i & 0xFF));
+		os.write((int) (i >> 8) & 0xFF);
+		os.write((int) (i >> 16) & 0xFF);
+		os.write((int) (i >> 24) & 0xFF);
+		return i;
+	}
+
+	private int writeShort(OutputStream os, int i) throws java.io.IOException {
+		os.write(i & 0xFF);
+		os.write((i >> 8) & 0xFF);
+		return i;
+
+	}
+
+	/**
+	 * Writes data for the current entry to the underlying stream.
+	 * 
+	 * @exception IOException
+	 *                If an error occurs writing to the stream
+	 */
+	public void write(byte[] buffer, int off, int nbytes)
+			throws java.io.IOException {
+		// avoid int overflow, check null buf
+		if ((off > buffer.length) || (nbytes < 0) || (off < 0)
+				|| (buffer.length - off < nbytes)) {
+			throw new IndexOutOfBoundsException();
+		}
+
+		if (currentEntry == null) {
+            /* [MSG "K00ab", "No active entry"] */
+            throw new ZipException(Msg.getString("K00ab"));
+        }
+
+		if (currentEntry.getMethod() == STORED)
+			out.write(buffer, off, nbytes);
+		else
+			super.write(buffer, off, nbytes);
+		crc.update(buffer, off, nbytes);
+	}
+
+	static int utf8Count(String value) {
+		int total = 0;
+		for (int i = value.length(); --i >= 0;) {
+			char ch = value.charAt(i);
+			if (ch < 0x80)
+				total++;
+			else if (ch < 0x800)
+				total += 2;
+			else
+				total += 3;
+		}
+		return total;
+	}
+
+	static byte[] toUTF8Bytes(String value, int length) {
+		byte[] result = new byte[length];
+		int pos = result.length;
+		for (int i = value.length(); --i >= 0;) {
+			char ch = value.charAt(i);
+			if (ch < 0x80)
+				result[--pos] = (byte) ch;
+			else if (ch < 0x800) {
+				result[--pos] = (byte) (0x80 | (ch & 0x3f));
+				result[--pos] = (byte) (0xc0 | (ch >> 6));
+			} else {
+				result[--pos] = (byte) (0x80 | (ch & 0x3f));
+				result[--pos] = (byte) (0x80 | ((ch >> 6) & 0x3f));
+				result[--pos] = (byte) (0xe0 | (ch >> 12));
+			}
+		}
+		return result;
+	}
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/java/util/zip/ZipOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/BHSDCodec.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/BHSDCodec.java?view=diff&rev=446478&r1=446477&r2=446478
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/BHSDCodec.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/BHSDCodec.java Thu Sep 14 19:40:33 2006
@@ -1,283 +1,283 @@
-/*
- *  Copyright 2006 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 org.apache.harmony.archive.internal.pack200;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * TODO Comment -- quite a lot can be nicked from Codec, since this was created
- * from it
- * 
- * @author Alex Blewitt
- * 
- */
-public final class BHSDCodec extends Codec {
-
-	/**
-	 * The maximum number of bytes in each coding word
-	 */
-	private int b;
-
-	/**
-	 * Whether delta encoding is used (0=false,1=true)
-	 */
-	private int d;
-
-	/**
-	 * The radix of the encoding
-	 */
-	private int h;
-
-	/**
-	 * The co-parameter of h; h-256
-	 */
-	private int l;
-
-	/**
-	 * Represents signed numbers or not (0=unsigned,1/2=signed)
-	 */
-	private int s;
-
-	/**
-	 * Constructs an unsigned, non-delta Codec with the given B and H values.
-	 * 
-	 * @param b
-	 *            the maximum number of bytes that a value can be encoded as
-	 *            [1..5]
-	 * @param h
-	 *            the radix of the encoding [1..256]
-	 */
-	public BHSDCodec(int b, int h) {
-		this(b, h, 0);
-	}
-
-	/**
-	 * Constructs a non-delta Codec with the given B, H and S values.
-	 * 
-	 * @param b
-	 *            the maximum number of bytes that a value can be encoded as
-	 *            [1..5]
-	 * @param h
-	 *            the radix of the encoding [1..256]
-	 * @param s
-	 *            whether the encoding represents signed numbers (s=0 is
-	 *            unsigned; s=1 is signed with 1s complement; s=2 is signed with ?)
-	 */
-	public BHSDCodec(int b, int h, int s) {
-		this(b, h, s, 0);
-	}
-
-	/**
-	 * Constructs a Codec with the given B, H, S and D values.
-	 * 
-	 * @param b
-	 *            the maximum number of bytes that a value can be encoded as
-	 *            [1..5]
-	 * @param h
-	 *            the radix of the encoding [1..256]
-	 * @param s
-	 *            whether the encoding represents signed numbers (s=0 is
-	 *            unsigned; s=1 is signed with 1s complement; s=2 is signed with ?)
-	 * @param d
-	 *            whether this is a delta encoding (d=0 is non-delta; d=1 is
-	 *            delta)
-	 */
-	public BHSDCodec(int b, int h, int s, int d) {
-		if (b < 1 || b > 5)
-			throw new IllegalArgumentException("1<=b<=5");
-		if (h < 1 || h > 256)
-			throw new IllegalArgumentException("1<=h<=256");
-		if (s < 0 || s > 2)
-			throw new IllegalArgumentException("0<=s<=2");
-		if (d < 0 || d > 1)
-			throw new IllegalArgumentException("0<=d<=1");
-		if (b == 1 && h != 256)
-			throw new IllegalArgumentException("b=1 -> h=256");
-		if (h == 256 && b == 5)
-			throw new IllegalArgumentException("h=256 -> b!=5");
-		this.b = b;
-		this.h = h;
-		this.s = s;
-		this.d = d;
-		this.l = 256 - h;
-	}
-
-	/**
-	 * Returns the cardinality of this codec; that is, the number of distinct
-	 * values that it can contain.
-	 * 
-	 * @return the cardinality of this codec
-	 */
-	public long cardinality() {
-		if (h > 1) {
-			return (long) (l * Math.pow(1 - h, b) / (1 - h) + Math.pow(h, b));
-		} else {
-			return (b * 255) + 1;
-		}
-	}
-
-	@Override
-	public long decode(InputStream in) throws IOException, Pack200Exception {
-		if (d != 0)
-			throw new Pack200Exception(
-					"Delta encoding used without passing in last value; this is a coding error");
-		return decode(in, 0);
-	}
-
-	@Override
-	public long decode(InputStream in, long last) throws IOException,
-			Pack200Exception {
-		int n = 0;
-		long z = 0;
-		long x;
-		do {
-			x = in.read();
-			if (x == -1)
-				throw new EOFException("End of stream reached whilst decoding");
-			z += x * Math.pow(h, n);
-		} while (++n < b && x >= l);
-		// This looks more complicated than it is
-		// When s=0, {1,2,3,4} is mapped to {1,2,3,4}
-		// When s=1, {1,2,3,4} is mapped to {-1,1,-2,2...}
-		// When s=2, {1,2,3,4} is mapped to {1,2,3,-1...}
-		if (isSigned()) {
-			int u = ((1 << s) - 1);
-			if ((z & u) == u) {
-				z = z >>> s ^ -1L;
-			} else {
-				z = z - (z >>> s);
-			}
-		}
-		if (isDelta())
-			z += last;
-		return z;
-	}
-
-	/**
-	 * True if this encoding can code the given value
-	 * 
-	 * @param value
-	 *            the value to check
-	 * @return <code>true</code> if the encoding can encode this value
-	 */
-	public boolean encodes(long value) {
-		return (value >= smallest() && value <= largest());
-	}
-
-	/**
-	 * Returns true if this codec is a delta codec
-	 * @return true if this codec is a delta codec
-	 */
-	public boolean isDelta() {
-		return d != 0;
-	}
-
-	/**
-	 * Returns true if this codec is a signed codec
-	 * @return true if this codec is a signed codec
-	 */
-	public boolean isSigned() {
-		return s != 0;
-	}
-
-	/**
-	 * Returns the largest value that this codec can represent.
-	 * 
-	 * @eturn the largest value that this codec can represent.
-	 */
-	public long largest() {
-		long result;
-		if (isDelta()) {
-			result = Long.MAX_VALUE;
-		} else {
-			// TODO This can probably be optimised into a better mathematical statement
-			if (s == 0) {
-				result = cardinality() - 1;
-			} else if (s == 1) {
-				result = cardinality() / 2 - 1;
-			} else if (s == 2) {
-				result = (3L * cardinality()) / 4 - 1;
-			} else {
-				throw new Error("Unknown s value");
-			}
-		}
-		return Math.min((s == 0 ? ((long) Integer.MAX_VALUE) << 1
-				: Integer.MAX_VALUE) - 1, result);
-	}
-	/**
-	 * Returns the smallest value that this codec can represent.
-	 * 
-	 * @eturn the smallest value that this codec can represent.
-	 */
-	public long smallest() {
-		long result;
-		if (isDelta()) {
-			result = Integer.MIN_VALUE;
-		} else {
-			if (isSigned()) {
-				result = -cardinality() / (1 << s);
-			} else {
-				result = 0;
-			}
-		}
-		return Math.max(Integer.MIN_VALUE, result);
-	}
-	/**
-	 * Returns the codec in the form (1,256) or (1,64,1,1). Note that trailing
-	 * zero fields are not shown.
-	 */
-	public String toString() {
-		StringBuffer buffer = new StringBuffer(11);
-		buffer.append('(');
-		buffer.append(b);
-		buffer.append(',');
-		buffer.append(h);
-		if (s != 0 || d != 0) {
-			buffer.append(",");
-			buffer.append(s);
-		}
-		if (d != 0) {
-			buffer.append(",");
-			buffer.append(d);
-		}
-		buffer.append(')');
-		return buffer.toString();
-	}
-
-	/**
-	 * @return the b
-	 */
-	public int getB() {
-		return b;
-	}
-
-	/**
-	 * @return the h
-	 */
-	public int getH() {
-		return h;
-	}
-
-	/**
-	 * @return the l
-	 */
-	public int getL() {
-		return l;
-	}
-}
+/*
+ *  Copyright 2006 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 org.apache.harmony.archive.internal.pack200;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * TODO Comment -- quite a lot can be nicked from Codec, since this was created
+ * from it
+ * 
+ * @author Alex Blewitt
+ * 
+ */
+public final class BHSDCodec extends Codec {
+
+	/**
+	 * The maximum number of bytes in each coding word
+	 */
+	private int b;
+
+	/**
+	 * Whether delta encoding is used (0=false,1=true)
+	 */
+	private int d;
+
+	/**
+	 * The radix of the encoding
+	 */
+	private int h;
+
+	/**
+	 * The co-parameter of h; h-256
+	 */
+	private int l;
+
+	/**
+	 * Represents signed numbers or not (0=unsigned,1/2=signed)
+	 */
+	private int s;
+
+	/**
+	 * Constructs an unsigned, non-delta Codec with the given B and H values.
+	 * 
+	 * @param b
+	 *            the maximum number of bytes that a value can be encoded as
+	 *            [1..5]
+	 * @param h
+	 *            the radix of the encoding [1..256]
+	 */
+	public BHSDCodec(int b, int h) {
+		this(b, h, 0);
+	}
+
+	/**
+	 * Constructs a non-delta Codec with the given B, H and S values.
+	 * 
+	 * @param b
+	 *            the maximum number of bytes that a value can be encoded as
+	 *            [1..5]
+	 * @param h
+	 *            the radix of the encoding [1..256]
+	 * @param s
+	 *            whether the encoding represents signed numbers (s=0 is
+	 *            unsigned; s=1 is signed with 1s complement; s=2 is signed with ?)
+	 */
+	public BHSDCodec(int b, int h, int s) {
+		this(b, h, s, 0);
+	}
+
+	/**
+	 * Constructs a Codec with the given B, H, S and D values.
+	 * 
+	 * @param b
+	 *            the maximum number of bytes that a value can be encoded as
+	 *            [1..5]
+	 * @param h
+	 *            the radix of the encoding [1..256]
+	 * @param s
+	 *            whether the encoding represents signed numbers (s=0 is
+	 *            unsigned; s=1 is signed with 1s complement; s=2 is signed with ?)
+	 * @param d
+	 *            whether this is a delta encoding (d=0 is non-delta; d=1 is
+	 *            delta)
+	 */
+	public BHSDCodec(int b, int h, int s, int d) {
+		if (b < 1 || b > 5)
+			throw new IllegalArgumentException("1<=b<=5");
+		if (h < 1 || h > 256)
+			throw new IllegalArgumentException("1<=h<=256");
+		if (s < 0 || s > 2)
+			throw new IllegalArgumentException("0<=s<=2");
+		if (d < 0 || d > 1)
+			throw new IllegalArgumentException("0<=d<=1");
+		if (b == 1 && h != 256)
+			throw new IllegalArgumentException("b=1 -> h=256");
+		if (h == 256 && b == 5)
+			throw new IllegalArgumentException("h=256 -> b!=5");
+		this.b = b;
+		this.h = h;
+		this.s = s;
+		this.d = d;
+		this.l = 256 - h;
+	}
+
+	/**
+	 * Returns the cardinality of this codec; that is, the number of distinct
+	 * values that it can contain.
+	 * 
+	 * @return the cardinality of this codec
+	 */
+	public long cardinality() {
+		if (h > 1) {
+			return (long) (l * Math.pow(1 - h, b) / (1 - h) + Math.pow(h, b));
+		} else {
+			return (b * 255) + 1;
+		}
+	}
+
+	@Override
+	public long decode(InputStream in) throws IOException, Pack200Exception {
+		if (d != 0)
+			throw new Pack200Exception(
+					"Delta encoding used without passing in last value; this is a coding error");
+		return decode(in, 0);
+	}
+
+	@Override
+	public long decode(InputStream in, long last) throws IOException,
+			Pack200Exception {
+		int n = 0;
+		long z = 0;
+		long x;
+		do {
+			x = in.read();
+			if (x == -1)
+				throw new EOFException("End of stream reached whilst decoding");
+			z += x * Math.pow(h, n);
+		} while (++n < b && x >= l);
+		// This looks more complicated than it is
+		// When s=0, {1,2,3,4} is mapped to {1,2,3,4}
+		// When s=1, {1,2,3,4} is mapped to {-1,1,-2,2...}
+		// When s=2, {1,2,3,4} is mapped to {1,2,3,-1...}
+		if (isSigned()) {
+			int u = ((1 << s) - 1);
+			if ((z & u) == u) {
+				z = z >>> s ^ -1L;
+			} else {
+				z = z - (z >>> s);
+			}
+		}
+		if (isDelta())
+			z += last;
+		return z;
+	}
+
+	/**
+	 * True if this encoding can code the given value
+	 * 
+	 * @param value
+	 *            the value to check
+	 * @return <code>true</code> if the encoding can encode this value
+	 */
+	public boolean encodes(long value) {
+		return (value >= smallest() && value <= largest());
+	}
+
+	/**
+	 * Returns true if this codec is a delta codec
+	 * @return true if this codec is a delta codec
+	 */
+	public boolean isDelta() {
+		return d != 0;
+	}
+
+	/**
+	 * Returns true if this codec is a signed codec
+	 * @return true if this codec is a signed codec
+	 */
+	public boolean isSigned() {
+		return s != 0;
+	}
+
+	/**
+	 * Returns the largest value that this codec can represent.
+	 * 
+	 * @eturn the largest value that this codec can represent.
+	 */
+	public long largest() {
+		long result;
+		if (isDelta()) {
+			result = Long.MAX_VALUE;
+		} else {
+			// TODO This can probably be optimised into a better mathematical statement
+			if (s == 0) {
+				result = cardinality() - 1;
+			} else if (s == 1) {
+				result = cardinality() / 2 - 1;
+			} else if (s == 2) {
+				result = (3L * cardinality()) / 4 - 1;
+			} else {
+				throw new Error("Unknown s value");
+			}
+		}
+		return Math.min((s == 0 ? ((long) Integer.MAX_VALUE) << 1
+				: Integer.MAX_VALUE) - 1, result);
+	}
+	/**
+	 * Returns the smallest value that this codec can represent.
+	 * 
+	 * @eturn the smallest value that this codec can represent.
+	 */
+	public long smallest() {
+		long result;
+		if (isDelta()) {
+			result = Integer.MIN_VALUE;
+		} else {
+			if (isSigned()) {
+				result = -cardinality() / (1 << s);
+			} else {
+				result = 0;
+			}
+		}
+		return Math.max(Integer.MIN_VALUE, result);
+	}
+	/**
+	 * Returns the codec in the form (1,256) or (1,64,1,1). Note that trailing
+	 * zero fields are not shown.
+	 */
+	public String toString() {
+		StringBuffer buffer = new StringBuffer(11);
+		buffer.append('(');
+		buffer.append(b);
+		buffer.append(',');
+		buffer.append(h);
+		if (s != 0 || d != 0) {
+			buffer.append(",");
+			buffer.append(s);
+		}
+		if (d != 0) {
+			buffer.append(",");
+			buffer.append(d);
+		}
+		buffer.append(')');
+		return buffer.toString();
+	}
+
+	/**
+	 * @return the b
+	 */
+	public int getB() {
+		return b;
+	}
+
+	/**
+	 * @return the h
+	 */
+	public int getH() {
+		return h;
+	}
+
+	/**
+	 * @return the l
+	 */
+	public int getL() {
+		return l;
+	}
+}

Propchange: incubator/harmony/enhanced/classlib/trunk/modules/archive/src/main/java/org/apache/harmony/archive/internal/pack200/BHSDCodec.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message