1 /*
2  * Copyright (c) 2014, 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.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /**
25  * Base class for Checksum tests
26  */
27 import java.nio.ByteBuffer;
28 import java.nio.ByteOrder;
29 import java.nio.charset.StandardCharsets;
30 import java.util.zip.Checksum;
31 
32 public class ChecksumBase {
33 
34     private static final byte[] BYTES_123456789 = "123456789".getBytes(StandardCharsets.US_ASCII);
35 
testAll(Checksum checksum, long expected)36     public static void testAll(Checksum checksum, long expected) {
37         testBytes(checksum, expected);
38         testByteArray(checksum, expected);
39         testWrappedByteBuffer(checksum, expected);
40         testReadonlyByteBuffer(checksum, expected);
41         testDirectByteBuffer(checksum, expected);
42         testByteArrayOffset(checksum, expected);
43         testDirectByteBufferOffset(checksum, expected);
44         testLittleEndianDirectByteBufferOffset(checksum, expected);
45         testWrappedByteBufferOffset(checksum, expected);
46         testLittleEndianWrappedByteBufferOffset(checksum, expected);
47         testReadonlyByteBufferOffset(checksum, expected);
48         testLittleEndianReadonlyByteBufferOffset(checksum, expected);
49     }
50 
testBytes(Checksum checksum, long expected)51     private static void testBytes(Checksum checksum, long expected) {
52         checksum.reset();
53         for (byte bits : BYTES_123456789) {
54             checksum.update(bits);
55         }
56         checkChecksum(checksum, expected);
57     }
58 
testByteArray(Checksum checksum, long expected)59     private static void testByteArray(Checksum checksum, long expected) {
60         checksum.reset();
61         checksum.update(BYTES_123456789);
62         checkChecksum(checksum, expected);
63     }
64 
testWrappedByteBuffer(Checksum checksum, long expected)65     private static void testWrappedByteBuffer(Checksum checksum, long expected) {
66         checksum.reset();
67         ByteBuffer bb = ByteBuffer.wrap(BYTES_123456789);
68         checksum.update(bb);
69         checkChecksum(checksum, expected);
70     }
71 
testReadonlyByteBuffer(Checksum checksum, long expected)72     private static void testReadonlyByteBuffer(Checksum checksum, long expected) {
73         checksum.reset();
74         ByteBuffer bb = ByteBuffer.wrap(BYTES_123456789).asReadOnlyBuffer();
75         checksum.update(bb);
76         checkChecksum(checksum, expected);
77     }
78 
testDirectByteBuffer(Checksum checksum, long expected)79     private static void testDirectByteBuffer(Checksum checksum, long expected) {
80         checksum.reset();
81         ByteBuffer bb = ByteBuffer.allocateDirect(BYTES_123456789.length);
82         bb.put(BYTES_123456789);
83         bb.rewind();
84         checksum.update(bb);
85         checkChecksum(checksum, expected);
86     }
87 
checkChecksum(Checksum checksum, long expected)88     private static void checkChecksum(Checksum checksum, long expected) {
89         if (checksum.getValue() != expected) {
90             throw new RuntimeException("Calculated checksum result was invalid."
91                     + " Expected " + Long.toHexString(expected)
92                     + ", but got " + Long.toHexString(checksum.getValue()) + ".");
93         }
94     }
95 
testByteArrayOffset(Checksum checksum, long expected)96     private static void testByteArrayOffset(Checksum checksum, long expected) {
97         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
98         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
99             checksum.reset();
100             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
101             checksum.update(unaligned_bytes_123456789, i, BYTES_123456789.length);
102             checkChecksumOffset(checksum, expected, i);
103         }
104     }
105 
testDirectByteBufferOffset(Checksum checksum, long expected)106     private static void testDirectByteBufferOffset(Checksum checksum, long expected) {
107         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
108         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
109             checksum.reset();
110             ByteBuffer bb = ByteBuffer.allocateDirect(unaligned_bytes_123456789.length);
111             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
112             bb.put(unaligned_bytes_123456789);
113             bb.position(i);
114             bb.limit(i + BYTES_123456789.length);
115             checksum.update(bb);
116             checkChecksumOffset(checksum, expected, i);
117         }
118     }
119 
testLittleEndianDirectByteBufferOffset(Checksum checksum, long expected)120     private static void testLittleEndianDirectByteBufferOffset(Checksum checksum, long expected) {
121         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
122         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
123             checksum.reset();
124             ByteBuffer bb = ByteBuffer.allocateDirect(unaligned_bytes_123456789.length);
125             bb.order(ByteOrder.LITTLE_ENDIAN);
126             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
127             bb.put(unaligned_bytes_123456789);
128             bb.position(i);
129             bb.limit(i + BYTES_123456789.length);
130             checksum.update(bb);
131             checkChecksumOffset(checksum, expected, i);
132         }
133     }
134 
testWrappedByteBufferOffset(Checksum checksum, long expected)135     private static void testWrappedByteBufferOffset(Checksum checksum, long expected) {
136         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
137         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
138             checksum.reset();
139             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
140             ByteBuffer bb = ByteBuffer.wrap(unaligned_bytes_123456789);
141             bb.position(i);
142             bb.limit(i + BYTES_123456789.length);
143             checksum.update(bb);
144             checkChecksumOffset(checksum, expected, i);
145         }
146     }
147 
testLittleEndianWrappedByteBufferOffset(Checksum checksum, long expected)148     private static void testLittleEndianWrappedByteBufferOffset(Checksum checksum, long expected) {
149         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
150         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
151             checksum.reset();
152             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
153             ByteBuffer bb = ByteBuffer.wrap(unaligned_bytes_123456789);
154             bb.order(ByteOrder.LITTLE_ENDIAN);
155             bb.position(i);
156             bb.limit(i + BYTES_123456789.length);
157             checksum.update(bb);
158             checkChecksumOffset(checksum, expected, i);
159         }
160     }
161 
testReadonlyByteBufferOffset(Checksum checksum, long expected)162     private static void testReadonlyByteBufferOffset(Checksum checksum, long expected) {
163         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
164         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
165             checksum.reset();
166             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
167             ByteBuffer bb = ByteBuffer.wrap(unaligned_bytes_123456789).asReadOnlyBuffer();
168             bb.position(i);
169             bb.limit(i + BYTES_123456789.length);
170             checksum.update(bb);
171             checkChecksumOffset(checksum, expected, i);
172         }
173     }
174 
testLittleEndianReadonlyByteBufferOffset(Checksum checksum, long expected)175     private static void testLittleEndianReadonlyByteBufferOffset(Checksum checksum, long expected) {
176         byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64];
177         for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) {
178             checksum.reset();
179             System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length);
180             ByteBuffer bb = ByteBuffer.wrap(unaligned_bytes_123456789).asReadOnlyBuffer();
181             bb.order(ByteOrder.LITTLE_ENDIAN);
182             bb.position(i);
183             bb.limit(i + BYTES_123456789.length);
184             checksum.update(bb);
185             checkChecksumOffset(checksum, expected, i);
186         }
187     }
188 
checkChecksumOffset(Checksum checksum, long expected, int offset)189     private static void checkChecksumOffset(Checksum checksum, long expected, int offset) {
190         if (checksum.getValue() != expected) {
191             throw new RuntimeException("Calculated CRC32C result was invalid. Array offset "
192                     + offset + ". Expected: " + Long.toHexString(expected) + ", Got: "
193                     + Long.toHexString(checksum.getValue()));
194         }
195     }
196 }
197