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.ExtensionRegistry;
19 import com.google.protobuf.ExtensionRegistryLite;
20 import com.google.protobuf.Message;
21 import com.google.protobuf.MessageLite;
22 import io.netty.buffer.ByteBuf;
23 import io.netty.channel.ChannelHandler.Sharable;
24 import io.netty.channel.ChannelHandlerContext;
25 import io.netty.channel.ChannelPipeline;
26 import io.netty.handler.codec.ByteToMessageDecoder;
27 import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
28 import io.netty.handler.codec.LengthFieldPrepender;
29 import io.netty.handler.codec.MessageToMessageDecoder;
30
31 import java.util.List;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 @Sharable
64 public class ProtobufDecoder extends MessageToMessageDecoder<ByteBuf> {
65
66 private static final boolean HAS_PARSER;
67
68 static {
69 boolean hasParser = false;
70 try {
71
72 MessageLite.class.getDeclaredMethod("getParserForType");
73 hasParser = true;
74 } catch (Throwable t) {
75
76 }
77
78 HAS_PARSER = hasParser;
79 }
80
81 private final MessageLite prototype;
82 private final ExtensionRegistryLite extensionRegistry;
83
84
85
86
87 public ProtobufDecoder(MessageLite prototype) {
88 this(prototype, null);
89 }
90
91 public ProtobufDecoder(MessageLite prototype, ExtensionRegistry extensionRegistry) {
92 this(prototype, (ExtensionRegistryLite) extensionRegistry);
93 }
94
95 public ProtobufDecoder(MessageLite prototype, ExtensionRegistryLite extensionRegistry) {
96 if (prototype == null) {
97 throw new NullPointerException("prototype");
98 }
99 this.prototype = prototype.getDefaultInstanceForType();
100 this.extensionRegistry = extensionRegistry;
101 }
102
103 @Override
104 protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
105 final byte[] array;
106 final int offset;
107 final int length = msg.readableBytes();
108 if (msg.hasArray()) {
109 array = msg.array();
110 offset = msg.arrayOffset() + msg.readerIndex();
111 } else {
112 array = new byte[length];
113 msg.getBytes(msg.readerIndex(), array, 0, length);
114 offset = 0;
115 }
116
117 if (extensionRegistry == null) {
118 if (HAS_PARSER) {
119 out.add(prototype.getParserForType().parseFrom(array, offset, length));
120 } else {
121 out.add(prototype.newBuilderForType().mergeFrom(array, offset, length).build());
122 }
123 } else {
124 if (HAS_PARSER) {
125 out.add(prototype.getParserForType().parseFrom(array, offset, length, extensionRegistry));
126 } else {
127 out.add(prototype.newBuilderForType().mergeFrom(array, offset, length, extensionRegistry).build());
128 }
129 }
130 }
131 }
132