View Javadoc
1   /*
2    * Copyright 2016 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty5.handler.codec.compression;
17  
18  import io.netty5.buffer.api.Buffer;
19  
20  import java.nio.ByteBuffer;
21  import java.util.zip.Checksum;
22  
23  import static java.util.Objects.requireNonNull;
24  
25  /**
26   * {@link Checksum} implementation which can directly act on a {@link Buffer}.
27   */
28  class BufferChecksum implements Checksum {
29  
30      private final Checksum checksum;
31  
32      BufferChecksum(Checksum checksum) {
33          this.checksum = requireNonNull(checksum);
34      }
35  
36      @Override
37      public void update(int b) {
38          checksum.update(b);
39      }
40  
41      @Override
42      public void update(byte[] b, int off, int len) {
43          checksum.update(b, off, len);
44      }
45  
46      @Override
47      public long getValue() {
48          return checksum.getValue();
49      }
50  
51      @Override
52      public void reset() {
53          checksum.reset();
54      }
55  
56      /**
57       * @see #update(byte[], int, int)
58       */
59      public void update(Buffer b, int off, int len) {
60          int readerOffset = b.readerOffset();
61          b.readerOffset(off);
62          try {
63              try (var iteration = b.forEachReadable()) {
64                  for (var c = iteration.first(); c != null; c = c.next()) {
65                      ByteBuffer componentBuffer = c.readableBuffer();
66                      if (componentBuffer.remaining() > len) {
67                          componentBuffer.limit(componentBuffer.position() + len);
68                          update(componentBuffer);
69                          break;
70                      } else {
71                          len -= componentBuffer.remaining();
72                          update(componentBuffer);
73                      }
74                  }
75              }
76          } finally {
77              b.readerOffset(readerOffset);
78          }
79      }
80  }