Эх сурвалжийг харах

Merge "Fixed packed repeated serialization."

Ulas Kirazci 12 жил өмнө
parent
commit
cebd784d19

+ 19 - 0
java/src/test/java/com/google/protobuf/NanoTest.java

@@ -47,6 +47,7 @@ import com.google.protobuf.nano.UnittestImportNano;
 import junit.framework.TestCase;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -1956,6 +1957,24 @@ public class NanoTest extends TestCase {
     assertEquals(TestAllTypesNano.BAR, msg.repeatedPackedNestedEnum[1]);
   }
 
+  public void testNanoRepeatedPackedSerializedSize() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.repeatedPackedInt32 = new int[] { 123, 789, 456 };
+    int msgSerializedSize = msg.getSerializedSize();
+    byte [] result = MessageNano.toByteArray(msg);
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 11);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano msg2 = new TestAllTypesNano();
+    msg2.repeatedPackedInt32 = new int[] { 123, 789, 456 };
+    byte [] result2 = new byte[msgSerializedSize];
+    MessageNano.toByteArray(msg2, result2, 0, msgSerializedSize);
+
+    // Check equal size and content.
+    assertEquals(msgSerializedSize, msg2.getSerializedSize());
+    assertTrue(Arrays.equals(result, result2));
+  }
+
   public void testNanoRepeatedInt32ReMerge() throws Exception {
     TestAllTypesNano msg = new TestAllTypesNano();
     msg.repeatedInt32 = new int[] { 234 };

+ 27 - 30
src/google/protobuf/compiler/javanano/javanano_primitive_field.cc

@@ -409,10 +409,6 @@ void RepeatedPrimitiveFieldGenerator::
 GenerateMembers(io::Printer* printer) const {
   printer->Print(variables_,
     "public $type$[] $name$ = $default$;\n");
-  if (descriptor_->options().packed()) {
-    printer->Print(variables_,
-      "private int $name$MemoizedSerializedSize;\n");
-  }
 }
 
 void RepeatedPrimitiveFieldGenerator::
@@ -461,13 +457,34 @@ GenerateParsingCode(io::Printer* printer) const {
   }
 }
 
+void RepeatedPrimitiveFieldGenerator::
+GenerateRepeatedDataSizeCode(io::Printer* printer) const {
+  // Creates a variable dataSize and puts the serialized size in
+  // there.
+  if (FixedSize(descriptor_->type()) == -1) {
+    printer->Print(variables_,
+      "int dataSize = 0;\n"
+      "for ($type$ element : this.$name$) {\n"
+      "  dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+      "    .compute$capitalized_type$SizeNoTag(element);\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "int dataSize = $fixed_size$ * this.$name$.length;\n");
+  }
+}
+
 void RepeatedPrimitiveFieldGenerator::
 GenerateSerializationCode(io::Printer* printer) const {
   if (descriptor_->options().packed()) {
     printer->Print(variables_,
-      "if (this.$name$.length > 0) {\n"
+      "if (this.$name$.length > 0) {\n");
+    printer->Indent();
+    GenerateRepeatedDataSizeCode(printer);
+    printer->Outdent();
+    printer->Print(variables_,
       "  output.writeRawVarint32($tag$);\n"
-      "  output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+      "  output.writeRawVarint32(dataSize);\n"
       "}\n");
     printer->Print(variables_,
       "for ($type$ element : this.$name$) {\n"
@@ -487,27 +504,15 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
     "if (this.$name$.length > 0) {\n");
   printer->Indent();
 
-  if (FixedSize(descriptor_->type()) == -1) {
-    printer->Print(variables_,
-      "int dataSize = 0;\n"
-      "for ($type$ element : this.$name$) {\n"
-      "  dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
-      "    .compute$capitalized_type$SizeNoTag(element);\n"
-      "}\n");
-  } else {
-    printer->Print(variables_,
-      "int dataSize = $fixed_size$ * this.$name$.length;\n");
-  }
+  GenerateRepeatedDataSizeCode(printer);
 
   printer->Print(
     "size += dataSize;\n");
   if (descriptor_->options().packed()) {
-    // cache the data size for packed fields.
     printer->Print(variables_,
       "size += $tag_size$;\n"
       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
-      "  .computeRawVarint32Size(dataSize);\n"
-      "$name$MemoizedSerializedSize = dataSize;\n");
+      "  .computeRawVarint32Size(dataSize);\n");
   } else {
     printer->Print(variables_,
         "size += $tag_size$ * this.$name$.length;\n");
@@ -515,16 +520,8 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
 
   printer->Outdent();
 
-  // set cached size to 0 for empty packed fields.
-  if (descriptor_->options().packed()) {
-    printer->Print(variables_,
-      "} else {\n"
-      "  $name$MemoizedSerializedSize = 0;\n"
-      "}\n");
-  } else {
-    printer->Print(
-      "}\n");
-  }
+  printer->Print(
+    "}\n");
 }
 
 string RepeatedPrimitiveFieldGenerator::GetBoxedType() const {

+ 2 - 0
src/google/protobuf/compiler/javanano/javanano_primitive_field.h

@@ -80,6 +80,8 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
   string GetBoxedType() const;
 
  private:
+  void GenerateRepeatedDataSizeCode(io::Printer* printer) const;
+
   const FieldDescriptor* descriptor_;
   map<string, string> variables_;