emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/Adler32.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 07 Feb 2013 12:58:12 +0100
branchemul
changeset 694 0d277415ed02
permissions -rw-r--r--
Rebasing the Inflater support on jzlib which, unlike GNU ClassPath, has correct implementation of Huffman code. Making the implementation more easily testable by turning Inflater and ZipInputStream into pure delegates. Current implementation is going to need proper long support.
jaroslav@694
     1
/* -*-mode:java; c-basic-offset:2; -*- */
jaroslav@694
     2
/*
jaroslav@694
     3
Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved.
jaroslav@694
     4
jaroslav@694
     5
Redistribution and use in source and binary forms, with or without
jaroslav@694
     6
modification, are permitted provided that the following conditions are met:
jaroslav@694
     7
jaroslav@694
     8
  1. Redistributions of source code must retain the above copyright notice,
jaroslav@694
     9
     this list of conditions and the following disclaimer.
jaroslav@694
    10
jaroslav@694
    11
  2. Redistributions in binary form must reproduce the above copyright 
jaroslav@694
    12
     notice, this list of conditions and the following disclaimer in 
jaroslav@694
    13
     the documentation and/or other materials provided with the distribution.
jaroslav@694
    14
jaroslav@694
    15
  3. The names of the authors may not be used to endorse or promote products
jaroslav@694
    16
     derived from this software without specific prior written permission.
jaroslav@694
    17
jaroslav@694
    18
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
jaroslav@694
    19
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
jaroslav@694
    20
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
jaroslav@694
    21
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
jaroslav@694
    22
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
jaroslav@694
    23
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
jaroslav@694
    24
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
jaroslav@694
    25
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
jaroslav@694
    26
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
jaroslav@694
    27
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
jaroslav@694
    28
 */
jaroslav@694
    29
/*
jaroslav@694
    30
 * This program is based on zlib-1.1.3, so all credit should go authors
jaroslav@694
    31
 * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
jaroslav@694
    32
 * and contributors of zlib.
jaroslav@694
    33
 */
jaroslav@694
    34
jaroslav@694
    35
package org.apidesign.bck2brwsr.emul.zip;
jaroslav@694
    36
jaroslav@694
    37
final class Adler32 implements Checksum {
jaroslav@694
    38
jaroslav@694
    39
  // largest prime smaller than 65536
jaroslav@694
    40
  static final private int BASE=65521; 
jaroslav@694
    41
  // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
jaroslav@694
    42
  static final private int NMAX=5552;
jaroslav@694
    43
jaroslav@694
    44
  private long s1=1L;
jaroslav@694
    45
  private long s2=0L;
jaroslav@694
    46
jaroslav@694
    47
  public void reset(long init){
jaroslav@694
    48
    s1=init&0xffff;
jaroslav@694
    49
    s2=(init>>16)&0xffff;
jaroslav@694
    50
  }
jaroslav@694
    51
jaroslav@694
    52
  public void reset(){
jaroslav@694
    53
    s1=1L;
jaroslav@694
    54
    s2=0L;
jaroslav@694
    55
  }
jaroslav@694
    56
jaroslav@694
    57
  public long getValue(){
jaroslav@694
    58
    return ((s2<<16)|s1);
jaroslav@694
    59
  }
jaroslav@694
    60
jaroslav@694
    61
  public void update(byte[] buf, int index, int len){
jaroslav@694
    62
jaroslav@694
    63
    if(len==1){
jaroslav@694
    64
      s1+=buf[index++]&0xff; s2+=s1;
jaroslav@694
    65
      s1%=BASE;
jaroslav@694
    66
      s2%=BASE;
jaroslav@694
    67
      return;
jaroslav@694
    68
    }
jaroslav@694
    69
jaroslav@694
    70
    int len1 = len/NMAX;
jaroslav@694
    71
    int len2 = len%NMAX;
jaroslav@694
    72
    while(len1-->0) {
jaroslav@694
    73
      int k=NMAX;
jaroslav@694
    74
      len-=k;
jaroslav@694
    75
      while(k-->0){
jaroslav@694
    76
	s1+=buf[index++]&0xff; s2+=s1;
jaroslav@694
    77
      }
jaroslav@694
    78
      s1%=BASE;
jaroslav@694
    79
      s2%=BASE;
jaroslav@694
    80
    }
jaroslav@694
    81
jaroslav@694
    82
    int k=len2;
jaroslav@694
    83
    len-=k;
jaroslav@694
    84
    while(k-->0){
jaroslav@694
    85
      s1+=buf[index++]&0xff; s2+=s1;
jaroslav@694
    86
    }
jaroslav@694
    87
    s1%=BASE;
jaroslav@694
    88
    s2%=BASE;
jaroslav@694
    89
  }
jaroslav@694
    90
jaroslav@694
    91
  public Adler32 copy(){
jaroslav@694
    92
    Adler32 foo = new Adler32();
jaroslav@694
    93
    foo.s1 = this.s1;
jaroslav@694
    94
    foo.s2 = this.s2;
jaroslav@694
    95
    return foo;
jaroslav@694
    96
  }
jaroslav@694
    97
jaroslav@694
    98
  // The following logic has come from zlib.1.2.
jaroslav@694
    99
  static long combine(long adler1, long adler2, long len2){
jaroslav@694
   100
    long BASEL = (long)BASE;
jaroslav@694
   101
    long sum1;
jaroslav@694
   102
    long sum2;
jaroslav@694
   103
    long rem;  // unsigned int
jaroslav@694
   104
jaroslav@694
   105
    rem = len2 % BASEL;
jaroslav@694
   106
    sum1 = adler1 & 0xffffL;
jaroslav@694
   107
    sum2 = rem * sum1;
jaroslav@694
   108
    sum2 %= BASEL; // MOD(sum2);
jaroslav@694
   109
    sum1 += (adler2 & 0xffffL) + BASEL - 1;
jaroslav@694
   110
    sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem;
jaroslav@694
   111
    if (sum1 >= BASEL) sum1 -= BASEL;
jaroslav@694
   112
    if (sum1 >= BASEL) sum1 -= BASEL;
jaroslav@694
   113
    if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1);
jaroslav@694
   114
    if (sum2 >= BASEL) sum2 -= BASEL;
jaroslav@694
   115
    return sum1 | (sum2 << 16);
jaroslav@694
   116
  }
jaroslav@694
   117
jaroslav@694
   118
/*
jaroslav@694
   119
  private java.util.zip.Adler32 adler=new java.util.zip.Adler32();
jaroslav@694
   120
  public void update(byte[] buf, int index, int len){
jaroslav@694
   121
    if(buf==null) {adler.reset();}
jaroslav@694
   122
    else{adler.update(buf, index, len);}
jaroslav@694
   123
  }
jaroslav@694
   124
  public void reset(){
jaroslav@694
   125
    adler.reset();
jaroslav@694
   126
  }
jaroslav@694
   127
  public void reset(long init){
jaroslav@694
   128
    if(init==1L){
jaroslav@694
   129
      adler.reset();
jaroslav@694
   130
    }
jaroslav@694
   131
    else{
jaroslav@694
   132
      System.err.println("unsupported operation");
jaroslav@694
   133
    }
jaroslav@694
   134
  }
jaroslav@694
   135
  public long getValue(){
jaroslav@694
   136
    return adler.getValue();
jaroslav@694
   137
  }
jaroslav@694
   138
*/
jaroslav@694
   139
}