protobuf: Support ByteBuffer based decode

Some storage systems might prefer to use java.nio.ByteBuffer for
decoding, so provide a utility method for those.

Change-Id: Ib57caf90c5cbfe8dfda822abb42bf3787146f0c1
diff --git a/pom.xml b/pom.xml
index 9fbb95f..a5f703f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -334,7 +334,7 @@
     <dependency>
       <groupId>com.google.protobuf</groupId>
       <artifactId>protobuf-java</artifactId>
-      <version>2.2.0</version>
+      <version>2.3.0</version>
       <scope>provided</scope>
     </dependency>
   </dependencies>
diff --git a/src/main/java/com/google/gwtorm/protobuf/ProtobufCodec.java b/src/main/java/com/google/gwtorm/protobuf/ProtobufCodec.java
index d13e7b3..ccb2247 100644
--- a/src/main/java/com/google/gwtorm/protobuf/ProtobufCodec.java
+++ b/src/main/java/com/google/gwtorm/protobuf/ProtobufCodec.java
@@ -18,6 +18,8 @@
 import com.google.protobuf.ByteString;
 import com.google.protobuf.CodedInputStream;
 
+import java.nio.ByteBuffer;
+
 /**
  * Encode and decode an arbitrary Java object as a Protobuf message.
  * <p>
@@ -36,11 +38,21 @@
     return decode(buf.newCodedInput());
   }
 
-  /** Decode a byte string into an object instance. */
+  /** Decode a byte array into an object instance. */
   public T decode(byte[] buf) {
     return decode(CodedInputStream.newInstance(buf));
   }
 
   /** Decode an object by reading it from the stream. */
   protected abstract T decode(CodedInputStream in);
+
+  /** Decode a byte buffer into an object instance. */
+  public T decode(ByteBuffer buf) {
+    if (buf.hasArray()) {
+      return decode(CodedInputStream.newInstance(buf.array(), buf.position(),
+          buf.remaining()));
+    } else {
+      return decode(ByteString.copyFrom(buf));
+    }
+  }
 }