• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.core.checksums;
17 
18 import java.nio.ByteBuffer;
19 import java.util.zip.Checksum;
20 import software.amazon.awssdk.annotations.SdkPublicApi;
21 
22 /**
23  * Extension of {@link Checksum} to support checksums and checksum validations used by the SDK that
24  * are not provided by the JDK.
25  */
26 @SdkPublicApi
27 public interface SdkChecksum extends Checksum {
28 
29     /**
30      * Returns the computed checksum in a byte array rather than the long provided by
31      * {@link #getValue()}.
32      *
33      * @return byte[] containing the checksum
34      */
getChecksumBytes()35     byte[] getChecksumBytes();
36 
37     /**
38      * Allows marking a checksum for checksums that support the ability to mark and reset.
39      *
40      * @param readLimit the maximum limit of bytes that can be read before the mark position becomes invalid.
41      */
mark(int readLimit)42     void mark(int readLimit);
43 
44 
45 
46     /**
47      * Gets the Checksum based on the required Algorithm.
48      * Instances for CRC32C, CRC32 Algorithm will be added from CRT Java library once they are available in release.
49      * @param algorithm Algorithm for calculating the checksum
50      * @return Optional Checksum instances.
51      */
forAlgorithm(Algorithm algorithm)52     static SdkChecksum forAlgorithm(Algorithm algorithm) {
53 
54         switch (algorithm) {
55             case SHA256:
56                 return new Sha256Checksum();
57             case SHA1:
58                 return new Sha1Checksum();
59             case CRC32:
60                 return new Crc32Checksum();
61             case CRC32C:
62                 return new Crc32CChecksum();
63             default:
64                 throw new UnsupportedOperationException("Checksum not supported for " + algorithm);
65         }
66     }
67 
68     /**
69      * Updates the current checksum with the specified array of bytes.
70      *
71      * @param b the array of bytes to update the checksum with
72      *
73      * @throws NullPointerException
74      *         if {@code b} is {@code null}
75      */
update(byte[] b)76     default void update(byte[] b) {
77         update(b, 0, b.length);
78     }
79 
80 
81     /**
82      * Updates the current checksum with the bytes from the specified buffer.
83      *
84      * The checksum is updated with the remaining bytes in the buffer, starting
85      * at the buffer's position. Upon return, the buffer's position will be
86      * updated to its limit; its limit will not have been changed.
87      *
88      * @apiNote For best performance with DirectByteBuffer and other ByteBuffer
89      * implementations without a backing array implementers of this interface
90      * should override this method.
91      *
92      * @implSpec The default implementation has the following behavior.<br>
93      * For ByteBuffers backed by an accessible byte array.
94      * <pre>{@code
95      * update(buffer.array(),
96      *        buffer.position() + buffer.arrayOffset(),
97      *        buffer.remaining());
98      * }</pre>
99      * For ByteBuffers not backed by an accessible byte array.
100      * <pre>{@code
101      * byte[] b = new byte[Math.min(buffer.remaining(), 4096)];
102      * while (buffer.hasRemaining()) {
103      *     int length = Math.min(buffer.remaining(), b.length);
104      *     buffer.get(b, 0, length);
105      *     update(b, 0, length);
106      * }
107      * }</pre>
108      *
109      * @param buffer the ByteBuffer to update the checksum with
110      *
111      * @throws NullPointerException
112      *         if {@code buffer} is {@code null}
113      *
114      */
update(ByteBuffer buffer)115     default void update(ByteBuffer buffer) {
116         int pos = buffer.position();
117         int limit = buffer.limit();
118         int rem = limit - pos;
119         if (rem <= 0) {
120             return;
121         }
122         if (buffer.hasArray()) {
123             update(buffer.array(), pos + buffer.arrayOffset(), rem);
124         } else {
125             byte[] b = new byte[Math.min(buffer.remaining(), 4096)];
126             while (buffer.hasRemaining()) {
127                 int length = Math.min(buffer.remaining(), b.length);
128                 buffer.get(b, 0, length);
129                 update(b, 0, length);
130             }
131         }
132         buffer.position(limit);
133     }
134 
135 }
136