De-serializes a protobuf from the given buffer. The protobuf is assumed to be prefixed by a varint indicating its size. @param buf The buffer to de-serialize the protobuf from. @param parser The protobuf parser to use for this type of protobuf. @return An instance of the de-serialized type. @thr
(final ChannelBuffer buf, final Parser<T> parser)
| 1121 | * protobuf that couldn't be de-serialized. |
| 1122 | */ |
| 1123 | static <T> T readProtobuf(final ChannelBuffer buf, final Parser<T> parser) { |
| 1124 | final int length = HBaseRpc.readProtoBufVarint(buf); |
| 1125 | HBaseRpc.checkArrayLength(buf, length); |
| 1126 | final byte[] payload; |
| 1127 | final int offset; |
| 1128 | if (buf.hasArray()) { // Zero copy. |
| 1129 | payload = buf.array(); |
| 1130 | offset = buf.arrayOffset() + buf.readerIndex(); |
| 1131 | buf.readerIndex(buf.readerIndex() + length); |
| 1132 | } else { // We have to copy the entire payload out of the buffer :( |
| 1133 | payload = new byte[length]; |
| 1134 | buf.readBytes(payload); |
| 1135 | offset = 0; |
| 1136 | } |
| 1137 | try { |
| 1138 | return parser.parseFrom(payload, offset, length); |
| 1139 | } catch (InvalidProtocolBufferException e) { |
| 1140 | final String msg = "Invalid RPC response: length=" + length |
| 1141 | + ", payload=" + Bytes.pretty(payload); |
| 1142 | LOG.error("Invalid RPC from buffer: " + buf); |
| 1143 | throw new InvalidResponseException(msg, e); |
| 1144 | } |
| 1145 | } |
| 1146 | |
| 1147 | // -------------------------------------- // |
| 1148 | // Variable-length integer value encoding // |