Adler32.java revision 49965c1dc9da104344f4893a05e45795a5740d20
1/*
2 * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.util.zip;
27
28import java.nio.ByteBuffer;
29import sun.nio.ch.DirectBuffer;
30
31/**
32 * A class that can be used to compute the Adler-32 checksum of a data
33 * stream. An Adler-32 checksum is almost as reliable as a CRC-32 but
34 * can be computed much faster.
35 *
36 * @see         Checksum
37 * @author      David Connelly
38 */
39public
40class Adler32 implements Checksum {
41    private int adler = 1;
42
43    /**
44     * Creates a new Adler32 object.
45     */
46    public Adler32() {
47    }
48
49    /**
50     * Updates the checksum with the specified byte (the low eight
51     * bits of the argument b).
52     *
53     * @param b the byte to update the checksum with
54     */
55    public void update(int b) {
56        adler = update(adler, b);
57    }
58
59    /**
60     * Updates the checksum with the specified array of bytes.
61     */
62    public void update(byte[] b, int off, int len) {
63        if (b == null) {
64            throw new NullPointerException();
65        }
66        if (off < 0 || len < 0 || off > b.length - len) {
67            throw new ArrayIndexOutOfBoundsException();
68        }
69        adler = updateBytes(adler, b, off, len);
70    }
71
72    /**
73     * Updates the checksum with the specified array of bytes.
74     *
75     * @param b the byte array to update the checksum with
76     */
77    public void update(byte[] b) {
78        adler = updateBytes(adler, b, 0, b.length);
79    }
80
81    /**
82     * Updates the checksum with the bytes from the specified buffer.
83     *
84     * The checksum is updated using
85     * buffer.{@link java.nio.Buffer#remaining() remaining()}
86     * bytes starting at
87     * buffer.{@link java.nio.Buffer#position() position()}
88     * Upon return, the buffer's position will be updated to its
89     * limit; its limit will not have been changed.
90     *
91     * @param buffer the ByteBuffer to update the checksum with
92     */
93    private void update(ByteBuffer buffer) {
94        int pos = buffer.position();
95        int limit = buffer.limit();
96        assert (pos <= limit);
97        int rem = limit - pos;
98        if (rem <= 0)
99            return;
100        if (buffer instanceof DirectBuffer) {
101            adler = updateByteBuffer(adler, ((DirectBuffer)buffer).address(), pos, rem);
102        } else if (buffer.hasArray()) {
103            adler = updateBytes(adler, buffer.array(), pos + buffer.arrayOffset(), rem);
104        } else {
105            byte[] b = new byte[rem];
106            buffer.get(b);
107            adler = updateBytes(adler, b, 0, b.length);
108        }
109        buffer.position(limit);
110    }
111
112    /**
113     * Resets the checksum to initial value.
114     */
115    public void reset() {
116        adler = 1;
117    }
118
119    /**
120     * Returns the checksum value.
121     */
122    public long getValue() {
123        return (long)adler & 0xffffffffL;
124    }
125
126    // Set up JavaUtilZipAccess in SharedSecrets
127    /* ----- BEGIN android -----
128    static {
129       sun.misc.SharedSecrets.setJavaUtilZipAccess(new sun.misc.JavaUtilZipAccess() {
130           public void update(Adler32 adler32, ByteBuffer buf) {
131               adler32.update(buf);
132           }
133        });
134    }*/
135
136    private native static int update(int adler, int b);
137    private native static int updateBytes(int adler, byte[] b, int off,
138                                          int len);
139    private native static int updateByteBuffer(int adler, long addr,
140                                               int off, int len);
141}
142