1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.protobuf;
17
18 import com.google.protobuf.CodedInputStream;
19 import com.google.protobuf.nano.CodedInputByteBufferNano;
20 import io.netty.buffer.ByteBuf;
21 import io.netty.channel.ChannelHandlerContext;
22 import io.netty.handler.codec.ByteToMessageDecoder;
23 import io.netty.handler.codec.CorruptedFrameException;
24
25 import java.util.List;
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public class ProtobufVarint32FrameDecoder extends ByteToMessageDecoder {
44
45
46
47
48 @Override
49 protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
50 throws Exception {
51 in.markReaderIndex();
52 int preIndex = in.readerIndex();
53 int length = readRawVarint32(in);
54 if (preIndex == in.readerIndex()) {
55 return;
56 }
57 if (length < 0) {
58 throw new CorruptedFrameException("negative length: " + length);
59 }
60
61 if (in.readableBytes() < length) {
62 in.resetReaderIndex();
63 } else {
64 out.add(in.readRetainedSlice(length));
65 }
66 }
67
68
69
70
71
72
73 private static int readRawVarint32(ByteBuf buffer) {
74 if (!buffer.isReadable()) {
75 return 0;
76 }
77 buffer.markReaderIndex();
78 byte tmp = buffer.readByte();
79 if (tmp >= 0) {
80 return tmp;
81 } else {
82 int result = tmp & 127;
83 if (!buffer.isReadable()) {
84 buffer.resetReaderIndex();
85 return 0;
86 }
87 if ((tmp = buffer.readByte()) >= 0) {
88 result |= tmp << 7;
89 } else {
90 result |= (tmp & 127) << 7;
91 if (!buffer.isReadable()) {
92 buffer.resetReaderIndex();
93 return 0;
94 }
95 if ((tmp = buffer.readByte()) >= 0) {
96 result |= tmp << 14;
97 } else {
98 result |= (tmp & 127) << 14;
99 if (!buffer.isReadable()) {
100 buffer.resetReaderIndex();
101 return 0;
102 }
103 if ((tmp = buffer.readByte()) >= 0) {
104 result |= tmp << 21;
105 } else {
106 result |= (tmp & 127) << 21;
107 if (!buffer.isReadable()) {
108 buffer.resetReaderIndex();
109 return 0;
110 }
111 result |= (tmp = buffer.readByte()) << 28;
112 if (tmp < 0) {
113 throw new CorruptedFrameException("malformed varint.");
114 }
115 }
116 }
117 }
118 return result;
119 }
120 }
121 }