Commit 6d0c7d7b by Michael Koch Committed by Michael Koch

Deflater.java, [...]: Reformated and javadoc comments merged from classpath.

2004-02-05  Michael Koch  <konqueror@gmx.de>

	* java/util/zip/Deflater.java,
	java/util/zip/DeflaterOutputStream.java,
	java/util/zip/GZIPInputStream.java:
	Reformated and javadoc comments merged from classpath.

From-SVN: r77319
parent 99814868
2004-02-05 Michael Koch <konqueror@gmx.de> 2004-02-05 Michael Koch <konqueror@gmx.de>
* java/util/zip/Deflater.java,
java/util/zip/DeflaterOutputStream.java,
java/util/zip/GZIPInputStream.java:
Reformated and javadoc comments merged from classpath.
2004-02-05 Michael Koch <konqueror@gmx.de>
* gnu/java/nio/NIOServerSocket.java * gnu/java/nio/NIOServerSocket.java
(impl): Unused, removed. (impl): Unused, removed.
* gnu/java/nio/SocketChannelImpl.java * gnu/java/nio/SocketChannelImpl.java
......
/* Deflater.java - Compress a data stream /* Deflater.java - Compress a data stream
Copyright (C) 1999, 2000 Free Software Foundation, Inc. Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath. This file is part of GNU Classpath.
...@@ -40,13 +40,15 @@ package java.util.zip; ...@@ -40,13 +40,15 @@ package java.util.zip;
import gnu.gcj.RawData; import gnu.gcj.RawData;
/** /**
* This is the Deflater class. The deflater class compresses input
* with the deflate algorithm described in RFC 1951. It has several
* compression levels and three different strategies described below.
*
* This class is <i>not</i> thread safe. This is inherent in the API, due
* to the split of deflate and setInput.
*
* @author Jochen Hoenicke
* @author Tom Tromey * @author Tom Tromey
* @date May 17, 1999
*/
/* Written using on-line Java Platform 1.2 API Specification
* and JCL book.
* Believed complete and correct.
*/ */
public class Deflater public class Deflater
{ {
...@@ -91,95 +93,236 @@ public class Deflater ...@@ -91,95 +93,236 @@ public class Deflater
*/ */
public static final int DEFLATED = 8; public static final int DEFLATED = 8;
public int deflate (byte[] buf) /** Compression level. */
{ private int level;
return deflate (buf, 0, buf.length);
}
public native int deflate (byte[] buf, int off, int len); /** Compression strategy. */
private native void init (int level, boolean noHeader); private int strategy;
private native void update ();
/** The zlib stream. */
private RawData zstream;
public Deflater () /** True if finished. */
private boolean is_finished;
/** `Flush' flag to pass to next call to deflate. */
private int flush_flag;
/**
* Creates a new deflater with default compression level.
*/
public Deflater()
{ {
this (DEFAULT_COMPRESSION, false); this(DEFAULT_COMPRESSION, false);
} }
public Deflater (int lvl) /**
* Creates a new deflater with given compression level.
* @param lvl the compression level, a value between NO_COMPRESSION
* and BEST_COMPRESSION, or DEFAULT_COMPRESSION.
* @exception IllegalArgumentException if lvl is out of range.
*/
public Deflater(int lvl)
{ {
this (lvl, false); this(lvl, false);
} }
public Deflater (int lvl, boolean noHeader) /**
* Creates a new deflater with given compression level.
* @param lvl the compression level, a value between NO_COMPRESSION
* and BEST_COMPRESSION.
* @param nowrap true, iff we should suppress the deflate header at the
* beginning and the adler checksum at the end of the output. This is
* useful for the GZIP format.
* @exception IllegalArgumentException if lvl is out of range.
*/
public Deflater(int lvl, boolean noHeader)
{ {
this.strategy = DEFAULT_STRATEGY; this.strategy = DEFAULT_STRATEGY;
init (lvl, noHeader); init(lvl, noHeader);
setLevel (lvl); setLevel(lvl);
} }
public native void end (); private native void init(int level, boolean noHeader);
private native void update();
protected void finalize () /**
{ * Resets the deflater. The deflater acts afterwards as if it was
end (); * just created with the same compression level and strategy as it
} * had before.
*/
public native void reset();
/**
* Frees all objects allocated by the compressor. There's no
* reason to call this, since you can just rely on garbage
* collection. Exists only for compatibility against Sun's JDK,
* where the compressor allocates native memory.
* If you call any method (even reset) afterwards the behaviour is
* <i>undefined</i>.
* @deprecated Just clear all references to deflater instead.
*/
public native void end();
public native void finish (); /**
* Gets the current adler checksum of the data that was processed so
* far.
*/
public native int getAdler();
public synchronized boolean finished () /**
* Gets the number of input bytes processed so far.
*/
public native int getTotalIn();
/**
* Gets the number of output bytes so far.
*/
public native int getTotalOut();
/**
* Finalizes this object.
*/
protected void finalize()
{ {
return is_finished; end();
} }
public native int getAdler (); /**
public native int getTotalIn (); * Finishes the deflater with the current input block. It is an error
public native int getTotalOut (); * to give more input after this method was called. This method must
public native boolean needsInput (); * be called to force all bytes to be flushed.
public native void reset (); */
public native void finish();
public void setDictionary (byte[] buf) /**
* Returns true iff the stream was finished and no more output bytes
* are available.
*/
public synchronized boolean finished()
{ {
setDictionary (buf, 0, buf.length); return is_finished;
} }
public native void setDictionary (byte[] buf, int off, int len); /**
* Returns true, if the input buffer is empty.
* You should then call setInput(). <br>
*
* <em>NOTE</em>: This method can also return true when the stream
* was finished.
*/
public native boolean needsInput();
public void setInput (byte[] buf) /**
* Sets the data which should be compressed next. This should be only
* called when needsInput indicates that more input is needed.
* If you call setInput when needsInput() returns false, the
* previous input that is still pending will be thrown away.
* The given byte array should not be changed, before needsInput() returns
* true again.
* This call is equivalent to <code>setInput(input, 0, input.length)</code>.
* @param input the buffer containing the input data.
* @exception IllegalStateException if the buffer was finished() or ended().
*/
public void setInput(byte[] input)
{ {
setInput (buf, 0, buf.length); setInput(input, 0, input.length);
} }
public native void setInput (byte[] buf, int off, int len); /**
* Sets the data which should be compressed next. This should be
* only called when needsInput indicates that more input is needed.
* The given byte array should not be changed, before needsInput() returns
* true again.
* @param input the buffer containing the input data.
* @param off the start of the data.
* @param len the length of the data.
* @exception IllegalStateException if the buffer was finished() or ended()
* or if previous input is still pending.
*/
public native void setInput(byte[] input, int off, int len);
public synchronized void setLevel (int lvl) /**
* Sets the compression level. There is no guarantee of the exact
* position of the change, but if you call this when needsInput is
* true the change of compression level will occur somewhere near
* before the end of the so far given input.
* @param lvl the new compression level.
*/
public synchronized void setLevel(int lvl)
{ {
if (lvl != -1 && (lvl < 0 || lvl > 9)) if (lvl != -1 && (lvl < 0 || lvl > 9))
throw new IllegalArgumentException (); throw new IllegalArgumentException();
level = (lvl == -1) ? 6 : lvl; level = (lvl == -1) ? 6 : lvl;
update (); update();
} }
public synchronized void setStrategy (int stgy) /**
* Sets the compression strategy. Strategy is one of
* DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED. For the exact
* position where the strategy is changed, the same as for
* setLevel() applies.
* @param stgy the new compression strategy.
*/
public synchronized void setStrategy(int stgy)
{ {
if (stgy != DEFAULT_STRATEGY && stgy != FILTERED if (stgy != DEFAULT_STRATEGY && stgy != FILTERED
&& stgy != HUFFMAN_ONLY) && stgy != HUFFMAN_ONLY)
throw new IllegalArgumentException (); throw new IllegalArgumentException();
strategy = stgy; strategy = stgy;
update (); update();
} }
// Compression level. /**
private int level; * Deflates the current input block to the given array. It returns
* the number of bytes compressed, or 0 if either
// Compression strategy. * needsInput() or finished() returns true or length is zero.
private int strategy; * @param output the buffer where to write the compressed data.
*/
public int deflate(byte[] output)
{
return deflate(output, 0, output.length);
}
// The zlib stream. /**
private RawData zstream; * Deflates the current input block to the given array. It returns
* the number of bytes compressed, or 0 if either
* needsInput() or finished() returns true or length is zero.
* @param output the buffer where to write the compressed data.
* @param offset the offset into the output array.
* @param length the maximum number of bytes that may be written.
* @exception IllegalStateException if end() was called.
* @exception IndexOutOfBoundsException if offset and/or length
* don't match the array length.
*/
public native int deflate(byte[] output, int off, int len);
// True if finished. /**
private boolean is_finished; * Sets the dictionary which should be used in the deflate process.
* This call is equivalent to <code>setDictionary(dict, 0,
* dict.length)</code>.
* @param dict the dictionary.
* @exception IllegalStateException if setInput () or deflate ()
* were already called or another dictionary was already set.
*/
public void setDictionary(byte[] dict)
{
setDictionary(dict, 0, dict.length);
}
// `Flush' flag to pass to next call to deflate. /**
private int flush_flag; * Sets the dictionary which should be used in the deflate process.
* The dictionary should be a byte array containing strings that are
* likely to occur in the data which should be compressed. The
* dictionary is not stored in the compressed output, only a
* checksum. To decompress the output you need to supply the same
* dictionary again.
* @param dict the dictionary.
* @param offset an offset into the dictionary.
* @param length the length of the dictionary.
* @exception IllegalStateException if setInput () or deflate () were
* already called or another dictionary was already set.
*/
public native void setDictionary(byte[] buf, int off, int len);
} }
/* DeflaterOutputStream.java - Output filter for compressing. /* DeflaterOutputStream.java - Output filter for compressing.
Copyright (C) 1999, 2000 Free Software Foundation, Inc. Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath. This file is part of GNU Classpath.
......
/* GZIPInputStream.java - Input filter for reading gzip file /* GZIPInputStream.java - Input filter for reading gzip file
Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath. This file is part of GNU Classpath.
...@@ -41,73 +41,81 @@ import java.io.InputStream; ...@@ -41,73 +41,81 @@ import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
/** /**
* This filter stream is used to decompress a "GZIP" format stream.
* The "GZIP" format is described in RFC 1952.
*
* @author John Leuner
* @author Tom Tromey * @author Tom Tromey
* @date May 17, 1999 * @since JDK 1.1
*/ */
public class GZIPInputStream
/* Written using on-line Java Platform 1.2 API Specification extends InflaterInputStream
* and JCL book.
* Believed complete and correct.
*/
public class GZIPInputStream extends InflaterInputStream
{ {
/**
* The magic number found at the start of a GZIP stream.
*/
public static final int GZIP_MAGIC = 0x8b1f; public static final int GZIP_MAGIC = 0x8b1f;
public void close () throws IOException /**
{ * Creates a GZIPInputStream with the default buffer size.
// Nothing to do here. *
super.close(); * @param in The stream to read compressed data from
} * (in GZIP format).
*
public GZIPInputStream (InputStream istream) throws IOException * @throws IOException if an error occurs during an I/O operation.
*/
public GZIPInputStream(InputStream in)
throws IOException
{ {
this (istream, 512); this(in, 512);
} }
private final int eof_read () throws IOException /**
{ * Creates a GZIPInputStream with the specified buffer size.
int r = in.read(); *
if (r == -1) * @param in The stream to read compressed data from
throw new ZipException ("gzip header corrupted"); * (in GZIP format).
return r & 0xff; * @param size The size of the buffer to use.
} *
* @throws IOException if an error occurs during an I/O operation.
public GZIPInputStream (InputStream istream, int readsize) * @throws IllegalArgumentException if <code>size</code>
* is less than or equal to 0.
*/
public GZIPInputStream(InputStream in, int size)
throws IOException throws IOException
{ {
super (istream, new Inflater (true), readsize); super(in, new Inflater(true), size);
// NOTE: header reading code taken from zlib's gzio.c. // NOTE: header reading code taken from zlib's gzio.c.
// Read the magic number. // Read the magic number.
int magic = eof_read () | (eof_read () << 8); int magic = eof_read() | (eof_read() << 8);
if (magic != GZIP_MAGIC) if (magic != GZIP_MAGIC)
throw new ZipException ("gzip header corrupted"); throw new ZipException("gzip header corrupted");
int method = eof_read (); int method = eof_read();
int flags = eof_read (); int flags = eof_read();
// Test from zlib. // Test from zlib.
if (method != Z_DEFLATED || (flags & RESERVED) != 0) if (method != Z_DEFLATED || (flags & RESERVED) != 0)
throw new ZipException ("gzip header corrupted"); throw new ZipException("gzip header corrupted");
// Discard time, xflags, OS code. // Discard time, xflags, OS code.
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
eof_read (); eof_read();
// Skip the extra field. // Skip the extra field.
if ((flags & EXTRA_FIELD) != 0) if ((flags & EXTRA_FIELD) != 0)
{ {
int len = eof_read () | (eof_read () << 8); int len = eof_read() | (eof_read() << 8);
while (len-- != 0) while (len-- != 0)
eof_read (); eof_read();
} }
if ((flags & ORIG_NAME) != 0) if ((flags & ORIG_NAME) != 0)
{ {
while (true) while (true)
{ {
int c = eof_read (); int c = eof_read();
if (c == 0) if (c == 0)
break; break;
} }
...@@ -117,7 +125,7 @@ public class GZIPInputStream extends InflaterInputStream ...@@ -117,7 +125,7 @@ public class GZIPInputStream extends InflaterInputStream
{ {
while (true) while (true)
{ {
int c = eof_read (); int c = eof_read();
if (c == 0) if (c == 0)
break; break;
} }
...@@ -126,46 +134,78 @@ public class GZIPInputStream extends InflaterInputStream ...@@ -126,46 +134,78 @@ public class GZIPInputStream extends InflaterInputStream
if ((flags & HEAD_CRC) != 0) if ((flags & HEAD_CRC) != 0)
{ {
// FIXME: consider checking CRC of the header. // FIXME: consider checking CRC of the header.
eof_read (); eof_read();
eof_read (); eof_read();
} }
crc = new CRC32 (); crc = new CRC32();
}
/**
* Closes the input stream.
*
* @throws IOException if an error occurs during an I/O operation.
*/
public void close()
throws IOException
{
// Nothing to do here.
super.close();
}
private final int eof_read() throws IOException
{
int r = in.read();
if (r == -1)
throw new ZipException("gzip header corrupted");
return r & 0xff;
} }
public int read (byte[] buf, int off, int len) throws IOException /**
* Reads in GZIP-compressed data and stores it in uncompressed form
* into an array of bytes. The method will block until either
* enough input data becomes available or the compressed stream
* reaches its end.
*
* @param buf the buffer into which the uncompressed data will
* be stored.
* @param offset the offset indicating where in <code>buf</code>
* the uncompressed data should be placed.
* @param len the number of uncompressed bytes to be read.
*/
public int read(byte[] buf, int offset, int len) throws IOException
{ {
if (eos) if (eos)
return -1; return -1;
int r = super.read(buf, off, len); int r = super.read(buf, offset, len);
if (r == -1) if (r == -1)
{ {
eos = true; eos = true;
byte[] tmp = new byte[8]; byte[] tmp = new byte[8];
// First copy remaining bytes from inflater input buffer. // First copy remaining bytes from inflater input buffer.
int avail = inf.getRemaining (); int avail = inf.getRemaining();
System.arraycopy (this.buf, this.len - avail, tmp, 0, avail); System.arraycopy(this.buf, this.len - avail, tmp, 0, avail);
// Now read remaining bytes from wrapped input stream. // Now read remaining bytes from wrapped input stream.
for (int i = avail; i < 8; ++i) for (int i = avail; i < 8; ++i)
{ {
tmp[i] = (byte) eof_read (); tmp[i] = (byte) eof_read();
} }
int header_crc = read4 (tmp, 0); int header_crc = read4(tmp, 0);
if (crc.getValue() != header_crc) if (crc.getValue() != header_crc)
throw new ZipException ("corrupted gzip file - crc mismatch"); throw new ZipException("corrupted gzip file - crc mismatch");
int isize = read4 (tmp, 4); int isize = read4(tmp, 4);
if (inf.getTotalOut() != isize) if (inf.getTotalOut() != isize)
throw new ZipException ("corrupted gzip file - size mismatch"); throw new ZipException("corrupted gzip file - size mismatch");
return -1; return -1;
} }
crc.update(buf, off, r); crc.update(buf, offset, r);
return r; return r;
} }
private final int read4 (byte[] buf, int offset) throws IOException private final int read4(byte[] buf, int offset) throws IOException
{ {
return (((buf[offset + 3] & 0xFF) << 24) + ((buf[offset + 2] & 0xFF) << 16) return (((buf[offset + 3] & 0xFF) << 24) + ((buf[offset + 2] & 0xFF) << 16)
+ ((buf[offset + 1] & 0xFF) << 8) + (buf[offset] & 0xFF)); + ((buf[offset + 1] & 0xFF) << 8) + (buf[offset] & 0xFF));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment