| /* | |
| * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| import java.lang.foreign.MemorySegment; | |
| import java.nio.ByteBuffer; | |
| import java.nio.ByteOrder; | |
| import java.nio.charset.StandardCharsets; | |
| import java.util.zip.Checksum; | |
| /** | |
| * Base class for Checksum tests | |
| */ | |
| public class ChecksumBase { | |
| private static final byte[] BYTES_123456789 = "123456789".getBytes(StandardCharsets.US_ASCII); | |
| public static void testAll(Checksum checksum, long expected) { | |
| testBytes(checksum, expected); | |
| testByteArray(checksum, expected); | |
| testWrappedMemorySegment(checksum, expected); | |
| testWrappedByteBuffer(checksum, expected); | |
| testReadonlyByteBuffer(checksum, expected); | |
| testDirectByteBuffer(checksum, expected); | |
| testByteArrayOffset(checksum, expected); | |
| testDirectByteBufferOffset(checksum, expected); | |
| testLittleEndianDirectByteBufferOffset(checksum, expected); | |
| testWrappedByteBufferOffset(checksum, expected); | |
| testLittleEndianWrappedByteBufferOffset(checksum, expected); | |
| testReadonlyByteBufferOffset(checksum, expected); | |
| testLittleEndianReadonlyByteBufferOffset(checksum, expected); | |
| } | |
| private static void testBytes(Checksum checksum, long expected) { | |
| checksum.reset(); | |
| for (byte bits : BYTES_123456789) { | |
| checksum.update(bits); | |
| } | |
| checkChecksum(checksum, expected); | |
| } | |
| private static void testByteArray(Checksum checksum, long expected) { | |
| checksum.reset(); | |
| checksum.update(BYTES_123456789); | |
| checkChecksum(checksum, expected); | |
| } | |
| private static void testWrappedByteBuffer(Checksum checksum, long expected) { | |
| checksum.reset(); | |
| ByteBuffer bb = ByteBuffer.wrap(BYTES_123456789); | |
| checksum.update(bb); | |
| checkChecksum(checksum, expected); | |
| } | |
| private static void testWrappedMemorySegment(Checksum checksum, long expected) { | |
| checksum.reset(); | |
| ByteBuffer bb = MemorySegment.ofArray(BYTES_123456789).asByteBuffer(); | |
| checksum.update(bb); | |
| checkChecksum(checksum, expected); | |
| } | |
| private static void testReadonlyByteBuffer(Checksum checksum, long expected) { | |
| checksum.reset(); | |
| ByteBuffer bb = ByteBuffer.wrap(BYTES_123456789).asReadOnlyBuffer(); | |
| checksum.update(bb); | |
| checkChecksum(checksum, expected); | |
| } | |
| private static void testDirectByteBuffer(Checksum checksum, long expected) { | |
| checksum.reset(); | |
| ByteBuffer bb = ByteBuffer.allocateDirect(BYTES_123456789.length); | |
| bb.put(BYTES_123456789); | |
| bb.rewind(); | |
| checksum.update(bb); | |
| checkChecksum(checksum, expected); | |
| } | |
| private static void checkChecksum(Checksum checksum, long expected) { | |
| if (checksum.getValue() != expected) { | |
| throw new RuntimeException("Calculated checksum result was invalid." | |
| + " Expected " + Long.toHexString(expected) | |
| + ", but got " + Long.toHexString(checksum.getValue()) + "."); | |
| } | |
| } | |
| private static void testByteArrayOffset(Checksum checksum, long expected) { | |
| byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64]; | |
| for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) { | |
| checksum.reset(); | |
| System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length); | |
| checksum.update(unaligned_bytes_123456789, i, BYTES_123456789.length); | |
| checkChecksumOffset(checksum, expected, i); | |
| } | |
| } | |
| private static void testDirectByteBufferOffset(Checksum checksum, long expected) { | |
| byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64]; | |
| for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) { | |
| checksum.reset(); | |
| ByteBuffer bb = ByteBuffer.allocateDirect(unaligned_bytes_123456789.length); | |
| System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length); | |
| bb.put(unaligned_bytes_123456789); | |
| bb.position(i); | |
| bb.limit(i + BYTES_123456789.length); | |
| checksum.update(bb); | |
| checkChecksumOffset(checksum, expected, i); | |
| } | |
| } | |
| private static void testLittleEndianDirectByteBufferOffset(Checksum checksum, long expected) { | |
| byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64]; | |
| for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) { | |
| checksum.reset(); | |
| ByteBuffer bb = ByteBuffer.allocateDirect(unaligned_bytes_123456789.length); | |
| bb.order(ByteOrder.LITTLE_ENDIAN); | |
| System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length); | |
| bb.put(unaligned_bytes_123456789); | |
| bb.position(i); | |
| bb.limit(i + BYTES_123456789.length); | |
| checksum.update(bb); | |
| checkChecksumOffset(checksum, expected, i); | |
| } | |
| } | |
| private static void testWrappedByteBufferOffset(Checksum checksum, long expected) { | |
| byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64]; | |
| for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) { | |
| checksum.reset(); | |
| System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length); | |
| ByteBuffer bb = ByteBuffer.wrap(unaligned_bytes_123456789); | |
| bb.position(i); | |
| bb.limit(i + BYTES_123456789.length); | |
| checksum.update(bb); | |
| checkChecksumOffset(checksum, expected, i); | |
| } | |
| } | |
| private static void testLittleEndianWrappedByteBufferOffset(Checksum checksum, long expected) { | |
| byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64]; | |
| for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) { | |
| checksum.reset(); | |
| System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length); | |
| ByteBuffer bb = ByteBuffer.wrap(unaligned_bytes_123456789); | |
| bb.order(ByteOrder.LITTLE_ENDIAN); | |
| bb.position(i); | |
| bb.limit(i + BYTES_123456789.length); | |
| checksum.update(bb); | |
| checkChecksumOffset(checksum, expected, i); | |
| } | |
| } | |
| private static void testReadonlyByteBufferOffset(Checksum checksum, long expected) { | |
| byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64]; | |
| for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) { | |
| checksum.reset(); | |
| System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length); | |
| ByteBuffer bb = ByteBuffer.wrap(unaligned_bytes_123456789).asReadOnlyBuffer(); | |
| bb.position(i); | |
| bb.limit(i + BYTES_123456789.length); | |
| checksum.update(bb); | |
| checkChecksumOffset(checksum, expected, i); | |
| } | |
| } | |
| private static void testLittleEndianReadonlyByteBufferOffset(Checksum checksum, long expected) { | |
| byte[] unaligned_bytes_123456789 = new byte[BYTES_123456789.length + 64]; | |
| for (int i = 0; i < unaligned_bytes_123456789.length - BYTES_123456789.length; i++) { | |
| checksum.reset(); | |
| System.arraycopy(BYTES_123456789, 0, unaligned_bytes_123456789, i, BYTES_123456789.length); | |
| ByteBuffer bb = ByteBuffer.wrap(unaligned_bytes_123456789).asReadOnlyBuffer(); | |
| bb.order(ByteOrder.LITTLE_ENDIAN); | |
| bb.position(i); | |
| bb.limit(i + BYTES_123456789.length); | |
| checksum.update(bb); | |
| checkChecksumOffset(checksum, expected, i); | |
| } | |
| } | |
| private static void checkChecksumOffset(Checksum checksum, long expected, int offset) { | |
| if (checksum.getValue() != expected) { | |
| throw new RuntimeException("Calculated CRC32C result was invalid. Array offset " | |
| + offset + ". Expected: " + Long.toHexString(expected) + ", Got: " | |
| + Long.toHexString(checksum.getValue())); | |
| } | |
| } | |
| } |