diff --git a/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs b/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs index 8caa953a6..b3f5d7b4c 100644 --- a/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs +++ b/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs @@ -155,8 +155,9 @@ namespace Google.ProtocolBuffers.ProtoGen { writer.WriteLine("size += dataSize;"); int tagSize = CodedOutputStream.ComputeTagSize(Descriptor.FieldNumber); if (Descriptor.IsPacked) { - writer.WriteLine("size += {0};", tagSize); - writer.WriteLine("size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);"); + writer.WriteLine("if ({0}_.Count != 0) {{", Name); + writer.WriteLine(" size += {0} + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);", tagSize); + writer.WriteLine("}"); } else { writer.WriteLine("size += {0} * {1}_.Count;", tagSize, Name); } diff --git a/src/ProtocolBuffers.Test/GeneratedMessageTest.cs b/src/ProtocolBuffers.Test/GeneratedMessageTest.cs index aee11d84f..5f9881797 100644 --- a/src/ProtocolBuffers.Test/GeneratedMessageTest.cs +++ b/src/ProtocolBuffers.Test/GeneratedMessageTest.cs @@ -452,5 +452,11 @@ namespace Google.ProtocolBuffers { Assert.AreEqual(UnitTestProtoFile.RepeatedNestedMessageExtensionFieldNumber, 48); Assert.AreEqual(UnitTestProtoFile.RepeatedNestedEnumExtensionFieldNumber, 51); } + + [Test] + public void EmptyPackedValue() { + TestPackedTypes empty = new TestPackedTypes.Builder().Build(); + Assert.AreEqual(0, empty.SerializedSize); + } } } diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs index 123b5eca7..811556d83 100644 --- a/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs +++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs @@ -12765,8 +12765,9 @@ namespace Google.ProtocolBuffers.TestProtos { dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element); } size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedInt32_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedInt32MemoizedSerializedSize = dataSize; } { @@ -12775,8 +12776,9 @@ namespace Google.ProtocolBuffers.TestProtos { dataSize += pb::CodedOutputStream.ComputeInt64SizeNoTag(element); } size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedInt64_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedInt64MemoizedSerializedSize = dataSize; } { @@ -12785,8 +12787,9 @@ namespace Google.ProtocolBuffers.TestProtos { dataSize += pb::CodedOutputStream.ComputeUInt32SizeNoTag(element); } size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedUint32_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedUint32MemoizedSerializedSize = dataSize; } { @@ -12795,8 +12798,9 @@ namespace Google.ProtocolBuffers.TestProtos { dataSize += pb::CodedOutputStream.ComputeUInt64SizeNoTag(element); } size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedUint64_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedUint64MemoizedSerializedSize = dataSize; } { @@ -12805,8 +12809,9 @@ namespace Google.ProtocolBuffers.TestProtos { dataSize += pb::CodedOutputStream.ComputeSInt32SizeNoTag(element); } size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedSint32_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedSint32MemoizedSerializedSize = dataSize; } { @@ -12815,64 +12820,72 @@ namespace Google.ProtocolBuffers.TestProtos { dataSize += pb::CodedOutputStream.ComputeSInt64SizeNoTag(element); } size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedSint64_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedSint64MemoizedSerializedSize = dataSize; } { int dataSize = 0; dataSize = 4 * packedFixed32_.Count; size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedFixed32_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedFixed32MemoizedSerializedSize = dataSize; } { int dataSize = 0; dataSize = 8 * packedFixed64_.Count; size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedFixed64_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedFixed64MemoizedSerializedSize = dataSize; } { int dataSize = 0; dataSize = 4 * packedSfixed32_.Count; size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedSfixed32_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedSfixed32MemoizedSerializedSize = dataSize; } { int dataSize = 0; dataSize = 8 * packedSfixed64_.Count; size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedSfixed64_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedSfixed64MemoizedSerializedSize = dataSize; } { int dataSize = 0; dataSize = 4 * packedFloat_.Count; size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedFloat_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedFloatMemoizedSerializedSize = dataSize; } { int dataSize = 0; dataSize = 8 * packedDouble_.Count; size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedDouble_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedDoubleMemoizedSerializedSize = dataSize; } { int dataSize = 0; dataSize = 1 * packedBool_.Count; size += dataSize; - size += 2; - size += pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + if (packedBool_.Count != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize); + } packedBoolMemoizedSerializedSize = dataSize; } {