Home | History | Annotate | Download | only in zip
      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 
     26 package java.util.zip;
     27 
     28 import java.nio.ByteBuffer;
     29 import 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  */
     39 public
     40 class 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