Home | History | Annotate | Download | only in zip
      1 /*
      2  * Copyright (c) 1996, 2013, 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  * <p> Passing a {@code null} argument to a method in this class will cause
     37  * a {@link NullPointerException} to be thrown.
     38  *
     39  * @see         Checksum
     40  * @author      David Connelly
     41  */
     42 public
     43 class Adler32 implements Checksum {
     44 
     45     private int adler = 1;
     46 
     47     /**
     48      * Creates a new Adler32 object.
     49      */
     50     public Adler32() {
     51     }
     52 
     53     /**
     54      * Updates the checksum with the specified byte (the low eight
     55      * bits of the argument b).
     56      *
     57      * @param b the byte to update the checksum with
     58      */
     59     public void update(int b) {
     60         adler = update(adler, b);
     61     }
     62 
     63     /**
     64      * Updates the checksum with the specified array of bytes.
     65      *
     66      * @throws  ArrayIndexOutOfBoundsException
     67      *          if {@code off} is negative, or {@code len} is negative,
     68      *          or {@code off+len} is greater than the length of the
     69      *          array {@code b}
     70      */
     71     public void update(byte[] b, int off, int len) {
     72         if (b == null) {
     73             throw new NullPointerException();
     74         }
     75         if (off < 0 || len < 0 || off > b.length - len) {
     76             throw new ArrayIndexOutOfBoundsException();
     77         }
     78         adler = updateBytes(adler, b, off, len);
     79     }
     80 
     81     /**
     82      * Updates the checksum with the specified array of bytes.
     83      *
     84      * @param b the byte array to update the checksum with
     85      */
     86     public void update(byte[] b) {
     87         adler = updateBytes(adler, b, 0, b.length);
     88     }
     89 
     90 
     91     /**
     92      * Updates the checksum with the bytes from the specified buffer.
     93      *
     94      * The checksum is updated using
     95      * buffer.{@link java.nio.Buffer#remaining() remaining()}
     96      * bytes starting at
     97      * buffer.{@link java.nio.Buffer#position() position()}
     98      * Upon return, the buffer's position will be updated to its
     99      * limit; its limit will not have been changed.
    100      *
    101      * @param buffer the ByteBuffer to update the checksum with
    102      * @since 1.8
    103      */
    104     public void update(ByteBuffer buffer) {
    105         int pos = buffer.position();
    106         int limit = buffer.limit();
    107         assert (pos <= limit);
    108         int rem = limit - pos;
    109         if (rem <= 0)
    110             return;
    111         if (buffer instanceof DirectBuffer) {
    112             adler = updateByteBuffer(adler, ((DirectBuffer)buffer).address(), pos, rem);
    113         } else if (buffer.hasArray()) {
    114             adler = updateBytes(adler, buffer.array(), pos + buffer.arrayOffset(), rem);
    115         } else {
    116             byte[] b = new byte[rem];
    117             buffer.get(b);
    118             adler = updateBytes(adler, b, 0, b.length);
    119         }
    120         buffer.position(limit);
    121     }
    122 
    123     /**
    124      * Resets the checksum to initial value.
    125      */
    126     public void reset() {
    127         adler = 1;
    128     }
    129 
    130     /**
    131      * Returns the checksum value.
    132      */
    133     public long getValue() {
    134         return (long)adler & 0xffffffffL;
    135     }
    136 
    137     private native static int update(int adler, int b);
    138     private native static int updateBytes(int adler, byte[] b, int off,
    139                                           int len);
    140     private native static int updateByteBuffer(int adler, long addr,
    141                                                int off, int len);
    142 }
    143