Upgrade to protobuf 2.5 and take advantage of MessageLite.getParserFromType()
- also fall back to MessageBuilder if getParserFromType() is not available.
This commit is contained in:
parent
559b860ff6
commit
c25513d5e1
@ -19,7 +19,6 @@ import com.google.protobuf.ExtensionRegistry;
|
||||
import com.google.protobuf.Message;
|
||||
import com.google.protobuf.MessageLite;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
import io.netty.channel.ChannelHandler.Sharable;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
@ -61,6 +60,21 @@ import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
@Sharable
|
||||
public class ProtobufDecoder extends MessageToMessageDecoder<ByteBuf> {
|
||||
|
||||
private static final boolean HAS_PARSER;
|
||||
|
||||
static {
|
||||
boolean hasParser = false;
|
||||
try {
|
||||
// MessageLite.getParsetForType() is not available until protobuf 2.5.0.
|
||||
MessageLite.class.getDeclaredMethod("getParserForType");
|
||||
hasParser = true;
|
||||
} catch (Throwable t) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
HAS_PARSER = hasParser;
|
||||
}
|
||||
|
||||
private final MessageLite prototype;
|
||||
private final ExtensionRegistry extensionRegistry;
|
||||
|
||||
@ -81,22 +95,29 @@ public class ProtobufDecoder extends MessageToMessageDecoder<ByteBuf> {
|
||||
|
||||
@Override
|
||||
protected Object decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
|
||||
final byte[] array;
|
||||
final int offset;
|
||||
final int length = msg.readableBytes();
|
||||
if (msg.hasArray()) {
|
||||
final int offset = msg.readerIndex();
|
||||
if (extensionRegistry == null) {
|
||||
return prototype.newBuilderForType().mergeFrom(
|
||||
msg.array(), msg.arrayOffset() + offset, msg.readableBytes()).build();
|
||||
array = msg.array();
|
||||
offset = msg.arrayOffset() + msg.readerIndex();
|
||||
} else {
|
||||
array = new byte[length];
|
||||
msg.getBytes(msg.readerIndex(), array, 0, length);
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if (extensionRegistry == null) {
|
||||
if (HAS_PARSER) {
|
||||
return prototype.getParserForType().parseFrom(array, offset, length);
|
||||
} else {
|
||||
return prototype.newBuilderForType().mergeFrom(
|
||||
msg.array(), msg.arrayOffset() + offset, msg.readableBytes(), extensionRegistry).build();
|
||||
return prototype.newBuilderForType().mergeFrom(array, offset, length).build();
|
||||
}
|
||||
} else {
|
||||
if (extensionRegistry == null) {
|
||||
return prototype.newBuilderForType().mergeFrom(
|
||||
new ByteBufInputStream(msg)).build();
|
||||
if (HAS_PARSER) {
|
||||
return prototype.getParserForType().parseFrom(array, offset, length, extensionRegistry);
|
||||
} else {
|
||||
return prototype.newBuilderForType().mergeFrom(
|
||||
new ByteBufInputStream(msg), extensionRegistry).build();
|
||||
return prototype.newBuilderForType().mergeFrom(array, offset, length, extensionRegistry).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user