summaryrefslogtreecommitdiffstats
path: root/libjava/java/util/zip/Adler32.java
diff options
context:
space:
mode:
authormark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>2001-10-05 15:21:35 +0000
committermark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>2001-10-05 15:21:35 +0000
commit7aba1b549bf4c5425638f5854f18b5db497182b8 (patch)
treec9459fab54de3e6eecd0a0042778b45554b49b19 /libjava/java/util/zip/Adler32.java
parente2260a141216bc6e7ce1f58410e816ea7f37a38c (diff)
downloadppe42-gcc-7aba1b549bf4c5425638f5854f18b5db497182b8.tar.gz
ppe42-gcc-7aba1b549bf4c5425638f5854f18b5db497182b8.zip
* 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 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@46035 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/java/util/zip/Adler32.java')
-rw-r--r--libjava/java/util/zip/Adler32.java131
1 files changed, 99 insertions, 32 deletions
diff --git a/libjava/java/util/zip/Adler32.java b/libjava/java/util/zip/Adler32.java
index 989a2049283..0ced8f02187 100644
--- a/libjava/java/util/zip/Adler32.java
+++ b/libjava/java/util/zip/Adler32.java
@@ -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;
}
}
OpenPOWER on IntegriCloud