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:
Trustin Lee 2013-03-12 16:25:35 +09:00
parent 559b860ff6
commit c25513d5e1
3 changed files with 1793 additions and 1102 deletions

View File

@ -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();
}
}
}

View File

@ -106,7 +106,7 @@
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.4.1</version>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>