1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.compression;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.util.ByteProcessor;
20 import io.netty.util.internal.ObjectUtil;
21 import io.netty.util.internal.PlatformDependent;
22
23 import java.nio.ByteBuffer;
24 import java.util.zip.Adler32;
25 import java.util.zip.CRC32;
26 import java.util.zip.Checksum;
27
28
29
30
31
32
33
34 abstract class ByteBufChecksum implements Checksum {
35 private final ByteProcessor updateProcessor = new ByteProcessor() {
36 @Override
37 public boolean process(byte value) throws Exception {
38 update(value);
39 return true;
40 }
41 };
42
43 static ByteBufChecksum wrapChecksum(Checksum checksum) {
44 ObjectUtil.checkNotNull(checksum, "checksum");
45 if (checksum instanceof ByteBufChecksum) {
46 return (ByteBufChecksum) checksum;
47 }
48 return new JdkByteBufChecksum(checksum);
49 }
50
51
52
53
54 public void update(ByteBuf b, int off, int len) {
55 if (b.hasArray()) {
56 update(b.array(), b.arrayOffset() + off, len);
57 } else {
58 b.forEachByte(off, len, updateProcessor);
59 }
60 }
61
62 private static class JdkByteBufChecksum extends ByteBufChecksum {
63 protected final Checksum checksum;
64 private byte[] scratchBuffer;
65
66 JdkByteBufChecksum(Checksum checksum) {
67 this.checksum = checksum;
68 }
69
70 @Override
71 public void update(int b) {
72 checksum.update(b);
73 }
74
75 @Override
76 public void update(ByteBuf b, int off, int len) {
77 if (b.hasArray()) {
78 update(b.array(), b.arrayOffset() + off, len);
79 } else if (checksum instanceof CRC32) {
80 ByteBuffer byteBuffer = getSafeBuffer(b, off, len);
81 ((CRC32) checksum).update(byteBuffer);
82 } else if (checksum instanceof Adler32) {
83 ByteBuffer byteBuffer = getSafeBuffer(b, off, len);
84 ((Adler32) checksum).update(byteBuffer);
85 } else {
86 super.update(b, off, len);
87 }
88 }
89
90 private ByteBuffer getSafeBuffer(ByteBuf b, int off, int len) {
91 ByteBuffer byteBuffer = CompressionUtil.safeNioBuffer(b, off, len);
92 int javaVersion = PlatformDependent.javaVersion();
93 if (javaVersion >= 22 && javaVersion < 25 && byteBuffer.isDirect()) {
94
95 if (scratchBuffer == null || scratchBuffer.length < len) {
96 scratchBuffer = new byte[len];
97 }
98 ByteBuffer copy = ByteBuffer.wrap(scratchBuffer, 0, len);
99 copy.put(byteBuffer).flip();
100 return copy;
101 }
102 return byteBuffer;
103 }
104
105 @Override
106 public void update(byte[] b, int off, int len) {
107 checksum.update(b, off, len);
108 }
109
110 @Override
111 public long getValue() {
112 return checksum.getValue();
113 }
114
115 @Override
116 public void reset() {
117 checksum.reset();
118 }
119 }
120 }