rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/CRC32.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 26 Feb 2013 16:54:16 +0100
changeset 772 d382dacfd73f
parent 694 emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/zip/CRC32.java@0d277415ed02
permissions -rw-r--r--
Moving modules around so the runtime is under one master pom and can be built without building other modules that are in the repository
jaroslav@694
     1
/* -*-mode:java; c-basic-offset:2; -*- */
jaroslav@694
     2
/*
jaroslav@694
     3
Copyright (c) 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
import org.apidesign.bck2brwsr.emul.lang.System;
jaroslav@694
    38
jaroslav@694
    39
final class CRC32 implements Checksum {
jaroslav@694
    40
jaroslav@694
    41
  /*
jaroslav@694
    42
   *  The following logic has come from RFC1952.
jaroslav@694
    43
   */
jaroslav@694
    44
  private int v = 0;
jaroslav@694
    45
  private static int[] crc_table = null;
jaroslav@694
    46
  static {
jaroslav@694
    47
    crc_table = new int[256];
jaroslav@694
    48
    for (int n = 0; n < 256; n++) {
jaroslav@694
    49
      int c = n;
jaroslav@694
    50
      for (int k = 8;  --k >= 0; ) {
jaroslav@694
    51
        if ((c & 1) != 0)
jaroslav@694
    52
	  c = 0xedb88320 ^ (c >>> 1);
jaroslav@694
    53
        else
jaroslav@694
    54
          c = c >>> 1;
jaroslav@694
    55
      }
jaroslav@694
    56
      crc_table[n] = c;
jaroslav@694
    57
    }
jaroslav@694
    58
  }
jaroslav@694
    59
jaroslav@694
    60
  public void update (byte[] buf, int index, int len) {
jaroslav@694
    61
    int c = ~v;
jaroslav@694
    62
    while (--len >= 0)
jaroslav@694
    63
      c = crc_table[(c^buf[index++])&0xff]^(c >>> 8);
jaroslav@694
    64
    v = ~c;
jaroslav@694
    65
  }
jaroslav@694
    66
jaroslav@694
    67
  public void reset(){
jaroslav@694
    68
    v = 0;
jaroslav@694
    69
  }
jaroslav@694
    70
jaroslav@694
    71
  public void reset(long vv){
jaroslav@694
    72
    v = (int)(vv&0xffffffffL);
jaroslav@694
    73
  }
jaroslav@694
    74
jaroslav@694
    75
  public long getValue(){
jaroslav@694
    76
    return (long)(v&0xffffffffL);
jaroslav@694
    77
  }
jaroslav@694
    78
jaroslav@694
    79
  // The following logic has come from zlib.1.2.
jaroslav@694
    80
  private static final int GF2_DIM = 32;
jaroslav@694
    81
  static long combine(long crc1, long crc2, long len2){
jaroslav@694
    82
    long row;
jaroslav@694
    83
    long[] even = new long[GF2_DIM];
jaroslav@694
    84
    long[] odd = new long[GF2_DIM];
jaroslav@694
    85
jaroslav@694
    86
    // degenerate case (also disallow negative lengths)
jaroslav@694
    87
    if (len2 <= 0)
jaroslav@694
    88
      return crc1;
jaroslav@694
    89
jaroslav@694
    90
    // put operator for one zero bit in odd
jaroslav@694
    91
    odd[0] = 0xedb88320L;          // CRC-32 polynomial
jaroslav@694
    92
    row = 1;
jaroslav@694
    93
    for (int n = 1; n < GF2_DIM; n++) {
jaroslav@694
    94
        odd[n] = row;
jaroslav@694
    95
        row <<= 1;
jaroslav@694
    96
    }
jaroslav@694
    97
jaroslav@694
    98
    // put operator for two zero bits in even
jaroslav@694
    99
    gf2_matrix_square(even, odd);
jaroslav@694
   100
jaroslav@694
   101
    // put operator for four zero bits in odd
jaroslav@694
   102
    gf2_matrix_square(odd, even);
jaroslav@694
   103
jaroslav@694
   104
    // apply len2 zeros to crc1 (first square will put the operator for one
jaroslav@694
   105
    // zero byte, eight zero bits, in even)
jaroslav@694
   106
    do {
jaroslav@694
   107
      // apply zeros operator for this bit of len2
jaroslav@694
   108
      gf2_matrix_square(even, odd);
jaroslav@694
   109
      if ((len2 & 1)!=0)
jaroslav@694
   110
        crc1 = gf2_matrix_times(even, crc1);
jaroslav@694
   111
      len2 >>= 1;
jaroslav@694
   112
jaroslav@694
   113
      // if no more bits set, then done
jaroslav@694
   114
      if (len2 == 0)
jaroslav@694
   115
        break;
jaroslav@694
   116
jaroslav@694
   117
      // another iteration of the loop with odd and even swapped
jaroslav@694
   118
      gf2_matrix_square(odd, even);
jaroslav@694
   119
      if ((len2 & 1)!=0)
jaroslav@694
   120
        crc1 = gf2_matrix_times(odd, crc1);
jaroslav@694
   121
      len2 >>= 1;
jaroslav@694
   122
jaroslav@694
   123
      // if no more bits set, then done
jaroslav@694
   124
    } while (len2 != 0);
jaroslav@694
   125
jaroslav@694
   126
    /* return combined crc */
jaroslav@694
   127
    crc1 ^= crc2;
jaroslav@694
   128
    return crc1;
jaroslav@694
   129
  }
jaroslav@694
   130
jaroslav@694
   131
  private static long gf2_matrix_times(long[] mat, long vec){
jaroslav@694
   132
    long sum = 0;
jaroslav@694
   133
    int index = 0;
jaroslav@694
   134
    while (vec!=0) {
jaroslav@694
   135
      if ((vec & 1)!=0)
jaroslav@694
   136
        sum ^= mat[index];
jaroslav@694
   137
      vec >>= 1;
jaroslav@694
   138
      index++;
jaroslav@694
   139
    }
jaroslav@694
   140
    return sum;
jaroslav@694
   141
  }
jaroslav@694
   142
jaroslav@694
   143
  static final void gf2_matrix_square(long[] square, long[] mat) {
jaroslav@694
   144
    for (int n = 0; n < GF2_DIM; n++)
jaroslav@694
   145
      square[n] = gf2_matrix_times(mat, mat[n]);
jaroslav@694
   146
  }
jaroslav@694
   147
jaroslav@694
   148
  /*
jaroslav@694
   149
  private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32();
jaroslav@694
   150
jaroslav@694
   151
  public void update(byte[] buf, int index, int len){
jaroslav@694
   152
    if(buf==null) {crc32.reset();}
jaroslav@694
   153
    else{crc32.update(buf, index, len);}
jaroslav@694
   154
  }
jaroslav@694
   155
  public void reset(){
jaroslav@694
   156
    crc32.reset();
jaroslav@694
   157
  }
jaroslav@694
   158
  public void reset(long init){
jaroslav@694
   159
    if(init==0L){
jaroslav@694
   160
      crc32.reset();
jaroslav@694
   161
    }
jaroslav@694
   162
    else{
jaroslav@694
   163
      System.err.println("unsupported operation");
jaroslav@694
   164
    }
jaroslav@694
   165
  }
jaroslav@694
   166
  public long getValue(){
jaroslav@694
   167
    return crc32.getValue();
jaroslav@694
   168
  }
jaroslav@694
   169
*/
jaroslav@694
   170
  public CRC32 copy(){
jaroslav@694
   171
    CRC32 foo = new CRC32();
jaroslav@694
   172
    foo.v = this.v;
jaroslav@694
   173
    return foo;
jaroslav@694
   174
  }
jaroslav@694
   175
jaroslav@694
   176
  public static int[] getCRC32Table(){
jaroslav@694
   177
    int[] tmp = new int[crc_table.length];
jaroslav@694
   178
    System.arraycopy(crc_table, 0, tmp, 0, tmp.length);
jaroslav@694
   179
    return tmp;
jaroslav@694
   180
  }
jaroslav@694
   181
}