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.buffer.ByteBufUtil;
24 import io.netty.channel.ChannelHandler.Sharable;
25 import io.netty.channel.ChannelHandlerContext;
26 import io.netty.channel.ChannelPipeline;
27 import io.netty.handler.codec.ByteToMessageDecoder;
28 import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
29 import io.netty.handler.codec.LengthFieldPrepender;
30 import io.netty.handler.codec.MessageToMessageDecoder;
31 import io.netty.util.internal.ObjectUtil;
32
33 import java.util.List;
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
64
65
66 @Sharable
67 public class ProtobufDecoder extends MessageToMessageDecoder<ByteBuf> {
68
69 private static final boolean HAS_PARSER;
70
71 static {
72 boolean hasParser = false;
73 try {
74
75 MessageLite.class.getDeclaredMethod("getParserForType");
76 hasParser = true;
77 } catch (Throwable t) {
78
79 }
80
81 HAS_PARSER = hasParser;
82 }
83
84 private final MessageLite prototype;
85 private final ExtensionRegistryLite extensionRegistry;
86
87
88
89
90 public ProtobufDecoder(MessageLite prototype) {
91 this(prototype, null);
92 }
93
94 public ProtobufDecoder(MessageLite prototype, ExtensionRegistry extensionRegistry) {
95 this(prototype, (ExtensionRegistryLite) extensionRegistry);
96 }
97
98 public ProtobufDecoder(MessageLite prototype, ExtensionRegistryLite extensionRegistry) {
99 this.prototype = ObjectUtil.checkNotNull(prototype, "prototype").getDefaultInstanceForType();
100 this.extensionRegistry = extensionRegistry;
101 }
102
103 @Override
104 protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out)
105 throws Exception {
106 final byte[] array;
107 final int offset;
108 final int length = msg.readableBytes();
109 if (msg.hasArray()) {
110 array = msg.array();
111 offset = msg.arrayOffset() + msg.readerIndex();
112 } else {
113 array = ByteBufUtil.getBytes(msg, msg.readerIndex(), length, false);
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(
126 array, offset, length, extensionRegistry));
127 } else {
128 out.add(prototype.newBuilderForType().mergeFrom(
129 array, offset, length, extensionRegistry).build());
130 }
131 }
132 }
133 }