diff --git a/src/flatland/protobuf/PersistentProtocolBufferMap.java b/src/flatland/protobuf/PersistentProtocolBufferMap.java index 640466e..4042415 100644 --- a/src/flatland/protobuf/PersistentProtocolBufferMap.java +++ b/src/flatland/protobuf/PersistentProtocolBufferMap.java @@ -173,6 +173,10 @@ public DynamicMessage parseFrom(CodedInputStream input) throws IOException { return DynamicMessage.parseFrom(type, input); } + public DynamicMessage parseFrom(InputStream input) throws IOException { + return DynamicMessage.parseFrom(type, input); + } + public DynamicMessage.Builder parseDelimitedFrom(InputStream input) throws IOException { DynamicMessage.Builder builder = newBuilder(); if (builder.mergeDelimitedFrom(input)) { @@ -305,6 +309,18 @@ static public PersistentProtocolBufferMap parseFrom(Def def, CodedInputStream in return new PersistentProtocolBufferMap(null, def, message); } + static public PersistentProtocolBufferMap parseFrom(Def def, InputStream input) + throws IOException { + DynamicMessage message = def.parseFrom(input); + return new PersistentProtocolBufferMap(null, def, message); + } + + static public PersistentProtocolBufferMap parseFrom(Def def, byte[] input) + throws IOException { + DynamicMessage message = def.parseFrom(input); + return new PersistentProtocolBufferMap(null, def, message); + } + static public PersistentProtocolBufferMap parseDelimitedFrom(Def def, InputStream input) throws IOException { DynamicMessage.Builder builder = def.parseDelimitedFrom(input); @@ -361,6 +377,10 @@ public byte[] toByteArray() { return message().toByteArray(); } + public void writeTo(OutputStream output) throws IOException { + message().writeTo(output); + } + public void writeTo(CodedOutputStream output) throws IOException { message().writeTo(output); } @@ -369,6 +389,15 @@ public void writeDelimitedTo(OutputStream output) throws IOException { message().writeDelimitedTo(output); } + public int getSerializedSize() { + return message().getSerializedSize(); + } + + public int getDelimitedSize() { + int serializedSize = getSerializedSize(); + return CodedOutputStream.computeRawVarint32Size(serializedSize) + serializedSize; + } + public Descriptors.Descriptor getMessageType() { return def.getMessageType(); } diff --git a/src/flatland/protobuf/core.clj b/src/flatland/protobuf/core.clj index 1a0431d..03ccb7e 100644 --- a/src/flatland/protobuf/core.clj +++ b/src/flatland/protobuf/core.clj @@ -104,3 +104,18 @@ "Get value at key ignoring extension fields." [^PersistentProtocolBufferMap p key] (.getValAt p key false)) + +(defn serialized-size + "Get the number of bytes required to encode this message. The result is only + computed on the first call and memoized after that." + [^PersistentProtocolBufferMap p] + (when p + (.getSerializedSize p))) + +(defn delimited-size + "Get the number of bytes required to encode this message with a length + delimiter. The result is only computed on the first call and memoized after + that." + [^PersistentProtocolBufferMap p] + (when p + (.getDelimitedSize p))) diff --git a/test/flatland/protobuf/core_test.clj b/test/flatland/protobuf/core_test.clj index a45b0b6..96b2277 100644 --- a/test/flatland/protobuf/core_test.clj +++ b/test/flatland/protobuf/core_test.clj @@ -3,7 +3,7 @@ [flatland.io.core :only [catbytes]] [flatland.useful.utils :only [adjoin]] ordered-map.core) - (:import (java.io PipedInputStream PipedOutputStream))) + (:import (java.io PipedInputStream PipedOutputStream ByteArrayOutputStream))) (def Foo (protodef flatland.protobuf.test.Core$Foo)) (def FooUnder (protodef flatland.protobuf.test.Core$Foo @@ -463,4 +463,20 @@ (is (thrown-with-msg? IllegalArgumentException #"error setting string field flatland.protobuf.test.core.Foo.label to 8" (protobuf Foo :label 8))) (is (thrown-with-msg? IllegalArgumentException #"error adding 1 to string field flatland.protobuf.test.core.Foo.tags" - (protobuf Foo :tags [1 2 3])))) \ No newline at end of file + (protobuf Foo :tags [1 2 3])))) + +(deftest test-serialized-size + (let [p (protobuf Foo :id 5 :tags ["fast" "shiny"] :label "nice") + q (protobuf Foo :id 5 :tags ["fast"])] + (is (= (serialized-size p) (alength (protobuf-dump p)))) + (is (= (serialized-size q) (alength (protobuf-dump q)))))) + +(deftest test-delimited-size + (let [p (protobuf Foo :id 5 :tags ["fast" "shiny"] :label "nice") + q (protobuf Foo :id 5 :tags ["fast"]) + p-out (ByteArrayOutputStream.) + q-out (ByteArrayOutputStream.)] + (protobuf-write p-out p) + (protobuf-write q-out q) + (is (= (delimited-size p) (alength (.toByteArray p-out)))) + (is (= (delimited-size q) (alength (.toByteArray q-out))))))