Adler32.java: Merge with Classpath

* java/util/zip/Adler32.java: Merge with Classpath
	* java/util/zip/CRC32.java: Ditto
	* java/util/zip/Checksum.java: Ditto
	* java/util/zip/DataFormatException.java: Ditto
	* java/util/zip/ZipException.java: Ditto

From-SVN: r46035
This commit is contained in:
Mark Wielaard
2001-10-05 15:21:35 +00:00
committed by Mark Wielaard
parent e62bad3dc9
commit 2600825ee1
6 changed files with 134 additions and 52 deletions
+99 -32
View File
@@ -1,5 +1,5 @@
/* Adler.java - Computes Adler32 data checksum of a data stream
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
/* Adler32.java - Computes Adler32 data checksum of a data stream
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -7,7 +7,7 @@ GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -34,29 +34,71 @@ package java.util.zip;
*/
/**
* Computes Adler32 data checksum of a data stream.
* The actual Adler32 algorithm is described in RFC 1950
* (ZLIB Compressed Data Format Specification version 3.3).
* Can be used to get the CRC32 over a stream if used with checked input/output
* streams.
* Computes Adler32 checksum for a stream of data. An Adler32
* checksum is not as reliable as a CRC32 checksum, but a lot faster to
* compute.
*<p>
* The specification for Adler32 may be found in RFC 1950.
* (ZLIB Compressed Data Format Specification version 3.3)
*<p>
*<p>
* From that document:
*<p>
* "ADLER32 (Adler-32 checksum)
* This contains a checksum value of the uncompressed data
* (excluding any dictionary data) computed according to Adler-32
* algorithm. This algorithm is a 32-bit extension and improvement
* of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
* standard.
*<p>
* Adler-32 is composed of two sums accumulated per byte: s1 is
* the sum of all bytes, s2 is the sum of all s1 values. Both sums
* are done modulo 65521. s1 is initialized to 1, s2 to zero. The
* Adler-32 checksum is stored as s2*65536 + s1 in most-
* significant-byte first (network) order."
*<p>
* "8.2. The Adler-32 algorithm
*<p>
* The Adler-32 algorithm is much faster than the CRC32 algorithm yet
* still provides an extremely low probability of undetected errors.
*<p>
* The modulo on unsigned long accumulators can be delayed for 5552
* bytes, so the modulo operation time is negligible. If the bytes
* are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
* and order sensitive, unlike the first sum, which is just a
* checksum. That 65521 is prime is important to avoid a possible
* large class of two-byte errors that leave the check unchanged.
* (The Fletcher checksum uses 255, which is not prime and which also
* makes the Fletcher check insensitive to single byte changes 0 <->
* 255.)
*<p>
* The sum s1 is initialized to 1 instead of zero to make the length
* of the sequence part of s2, so that the length does not have to be
* checked separately. (Any sequence of zeroes has a Fletcher
* checksum of zero.)"
*
* @author John Leuner, Per Bothner
* @since JDK 1.1
*
* @see InflaterInputStream
* @see InflaterOutputStream
*
* @author Per Bothner
* @date April 6, 1999.
*/
public class Adler32 implements Checksum
{
/** largest prime smaller than 65536 */
private static int BASE = 65521;
private int s1;
private int s2;
private static final int BASE = 65521;
private int checksum; //we do all in int.
//Note that java doesn't have unsigned integers,
//so we have to be careful with what arithmetic
//we do. We return the checksum as a long to
//avoid sign confusion.
/**
* Creates an Adler32 data checksum.
* Creates a new instance of the <code>Adler32</code> class.
* The checksum starts off with a value of 1.
*/
public Adler32 ()
{
@@ -64,23 +106,35 @@ public class Adler32 implements Checksum
}
/**
* Resets the Adler32 data checksum as if no update was ever called.
* Resets the Adler32 checksum to the initial value.
*/
public void reset () { s1 = 1; s2 = 0; }
public void reset ()
{
checksum = 1; //Initialize to 1
}
/**
* Adds one byte to the data checksum.
* Updates the checksum with the byte b.
*
* @param bval the data value to add. The high byte of the int is ignored.
*/
public void update (int bval)
{
//We could make a length 1 byte array and call update again, but I
//would rather not have that overhead
int s1 = checksum & 0xffff;
int s2 = checksum >>> 16;
s1 = (s1 + (bval & 0xFF)) % BASE;
s2 = (s1 + s2) % BASE;
checksum = (s2 << 16) + s1;
}
/**
* Adds the complete byte array to the data checksum.
* Updates the checksum with the bytes taken from the array.
*
* @param buffer an array of bytes
*/
public void update (byte[] buffer)
{
@@ -88,20 +142,24 @@ public class Adler32 implements Checksum
}
/**
* Adds the byte array to the data checksum.
*
* @param buf the buffer which contains the data
* @param off the offset in the buffer where the data starts
* @param len the length of the data
* Updates the checksum with the bytes taken from the array.
*
* @param buf an array of bytes
* @param off the start of the data used for this update
* @param len the number of bytes to use for this update
*/
public void update (byte[] buf, int off, int len)
{
int s1 = this.s1;
int s2 = this.s2;
//(By Per Bothner)
int s1 = checksum & 0xffff;
int s2 = checksum >>> 16;
while (len > 0)
{
// We can defer the modulo operation.
int n = 4000;
// We can defer the modulo operation:
// s1 maximally grows from 65521 to 65521 + 255 * 3800
// s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
int n = 3800;
if (n > len)
n = len;
len -= n;
@@ -113,8 +171,17 @@ public class Adler32 implements Checksum
s1 %= BASE;
s2 %= BASE;
}
this.s1 = s1;
this.s2 = s2;
/*Old implementation, borrowed from somewhere:
int n;
while (len-- > 0) {
s1 = (s1 + (bs[offset++] & 0xff)) % BASE;
s2 = (s2 + s1) % BASE;
}*/
checksum = (s2 << 16) | s1;
}
/**
@@ -122,6 +189,6 @@ public class Adler32 implements Checksum
*/
public long getValue()
{
return ((long) s2 << 16) + s1;
return (long) checksum & 0xffffffffL;
}
}