diff options
25 files changed, 1561 insertions, 2353 deletions
diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs index c88ca424..4fd46471 100644 --- a/csharp/src/AddressBook/Addressbook.cs +++ b/csharp/src/AddressBook/Addressbook.cs @@ -131,6 +131,8 @@ namespace Google.Protobuf.Examples.AddressBook { } public const int PhoneFieldNumber = 4; + private static readonly pb::FieldCodec<global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber> _repeated_phone_codec + = pb::FieldCodec.ForMessage(34, global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber> phone_ = new pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber>(); public pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber> Phone { get { return phone_; } @@ -176,9 +178,7 @@ namespace Google.Protobuf.Examples.AddressBook { output.WriteRawTag(26); output.WriteString(Email); } - if (phone_.Count > 0) { - output.WriteMessageArray(4, phone_); - } + phone_.WriteTo(output, _repeated_phone_codec); } public int CalculateSize() { @@ -192,12 +192,7 @@ namespace Google.Protobuf.Examples.AddressBook { if (Email.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Email); } - if (phone_.Count > 0) { - foreach (global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber element in phone_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * phone_.Count; - } + size += phone_.CalculateSize(_repeated_phone_codec); return size; } @@ -241,7 +236,7 @@ namespace Google.Protobuf.Examples.AddressBook { break; } case 34: { - input.ReadMessageArray(phone_, global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber.Parser); + phone_.AddEntriesFrom(input, _repeated_phone_codec); break; } } @@ -437,6 +432,8 @@ namespace Google.Protobuf.Examples.AddressBook { } public const int PersonFieldNumber = 1; + private static readonly pb::FieldCodec<global::Google.Protobuf.Examples.AddressBook.Person> _repeated_person_codec + = pb::FieldCodec.ForMessage(10, global::Google.Protobuf.Examples.AddressBook.Person.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person> person_ = new pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person>(); public pbc::RepeatedField<global::Google.Protobuf.Examples.AddressBook.Person> Person { get { return person_; } @@ -464,19 +461,12 @@ namespace Google.Protobuf.Examples.AddressBook { } public void WriteTo(pb::CodedOutputStream output) { - if (person_.Count > 0) { - output.WriteMessageArray(1, person_); - } + person_.WriteTo(output, _repeated_person_codec); } public int CalculateSize() { int size = 0; - if (person_.Count > 0) { - foreach (global::Google.Protobuf.Examples.AddressBook.Person element in person_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * person_.Count; - } + size += person_.CalculateSize(_repeated_person_codec); return size; } @@ -499,7 +489,7 @@ namespace Google.Protobuf.Examples.AddressBook { } break; case 10: { - input.ReadMessageArray(person_, global::Google.Protobuf.Examples.AddressBook.Person.Parser); + person_.AddEntriesFrom(input, _repeated_person_codec); break; } } diff --git a/csharp/src/ProtocolBuffers.Test/CodedInputStreamExtensions.cs b/csharp/src/ProtocolBuffers.Test/CodedInputStreamExtensions.cs new file mode 100644 index 00000000..408c7cb9 --- /dev/null +++ b/csharp/src/ProtocolBuffers.Test/CodedInputStreamExtensions.cs @@ -0,0 +1,54 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2015 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using NUnit.Framework; + +namespace Google.Protobuf +{ + internal static class CodedInputStreamExtensions + { + public static void AssertNextTag(this CodedInputStream input, uint expectedTag) + { + uint tag; + Assert.IsTrue(input.ReadTag(out tag)); + Assert.AreEqual(expectedTag, tag); + } + + public static T ReadMessage<T>(this CodedInputStream stream, MessageParser<T> parser) + where T : IMessage<T> + { + var message = parser.CreateTemplate(); + stream.ReadMessage(message); + return message; + } + } +} diff --git a/csharp/src/ProtocolBuffers.Test/CodedInputStreamTest.cs b/csharp/src/ProtocolBuffers.Test/CodedInputStreamTest.cs index 52757d4d..a64994fd 100644 --- a/csharp/src/ProtocolBuffers.Test/CodedInputStreamTest.cs +++ b/csharp/src/ProtocolBuffers.Test/CodedInputStreamTest.cs @@ -35,10 +35,8 @@ #endregion
using System;
-using System.Collections.Generic;
using System.IO;
using Google.Protobuf.Collections;
-using Google.Protobuf.Descriptors;
using Google.Protobuf.TestProtos;
using NUnit.Framework;
@@ -62,7 +60,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
+ /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64()
/// </summary>
private static void AssertReadVarint(byte[] data, ulong value)
{
@@ -232,66 +230,26 @@ namespace Google.Protobuf Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL));
Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL));
}
- /*
+
[Test]
- public void ReadWholeMessage()
+ public void ReadWholeMessage_VaryingBlockSizes()
{
- TestAllTypes message = TestUtil.GetAllSet();
+ TestAllTypes message = GeneratedMessageTest.GetSampleMessage();
byte[] rawBytes = message.ToByteArray();
- Assert.AreEqual(rawBytes.Length, message.SerializedSize);
- TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
- TestUtil.AssertAllFieldsSet(message2);
+ Assert.AreEqual(rawBytes.Length, message.CalculateSize());
+ TestAllTypes message2 = TestAllTypes.Parser.ParseFrom(rawBytes);
+ Assert.AreEqual(message, message2);
// Try different block sizes.
for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{
- message2 = TestAllTypes.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize));
- TestUtil.AssertAllFieldsSet(message2);
+ message2 = TestAllTypes.Parser.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize));
+ Assert.AreEqual(message, message2);
}
}
-
+
[Test]
- public void SkipWholeMessage()
- {
- TestAllTypes message = TestUtil.GetAllSet();
- byte[] rawBytes = message.ToByteArray();
-
- // Create two parallel inputs. Parse one as unknown fields while using
- // skipField() to skip each field on the other. Expect the same tags.
- CodedInputStream input1 = CodedInputStream.CreateInstance(rawBytes);
- CodedInputStream input2 = CodedInputStream.CreateInstance(rawBytes);
- UnknownFieldSet.Builder unknownFields = UnknownFieldSet.CreateBuilder();
-
- uint tag;
- string name;
- while (input1.ReadTag(out tag, out name))
- {
- uint tag2;
- Assert.IsTrue(input2.ReadTag(out tag2, out name));
- Assert.AreEqual(tag, tag2);
-
- unknownFields.MergeFieldFrom(tag, input1);
- input2.SkipField();
- }
- }*/
-
- /// <summary>
- /// Test that a bug in SkipRawBytes has been fixed: if the skip
- /// skips exactly up to a limit, this should bnot break things
- /// </summary>
- [Test]
- public void SkipRawBytesBug()
- {
- byte[] rawBytes = new byte[] {1, 2};
- CodedInputStream input = CodedInputStream.CreateInstance(rawBytes);
-
- int limit = input.PushLimit(1);
- input.SkipRawBytes(1);
- input.PopLimit(limit);
- Assert.AreEqual(2, input.ReadRawByte());
- }
- /*
public void ReadHugeBlob()
{
// Allocate and initialize a 1MB blob.
@@ -302,24 +260,15 @@ namespace Google.Protobuf }
// Make a message containing it.
- TestAllTypes.Builder builder = TestAllTypes.CreateBuilder();
- TestUtil.SetAllFields(builder);
- builder.SetOptionalBytes(ByteString.CopyFrom(blob));
- TestAllTypes message = builder.Build();
+ var message = new TestAllTypes { SingleBytes = ByteString.CopyFrom(blob) };
// Serialize and parse it. Make sure to parse from an InputStream, not
// directly from a ByteString, so that CodedInputStream uses buffered
// reading.
- TestAllTypes message2 = TestAllTypes.ParseFrom(message.ToByteString().CreateCodedInput());
+ TestAllTypes message2 = TestAllTypes.Parser.ParseFrom(message.ToByteString());
- Assert.AreEqual(message.OptionalBytes, message2.OptionalBytes);
-
- // Make sure all the other fields were parsed correctly.
- TestAllTypes message3 = TestAllTypes.CreateBuilder(message2)
- .SetOptionalBytes(TestUtil.GetAllSet().OptionalBytes)
- .Build();
- TestUtil.AssertAllFieldsSet(message3);
- }*/
+ Assert.AreEqual(message, message2);
+ }
[Test]
public void ReadMaliciouslyLargeBlob()
@@ -461,66 +410,15 @@ namespace Google.Protobuf }
}
- enum TestNegEnum { None = 0, Value = -2 }
-
[Test]
public void TestNegativeEnum()
{
- byte[] bytes = new byte[10] { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };
+ byte[] bytes = { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };
CodedInputStream input = CodedInputStream.CreateInstance(bytes);
- Assert.AreEqual((int)TestNegEnum.Value, input.ReadEnum());
+ Assert.AreEqual((int)SampleEnum.NegativeValue, input.ReadEnum());
Assert.IsTrue(input.IsAtEnd);
}
- [Test]
- public void TestNegativeEnumPackedArray()
- {
- int arraySize = 1 + (10 * 5);
- int msgSize = 1 + 1 + arraySize;
- byte[] bytes = new byte[msgSize];
- CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
- output.WriteTag(8, WireFormat.WireType.LengthDelimited);
- output.WritePackedInt32Array(new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });
-
- Assert.AreEqual(0, output.SpaceLeft);
-
- CodedInputStream input = CodedInputStream.CreateInstance(bytes);
- uint tag;
- Assert.IsTrue(input.ReadTag(out tag));
-
- RepeatedField<TestNegEnum> values = new RepeatedField<TestNegEnum>();
- input.ReadEnumArray(values);
-
- Assert.AreEqual(6, values.Count);
- Assert.AreEqual(TestNegEnum.None, values[0]);
- Assert.AreEqual(TestNegEnum.Value, values[2]);
- // TODO(jonskeet): Test unknown value preservation
- }
-
- [Test]
- public void TestNegativeEnumArray()
- {
- int arraySize = 1 + 1 + (11 * 5);
- int msgSize = arraySize;
- byte[] bytes = new byte[msgSize];
- CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
- output.WriteInt32Array(8, new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });
-
- Assert.AreEqual(0, output.SpaceLeft);
-
- CodedInputStream input = CodedInputStream.CreateInstance(bytes);
- uint tag;
- Assert.IsTrue(input.ReadTag(out tag));
-
- RepeatedField<TestNegEnum> values = new RepeatedField<TestNegEnum>();
- input.ReadEnumArray(values);
-
- Assert.AreEqual(6, values.Count);
- Assert.AreEqual(TestNegEnum.None, values[0]);
- Assert.AreEqual(TestNegEnum.Value, values[2]);
- // TODO(jonskeet): Test unknown value preservation
- }
-
//Issue 71: CodedInputStream.ReadBytes go to slow path unnecessarily
[Test]
public void TestSlowPathAvoidance()
diff --git a/csharp/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs b/csharp/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs index 223374e0..ab5dcbd6 100644 --- a/csharp/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs +++ b/csharp/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs @@ -35,9 +35,8 @@ #endregion
using System;
-using System.Collections.Generic;
using System.IO;
-using Google.Protobuf.Collections;
+using Google.Protobuf.TestProtos;
using NUnit.Framework;
namespace Google.Protobuf
@@ -195,42 +194,24 @@ namespace Google.Protobuf 0x9abcdef012345678UL);
}
- /*
[Test]
- public void WriteWholeMessage()
+ public void WriteWholeMessage_VaryingBlockSizes()
{
- TestAllTypes message = TestUtil.GetAllSet();
+ TestAllTypes message = GeneratedMessageTest.GetSampleMessage();
byte[] rawBytes = message.ToByteArray();
- TestUtil.AssertEqualBytes(TestUtil.GoldenMessage.ToByteArray(), rawBytes);
// Try different block sizes.
for (int blockSize = 1; blockSize < 256; blockSize *= 2)
{
MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output =
- CodedOutputStream.CreateInstance(rawOutput, blockSize);
+ CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput, blockSize);
message.WriteTo(output);
output.Flush();
- TestUtil.AssertEqualBytes(rawBytes, rawOutput.ToArray());
+ Assert.AreEqual(rawBytes, rawOutput.ToArray());
}
}
-
- /// <summary>
- /// Tests writing a whole message with every packed field type. Ensures the
- /// wire format of packed fields is compatible with C++.
- /// </summary>
- [Test]
- public void WriteWholePackedFieldsMessage()
- {
- TestPackedTypes message = TestUtil.GetPackedSet();
-
- byte[] rawBytes = message.ToByteArray();
- TestUtil.AssertEqualBytes(TestUtil.GetGoldenPackedFieldsMessage().ToByteArray(),
- rawBytes);
- }
- */
-
+
[Test]
public void EncodeZigZag32()
{
@@ -296,66 +277,16 @@ namespace Google.Protobuf public void TestNegativeEnumNoTag()
{
Assert.AreEqual(10, CodedOutputStream.ComputeInt32Size(-2));
- Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) TestNegEnum.Value));
+ Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) SampleEnum.NegativeValue));
byte[] bytes = new byte[10];
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
- output.WriteEnum((int) TestNegEnum.Value);
+ output.WriteEnum((int) SampleEnum.NegativeValue);
Assert.AreEqual(0, output.SpaceLeft);
Assert.AreEqual("FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes));
}
- enum TestNegEnum { None = 0, Value = -2 }
-
- [Test]
- public void TestNegativeEnumArrayPacked()
- {
- int arraySize = 1 + (10 * 5);
- int msgSize = 1 + 1 + arraySize;
- byte[] bytes = new byte[msgSize];
- CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
- output.WriteTag(8, WireFormat.WireType.LengthDelimited);
- output.WritePackedEnumArray(new RepeatedField<TestNegEnum> {
- 0, (TestNegEnum) (-1), TestNegEnum.Value, (TestNegEnum) (-3), (TestNegEnum) (-4), (TestNegEnum) (-5) });
-
- Assert.AreEqual(0, output.SpaceLeft);
-
- CodedInputStream input = CodedInputStream.CreateInstance(bytes);
- uint tag;
- Assert.IsTrue(input.ReadTag(out tag));
-
- List<int> values = new List<int>();
- input.ReadInt32Array(values);
-
- Assert.AreEqual(6, values.Count);
- for (int i = 0; i > -6; i--)
- Assert.AreEqual(i, values[Math.Abs(i)]);
- }
-
- [Test]
- public void TestNegativeEnumArray()
- {
- int arraySize = 1 + 1 + (11 * 5);
- int msgSize = arraySize;
- byte[] bytes = new byte[msgSize];
- CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
- output.WriteEnumArray(8, new RepeatedField<TestNegEnum> {
- 0, (TestNegEnum) (-1), TestNegEnum.Value, (TestNegEnum) (-3), (TestNegEnum) (-4), (TestNegEnum) (-5) });
- Assert.AreEqual(0, output.SpaceLeft);
-
- CodedInputStream input = CodedInputStream.CreateInstance(bytes);
- uint tag;
- Assert.IsTrue(input.ReadTag(out tag));
-
- List<int> values = new List<int>();
- input.ReadInt32Array(values);
-
- Assert.AreEqual(6, values.Count);
- for (int i = 0; i > -6; i--)
- Assert.AreEqual(i, values[Math.Abs(i)]);
- }
-
[Test]
public void TestCodedInputOutputPosition()
{
@@ -405,7 +336,7 @@ namespace Google.Protobuf Assert.AreEqual(130, cout.Position);
cout.Flush();
}
- //Now test Input stream:
+ // Now test Input stream:
{
CodedInputStream cin = CodedInputStream.CreateInstance(new MemoryStream(bytes), new byte[50]);
uint tag;
@@ -418,8 +349,8 @@ namespace Google.Protobuf //Field 2:
Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 2);
Assert.AreEqual(4, cin.Position);
- uint childlen = cin.ReadRawVarint32();
- Assert.AreEqual(120u, childlen);
+ int childlen = cin.ReadLength();
+ Assert.AreEqual(120, childlen);
Assert.AreEqual(5, cin.Position);
int oldlimit = cin.PushLimit((int)childlen);
Assert.AreEqual(5, cin.Position);
diff --git a/csharp/src/ProtocolBuffers.Test/Collections/RepeatedFieldTest.cs b/csharp/src/ProtocolBuffers.Test/Collections/RepeatedFieldTest.cs index 29945c36..988801b7 100644 --- a/csharp/src/ProtocolBuffers.Test/Collections/RepeatedFieldTest.cs +++ b/csharp/src/ProtocolBuffers.Test/Collections/RepeatedFieldTest.cs @@ -1,5 +1,39 @@ -using System; +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2015 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; using System.Collections.Generic; +using System.IO; +using System.Linq; using Google.Protobuf.TestProtos; using NUnit.Framework; @@ -89,5 +123,260 @@ namespace Google.Protobuf.Collections var clone = list.Clone(); clone[0] = 1; } + + [Test] + public void AddEntriesFrom_PackedInt32() + { + uint packedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var stream = new MemoryStream(); + var output = CodedOutputStream.CreateInstance(stream); + var length = CodedOutputStream.ComputeInt32Size(10) + + CodedOutputStream.ComputeInt32Size(999) + + CodedOutputStream.ComputeInt32Size(-1000); + output.WriteTag(packedTag); + output.WriteRawVarint32((uint) length); + output.WriteInt32(10); + output.WriteInt32(999); + output.WriteInt32(-1000); + output.Flush(); + stream.Position = 0; + + // Deliberately "expecting" a non-packed tag, but we detect that the data is + // actually packed. + uint nonPackedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var field = new RepeatedField<int>(); + var input = CodedInputStream.CreateInstance(stream); + input.AssertNextTag(packedTag); + field.AddEntriesFrom(input, FieldCodec.ForInt32(nonPackedTag)); + CollectionAssert.AreEqual(new[] { 10, 999, -1000 }, field); + Assert.IsTrue(input.IsAtEnd); + } + + [Test] + public void AddEntriesFrom_NonPackedInt32() + { + uint nonPackedTag = WireFormat.MakeTag(10, WireFormat.WireType.Varint); + var stream = new MemoryStream(); + var output = CodedOutputStream.CreateInstance(stream); + output.WriteTag(nonPackedTag); + output.WriteInt32(10); + output.WriteTag(nonPackedTag); + output.WriteInt32(999); + output.WriteTag(nonPackedTag); + output.WriteInt32(-1000); // Just for variety... + output.Flush(); + stream.Position = 0; + + // Deliberately "expecting" a packed tag, but we detect that the data is + // actually not packed. + uint packedTag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var field = new RepeatedField<int>(); + var input = CodedInputStream.CreateInstance(stream); + input.AssertNextTag(nonPackedTag); + field.AddEntriesFrom(input, FieldCodec.ForInt32(packedTag)); + CollectionAssert.AreEqual(new[] { 10, 999, -1000 }, field); + Assert.IsTrue(input.IsAtEnd); + } + + [Test] + public void AddEntriesFrom_String() + { + uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var stream = new MemoryStream(); + var output = CodedOutputStream.CreateInstance(stream); + output.WriteTag(tag); + output.WriteString("Foo"); + output.WriteTag(tag); + output.WriteString(""); + output.WriteTag(tag); + output.WriteString("Bar"); + output.Flush(); + stream.Position = 0; + + var field = new RepeatedField<string>(); + var input = CodedInputStream.CreateInstance(stream); + input.AssertNextTag(tag); + field.AddEntriesFrom(input, FieldCodec.ForString(tag)); + CollectionAssert.AreEqual(new[] { "Foo", "", "Bar" }, field); + Assert.IsTrue(input.IsAtEnd); + } + + [Test] + public void AddEntriesFrom_Message() + { + var message1 = new ForeignMessage { C = 2000 }; + var message2 = new ForeignMessage { C = -250 }; + + uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var stream = new MemoryStream(); + var output = CodedOutputStream.CreateInstance(stream); + output.WriteTag(tag); + output.WriteMessage(message1); + output.WriteTag(tag); + output.WriteMessage(message2); + output.Flush(); + stream.Position = 0; + + var field = new RepeatedField<ForeignMessage>(); + var input = CodedInputStream.CreateInstance(stream); + input.AssertNextTag(tag); + field.AddEntriesFrom(input, FieldCodec.ForMessage(tag, ForeignMessage.Parser)); + CollectionAssert.AreEqual(new[] { message1, message2}, field); + Assert.IsTrue(input.IsAtEnd); + } + + [Test] + public void WriteTo_PackedInt32() + { + uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var field = new RepeatedField<int> { 10, 1000, 1000000 }; + var stream = new MemoryStream(); + var output = CodedOutputStream.CreateInstance(stream); + field.WriteTo(output, FieldCodec.ForInt32(tag)); + output.Flush(); + stream.Position = 0; + + var input = CodedInputStream.CreateInstance(stream); + input.AssertNextTag(tag); + var length = input.ReadLength(); + Assert.AreEqual(10, input.ReadInt32()); + Assert.AreEqual(1000, input.ReadInt32()); + Assert.AreEqual(1000000, input.ReadInt32()); + Assert.IsTrue(input.IsAtEnd); + Assert.AreEqual(1 + CodedOutputStream.ComputeLengthSize(length) + length, stream.Length); + } + + [Test] + public void WriteTo_NonPackedInt32() + { + uint tag = WireFormat.MakeTag(10, WireFormat.WireType.Varint); + var field = new RepeatedField<int> { 10, 1000, 1000000}; + var stream = new MemoryStream(); + var output = CodedOutputStream.CreateInstance(stream); + field.WriteTo(output, FieldCodec.ForInt32(tag)); + output.Flush(); + stream.Position = 0; + + var input = CodedInputStream.CreateInstance(stream); + input.AssertNextTag(tag); + Assert.AreEqual(10, input.ReadInt32()); + input.AssertNextTag(tag); + Assert.AreEqual(1000, input.ReadInt32()); + input.AssertNextTag(tag); + Assert.AreEqual(1000000, input.ReadInt32()); + Assert.IsTrue(input.IsAtEnd); + } + + [Test] + public void WriteTo_String() + { + uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var field = new RepeatedField<string> { "Foo", "", "Bar" }; + var stream = new MemoryStream(); + var output = CodedOutputStream.CreateInstance(stream); + field.WriteTo(output, FieldCodec.ForString(tag)); + output.Flush(); + stream.Position = 0; + + var input = CodedInputStream.CreateInstance(stream); + input.AssertNextTag(tag); + Assert.AreEqual("Foo", input.ReadString()); + input.AssertNextTag(tag); + Assert.AreEqual("", input.ReadString()); + input.AssertNextTag(tag); + Assert.AreEqual("Bar", input.ReadString()); + Assert.IsTrue(input.IsAtEnd); + } + + [Test] + public void WriteTo_Message() + { + var message1 = new ForeignMessage { C = 20 }; + var message2 = new ForeignMessage { C = 25 }; + uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var field = new RepeatedField<ForeignMessage> { message1, message2 }; + var stream = new MemoryStream(); + var output = CodedOutputStream.CreateInstance(stream); + field.WriteTo(output, FieldCodec.ForMessage(tag, ForeignMessage.Parser)); + output.Flush(); + stream.Position = 0; + + var input = CodedInputStream.CreateInstance(stream); + input.AssertNextTag(tag); + Assert.AreEqual(message1, input.ReadMessage(ForeignMessage.Parser)); + input.AssertNextTag(tag); + Assert.AreEqual(message2, input.ReadMessage(ForeignMessage.Parser)); + Assert.IsTrue(input.IsAtEnd); + } + + + [Test] + public void TestNegativeEnumArray() + { + int arraySize = 1 + 1 + (11 * 5); + int msgSize = arraySize; + byte[] bytes = new byte[msgSize]; + CodedOutputStream output = CodedOutputStream.CreateInstance(bytes); + uint tag = WireFormat.MakeTag(8, WireFormat.WireType.Varint); + for (int i = 0; i >= -5; i--) + { + output.WriteTag(tag); + output.WriteEnum(i); + } + + Assert.AreEqual(0, output.SpaceLeft); + + CodedInputStream input = CodedInputStream.CreateInstance(bytes); + Assert.IsTrue(input.ReadTag(out tag)); + + RepeatedField<SampleEnum> values = new RepeatedField<SampleEnum>(); + values.AddEntriesFrom(input, FieldCodec.ForEnum(tag, x => (int)x, x => (SampleEnum)x)); + + Assert.AreEqual(6, values.Count); + Assert.AreEqual(SampleEnum.None, values[0]); + Assert.AreEqual(((SampleEnum)(-1)), values[1]); + Assert.AreEqual(SampleEnum.NegativeValue, values[2]); + Assert.AreEqual(((SampleEnum)(-3)), values[3]); + Assert.AreEqual(((SampleEnum)(-4)), values[4]); + Assert.AreEqual(((SampleEnum)(-5)), values[5]); + } + + + [Test] + public void TestNegativeEnumPackedArray() + { + int arraySize = 1 + (10 * 5); + int msgSize = 1 + 1 + arraySize; + byte[] bytes = new byte[msgSize]; + CodedOutputStream output = CodedOutputStream.CreateInstance(bytes); + // Length-delimited to show we want the packed representation + uint tag = WireFormat.MakeTag(8, WireFormat.WireType.LengthDelimited); + output.WriteTag(tag); + int size = 0; + for (int i = 0; i >= -5; i--) + { + size += CodedOutputStream.ComputeEnumSize(i); + } + output.WriteRawVarint32((uint)size); + for (int i = 0; i >= -5; i--) + { + output.WriteEnum(i); + } + Assert.AreEqual(0, output.SpaceLeft); + + CodedInputStream input = CodedInputStream.CreateInstance(bytes); + Assert.IsTrue(input.ReadTag(out tag)); + + RepeatedField<SampleEnum> values = new RepeatedField<SampleEnum>(); + values.AddEntriesFrom(input, FieldCodec.ForEnum(tag, x => (int)x, x => (SampleEnum)x)); + + Assert.AreEqual(6, values.Count); + Assert.AreEqual(SampleEnum.None, values[0]); + Assert.AreEqual(((SampleEnum)(-1)), values[1]); + Assert.AreEqual(SampleEnum.NegativeValue, values[2]); + Assert.AreEqual(((SampleEnum)(-3)), values[3]); + Assert.AreEqual(((SampleEnum)(-4)), values[4]); + Assert.AreEqual(((SampleEnum)(-5)), values[5]); + } } } diff --git a/csharp/src/ProtocolBuffers.Test/FieldCodecTest.cs b/csharp/src/ProtocolBuffers.Test/FieldCodecTest.cs index e2b8e3ef..a14040d1 100644 --- a/csharp/src/ProtocolBuffers.Test/FieldCodecTest.cs +++ b/csharp/src/ProtocolBuffers.Test/FieldCodecTest.cs @@ -63,15 +63,21 @@ namespace Google.Protobuf }; [Test, TestCaseSource("Codecs")] - public void RoundTrip(ICodecTestData codec) + public void RoundTripWithTag(ICodecTestData codec) { - codec.TestRoundTrip(); + codec.TestRoundTripWithTag(); + } + + [Test, TestCaseSource("Codecs")] + public void RoundTripRaw(ICodecTestData codec) + { + codec.TestRoundTripRaw(); } [Test, TestCaseSource("Codecs")] public void CalculateSize(ICodecTestData codec) { - codec.TestCalculateSize(); + codec.TestCalculateSizeWithTag(); } [Test, TestCaseSource("Codecs")] @@ -82,8 +88,9 @@ namespace Google.Protobuf public interface ICodecTestData { - void TestRoundTrip(); - void TestCalculateSize(); + void TestRoundTripRaw(); + void TestRoundTripWithTag(); + void TestCalculateSizeWithTag(); void TestDefaultValue(); } @@ -100,45 +107,67 @@ namespace Google.Protobuf this.name = name; } - public void TestRoundTrip() + public void TestRoundTripRaw() { var stream = new MemoryStream(); var codedOutput = CodedOutputStream.CreateInstance(stream); - codec.Write(codedOutput, sampleValue); + codec.ValueWriter(codedOutput, sampleValue); codedOutput.Flush(); stream.Position = 0; var codedInput = CodedInputStream.CreateInstance(stream); - uint tag; - Assert.IsTrue(codedInput.ReadTag(out tag)); - Assert.AreEqual(codec.Tag, tag); + Assert.AreEqual(sampleValue, codec.ValueReader(codedInput)); + Assert.IsTrue(codedInput.IsAtEnd); + } + + public void TestRoundTripWithTag() + { + var stream = new MemoryStream(); + var codedOutput = CodedOutputStream.CreateInstance(stream); + codec.WriteTagAndValue(codedOutput, sampleValue); + codedOutput.Flush(); + stream.Position = 0; + var codedInput = CodedInputStream.CreateInstance(stream); + codedInput.AssertNextTag(codec.Tag); Assert.AreEqual(sampleValue, codec.Read(codedInput)); Assert.IsTrue(codedInput.IsAtEnd); } - public void TestCalculateSize() + public void TestCalculateSizeWithTag() { var stream = new MemoryStream(); var codedOutput = CodedOutputStream.CreateInstance(stream); - codec.Write(codedOutput, sampleValue); + codec.WriteTagAndValue(codedOutput, sampleValue); codedOutput.Flush(); - Assert.AreEqual(stream.Position, codec.CalculateSize(sampleValue)); + Assert.AreEqual(stream.Position, codec.CalculateSizeWithTag(sampleValue)); } public void TestDefaultValue() { + // WriteTagAndValue ignores default values var stream = new MemoryStream(); var codedOutput = CodedOutputStream.CreateInstance(stream); - codec.Write(codedOutput, codec.DefaultValue); + codec.WriteTagAndValue(codedOutput, codec.DefaultValue); codedOutput.Flush(); Assert.AreEqual(0, stream.Position); - Assert.AreEqual(0, codec.CalculateSize(codec.DefaultValue)); + Assert.AreEqual(0, codec.CalculateSizeWithTag(codec.DefaultValue)); if (typeof(T).IsValueType) { Assert.AreEqual(default(T), codec.DefaultValue); } - } - public string Description { get { return name; } } + // The plain ValueWriter/ValueReader delegates don't. + if (codec.DefaultValue != null) // This part isn't appropriate for message types. + { + codedOutput = CodedOutputStream.CreateInstance(stream); + codec.ValueWriter(codedOutput, codec.DefaultValue); + codedOutput.Flush(); + Assert.AreNotEqual(0, stream.Position); + Assert.AreEqual(stream.Position, codec.ValueSizeCalculator(codec.DefaultValue)); + stream.Position = 0; + var codedInput = CodedInputStream.CreateInstance(stream); + Assert.AreEqual(codec.DefaultValue, codec.ValueReader(codedInput)); + } + } public override string ToString() { diff --git a/csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs b/csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs index f8668662..a094e46b 100644 --- a/csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs +++ b/csharp/src/ProtocolBuffers.Test/GeneratedMessageTest.cs @@ -10,6 +10,61 @@ namespace Google.Protobuf /// </summary>
public class GeneratedMessageTest
{
+ /// <summary>
+ /// Returns a sample TestAllTypes with all fields populated
+ /// </summary>
+ public static TestAllTypes GetSampleMessage()
+ {
+ return new TestAllTypes
+ {
+ SingleBool = true,
+ SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
+ SingleDouble = 23.5,
+ SingleFixed32 = 23,
+ SingleFixed64 = 1234567890123,
+ SingleFloat = 12.25f,
+ SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
+ SingleForeignMessage = new ForeignMessage { C = 10 },
+ SingleImportEnum = ImportEnum.IMPORT_BAZ,
+ SingleImportMessage = new ImportMessage { D = 20 },
+ SingleInt32 = 100,
+ SingleInt64 = 3210987654321,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
+ SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
+ SinglePublicImportMessage = new PublicImportMessage { E = 54 },
+ SingleSfixed32 = -123,
+ SingleSfixed64 = -12345678901234,
+ SingleSint32 = -456,
+ SingleSint64 = -12345678901235,
+ SingleString = "test",
+ SingleUint32 = uint.MaxValue,
+ SingleUint64 = ulong.MaxValue,
+ RepeatedBool = { true, false },
+ RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6), ByteString.CopyFrom(new byte[1000]) },
+ RepeatedDouble = { -12.25, 23.5 },
+ RepeatedFixed32 = { uint.MaxValue, 23 },
+ RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
+ RepeatedFloat = { 100f, 12.25f },
+ RepeatedForeignEnum = { ForeignEnum.FOREIGN_FOO, ForeignEnum.FOREIGN_BAR },
+ RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
+ RepeatedImportEnum = { ImportEnum.IMPORT_BAZ, ImportEnum.IMPORT_ENUM_UNSPECIFIED },
+ RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
+ RepeatedInt32 = { 100, 200 },
+ RepeatedInt64 = { 3210987654321, long.MaxValue },
+ RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
+ RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
+ RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
+ RepeatedSfixed32 = { -123, 123 },
+ RepeatedSfixed64 = { -12345678901234, 12345678901234 },
+ RepeatedSint32 = { -456, 100 },
+ RepeatedSint64 = { -12345678901235, 123 },
+ RepeatedString = { "foo", "bar" },
+ RepeatedUint32 = { uint.MaxValue, uint.MinValue },
+ RepeatedUint64 = { ulong.MaxValue, uint.MinValue },
+ OneofString = "Oneof string"
+ };
+ }
+
[Test]
public void EmptyMessageFieldDistinctFromMissingMessageField()
{
@@ -485,5 +540,83 @@ namespace Google.Protobuf Assert.Throws<InvalidOperationException>(() => frozen.RepeatedDouble.Add(0.0));
Assert.Throws<InvalidOperationException>(() => frozen.RepeatedNestedMessage.Add(new TestAllTypes.Types.NestedMessage()));
}
+
+ [Test]
+ public void OneofProperties()
+ {
+ // Switch the oneof case between each of the different options, and check everything behaves
+ // as expected in each case.
+ var message = new TestAllTypes();
+ Assert.AreEqual("", message.OneofString);
+ Assert.AreEqual(0, message.OneofUint32);
+ Assert.AreEqual(ByteString.Empty, message.OneofBytes);
+ Assert.IsNull(message.OneofNestedMessage);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
+
+ message.OneofString = "sample";
+ Assert.AreEqual("sample", message.OneofString);
+ Assert.AreEqual(0, message.OneofUint32);
+ Assert.AreEqual(ByteString.Empty, message.OneofBytes);
+ Assert.IsNull(message.OneofNestedMessage);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message.OneofFieldCase);
+
+ var bytes = ByteString.CopyFrom(1, 2, 3);
+ message.OneofBytes = bytes;
+ Assert.AreEqual("", message.OneofString);
+ Assert.AreEqual(0, message.OneofUint32);
+ Assert.AreEqual(bytes, message.OneofBytes);
+ Assert.IsNull(message.OneofNestedMessage);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofBytes, message.OneofFieldCase);
+
+ message.OneofUint32 = 20;
+ Assert.AreEqual("", message.OneofString);
+ Assert.AreEqual(20, message.OneofUint32);
+ Assert.AreEqual(ByteString.Empty, message.OneofBytes);
+ Assert.IsNull(message.OneofNestedMessage);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message.OneofFieldCase);
+
+ var nestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 25 };
+ message.OneofNestedMessage = nestedMessage;
+ Assert.AreEqual("", message.OneofString);
+ Assert.AreEqual(0, message.OneofUint32);
+ Assert.AreEqual(ByteString.Empty, message.OneofBytes);
+ Assert.AreEqual(nestedMessage, message.OneofNestedMessage);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofNestedMessage, message.OneofFieldCase);
+
+ message.ClearOneofField();
+ Assert.AreEqual("", message.OneofString);
+ Assert.AreEqual(0, message.OneofUint32);
+ Assert.AreEqual(ByteString.Empty, message.OneofBytes);
+ Assert.IsNull(message.OneofNestedMessage);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
+ }
+
+ [Test]
+ public void OneofSerialization_NonDefaultValue()
+ {
+ var message = new TestAllTypes();
+ message.OneofString = "this would take a bit of space";
+ message.OneofUint32 = 10;
+ var bytes = message.ToByteArray();
+ Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string!
+
+ var message2 = TestAllTypes.Parser.ParseFrom(bytes);
+ Assert.AreEqual(message, message2);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
+ }
+
+ [Test]
+ public void OneofSerialization_DefaultValue()
+ {
+ var message = new TestAllTypes();
+ message.OneofString = "this would take a bit of space";
+ message.OneofUint32 = 0; // This is the default value for UInt32; normally wouldn't be serialized
+ var bytes = message.ToByteArray();
+ Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - it's still serialized
+
+ var message2 = TestAllTypes.Parser.ParseFrom(bytes);
+ Assert.AreEqual(message, message2);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
+ }
}
}
diff --git a/csharp/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj b/csharp/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj index 80b504aa..ae7d7575 100644 --- a/csharp/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj +++ b/csharp/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj @@ -72,6 +72,7 @@ </ItemGroup>
<ItemGroup>
<Compile Include="ByteStringTest.cs" />
+ <Compile Include="CodedInputStreamExtensions.cs" />
<Compile Include="CodedInputStreamTest.cs" />
<Compile Include="CodedOutputStreamTest.cs" />
<Compile Include="EqualityTester.cs" />
@@ -79,6 +80,7 @@ <Compile Include="GeneratedMessageTest.cs" />
<Compile Include="Collections\MapFieldTest.cs" />
<Compile Include="Collections\RepeatedFieldTest.cs" />
+ <Compile Include="SampleEnum.cs" />
<Compile Include="TestProtos\MapUnittestProto3.cs" />
<Compile Include="TestProtos\UnittestImportProto3.cs" />
<Compile Include="TestProtos\UnittestImportPublicProto3.cs" />
diff --git a/csharp/src/ProtocolBuffers.Test/SampleEnum.cs b/csharp/src/ProtocolBuffers.Test/SampleEnum.cs new file mode 100644 index 00000000..001f9b08 --- /dev/null +++ b/csharp/src/ProtocolBuffers.Test/SampleEnum.cs @@ -0,0 +1,42 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2015 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +namespace Google.Protobuf +{ + // Just a sample enum with positive and negative values to be used in tests. + internal enum SampleEnum + { + NegativeValue = -2, + None = 0, + PositiveValue = 3 + } +}
\ No newline at end of file diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs index 19de87de..16bdb3f2 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs @@ -422,13 +422,15 @@ namespace UnitTest.Issues.TestProtos { } public const int ValuesFieldNumber = 2; - private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> values_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum>(); + private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.NegativeEnum> _repeated_values_codec + = pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::UnitTest.Issues.TestProtos.NegativeEnum) x);private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> values_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum>(); public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> Values { get { return values_; } } public const int PackedValuesFieldNumber = 3; - private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> packedValues_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum>(); + private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.NegativeEnum> _repeated_packedValues_codec + = pb::FieldCodec.ForEnum(26, x => (int) x, x => (global::UnitTest.Issues.TestProtos.NegativeEnum) x);private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> packedValues_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum>(); public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> PackedValues { get { return packedValues_; } } @@ -463,13 +465,8 @@ namespace UnitTest.Issues.TestProtos { output.WriteRawTag(8); output.WriteEnum((int) Value); } - if (values_.Count > 0) { - output.WriteEnumArray(2, values_); - } - if (packedValues_.Count > 0) { - output.WriteRawTag(26); - output.WritePackedEnumArray(packedValues_); - } + values_.WriteTo(output, _repeated_values_codec); + packedValues_.WriteTo(output, _repeated_packedValues_codec); } public int CalculateSize() { @@ -477,22 +474,8 @@ namespace UnitTest.Issues.TestProtos { if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Value); } - if (values_.Count > 0) { - int dataSize = 0; - foreach (global::UnitTest.Issues.TestProtos.NegativeEnum element in values_) { - dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element); - } - size += dataSize; - size += 1 * values_.Count; - } - if (packedValues_.Count > 0) { - int dataSize = 0; - foreach (global::UnitTest.Issues.TestProtos.NegativeEnum element in packedValues_) { - dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element); - } - size += dataSize; - size += 1 + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize); - } + size += values_.CalculateSize(_repeated_values_codec); + size += packedValues_.CalculateSize(_repeated_packedValues_codec); return size; } @@ -524,12 +507,12 @@ namespace UnitTest.Issues.TestProtos { } case 18: case 16: { - input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(values_); + values_.AddEntriesFrom(input, _repeated_values_codec); break; } case 26: case 24: { - input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(packedValues_); + packedValues_.AddEntriesFrom(input, _repeated_packedValues_codec); break; } } @@ -678,6 +661,8 @@ namespace UnitTest.Issues.TestProtos { } public const int PrimitiveArrayFieldNumber = 2; + private static readonly pb::FieldCodec<int> _repeated_primitiveArray_codec + = pb::FieldCodec.ForInt32(18); private readonly pbc::RepeatedField<int> primitiveArray_ = new pbc::RepeatedField<int>(); [global::System.ObsoleteAttribute()] public pbc::RepeatedField<int> PrimitiveArray { @@ -696,6 +681,8 @@ namespace UnitTest.Issues.TestProtos { } public const int MessageArrayFieldNumber = 4; + private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.DeprecatedChild> _repeated_messageArray_codec + = pb::FieldCodec.ForMessage(34, global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser); private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedChild> messageArray_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedChild>(); [global::System.ObsoleteAttribute()] public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedChild> MessageArray { @@ -714,7 +701,8 @@ namespace UnitTest.Issues.TestProtos { } public const int EnumArrayFieldNumber = 6; - private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum> enumArray_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum>(); + private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.DeprecatedEnum> _repeated_enumArray_codec + = pb::FieldCodec.ForEnum(50, x => (int) x, x => (global::UnitTest.Issues.TestProtos.DeprecatedEnum) x);private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum> enumArray_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum>(); [global::System.ObsoleteAttribute()] public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum> EnumArray { get { return enumArray_; } @@ -756,25 +744,17 @@ namespace UnitTest.Issues.TestProtos { output.WriteRawTag(8); output.WriteInt32(PrimitiveValue); } - if (primitiveArray_.Count > 0) { - output.WriteRawTag(18); - output.WritePackedInt32Array(primitiveArray_); - } + primitiveArray_.WriteTo(output, _repeated_primitiveArray_codec); if (messageValue_ != null) { output.WriteRawTag(26); output.WriteMessage(MessageValue); } - if (messageArray_.Count > 0) { - output.WriteMessageArray(4, messageArray_); - } + messageArray_.WriteTo(output, _repeated_messageArray_codec); if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) { output.WriteRawTag(40); output.WriteEnum((int) EnumValue); } - if (enumArray_.Count > 0) { - output.WriteRawTag(50); - output.WritePackedEnumArray(enumArray_); - } + enumArray_.WriteTo(output, _repeated_enumArray_codec); } public int CalculateSize() { @@ -782,34 +762,15 @@ namespace UnitTest.Issues.TestProtos { if (PrimitiveValue != 0) { size += 1 + pb::CodedOutputStream.ComputeInt32Size(PrimitiveValue); } - if (primitiveArray_.Count > 0) { - int dataSize = 0; - foreach (int element in primitiveArray_) { - dataSize += pb::CodedOutputStream.ComputeInt32Size(element); - } - size += dataSize; - size += 1 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } + size += primitiveArray_.CalculateSize(_repeated_primitiveArray_codec); if (messageValue_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(MessageValue); } - if (messageArray_.Count > 0) { - foreach (global::UnitTest.Issues.TestProtos.DeprecatedChild element in messageArray_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * messageArray_.Count; - } + size += messageArray_.CalculateSize(_repeated_messageArray_codec); if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumValue); } - if (enumArray_.Count > 0) { - int dataSize = 0; - foreach (global::UnitTest.Issues.TestProtos.DeprecatedEnum element in enumArray_) { - dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element); - } - size += dataSize; - size += 1 + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize); - } + size += enumArray_.CalculateSize(_repeated_enumArray_codec); return size; } @@ -851,7 +812,7 @@ namespace UnitTest.Issues.TestProtos { } case 18: case 16: { - input.ReadInt32Array(primitiveArray_); + primitiveArray_.AddEntriesFrom(input, _repeated_primitiveArray_codec); break; } case 26: { @@ -862,7 +823,7 @@ namespace UnitTest.Issues.TestProtos { break; } case 34: { - input.ReadMessageArray(messageArray_, global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser); + messageArray_.AddEntriesFrom(input, _repeated_messageArray_codec); break; } case 40: { @@ -871,7 +832,7 @@ namespace UnitTest.Issues.TestProtos { } case 50: case 48: { - input.ReadEnumArray<global::UnitTest.Issues.TestProtos.DeprecatedEnum>(enumArray_); + enumArray_.AddEntriesFrom(input, _repeated_enumArray_codec); break; } } diff --git a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs index 1ae2d9a9..ea486fcc 100644 --- a/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs +++ b/csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs @@ -742,132 +742,173 @@ namespace Google.Protobuf.TestProtos { } public const int RepeatedInt32FieldNumber = 31; + private static readonly pb::FieldCodec<int> _repeated_repeatedInt32_codec + = pb::FieldCodec.ForInt32(250); private readonly pbc::RepeatedField<int> repeatedInt32_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> RepeatedInt32 { get { return repeatedInt32_; } } public const int RepeatedInt64FieldNumber = 32; + private static readonly pb::FieldCodec<long> _repeated_repeatedInt64_codec + = pb::FieldCodec.ForInt64(258); private readonly pbc::RepeatedField<long> repeatedInt64_ = new pbc::RepeatedField<long>(); public pbc::RepeatedField<long> RepeatedInt64 { get { return repeatedInt64_; } } public const int RepeatedUint32FieldNumber = 33; + private static readonly pb::FieldCodec<uint> _repeated_repeatedUint32_codec + = pb::FieldCodec.ForUInt32(266); private readonly pbc::RepeatedField<uint> repeatedUint32_ = new pbc::RepeatedField<uint>(); public pbc::RepeatedField<uint> RepeatedUint32 { get { return repeatedUint32_; } } public const int RepeatedUint64FieldNumber = 34; + private static readonly pb::FieldCodec<ulong> _repeated_repeatedUint64_codec + = pb::FieldCodec.ForUInt64(274); private readonly pbc::RepeatedField<ulong> repeatedUint64_ = new pbc::RepeatedField<ulong>(); public pbc::RepeatedField<ulong> RepeatedUint64 { get { return repeatedUint64_; } } public const int RepeatedSint32FieldNumber = 35; + private static readonly pb::FieldCodec<int> _repeated_repeatedSint32_codec + = pb::FieldCodec.ForSInt32(282); private readonly pbc::RepeatedField<int> repeatedSint32_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> RepeatedSint32 { get { return repeatedSint32_; } } public const int RepeatedSint64FieldNumber = 36; + private static readonly pb::FieldCodec<long> _repeated_repeatedSint64_codec + = pb::FieldCodec.ForSInt64(290); private readonly pbc::RepeatedField<long> repeatedSint64_ = new pbc::RepeatedField<long>(); public pbc::RepeatedField<long> RepeatedSint64 { get { return repeatedSint64_; } } public const int RepeatedFixed32FieldNumber = 37; + private static readonly pb::FieldCodec<uint> _repeated_repeatedFixed32_codec + = pb::FieldCodec.ForFixed32(298); private readonly pbc::RepeatedField<uint> repeatedFixed32_ = new pbc::RepeatedField<uint>(); public pbc::RepeatedField<uint> RepeatedFixed32 { get { return repeatedFixed32_; } } public const int RepeatedFixed64FieldNumber = 38; + private static readonly pb::FieldCodec<ulong> _repeated_repeatedFixed64_codec + = pb::FieldCodec.ForFixed64(306); private readonly pbc::RepeatedField<ulong> repeatedFixed64_ = new pbc::RepeatedField<ulong>(); public pbc::RepeatedField<ulong> RepeatedFixed64 { get { return repeatedFixed64_; } } public const int RepeatedSfixed32FieldNumber = 39; + private static readonly pb::FieldCodec<int> _repeated_repeatedSfixed32_codec + = pb::FieldCodec.ForSFixed32(314); private readonly pbc::RepeatedField<int> repeatedSfixed32_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> RepeatedSfixed32 { get { return repeatedSfixed32_; } } public const int RepeatedSfixed64FieldNumber = 40; + private static readonly pb::FieldCodec<long> _repeated_repeatedSfixed64_codec + = pb::FieldCodec.ForSFixed64(322); private readonly pbc::RepeatedField<long> repeatedSfixed64_ = new pbc::RepeatedField<long>(); public pbc::RepeatedField<long> RepeatedSfixed64 { get { return repeatedSfixed64_; } } public const int RepeatedFloatFieldNumber = 41; + private static readonly pb::FieldCodec<float> _repeated_repeatedFloat_codec + = pb::FieldCodec.ForFloat(330); private readonly pbc::RepeatedField<float> repeatedFloat_ = new pbc::RepeatedField<float>(); public pbc::RepeatedField<float> RepeatedFloat { get { return repeatedFloat_; } } public const int RepeatedDoubleFieldNumber = 42; + private static readonly pb::FieldCodec<double> _repeated_repeatedDouble_codec + = pb::FieldCodec.ForDouble(338); private readonly pbc::RepeatedField<double> repeatedDouble_ = new pbc::RepeatedField<double>(); public pbc::RepeatedField<double> RepeatedDouble { get { return repeatedDouble_; } } public const int RepeatedBoolFieldNumber = 43; + private static readonly pb::FieldCodec<bool> _repeated_repeatedBool_codec + = pb::FieldCodec.ForBool(346); private readonly pbc::RepeatedField<bool> repeatedBool_ = new pbc::RepeatedField<bool>(); public pbc::RepeatedField<bool> RepeatedBool { get { return repeatedBool_; } } public const int RepeatedStringFieldNumber = 44; + private static readonly pb::FieldCodec<string> _repeated_repeatedString_codec + = pb::FieldCodec.ForString(354); private readonly pbc::RepeatedField<string> repeatedString_ = new pbc::RepeatedField<string>(); public pbc::RepeatedField<string> RepeatedString { get { return repeatedString_; } } public const int RepeatedBytesFieldNumber = 45; + private static readonly pb::FieldCodec<pb::ByteString> _repeated_repeatedBytes_codec + = pb::FieldCodec.ForBytes(362); private readonly pbc::RepeatedField<pb::ByteString> repeatedBytes_ = new pbc::RepeatedField<pb::ByteString>(); public pbc::RepeatedField<pb::ByteString> RepeatedBytes { get { return repeatedBytes_; } } public const int RepeatedNestedMessageFieldNumber = 48; + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage> _repeated_repeatedNestedMessage_codec + = pb::FieldCodec.ForMessage(386, global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage> repeatedNestedMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage> RepeatedNestedMessage { get { return repeatedNestedMessage_; } } public const int RepeatedForeignMessageFieldNumber = 49; + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignMessage> _repeated_repeatedForeignMessage_codec + = pb::FieldCodec.ForMessage(394, global::Google.Protobuf.TestProtos.ForeignMessage.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> repeatedForeignMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> RepeatedForeignMessage { get { return repeatedForeignMessage_; } } public const int RepeatedImportMessageFieldNumber = 50; + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ImportMessage> _repeated_repeatedImportMessage_codec + = pb::FieldCodec.ForMessage(402, global::Google.Protobuf.TestProtos.ImportMessage.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportMessage> repeatedImportMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportMessage>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportMessage> RepeatedImportMessage { get { return repeatedImportMessage_; } } public const int RepeatedNestedEnumFieldNumber = 51; - private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum> repeatedNestedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum>(); + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum> _repeated_repeatedNestedEnum_codec + = pb::FieldCodec.ForEnum(410, x => (int) x, x => (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) x);private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum> repeatedNestedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum> RepeatedNestedEnum { get { return repeatedNestedEnum_; } } public const int RepeatedForeignEnumFieldNumber = 52; - private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> repeatedForeignEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>(); + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_repeatedForeignEnum_codec + = pb::FieldCodec.ForEnum(418, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> repeatedForeignEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> RepeatedForeignEnum { get { return repeatedForeignEnum_; } } public const int RepeatedImportEnumFieldNumber = 53; - private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum> repeatedImportEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum>(); + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ImportEnum> _repeated_repeatedImportEnum_codec + = pb::FieldCodec.ForEnum(426, x => (int) x, x => (global::Google.Protobuf.TestProtos.ImportEnum) x);private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum> repeatedImportEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ImportEnum> RepeatedImportEnum { get { return repeatedImportEnum_; } } public const int RepeatedPublicImportMessageFieldNumber = 54; + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.PublicImportMessage> _repeated_repeatedPublicImportMessage_codec + = pb::FieldCodec.ForMessage(434, global::Google.Protobuf.TestProtos.PublicImportMessage.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.PublicImportMessage> repeatedPublicImportMessage_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.PublicImportMessage>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.PublicImportMessage> RepeatedPublicImportMessage { get { return repeatedPublicImportMessage_; } @@ -1136,88 +1177,28 @@ namespace Google.Protobuf.TestProtos { output.WriteRawTag(210, 1); output.WriteMessage(SinglePublicImportMessage); } - if (repeatedInt32_.Count > 0) { - output.WriteRawTag(250, 1); - output.WritePackedInt32Array(repeatedInt32_); - } - if (repeatedInt64_.Count > 0) { - output.WriteRawTag(130, 2); - output.WritePackedInt64Array(repeatedInt64_); - } - if (repeatedUint32_.Count > 0) { - output.WriteRawTag(138, 2); - output.WritePackedUInt32Array(repeatedUint32_); - } - if (repeatedUint64_.Count > 0) { - output.WriteRawTag(146, 2); - output.WritePackedUInt64Array(repeatedUint64_); - } - if (repeatedSint32_.Count > 0) { - output.WriteRawTag(154, 2); - output.WritePackedSInt32Array(repeatedSint32_); - } - if (repeatedSint64_.Count > 0) { - output.WriteRawTag(162, 2); - output.WritePackedSInt64Array(repeatedSint64_); - } - if (repeatedFixed32_.Count > 0) { - output.WriteRawTag(170, 2); - output.WritePackedFixed32Array(repeatedFixed32_); - } - if (repeatedFixed64_.Count > 0) { - output.WriteRawTag(178, 2); - output.WritePackedFixed64Array(repeatedFixed64_); - } - if (repeatedSfixed32_.Count > 0) { - output.WriteRawTag(186, 2); - output.WritePackedSFixed32Array(repeatedSfixed32_); - } - if (repeatedSfixed64_.Count > 0) { - output.WriteRawTag(194, 2); - output.WritePackedSFixed64Array(repeatedSfixed64_); - } - if (repeatedFloat_.Count > 0) { - output.WriteRawTag(202, 2); - output.WritePackedFloatArray(repeatedFloat_); - } - if (repeatedDouble_.Count > 0) { - output.WriteRawTag(210, 2); - output.WritePackedDoubleArray(repeatedDouble_); - } - if (repeatedBool_.Count > 0) { - output.WriteRawTag(218, 2); - output.WritePackedBoolArray(repeatedBool_); - } - if (repeatedString_.Count > 0) { - output.WriteStringArray(44, repeatedString_); - } - if (repeatedBytes_.Count > 0) { - output.WriteBytesArray(45, repeatedBytes_); - } - if (repeatedNestedMessage_.Count > 0) { - output.WriteMessageArray(48, repeatedNestedMessage_); - } - if (repeatedForeignMessage_.Count > 0) { - output.WriteMessageArray(49, repeatedForeignMessage_); - } - if (repeatedImportMessage_.Count > 0) { - output.WriteMessageArray(50, repeatedImportMessage_); - } - if (repeatedNestedEnum_.Count > 0) { - output.WriteRawTag(154, 3); - output.WritePackedEnumArray(repeatedNestedEnum_); - } - if (repeatedForeignEnum_.Count > 0) { - output.WriteRawTag(162, 3); - output.WritePackedEnumArray(repeatedForeignEnum_); - } - if (repeatedImportEnum_.Count > 0) { - output.WriteRawTag(170, 3); - output.WritePackedEnumArray(repeatedImportEnum_); - } - if (repeatedPublicImportMessage_.Count > 0) { - output.WriteMessageArray(54, repeatedPublicImportMessage_); - } + repeatedInt32_.WriteTo(output, _repeated_repeatedInt32_codec); + repeatedInt64_.WriteTo(output, _repeated_repeatedInt64_codec); + repeatedUint32_.WriteTo(output, _repeated_repeatedUint32_codec); + repeatedUint64_.WriteTo(output, _repeated_repeatedUint64_codec); + repeatedSint32_.WriteTo(output, _repeated_repeatedSint32_codec); + repeatedSint64_.WriteTo(output, _repeated_repeatedSint64_codec); + repeatedFixed32_.WriteTo(output, _repeated_repeatedFixed32_codec); + repeatedFixed64_.WriteTo(output, _repeated_repeatedFixed64_codec); + repeatedSfixed32_.WriteTo(output, _repeated_repeatedSfixed32_codec); + repeatedSfixed64_.WriteTo(output, _repeated_repeatedSfixed64_codec); + repeatedFloat_.WriteTo(output, _repeated_repeatedFloat_codec); + repeatedDouble_.WriteTo(output, _repeated_repeatedDouble_codec); + repeatedBool_.WriteTo(output, _repeated_repeatedBool_codec); + repeatedString_.WriteTo(output, _repeated_repeatedString_codec); + repeatedBytes_.WriteTo(output, _repeated_repeatedBytes_codec); + repeatedNestedMessage_.WriteTo(output, _repeated_repeatedNestedMessage_codec); + repeatedForeignMessage_.WriteTo(output, _repeated_repeatedForeignMessage_codec); + repeatedImportMessage_.WriteTo(output, _repeated_repeatedImportMessage_codec); + repeatedNestedEnum_.WriteTo(output, _repeated_repeatedNestedEnum_codec); + repeatedForeignEnum_.WriteTo(output, _repeated_repeatedForeignEnum_codec); + repeatedImportEnum_.WriteTo(output, _repeated_repeatedImportEnum_codec); + repeatedPublicImportMessage_.WriteTo(output, _repeated_repeatedPublicImportMessage_codec); if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint32) { output.WriteRawTag(248, 6); output.WriteUInt32(OneofUint32); @@ -1304,160 +1285,28 @@ namespace Google.Protobuf.TestProtos { if (singlePublicImportMessage_ != null) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(SinglePublicImportMessage); } - if (repeatedInt32_.Count > 0) { - int dataSize = 0; - foreach (int element in repeatedInt32_) { - dataSize += pb::CodedOutputStream.ComputeInt32Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedInt64_.Count > 0) { - int dataSize = 0; - foreach (long element in repeatedInt64_) { - dataSize += pb::CodedOutputStream.ComputeInt64Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedUint32_.Count > 0) { - int dataSize = 0; - foreach (uint element in repeatedUint32_) { - dataSize += pb::CodedOutputStream.ComputeUInt32Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedUint64_.Count > 0) { - int dataSize = 0; - foreach (ulong element in repeatedUint64_) { - dataSize += pb::CodedOutputStream.ComputeUInt64Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedSint32_.Count > 0) { - int dataSize = 0; - foreach (int element in repeatedSint32_) { - dataSize += pb::CodedOutputStream.ComputeSInt32Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedSint64_.Count > 0) { - int dataSize = 0; - foreach (long element in repeatedSint64_) { - dataSize += pb::CodedOutputStream.ComputeSInt64Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedFixed32_.Count > 0) { - int dataSize = 0; - dataSize = 4 * repeatedFixed32_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedFixed64_.Count > 0) { - int dataSize = 0; - dataSize = 8 * repeatedFixed64_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedSfixed32_.Count > 0) { - int dataSize = 0; - dataSize = 4 * repeatedSfixed32_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedSfixed64_.Count > 0) { - int dataSize = 0; - dataSize = 8 * repeatedSfixed64_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedFloat_.Count > 0) { - int dataSize = 0; - dataSize = 4 * repeatedFloat_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedDouble_.Count > 0) { - int dataSize = 0; - dataSize = 8 * repeatedDouble_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedBool_.Count > 0) { - int dataSize = 0; - dataSize = 1 * repeatedBool_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedString_.Count > 0) { - int dataSize = 0; - foreach (string element in repeatedString_) { - dataSize += pb::CodedOutputStream.ComputeStringSize(element); - } - size += dataSize; - size += 2 * repeatedString_.Count; - } - if (repeatedBytes_.Count > 0) { - int dataSize = 0; - foreach (pb::ByteString element in repeatedBytes_) { - dataSize += pb::CodedOutputStream.ComputeBytesSize(element); - } - size += dataSize; - size += 2 * repeatedBytes_.Count; - } - if (repeatedNestedMessage_.Count > 0) { - foreach (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage element in repeatedNestedMessage_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * repeatedNestedMessage_.Count; - } - if (repeatedForeignMessage_.Count > 0) { - foreach (global::Google.Protobuf.TestProtos.ForeignMessage element in repeatedForeignMessage_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * repeatedForeignMessage_.Count; - } - if (repeatedImportMessage_.Count > 0) { - foreach (global::Google.Protobuf.TestProtos.ImportMessage element in repeatedImportMessage_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * repeatedImportMessage_.Count; - } - if (repeatedNestedEnum_.Count > 0) { - int dataSize = 0; - foreach (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum element in repeatedNestedEnum_) { - dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize); - } - if (repeatedForeignEnum_.Count > 0) { - int dataSize = 0; - foreach (global::Google.Protobuf.TestProtos.ForeignEnum element in repeatedForeignEnum_) { - dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize); - } - if (repeatedImportEnum_.Count > 0) { - int dataSize = 0; - foreach (global::Google.Protobuf.TestProtos.ImportEnum element in repeatedImportEnum_) { - dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize); - } - if (repeatedPublicImportMessage_.Count > 0) { - foreach (global::Google.Protobuf.TestProtos.PublicImportMessage element in repeatedPublicImportMessage_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * repeatedPublicImportMessage_.Count; - } + size += repeatedInt32_.CalculateSize(_repeated_repeatedInt32_codec); + size += repeatedInt64_.CalculateSize(_repeated_repeatedInt64_codec); + size += repeatedUint32_.CalculateSize(_repeated_repeatedUint32_codec); + size += repeatedUint64_.CalculateSize(_repeated_repeatedUint64_codec); + size += repeatedSint32_.CalculateSize(_repeated_repeatedSint32_codec); + size += repeatedSint64_.CalculateSize(_repeated_repeatedSint64_codec); + size += repeatedFixed32_.CalculateSize(_repeated_repeatedFixed32_codec); + size += repeatedFixed64_.CalculateSize(_repeated_repeatedFixed64_codec); + size += repeatedSfixed32_.CalculateSize(_repeated_repeatedSfixed32_codec); + size += repeatedSfixed64_.CalculateSize(_repeated_repeatedSfixed64_codec); + size += repeatedFloat_.CalculateSize(_repeated_repeatedFloat_codec); + size += repeatedDouble_.CalculateSize(_repeated_repeatedDouble_codec); + size += repeatedBool_.CalculateSize(_repeated_repeatedBool_codec); + size += repeatedString_.CalculateSize(_repeated_repeatedString_codec); + size += repeatedBytes_.CalculateSize(_repeated_repeatedBytes_codec); + size += repeatedNestedMessage_.CalculateSize(_repeated_repeatedNestedMessage_codec); + size += repeatedForeignMessage_.CalculateSize(_repeated_repeatedForeignMessage_codec); + size += repeatedImportMessage_.CalculateSize(_repeated_repeatedImportMessage_codec); + size += repeatedNestedEnum_.CalculateSize(_repeated_repeatedNestedEnum_codec); + size += repeatedForeignEnum_.CalculateSize(_repeated_repeatedForeignEnum_codec); + size += repeatedImportEnum_.CalculateSize(_repeated_repeatedImportEnum_codec); + size += repeatedPublicImportMessage_.CalculateSize(_repeated_repeatedPublicImportMessage_codec); if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint32) { size += 2 + pb::CodedOutputStream.ComputeUInt32Size(OneofUint32); } @@ -1707,106 +1556,106 @@ namespace Google.Protobuf.TestProtos { } case 250: case 248: { - input.ReadInt32Array(repeatedInt32_); + repeatedInt32_.AddEntriesFrom(input, _repeated_repeatedInt32_codec); break; } case 258: case 256: { - input.ReadInt64Array(repeatedInt64_); + repeatedInt64_.AddEntriesFrom(input, _repeated_repeatedInt64_codec); break; } case 266: case 264: { - input.ReadUInt32Array(repeatedUint32_); + repeatedUint32_.AddEntriesFrom(input, _repeated_repeatedUint32_codec); break; } case 274: case 272: { - input.ReadUInt64Array(repeatedUint64_); + repeatedUint64_.AddEntriesFrom(input, _repeated_repeatedUint64_codec); break; } case 282: case 280: { - input.ReadSInt32Array(repeatedSint32_); + repeatedSint32_.AddEntriesFrom(input, _repeated_repeatedSint32_codec); break; } case 290: case 288: { - input.ReadSInt64Array(repeatedSint64_); + repeatedSint64_.AddEntriesFrom(input, _repeated_repeatedSint64_codec); break; } case 298: case 301: { - input.ReadFixed32Array(repeatedFixed32_); + repeatedFixed32_.AddEntriesFrom(input, _repeated_repeatedFixed32_codec); break; } case 306: case 305: { - input.ReadFixed64Array(repeatedFixed64_); + repeatedFixed64_.AddEntriesFrom(input, _repeated_repeatedFixed64_codec); break; } case 314: case 317: { - input.ReadSFixed32Array(repeatedSfixed32_); + repeatedSfixed32_.AddEntriesFrom(input, _repeated_repeatedSfixed32_codec); break; } case 322: case 321: { - input.ReadSFixed64Array(repeatedSfixed64_); + repeatedSfixed64_.AddEntriesFrom(input, _repeated_repeatedSfixed64_codec); break; } case 330: case 333: { - input.ReadFloatArray(repeatedFloat_); + repeatedFloat_.AddEntriesFrom(input, _repeated_repeatedFloat_codec); break; } case 338: case 337: { - input.ReadDoubleArray(repeatedDouble_); + repeatedDouble_.AddEntriesFrom(input, _repeated_repeatedDouble_codec); break; } case 346: case 344: { - input.ReadBoolArray(repeatedBool_); + repeatedBool_.AddEntriesFrom(input, _repeated_repeatedBool_codec); break; } case 354: { - input.ReadStringArray(repeatedString_); + repeatedString_.AddEntriesFrom(input, _repeated_repeatedString_codec); break; } case 362: { - input.ReadBytesArray(repeatedBytes_); + repeatedBytes_.AddEntriesFrom(input, _repeated_repeatedBytes_codec); break; } case 386: { - input.ReadMessageArray(repeatedNestedMessage_, global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage.Parser); + repeatedNestedMessage_.AddEntriesFrom(input, _repeated_repeatedNestedMessage_codec); break; } case 394: { - input.ReadMessageArray(repeatedForeignMessage_, global::Google.Protobuf.TestProtos.ForeignMessage.Parser); + repeatedForeignMessage_.AddEntriesFrom(input, _repeated_repeatedForeignMessage_codec); break; } case 402: { - input.ReadMessageArray(repeatedImportMessage_, global::Google.Protobuf.TestProtos.ImportMessage.Parser); + repeatedImportMessage_.AddEntriesFrom(input, _repeated_repeatedImportMessage_codec); break; } case 410: case 408: { - input.ReadEnumArray<global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum>(repeatedNestedEnum_); + repeatedNestedEnum_.AddEntriesFrom(input, _repeated_repeatedNestedEnum_codec); break; } case 418: case 416: { - input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(repeatedForeignEnum_); + repeatedForeignEnum_.AddEntriesFrom(input, _repeated_repeatedForeignEnum_codec); break; } case 426: case 424: { - input.ReadEnumArray<global::Google.Protobuf.TestProtos.ImportEnum>(repeatedImportEnum_); + repeatedImportEnum_.AddEntriesFrom(input, _repeated_repeatedImportEnum_codec); break; } case 434: { - input.ReadMessageArray(repeatedPublicImportMessage_, global::Google.Protobuf.TestProtos.PublicImportMessage.Parser); + repeatedPublicImportMessage_.AddEntriesFrom(input, _repeated_repeatedPublicImportMessage_codec); break; } case 888: { @@ -2022,6 +1871,8 @@ namespace Google.Protobuf.TestProtos { } public const int RepeatedChildFieldNumber = 3; + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.NestedTestAllTypes> _repeated_repeatedChild_codec + = pb::FieldCodec.ForMessage(26, global::Google.Protobuf.TestProtos.NestedTestAllTypes.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.NestedTestAllTypes> repeatedChild_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.NestedTestAllTypes>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.NestedTestAllTypes> RepeatedChild { get { return repeatedChild_; } @@ -2061,9 +1912,7 @@ namespace Google.Protobuf.TestProtos { output.WriteRawTag(18); output.WriteMessage(Payload); } - if (repeatedChild_.Count > 0) { - output.WriteMessageArray(3, repeatedChild_); - } + repeatedChild_.WriteTo(output, _repeated_repeatedChild_codec); } public int CalculateSize() { @@ -2074,12 +1923,7 @@ namespace Google.Protobuf.TestProtos { if (payload_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Payload); } - if (repeatedChild_.Count > 0) { - foreach (global::Google.Protobuf.TestProtos.NestedTestAllTypes element in repeatedChild_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * repeatedChild_.Count; - } + size += repeatedChild_.CalculateSize(_repeated_repeatedChild_codec); return size; } @@ -2128,7 +1972,7 @@ namespace Google.Protobuf.TestProtos { break; } case 26: { - input.ReadMessageArray(repeatedChild_, global::Google.Protobuf.TestProtos.NestedTestAllTypes.Parser); + repeatedChild_.AddEntriesFrom(input, _repeated_repeatedChild_codec); break; } } @@ -3196,24 +3040,31 @@ namespace Google.Protobuf.TestProtos { } public const int RepeatedPrimitiveFieldFieldNumber = 7; + private static readonly pb::FieldCodec<int> _repeated_repeatedPrimitiveField_codec + = pb::FieldCodec.ForInt32(58); private readonly pbc::RepeatedField<int> repeatedPrimitiveField_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> RepeatedPrimitiveField { get { return repeatedPrimitiveField_; } } public const int RepeatedStringFieldFieldNumber = 8; + private static readonly pb::FieldCodec<string> _repeated_repeatedStringField_codec + = pb::FieldCodec.ForString(66); private readonly pbc::RepeatedField<string> repeatedStringField_ = new pbc::RepeatedField<string>(); public pbc::RepeatedField<string> RepeatedStringField { get { return repeatedStringField_; } } public const int RepeatedEnumFieldFieldNumber = 9; - private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> repeatedEnumField_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>(); + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_repeatedEnumField_codec + = pb::FieldCodec.ForEnum(74, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> repeatedEnumField_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> RepeatedEnumField { get { return repeatedEnumField_; } } public const int RepeatedMessageFieldFieldNumber = 10; + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignMessage> _repeated_repeatedMessageField_codec + = pb::FieldCodec.ForMessage(82, global::Google.Protobuf.TestProtos.ForeignMessage.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> repeatedMessageField_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignMessage> RepeatedMessageField { get { return repeatedMessageField_; } @@ -3271,20 +3122,10 @@ namespace Google.Protobuf.TestProtos { output.WriteRawTag(34); output.WriteMessage(MessageField); } - if (repeatedPrimitiveField_.Count > 0) { - output.WriteRawTag(58); - output.WritePackedInt32Array(repeatedPrimitiveField_); - } - if (repeatedStringField_.Count > 0) { - output.WriteStringArray(8, repeatedStringField_); - } - if (repeatedEnumField_.Count > 0) { - output.WriteRawTag(74); - output.WritePackedEnumArray(repeatedEnumField_); - } - if (repeatedMessageField_.Count > 0) { - output.WriteMessageArray(10, repeatedMessageField_); - } + repeatedPrimitiveField_.WriteTo(output, _repeated_repeatedPrimitiveField_codec); + repeatedStringField_.WriteTo(output, _repeated_repeatedStringField_codec); + repeatedEnumField_.WriteTo(output, _repeated_repeatedEnumField_codec); + repeatedMessageField_.WriteTo(output, _repeated_repeatedMessageField_codec); } public int CalculateSize() { @@ -3301,36 +3142,10 @@ namespace Google.Protobuf.TestProtos { if (messageField_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(MessageField); } - if (repeatedPrimitiveField_.Count > 0) { - int dataSize = 0; - foreach (int element in repeatedPrimitiveField_) { - dataSize += pb::CodedOutputStream.ComputeInt32Size(element); - } - size += dataSize; - size += 1 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedStringField_.Count > 0) { - int dataSize = 0; - foreach (string element in repeatedStringField_) { - dataSize += pb::CodedOutputStream.ComputeStringSize(element); - } - size += dataSize; - size += 1 * repeatedStringField_.Count; - } - if (repeatedEnumField_.Count > 0) { - int dataSize = 0; - foreach (global::Google.Protobuf.TestProtos.ForeignEnum element in repeatedEnumField_) { - dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element); - } - size += dataSize; - size += 1 + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize); - } - if (repeatedMessageField_.Count > 0) { - foreach (global::Google.Protobuf.TestProtos.ForeignMessage element in repeatedMessageField_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * repeatedMessageField_.Count; - } + size += repeatedPrimitiveField_.CalculateSize(_repeated_repeatedPrimitiveField_codec); + size += repeatedStringField_.CalculateSize(_repeated_repeatedStringField_codec); + size += repeatedEnumField_.CalculateSize(_repeated_repeatedEnumField_codec); + size += repeatedMessageField_.CalculateSize(_repeated_repeatedMessageField_codec); return size; } @@ -3391,20 +3206,20 @@ namespace Google.Protobuf.TestProtos { } case 58: case 56: { - input.ReadInt32Array(repeatedPrimitiveField_); + repeatedPrimitiveField_.AddEntriesFrom(input, _repeated_repeatedPrimitiveField_codec); break; } case 66: { - input.ReadStringArray(repeatedStringField_); + repeatedStringField_.AddEntriesFrom(input, _repeated_repeatedStringField_codec); break; } case 74: case 72: { - input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(repeatedEnumField_); + repeatedEnumField_.AddEntriesFrom(input, _repeated_repeatedEnumField_codec); break; } case 82: { - input.ReadMessageArray(repeatedMessageField_, global::Google.Protobuf.TestProtos.ForeignMessage.Parser); + repeatedMessageField_.AddEntriesFrom(input, _repeated_repeatedMessageField_codec); break; } } @@ -4015,6 +3830,8 @@ namespace Google.Protobuf.TestProtos { } public const int DataFieldNumber = 1; + private static readonly pb::FieldCodec<string> _repeated_data_codec + = pb::FieldCodec.ForString(10); private readonly pbc::RepeatedField<string> data_ = new pbc::RepeatedField<string>(); public pbc::RepeatedField<string> Data { get { return data_; } @@ -4042,21 +3859,12 @@ namespace Google.Protobuf.TestProtos { } public void WriteTo(pb::CodedOutputStream output) { - if (data_.Count > 0) { - output.WriteStringArray(1, data_); - } + data_.WriteTo(output, _repeated_data_codec); } public int CalculateSize() { int size = 0; - if (data_.Count > 0) { - int dataSize = 0; - foreach (string element in data_) { - dataSize += pb::CodedOutputStream.ComputeStringSize(element); - } - size += dataSize; - size += 1 * data_.Count; - } + size += data_.CalculateSize(_repeated_data_codec); return size; } @@ -4079,7 +3887,7 @@ namespace Google.Protobuf.TestProtos { } break; case 10: { - input.ReadStringArray(data_); + data_.AddEntriesFrom(input, _repeated_data_codec); break; } } @@ -5129,85 +4937,112 @@ namespace Google.Protobuf.TestProtos { } public const int PackedInt32FieldNumber = 90; + private static readonly pb::FieldCodec<int> _repeated_packedInt32_codec + = pb::FieldCodec.ForInt32(722); private readonly pbc::RepeatedField<int> packedInt32_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> PackedInt32 { get { return packedInt32_; } } public const int PackedInt64FieldNumber = 91; + private static readonly pb::FieldCodec<long> _repeated_packedInt64_codec + = pb::FieldCodec.ForInt64(730); private readonly pbc::RepeatedField<long> packedInt64_ = new pbc::RepeatedField<long>(); public pbc::RepeatedField<long> PackedInt64 { get { return packedInt64_; } } public const int PackedUint32FieldNumber = 92; + private static readonly pb::FieldCodec<uint> _repeated_packedUint32_codec + = pb::FieldCodec.ForUInt32(738); private readonly pbc::RepeatedField<uint> packedUint32_ = new pbc::RepeatedField<uint>(); public pbc::RepeatedField<uint> PackedUint32 { get { return packedUint32_; } } public const int PackedUint64FieldNumber = 93; + private static readonly pb::FieldCodec<ulong> _repeated_packedUint64_codec + = pb::FieldCodec.ForUInt64(746); private readonly pbc::RepeatedField<ulong> packedUint64_ = new pbc::RepeatedField<ulong>(); public pbc::RepeatedField<ulong> PackedUint64 { get { return packedUint64_; } } public const int PackedSint32FieldNumber = 94; + private static readonly pb::FieldCodec<int> _repeated_packedSint32_codec + = pb::FieldCodec.ForSInt32(754); private readonly pbc::RepeatedField<int> packedSint32_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> PackedSint32 { get { return packedSint32_; } } public const int PackedSint64FieldNumber = 95; + private static readonly pb::FieldCodec<long> _repeated_packedSint64_codec + = pb::FieldCodec.ForSInt64(762); private readonly pbc::RepeatedField<long> packedSint64_ = new pbc::RepeatedField<long>(); public pbc::RepeatedField<long> PackedSint64 { get { return packedSint64_; } } public const int PackedFixed32FieldNumber = 96; + private static readonly pb::FieldCodec<uint> _repeated_packedFixed32_codec + = pb::FieldCodec.ForFixed32(770); private readonly pbc::RepeatedField<uint> packedFixed32_ = new pbc::RepeatedField<uint>(); public pbc::RepeatedField<uint> PackedFixed32 { get { return packedFixed32_; } } public const int PackedFixed64FieldNumber = 97; + private static readonly pb::FieldCodec<ulong> _repeated_packedFixed64_codec + = pb::FieldCodec.ForFixed64(778); private readonly pbc::RepeatedField<ulong> packedFixed64_ = new pbc::RepeatedField<ulong>(); public pbc::RepeatedField<ulong> PackedFixed64 { get { return packedFixed64_; } } public const int PackedSfixed32FieldNumber = 98; + private static readonly pb::FieldCodec<int> _repeated_packedSfixed32_codec + = pb::FieldCodec.ForSFixed32(786); private readonly pbc::RepeatedField<int> packedSfixed32_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> PackedSfixed32 { get { return packedSfixed32_; } } public const int PackedSfixed64FieldNumber = 99; + private static readonly pb::FieldCodec<long> _repeated_packedSfixed64_codec + = pb::FieldCodec.ForSFixed64(794); private readonly pbc::RepeatedField<long> packedSfixed64_ = new pbc::RepeatedField<long>(); public pbc::RepeatedField<long> PackedSfixed64 { get { return packedSfixed64_; } } public const int PackedFloatFieldNumber = 100; + private static readonly pb::FieldCodec<float> _repeated_packedFloat_codec + = pb::FieldCodec.ForFloat(802); private readonly pbc::RepeatedField<float> packedFloat_ = new pbc::RepeatedField<float>(); public pbc::RepeatedField<float> PackedFloat { get { return packedFloat_; } } public const int PackedDoubleFieldNumber = 101; + private static readonly pb::FieldCodec<double> _repeated_packedDouble_codec + = pb::FieldCodec.ForDouble(810); private readonly pbc::RepeatedField<double> packedDouble_ = new pbc::RepeatedField<double>(); public pbc::RepeatedField<double> PackedDouble { get { return packedDouble_; } } public const int PackedBoolFieldNumber = 102; + private static readonly pb::FieldCodec<bool> _repeated_packedBool_codec + = pb::FieldCodec.ForBool(818); private readonly pbc::RepeatedField<bool> packedBool_ = new pbc::RepeatedField<bool>(); public pbc::RepeatedField<bool> PackedBool { get { return packedBool_; } } public const int PackedEnumFieldNumber = 103; - private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> packedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>(); + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_packedEnum_codec + = pb::FieldCodec.ForEnum(826, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> packedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> PackedEnum { get { return packedEnum_; } } @@ -5260,164 +5095,38 @@ namespace Google.Protobuf.TestProtos { } public void WriteTo(pb::CodedOutputStream output) { - if (packedInt32_.Count > 0) { - output.WriteRawTag(210, 5); - output.WritePackedInt32Array(packedInt32_); - } - if (packedInt64_.Count > 0) { - output.WriteRawTag(218, 5); - output.WritePackedInt64Array(packedInt64_); - } - if (packedUint32_.Count > 0) { - output.WriteRawTag(226, 5); - output.WritePackedUInt32Array(packedUint32_); - } - if (packedUint64_.Count > 0) { - output.WriteRawTag(234, 5); - output.WritePackedUInt64Array(packedUint64_); - } - if (packedSint32_.Count > 0) { - output.WriteRawTag(242, 5); - output.WritePackedSInt32Array(packedSint32_); - } - if (packedSint64_.Count > 0) { - output.WriteRawTag(250, 5); - output.WritePackedSInt64Array(packedSint64_); - } - if (packedFixed32_.Count > 0) { - output.WriteRawTag(130, 6); - output.WritePackedFixed32Array(packedFixed32_); - } - if (packedFixed64_.Count > 0) { - output.WriteRawTag(138, 6); - output.WritePackedFixed64Array(packedFixed64_); - } - if (packedSfixed32_.Count > 0) { - output.WriteRawTag(146, 6); - output.WritePackedSFixed32Array(packedSfixed32_); - } - if (packedSfixed64_.Count > 0) { - output.WriteRawTag(154, 6); - output.WritePackedSFixed64Array(packedSfixed64_); - } - if (packedFloat_.Count > 0) { - output.WriteRawTag(162, 6); - output.WritePackedFloatArray(packedFloat_); - } - if (packedDouble_.Count > 0) { - output.WriteRawTag(170, 6); - output.WritePackedDoubleArray(packedDouble_); - } - if (packedBool_.Count > 0) { - output.WriteRawTag(178, 6); - output.WritePackedBoolArray(packedBool_); - } - if (packedEnum_.Count > 0) { - output.WriteRawTag(186, 6); - output.WritePackedEnumArray(packedEnum_); - } + packedInt32_.WriteTo(output, _repeated_packedInt32_codec); + packedInt64_.WriteTo(output, _repeated_packedInt64_codec); + packedUint32_.WriteTo(output, _repeated_packedUint32_codec); + packedUint64_.WriteTo(output, _repeated_packedUint64_codec); + packedSint32_.WriteTo(output, _repeated_packedSint32_codec); + packedSint64_.WriteTo(output, _repeated_packedSint64_codec); + packedFixed32_.WriteTo(output, _repeated_packedFixed32_codec); + packedFixed64_.WriteTo(output, _repeated_packedFixed64_codec); + packedSfixed32_.WriteTo(output, _repeated_packedSfixed32_codec); + packedSfixed64_.WriteTo(output, _repeated_packedSfixed64_codec); + packedFloat_.WriteTo(output, _repeated_packedFloat_codec); + packedDouble_.WriteTo(output, _repeated_packedDouble_codec); + packedBool_.WriteTo(output, _repeated_packedBool_codec); + packedEnum_.WriteTo(output, _repeated_packedEnum_codec); } public int CalculateSize() { int size = 0; - if (packedInt32_.Count > 0) { - int dataSize = 0; - foreach (int element in packedInt32_) { - dataSize += pb::CodedOutputStream.ComputeInt32Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedInt64_.Count > 0) { - int dataSize = 0; - foreach (long element in packedInt64_) { - dataSize += pb::CodedOutputStream.ComputeInt64Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedUint32_.Count > 0) { - int dataSize = 0; - foreach (uint element in packedUint32_) { - dataSize += pb::CodedOutputStream.ComputeUInt32Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedUint64_.Count > 0) { - int dataSize = 0; - foreach (ulong element in packedUint64_) { - dataSize += pb::CodedOutputStream.ComputeUInt64Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedSint32_.Count > 0) { - int dataSize = 0; - foreach (int element in packedSint32_) { - dataSize += pb::CodedOutputStream.ComputeSInt32Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedSint64_.Count > 0) { - int dataSize = 0; - foreach (long element in packedSint64_) { - dataSize += pb::CodedOutputStream.ComputeSInt64Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedFixed32_.Count > 0) { - int dataSize = 0; - dataSize = 4 * packedFixed32_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedFixed64_.Count > 0) { - int dataSize = 0; - dataSize = 8 * packedFixed64_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedSfixed32_.Count > 0) { - int dataSize = 0; - dataSize = 4 * packedSfixed32_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedSfixed64_.Count > 0) { - int dataSize = 0; - dataSize = 8 * packedSfixed64_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedFloat_.Count > 0) { - int dataSize = 0; - dataSize = 4 * packedFloat_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedDouble_.Count > 0) { - int dataSize = 0; - dataSize = 8 * packedDouble_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedBool_.Count > 0) { - int dataSize = 0; - dataSize = 1 * packedBool_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (packedEnum_.Count > 0) { - int dataSize = 0; - foreach (global::Google.Protobuf.TestProtos.ForeignEnum element in packedEnum_) { - dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize); - } + size += packedInt32_.CalculateSize(_repeated_packedInt32_codec); + size += packedInt64_.CalculateSize(_repeated_packedInt64_codec); + size += packedUint32_.CalculateSize(_repeated_packedUint32_codec); + size += packedUint64_.CalculateSize(_repeated_packedUint64_codec); + size += packedSint32_.CalculateSize(_repeated_packedSint32_codec); + size += packedSint64_.CalculateSize(_repeated_packedSint64_codec); + size += packedFixed32_.CalculateSize(_repeated_packedFixed32_codec); + size += packedFixed64_.CalculateSize(_repeated_packedFixed64_codec); + size += packedSfixed32_.CalculateSize(_repeated_packedSfixed32_codec); + size += packedSfixed64_.CalculateSize(_repeated_packedSfixed64_codec); + size += packedFloat_.CalculateSize(_repeated_packedFloat_codec); + size += packedDouble_.CalculateSize(_repeated_packedDouble_codec); + size += packedBool_.CalculateSize(_repeated_packedBool_codec); + size += packedEnum_.CalculateSize(_repeated_packedEnum_codec); return size; } @@ -5454,72 +5163,72 @@ namespace Google.Protobuf.TestProtos { break; case 722: case 720: { - input.ReadInt32Array(packedInt32_); + packedInt32_.AddEntriesFrom(input, _repeated_packedInt32_codec); break; } case 730: case 728: { - input.ReadInt64Array(packedInt64_); + packedInt64_.AddEntriesFrom(input, _repeated_packedInt64_codec); break; } case 738: case 736: { - input.ReadUInt32Array(packedUint32_); + packedUint32_.AddEntriesFrom(input, _repeated_packedUint32_codec); break; } case 746: case 744: { - input.ReadUInt64Array(packedUint64_); + packedUint64_.AddEntriesFrom(input, _repeated_packedUint64_codec); break; } case 754: case 752: { - input.ReadSInt32Array(packedSint32_); + packedSint32_.AddEntriesFrom(input, _repeated_packedSint32_codec); break; } case 762: case 760: { - input.ReadSInt64Array(packedSint64_); + packedSint64_.AddEntriesFrom(input, _repeated_packedSint64_codec); break; } case 770: case 773: { - input.ReadFixed32Array(packedFixed32_); + packedFixed32_.AddEntriesFrom(input, _repeated_packedFixed32_codec); break; } case 778: case 777: { - input.ReadFixed64Array(packedFixed64_); + packedFixed64_.AddEntriesFrom(input, _repeated_packedFixed64_codec); break; } case 786: case 789: { - input.ReadSFixed32Array(packedSfixed32_); + packedSfixed32_.AddEntriesFrom(input, _repeated_packedSfixed32_codec); break; } case 794: case 793: { - input.ReadSFixed64Array(packedSfixed64_); + packedSfixed64_.AddEntriesFrom(input, _repeated_packedSfixed64_codec); break; } case 802: case 805: { - input.ReadFloatArray(packedFloat_); + packedFloat_.AddEntriesFrom(input, _repeated_packedFloat_codec); break; } case 810: case 809: { - input.ReadDoubleArray(packedDouble_); + packedDouble_.AddEntriesFrom(input, _repeated_packedDouble_codec); break; } case 818: case 816: { - input.ReadBoolArray(packedBool_); + packedBool_.AddEntriesFrom(input, _repeated_packedBool_codec); break; } case 826: case 824: { - input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(packedEnum_); + packedEnum_.AddEntriesFrom(input, _repeated_packedEnum_codec); break; } } @@ -5591,85 +5300,112 @@ namespace Google.Protobuf.TestProtos { } public const int UnpackedInt32FieldNumber = 90; + private static readonly pb::FieldCodec<int> _repeated_unpackedInt32_codec + = pb::FieldCodec.ForInt32(720); private readonly pbc::RepeatedField<int> unpackedInt32_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> UnpackedInt32 { get { return unpackedInt32_; } } public const int UnpackedInt64FieldNumber = 91; + private static readonly pb::FieldCodec<long> _repeated_unpackedInt64_codec + = pb::FieldCodec.ForInt64(728); private readonly pbc::RepeatedField<long> unpackedInt64_ = new pbc::RepeatedField<long>(); public pbc::RepeatedField<long> UnpackedInt64 { get { return unpackedInt64_; } } public const int UnpackedUint32FieldNumber = 92; + private static readonly pb::FieldCodec<uint> _repeated_unpackedUint32_codec + = pb::FieldCodec.ForUInt32(736); private readonly pbc::RepeatedField<uint> unpackedUint32_ = new pbc::RepeatedField<uint>(); public pbc::RepeatedField<uint> UnpackedUint32 { get { return unpackedUint32_; } } public const int UnpackedUint64FieldNumber = 93; + private static readonly pb::FieldCodec<ulong> _repeated_unpackedUint64_codec + = pb::FieldCodec.ForUInt64(744); private readonly pbc::RepeatedField<ulong> unpackedUint64_ = new pbc::RepeatedField<ulong>(); public pbc::RepeatedField<ulong> UnpackedUint64 { get { return unpackedUint64_; } } public const int UnpackedSint32FieldNumber = 94; + private static readonly pb::FieldCodec<int> _repeated_unpackedSint32_codec + = pb::FieldCodec.ForSInt32(752); private readonly pbc::RepeatedField<int> unpackedSint32_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> UnpackedSint32 { get { return unpackedSint32_; } } public const int UnpackedSint64FieldNumber = 95; + private static readonly pb::FieldCodec<long> _repeated_unpackedSint64_codec + = pb::FieldCodec.ForSInt64(760); private readonly pbc::RepeatedField<long> unpackedSint64_ = new pbc::RepeatedField<long>(); public pbc::RepeatedField<long> UnpackedSint64 { get { return unpackedSint64_; } } public const int UnpackedFixed32FieldNumber = 96; + private static readonly pb::FieldCodec<uint> _repeated_unpackedFixed32_codec + = pb::FieldCodec.ForFixed32(773); private readonly pbc::RepeatedField<uint> unpackedFixed32_ = new pbc::RepeatedField<uint>(); public pbc::RepeatedField<uint> UnpackedFixed32 { get { return unpackedFixed32_; } } public const int UnpackedFixed64FieldNumber = 97; + private static readonly pb::FieldCodec<ulong> _repeated_unpackedFixed64_codec + = pb::FieldCodec.ForFixed64(777); private readonly pbc::RepeatedField<ulong> unpackedFixed64_ = new pbc::RepeatedField<ulong>(); public pbc::RepeatedField<ulong> UnpackedFixed64 { get { return unpackedFixed64_; } } public const int UnpackedSfixed32FieldNumber = 98; + private static readonly pb::FieldCodec<int> _repeated_unpackedSfixed32_codec + = pb::FieldCodec.ForSFixed32(789); private readonly pbc::RepeatedField<int> unpackedSfixed32_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> UnpackedSfixed32 { get { return unpackedSfixed32_; } } public const int UnpackedSfixed64FieldNumber = 99; + private static readonly pb::FieldCodec<long> _repeated_unpackedSfixed64_codec + = pb::FieldCodec.ForSFixed64(793); private readonly pbc::RepeatedField<long> unpackedSfixed64_ = new pbc::RepeatedField<long>(); public pbc::RepeatedField<long> UnpackedSfixed64 { get { return unpackedSfixed64_; } } public const int UnpackedFloatFieldNumber = 100; + private static readonly pb::FieldCodec<float> _repeated_unpackedFloat_codec + = pb::FieldCodec.ForFloat(805); private readonly pbc::RepeatedField<float> unpackedFloat_ = new pbc::RepeatedField<float>(); public pbc::RepeatedField<float> UnpackedFloat { get { return unpackedFloat_; } } public const int UnpackedDoubleFieldNumber = 101; + private static readonly pb::FieldCodec<double> _repeated_unpackedDouble_codec + = pb::FieldCodec.ForDouble(809); private readonly pbc::RepeatedField<double> unpackedDouble_ = new pbc::RepeatedField<double>(); public pbc::RepeatedField<double> UnpackedDouble { get { return unpackedDouble_; } } public const int UnpackedBoolFieldNumber = 102; + private static readonly pb::FieldCodec<bool> _repeated_unpackedBool_codec + = pb::FieldCodec.ForBool(816); private readonly pbc::RepeatedField<bool> unpackedBool_ = new pbc::RepeatedField<bool>(); public pbc::RepeatedField<bool> UnpackedBool { get { return unpackedBool_; } } public const int UnpackedEnumFieldNumber = 103; - private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> unpackedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>(); + private static readonly pb::FieldCodec<global::Google.Protobuf.TestProtos.ForeignEnum> _repeated_unpackedEnum_codec + = pb::FieldCodec.ForEnum(824, x => (int) x, x => (global::Google.Protobuf.TestProtos.ForeignEnum) x);private readonly pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> unpackedEnum_ = new pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum>(); public pbc::RepeatedField<global::Google.Protobuf.TestProtos.ForeignEnum> UnpackedEnum { get { return unpackedEnum_; } } @@ -5722,150 +5458,38 @@ namespace Google.Protobuf.TestProtos { } public void WriteTo(pb::CodedOutputStream output) { - if (unpackedInt32_.Count > 0) { - output.WriteInt32Array(90, unpackedInt32_); - } - if (unpackedInt64_.Count > 0) { - output.WriteInt64Array(91, unpackedInt64_); - } - if (unpackedUint32_.Count > 0) { - output.WriteUInt32Array(92, unpackedUint32_); - } - if (unpackedUint64_.Count > 0) { - output.WriteUInt64Array(93, unpackedUint64_); - } - if (unpackedSint32_.Count > 0) { - output.WriteSInt32Array(94, unpackedSint32_); - } - if (unpackedSint64_.Count > 0) { - output.WriteSInt64Array(95, unpackedSint64_); - } - if (unpackedFixed32_.Count > 0) { - output.WriteFixed32Array(96, unpackedFixed32_); - } - if (unpackedFixed64_.Count > 0) { - output.WriteFixed64Array(97, unpackedFixed64_); - } - if (unpackedSfixed32_.Count > 0) { - output.WriteSFixed32Array(98, unpackedSfixed32_); - } - if (unpackedSfixed64_.Count > 0) { - output.WriteSFixed64Array(99, unpackedSfixed64_); - } - if (unpackedFloat_.Count > 0) { - output.WriteFloatArray(100, unpackedFloat_); - } - if (unpackedDouble_.Count > 0) { - output.WriteDoubleArray(101, unpackedDouble_); - } - if (unpackedBool_.Count > 0) { - output.WriteBoolArray(102, unpackedBool_); - } - if (unpackedEnum_.Count > 0) { - output.WriteEnumArray(103, unpackedEnum_); - } + unpackedInt32_.WriteTo(output, _repeated_unpackedInt32_codec); + unpackedInt64_.WriteTo(output, _repeated_unpackedInt64_codec); + unpackedUint32_.WriteTo(output, _repeated_unpackedUint32_codec); + unpackedUint64_.WriteTo(output, _repeated_unpackedUint64_codec); + unpackedSint32_.WriteTo(output, _repeated_unpackedSint32_codec); + unpackedSint64_.WriteTo(output, _repeated_unpackedSint64_codec); + unpackedFixed32_.WriteTo(output, _repeated_unpackedFixed32_codec); + unpackedFixed64_.WriteTo(output, _repeated_unpackedFixed64_codec); + unpackedSfixed32_.WriteTo(output, _repeated_unpackedSfixed32_codec); + unpackedSfixed64_.WriteTo(output, _repeated_unpackedSfixed64_codec); + unpackedFloat_.WriteTo(output, _repeated_unpackedFloat_codec); + unpackedDouble_.WriteTo(output, _repeated_unpackedDouble_codec); + unpackedBool_.WriteTo(output, _repeated_unpackedBool_codec); + unpackedEnum_.WriteTo(output, _repeated_unpackedEnum_codec); } public int CalculateSize() { int size = 0; - if (unpackedInt32_.Count > 0) { - int dataSize = 0; - foreach (int element in unpackedInt32_) { - dataSize += pb::CodedOutputStream.ComputeInt32Size(element); - } - size += dataSize; - size += 2 * unpackedInt32_.Count; - } - if (unpackedInt64_.Count > 0) { - int dataSize = 0; - foreach (long element in unpackedInt64_) { - dataSize += pb::CodedOutputStream.ComputeInt64Size(element); - } - size += dataSize; - size += 2 * unpackedInt64_.Count; - } - if (unpackedUint32_.Count > 0) { - int dataSize = 0; - foreach (uint element in unpackedUint32_) { - dataSize += pb::CodedOutputStream.ComputeUInt32Size(element); - } - size += dataSize; - size += 2 * unpackedUint32_.Count; - } - if (unpackedUint64_.Count > 0) { - int dataSize = 0; - foreach (ulong element in unpackedUint64_) { - dataSize += pb::CodedOutputStream.ComputeUInt64Size(element); - } - size += dataSize; - size += 2 * unpackedUint64_.Count; - } - if (unpackedSint32_.Count > 0) { - int dataSize = 0; - foreach (int element in unpackedSint32_) { - dataSize += pb::CodedOutputStream.ComputeSInt32Size(element); - } - size += dataSize; - size += 2 * unpackedSint32_.Count; - } - if (unpackedSint64_.Count > 0) { - int dataSize = 0; - foreach (long element in unpackedSint64_) { - dataSize += pb::CodedOutputStream.ComputeSInt64Size(element); - } - size += dataSize; - size += 2 * unpackedSint64_.Count; - } - if (unpackedFixed32_.Count > 0) { - int dataSize = 0; - dataSize = 4 * unpackedFixed32_.Count; - size += dataSize; - size += 2 * unpackedFixed32_.Count; - } - if (unpackedFixed64_.Count > 0) { - int dataSize = 0; - dataSize = 8 * unpackedFixed64_.Count; - size += dataSize; - size += 2 * unpackedFixed64_.Count; - } - if (unpackedSfixed32_.Count > 0) { - int dataSize = 0; - dataSize = 4 * unpackedSfixed32_.Count; - size += dataSize; - size += 2 * unpackedSfixed32_.Count; - } - if (unpackedSfixed64_.Count > 0) { - int dataSize = 0; - dataSize = 8 * unpackedSfixed64_.Count; - size += dataSize; - size += 2 * unpackedSfixed64_.Count; - } - if (unpackedFloat_.Count > 0) { - int dataSize = 0; - dataSize = 4 * unpackedFloat_.Count; - size += dataSize; - size += 2 * unpackedFloat_.Count; - } - if (unpackedDouble_.Count > 0) { - int dataSize = 0; - dataSize = 8 * unpackedDouble_.Count; - size += dataSize; - size += 2 * unpackedDouble_.Count; - } - if (unpackedBool_.Count > 0) { - int dataSize = 0; - dataSize = 1 * unpackedBool_.Count; - size += dataSize; - size += 2 * unpackedBool_.Count; - } - if (unpackedEnum_.Count > 0) { - int dataSize = 0; - foreach (global::Google.Protobuf.TestProtos.ForeignEnum element in unpackedEnum_) { - dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element); - } - size += dataSize; - size += 2 * unpackedEnum_.Count; - } + size += unpackedInt32_.CalculateSize(_repeated_unpackedInt32_codec); + size += unpackedInt64_.CalculateSize(_repeated_unpackedInt64_codec); + size += unpackedUint32_.CalculateSize(_repeated_unpackedUint32_codec); + size += unpackedUint64_.CalculateSize(_repeated_unpackedUint64_codec); + size += unpackedSint32_.CalculateSize(_repeated_unpackedSint32_codec); + size += unpackedSint64_.CalculateSize(_repeated_unpackedSint64_codec); + size += unpackedFixed32_.CalculateSize(_repeated_unpackedFixed32_codec); + size += unpackedFixed64_.CalculateSize(_repeated_unpackedFixed64_codec); + size += unpackedSfixed32_.CalculateSize(_repeated_unpackedSfixed32_codec); + size += unpackedSfixed64_.CalculateSize(_repeated_unpackedSfixed64_codec); + size += unpackedFloat_.CalculateSize(_repeated_unpackedFloat_codec); + size += unpackedDouble_.CalculateSize(_repeated_unpackedDouble_codec); + size += unpackedBool_.CalculateSize(_repeated_unpackedBool_codec); + size += unpackedEnum_.CalculateSize(_repeated_unpackedEnum_codec); return size; } @@ -5902,72 +5526,72 @@ namespace Google.Protobuf.TestProtos { break; case 722: case 720: { - input.ReadInt32Array(unpackedInt32_); + unpackedInt32_.AddEntriesFrom(input, _repeated_unpackedInt32_codec); break; } case 730: case 728: { - input.ReadInt64Array(unpackedInt64_); + unpackedInt64_.AddEntriesFrom(input, _repeated_unpackedInt64_codec); break; } case 738: case 736: { - input.ReadUInt32Array(unpackedUint32_); + unpackedUint32_.AddEntriesFrom(input, _repeated_unpackedUint32_codec); break; } case 746: case 744: { - input.ReadUInt64Array(unpackedUint64_); + unpackedUint64_.AddEntriesFrom(input, _repeated_unpackedUint64_codec); break; } case 754: case 752: { - input.ReadSInt32Array(unpackedSint32_); + unpackedSint32_.AddEntriesFrom(input, _repeated_unpackedSint32_codec); break; } case 762: case 760: { - input.ReadSInt64Array(unpackedSint64_); + unpackedSint64_.AddEntriesFrom(input, _repeated_unpackedSint64_codec); break; } case 770: case 773: { - input.ReadFixed32Array(unpackedFixed32_); + unpackedFixed32_.AddEntriesFrom(input, _repeated_unpackedFixed32_codec); break; } case 778: case 777: { - input.ReadFixed64Array(unpackedFixed64_); + unpackedFixed64_.AddEntriesFrom(input, _repeated_unpackedFixed64_codec); break; } case 786: case 789: { - input.ReadSFixed32Array(unpackedSfixed32_); + unpackedSfixed32_.AddEntriesFrom(input, _repeated_unpackedSfixed32_codec); break; } case 794: case 793: { - input.ReadSFixed64Array(unpackedSfixed64_); + unpackedSfixed64_.AddEntriesFrom(input, _repeated_unpackedSfixed64_codec); break; } case 802: case 805: { - input.ReadFloatArray(unpackedFloat_); + unpackedFloat_.AddEntriesFrom(input, _repeated_unpackedFloat_codec); break; } case 810: case 809: { - input.ReadDoubleArray(unpackedDouble_); + unpackedDouble_.AddEntriesFrom(input, _repeated_unpackedDouble_codec); break; } case 818: case 816: { - input.ReadBoolArray(unpackedBool_); + unpackedBool_.AddEntriesFrom(input, _repeated_unpackedBool_codec); break; } case 826: case 824: { - input.ReadEnumArray<global::Google.Protobuf.TestProtos.ForeignEnum>(unpackedEnum_); + unpackedEnum_.AddEntriesFrom(input, _repeated_unpackedEnum_codec); break; } } @@ -6023,36 +5647,48 @@ namespace Google.Protobuf.TestProtos { } public const int RepeatedFixed32FieldNumber = 12; + private static readonly pb::FieldCodec<uint> _repeated_repeatedFixed32_codec + = pb::FieldCodec.ForFixed32(98); private readonly pbc::RepeatedField<uint> repeatedFixed32_ = new pbc::RepeatedField<uint>(); public pbc::RepeatedField<uint> RepeatedFixed32 { get { return repeatedFixed32_; } } public const int RepeatedInt32FieldNumber = 13; + private static readonly pb::FieldCodec<int> _repeated_repeatedInt32_codec + = pb::FieldCodec.ForInt32(106); private readonly pbc::RepeatedField<int> repeatedInt32_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> RepeatedInt32 { get { return repeatedInt32_; } } public const int RepeatedFixed64FieldNumber = 2046; + private static readonly pb::FieldCodec<ulong> _repeated_repeatedFixed64_codec + = pb::FieldCodec.ForFixed64(16370); private readonly pbc::RepeatedField<ulong> repeatedFixed64_ = new pbc::RepeatedField<ulong>(); public pbc::RepeatedField<ulong> RepeatedFixed64 { get { return repeatedFixed64_; } } public const int RepeatedInt64FieldNumber = 2047; + private static readonly pb::FieldCodec<long> _repeated_repeatedInt64_codec + = pb::FieldCodec.ForInt64(16378); private readonly pbc::RepeatedField<long> repeatedInt64_ = new pbc::RepeatedField<long>(); public pbc::RepeatedField<long> RepeatedInt64 { get { return repeatedInt64_; } } public const int RepeatedFloatFieldNumber = 262142; + private static readonly pb::FieldCodec<float> _repeated_repeatedFloat_codec + = pb::FieldCodec.ForFloat(2097138); private readonly pbc::RepeatedField<float> repeatedFloat_ = new pbc::RepeatedField<float>(); public pbc::RepeatedField<float> RepeatedFloat { get { return repeatedFloat_; } } public const int RepeatedUint64FieldNumber = 262143; + private static readonly pb::FieldCodec<ulong> _repeated_repeatedUint64_codec + = pb::FieldCodec.ForUInt64(2097146); private readonly pbc::RepeatedField<ulong> repeatedUint64_ = new pbc::RepeatedField<ulong>(); public pbc::RepeatedField<ulong> RepeatedUint64 { get { return repeatedUint64_; } @@ -6090,76 +5726,22 @@ namespace Google.Protobuf.TestProtos { } public void WriteTo(pb::CodedOutputStream output) { - if (repeatedFixed32_.Count > 0) { - output.WriteRawTag(98); - output.WritePackedFixed32Array(repeatedFixed32_); - } - if (repeatedInt32_.Count > 0) { - output.WriteRawTag(106); - output.WritePackedInt32Array(repeatedInt32_); - } - if (repeatedFixed64_.Count > 0) { - output.WriteRawTag(242, 127); - output.WritePackedFixed64Array(repeatedFixed64_); - } - if (repeatedInt64_.Count > 0) { - output.WriteRawTag(250, 127); - output.WritePackedInt64Array(repeatedInt64_); - } - if (repeatedFloat_.Count > 0) { - output.WriteRawTag(242, 255, 127); - output.WritePackedFloatArray(repeatedFloat_); - } - if (repeatedUint64_.Count > 0) { - output.WriteRawTag(250, 255, 127); - output.WritePackedUInt64Array(repeatedUint64_); - } + repeatedFixed32_.WriteTo(output, _repeated_repeatedFixed32_codec); + repeatedInt32_.WriteTo(output, _repeated_repeatedInt32_codec); + repeatedFixed64_.WriteTo(output, _repeated_repeatedFixed64_codec); + repeatedInt64_.WriteTo(output, _repeated_repeatedInt64_codec); + repeatedFloat_.WriteTo(output, _repeated_repeatedFloat_codec); + repeatedUint64_.WriteTo(output, _repeated_repeatedUint64_codec); } public int CalculateSize() { int size = 0; - if (repeatedFixed32_.Count > 0) { - int dataSize = 0; - dataSize = 4 * repeatedFixed32_.Count; - size += dataSize; - size += 1 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedInt32_.Count > 0) { - int dataSize = 0; - foreach (int element in repeatedInt32_) { - dataSize += pb::CodedOutputStream.ComputeInt32Size(element); - } - size += dataSize; - size += 1 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedFixed64_.Count > 0) { - int dataSize = 0; - dataSize = 8 * repeatedFixed64_.Count; - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedInt64_.Count > 0) { - int dataSize = 0; - foreach (long element in repeatedInt64_) { - dataSize += pb::CodedOutputStream.ComputeInt64Size(element); - } - size += dataSize; - size += 2 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedFloat_.Count > 0) { - int dataSize = 0; - dataSize = 4 * repeatedFloat_.Count; - size += dataSize; - size += 3 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (repeatedUint64_.Count > 0) { - int dataSize = 0; - foreach (ulong element in repeatedUint64_) { - dataSize += pb::CodedOutputStream.ComputeUInt64Size(element); - } - size += dataSize; - size += 3 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } + size += repeatedFixed32_.CalculateSize(_repeated_repeatedFixed32_codec); + size += repeatedInt32_.CalculateSize(_repeated_repeatedInt32_codec); + size += repeatedFixed64_.CalculateSize(_repeated_repeatedFixed64_codec); + size += repeatedInt64_.CalculateSize(_repeated_repeatedInt64_codec); + size += repeatedFloat_.CalculateSize(_repeated_repeatedFloat_codec); + size += repeatedUint64_.CalculateSize(_repeated_repeatedUint64_codec); return size; } @@ -6188,32 +5770,32 @@ namespace Google.Protobuf.TestProtos { break; case 98: case 101: { - input.ReadFixed32Array(repeatedFixed32_); + repeatedFixed32_.AddEntriesFrom(input, _repeated_repeatedFixed32_codec); break; } case 106: case 104: { - input.ReadInt32Array(repeatedInt32_); + repeatedInt32_.AddEntriesFrom(input, _repeated_repeatedInt32_codec); break; } case 16370: case 16369: { - input.ReadFixed64Array(repeatedFixed64_); + repeatedFixed64_.AddEntriesFrom(input, _repeated_repeatedFixed64_codec); break; } case 16378: case 16376: { - input.ReadInt64Array(repeatedInt64_); + repeatedInt64_.AddEntriesFrom(input, _repeated_repeatedInt64_codec); break; } case 2097138: case 2097141: { - input.ReadFloatArray(repeatedFloat_); + repeatedFloat_.AddEntriesFrom(input, _repeated_repeatedFloat_codec); break; } case 2097146: case 2097144: { - input.ReadUInt64Array(repeatedUint64_); + repeatedUint64_.AddEntriesFrom(input, _repeated_repeatedUint64_codec); break; } } diff --git a/csharp/src/ProtocolBuffers/CodedInputStream.cs b/csharp/src/ProtocolBuffers/CodedInputStream.cs index dab3e5e3..5c64fd97 100644 --- a/csharp/src/ProtocolBuffers/CodedInputStream.cs +++ b/csharp/src/ProtocolBuffers/CodedInputStream.cs @@ -37,7 +37,6 @@ using System;
using System.Collections.Generic;
using System.IO;
-using Google.Protobuf.Collections;
namespace Google.Protobuf
{
@@ -172,9 +171,68 @@ namespace Google.Protobuf }
}
- #region Validation
+ /// <summary>
+ /// Returns the last tag read, or 0 if no tags have been read or we've read beyond
+ /// the end of the stream.
+ /// </summary>
+ internal uint LastTag { get { return lastTag; } }
+
+ #region Limits for recursion and length
+ /// <summary>
+ /// Set the maximum message recursion depth.
+ /// </summary>
+ /// <remarks>
+ /// In order to prevent malicious
+ /// messages from causing stack overflows, CodedInputStream limits
+ /// how deeply messages may be nested. The default limit is 64.
+ /// </remarks>
+ public int SetRecursionLimit(int limit)
+ {
+ if (limit < 0)
+ {
+ throw new ArgumentOutOfRangeException("Recursion limit cannot be negative: " + limit);
+ }
+ int oldLimit = recursionLimit;
+ recursionLimit = limit;
+ return oldLimit;
+ }
/// <summary>
+ /// Set the maximum message size.
+ /// </summary>
+ /// <remarks>
+ /// In order to prevent malicious messages from exhausting memory or
+ /// causing integer overflows, CodedInputStream limits how large a message may be.
+ /// The default limit is 64MB. You should set this limit as small
+ /// as you can without harming your app's functionality. Note that
+ /// size limits only apply when reading from an InputStream, not
+ /// when constructed around a raw byte array (nor with ByteString.NewCodedInput).
+ /// If you want to read several messages from a single CodedInputStream, you
+ /// can call ResetSizeCounter() after each message to avoid hitting the
+ /// size limit.
+ /// </remarks>
+ public int SetSizeLimit(int limit)
+ {
+ if (limit < 0)
+ {
+ throw new ArgumentOutOfRangeException("Size limit cannot be negative: " + limit);
+ }
+ int oldLimit = sizeLimit;
+ sizeLimit = limit;
+ return oldLimit;
+ }
+
+ /// <summary>
+ /// Resets the current size counter to zero (see <see cref="SetSizeLimit"/>).
+ /// </summary>
+ public void ResetSizeCounter()
+ {
+ totalBytesRetired = 0;
+ }
+ #endregion
+
+ #region Validation
+ /// <summary>
/// Verifies that the last call to ReadTag() returned the given tag value.
/// This is used to verify that a nested group ended with the correct
/// end tag.
@@ -188,13 +246,12 @@ namespace Google.Protobuf throw InvalidProtocolBufferException.InvalidEndTag();
}
}
-
#endregion
#region Reading of tags etc
/// <summary>
- /// Attempt to peek at the next field tag.
+ /// Attempts to peek at the next field tag.
/// </summary>
public bool PeekNextTag(out uint fieldTag)
{
@@ -212,7 +269,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Attempt to read a field tag, returning false if we have reached the end
+ /// Attempts to read a field tag, returning false if we have reached the end
/// of the input data.
/// </summary>
/// <param name="fieldTag">The 'tag' of the field (id * 8 + wire-format)</param>
@@ -227,14 +284,42 @@ namespace Google.Protobuf return true;
}
- if (IsAtEnd)
+ // Optimize for the incredibly common case of having at least two bytes left in the buffer,
+ // and those two bytes being enough to get the tag. This will be true for fields up to 4095.
+ if (bufferPos + 2 <= bufferSize)
{
- fieldTag = 0;
- lastTag = fieldTag;
- return false;
+ int tmp = buffer[bufferPos++];
+ if (tmp < 128)
+ {
+ fieldTag = (uint)tmp;
+ }
+ else
+ {
+ int result = tmp & 0x7f;
+ if ((tmp = buffer[bufferPos++]) < 128)
+ {
+ result |= tmp << 7;
+ fieldTag = (uint) result;
+ }
+ else
+ {
+ // Nope, rewind and go the potentially slow route.
+ bufferPos -= 2;
+ fieldTag = ReadRawVarint32();
+ }
+ }
}
+ else
+ {
+ if (IsAtEnd)
+ {
+ fieldTag = 0;
+ lastTag = fieldTag;
+ return false;
+ }
- fieldTag = ReadRawVarint32();
+ fieldTag = ReadRawVarint32();
+ }
lastTag = fieldTag;
if (lastTag == 0)
{
@@ -245,7 +330,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a double field from the stream.
+ /// Reads a double field from the stream.
/// </summary>
public double ReadDouble()
{
@@ -253,7 +338,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a float field from the stream.
+ /// Reads a float field from the stream.
/// </summary>
public float ReadFloat()
{
@@ -275,7 +360,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a uint64 field from the stream.
+ /// Reads a uint64 field from the stream.
/// </summary>
public ulong ReadUInt64()
{
@@ -283,7 +368,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Read an int64 field from the stream.
+ /// Reads an int64 field from the stream.
/// </summary>
public long ReadInt64()
{
@@ -291,7 +376,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Read an int32 field from the stream.
+ /// Reads an int32 field from the stream.
/// </summary>
public int ReadInt32()
{
@@ -299,7 +384,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a fixed64 field from the stream.
+ /// Reads a fixed64 field from the stream.
/// </summary>
public ulong ReadFixed64()
{
@@ -307,7 +392,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a fixed32 field from the stream.
+ /// Reads a fixed32 field from the stream.
/// </summary>
public uint ReadFixed32()
{
@@ -315,7 +400,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a bool field from the stream.
+ /// Reads a bool field from the stream.
/// </summary>
public bool ReadBool()
{
@@ -327,22 +412,22 @@ namespace Google.Protobuf /// </summary>
public string ReadString()
{
- int size = (int) ReadRawVarint32();
+ int length = ReadLength();
// No need to read any data for an empty string.
- if (size == 0)
+ if (length == 0)
{
return "";
}
- if (size <= bufferSize - bufferPos)
+ if (length <= bufferSize - bufferPos)
{
// Fast path: We already have the bytes in a contiguous buffer, so
// just copy directly from it.
- String result = CodedOutputStream.Utf8Encoding.GetString(buffer, bufferPos, size);
- bufferPos += size;
+ String result = CodedOutputStream.Utf8Encoding.GetString(buffer, bufferPos, length);
+ bufferPos += length;
return result;
}
// Slow path: Build a byte array first then copy it.
- return CodedOutputStream.Utf8Encoding.GetString(ReadRawBytes(size), 0, size);
+ return CodedOutputStream.Utf8Encoding.GetString(ReadRawBytes(length), 0, length);
}
/// <summary>
@@ -350,7 +435,7 @@ namespace Google.Protobuf /// </summary>
public void ReadMessage(IMessage builder)
{
- int length = (int) ReadRawVarint32();
+ int length = ReadLength();
if (recursionDepth >= recursionLimit)
{
throw InvalidProtocolBufferException.RecursionLimitExceeded();
@@ -368,19 +453,19 @@ namespace Google.Protobuf /// </summary>
public ByteString ReadBytes()
{
- int size = (int) ReadRawVarint32();
- if (size <= bufferSize - bufferPos && size > 0)
+ int length = ReadLength();
+ if (length <= bufferSize - bufferPos && length > 0)
{
// Fast path: We already have the bytes in a contiguous buffer, so
// just copy directly from it.
- ByteString result = ByteString.CopyFrom(buffer, bufferPos, size);
- bufferPos += size;
+ ByteString result = ByteString.CopyFrom(buffer, bufferPos, length);
+ bufferPos += length;
return result;
}
else
{
// Slow path: Build a byte array and attach it to a new ByteString.
- return ByteString.AttachBytes(ReadRawBytes(size));
+ return ByteString.AttachBytes(ReadRawBytes(length));
}
}
@@ -435,24 +520,16 @@ namespace Google.Protobuf return DecodeZigZag64(ReadRawVarint64());
}
- private bool BeginArray(uint fieldTag, out bool isPacked, out int oldLimit)
+ /// <summary>
+ /// Reads a length for length-delimited data.
+ /// </summary>
+ /// <remarks>
+ /// This is internally just reading a varint, but this method exists
+ /// to make the calling code clearer.
+ /// </remarks>
+ public int ReadLength()
{
- isPacked = WireFormat.GetTagWireType(fieldTag) == WireFormat.WireType.LengthDelimited;
-
- if (isPacked)
- {
- int length = (int) (ReadRawVarint32() & int.MaxValue);
- if (length > 0)
- {
- oldLimit = PushLimit(length);
- return true;
- }
- oldLimit = -1;
- return false; //packed but empty
- }
-
- oldLimit = -1;
- return true;
+ return (int) ReadRawVarint32();
}
/// <summary>
@@ -474,268 +551,6 @@ namespace Google.Protobuf return false;
}
- /// <summary>
- /// Returns true if the next tag is also part of the same array, which may or may not be packed.
- /// </summary>
- private bool ContinueArray(uint currentTag, bool packed, int oldLimit)
- {
- if (packed)
- {
- if (ReachedLimit)
- {
- PopLimit(oldLimit);
- return false;
- }
- return true;
- }
- return MaybeConsumeTag(currentTag);
- }
-
- /// <summary>
- /// Reads a string array.
- /// </summary>
- /// <remarks>The stream is assumed to be positioned after a tag indicating the field
- /// repeated string value. A string is read, and then if the next tag is the same,
- /// the process is repeated, until the next tag is a different one.</remarks>
- /// <param name="list"></param>
- public void ReadStringArray(ICollection<string> list)
- {
- uint fieldTag = lastTag;
- do
- {
- list.Add(ReadString());
- } while (MaybeConsumeTag(fieldTag));
- }
-
- public void ReadBytesArray(ICollection<ByteString> list)
- {
- uint fieldTag = lastTag;
- do
- {
- list.Add(ReadBytes());
- } while (MaybeConsumeTag(fieldTag));
- }
-
- public void ReadBoolArray(ICollection<bool> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadBool());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadInt32Array(ICollection<int> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadInt32());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadSInt32Array(ICollection<int> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadSInt32());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadUInt32Array(ICollection<uint> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadUInt32());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadFixed32Array(ICollection<uint> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadFixed32());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadSFixed32Array(ICollection<int> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadSFixed32());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadInt64Array(ICollection<long> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadInt64());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadSInt64Array(ICollection<long> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadSInt64());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadUInt64Array(ICollection<ulong> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadUInt64());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadFixed64Array(ICollection<ulong> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadFixed64());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadSFixed64Array(ICollection<long> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadSFixed64());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadDoubleArray(ICollection<double> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadDouble());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadFloatArray(ICollection<float> list)
- {
- uint fieldTag = lastTag;
- bool isPacked;
- int holdLimit;
- if (BeginArray(fieldTag, out isPacked, out holdLimit))
- {
- do
- {
- list.Add(ReadFloat());
- } while (ContinueArray(fieldTag, isPacked, holdLimit));
- }
- }
-
- public void ReadEnumArray<T>(RepeatedField<T> list)
- where T : struct, IComparable, IFormattable
- {
- uint fieldTag = lastTag;
- WireFormat.WireType wformat = WireFormat.GetTagWireType(fieldTag);
-
- // 2.3 allows packed form even if the field is not declared packed.
- if (wformat == WireFormat.WireType.LengthDelimited)
- {
- int length = (int) (ReadRawVarint32() & int.MaxValue);
- int limit = PushLimit(length);
- while (!ReachedLimit)
- {
- // Ghastly hack, but it works...
- list.AddInt32(ReadEnum());
- }
- PopLimit(limit);
- }
- else
- {
- do
- {
- list.Add((T)(object) ReadEnum());
- } while (MaybeConsumeTag(fieldTag));
- }
- }
-
- public void ReadMessageArray<T>(ICollection<T> list, MessageParser<T> messageParser)
- where T : IMessage<T>
- {
- uint fieldTag = lastTag;
- do
- {
- T message = messageParser.CreateTemplate();
- ReadMessage(message);
- list.Add(message);
- } while (MaybeConsumeTag(fieldTag));
- }
#endregion
#region Underlying reading primitives
@@ -793,12 +608,12 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a raw Varint from the stream. If larger than 32 bits, discard the upper bits.
+ /// Reads a raw Varint from the stream. If larger than 32 bits, discard the upper bits.
/// This method is optimised for the case where we've got lots of data in the buffer.
/// That means we can check the size just once, then just read directly from the buffer
/// without constant rechecking of the buffer length.
/// </summary>
- public uint ReadRawVarint32()
+ internal uint ReadRawVarint32()
{
if (bufferPos + 5 > bufferSize)
{
@@ -857,13 +672,13 @@ namespace Google.Protobuf /// <summary>
/// Reads a varint from the input one byte at a time, so that it does not
/// read any bytes after the end of the varint. If you simply wrapped the
- /// stream in a CodedInputStream and used ReadRawVarint32(Stream)}
+ /// stream in a CodedInputStream and used ReadRawVarint32(Stream)
/// then you would probably end up reading past the end of the varint since
/// CodedInputStream buffers its input.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
- public static uint ReadRawVarint32(Stream input)
+ internal static uint ReadRawVarint32(Stream input)
{
int result = 0;
int offset = 0;
@@ -897,9 +712,9 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a raw varint from the stream.
+ /// Reads a raw varint from the stream.
/// </summary>
- public ulong ReadRawVarint64()
+ internal ulong ReadRawVarint64()
{
int shift = 0;
ulong result = 0;
@@ -917,9 +732,9 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a 32-bit little-endian integer from the stream.
+ /// Reads a 32-bit little-endian integer from the stream.
/// </summary>
- public uint ReadRawLittleEndian32()
+ internal uint ReadRawLittleEndian32()
{
uint b1 = ReadRawByte();
uint b2 = ReadRawByte();
@@ -929,9 +744,9 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a 64-bit little-endian integer from the stream.
+ /// Reads a 64-bit little-endian integer from the stream.
/// </summary>
- public ulong ReadRawLittleEndian64()
+ internal ulong ReadRawLittleEndian64()
{
ulong b1 = ReadRawByte();
ulong b2 = ReadRawByte();
@@ -945,8 +760,6 @@ namespace Google.Protobuf | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
}
- #endregion
-
/// <summary>
/// Decode a 32-bit value with ZigZag encoding.
/// </summary>
@@ -956,9 +769,9 @@ namespace Google.Protobuf /// sign-extended to 64 bits to be varint encoded, thus always taking
/// 10 bytes on the wire.)
/// </remarks>
- public static int DecodeZigZag32(uint n)
+ internal static int DecodeZigZag32(uint n)
{
- return (int) (n >> 1) ^ -(int) (n & 1);
+ return (int)(n >> 1) ^ -(int)(n & 1);
}
/// <summary>
@@ -970,72 +783,21 @@ namespace Google.Protobuf /// sign-extended to 64 bits to be varint encoded, thus always taking
/// 10 bytes on the wire.)
/// </remarks>
- public static long DecodeZigZag64(ulong n)
+ internal static long DecodeZigZag64(ulong n)
{
- return (long) (n >> 1) ^ -(long) (n & 1);
- }
-
- /// <summary>
- /// Set the maximum message recursion depth.
- /// </summary>
- /// <remarks>
- /// In order to prevent malicious
- /// messages from causing stack overflows, CodedInputStream limits
- /// how deeply messages may be nested. The default limit is 64.
- /// </remarks>
- public int SetRecursionLimit(int limit)
- {
- if (limit < 0)
- {
- throw new ArgumentOutOfRangeException("Recursion limit cannot be negative: " + limit);
- }
- int oldLimit = recursionLimit;
- recursionLimit = limit;
- return oldLimit;
- }
-
- /// <summary>
- /// Set the maximum message size.
- /// </summary>
- /// <remarks>
- /// In order to prevent malicious messages from exhausting memory or
- /// causing integer overflows, CodedInputStream limits how large a message may be.
- /// The default limit is 64MB. You should set this limit as small
- /// as you can without harming your app's functionality. Note that
- /// size limits only apply when reading from an InputStream, not
- /// when constructed around a raw byte array (nor with ByteString.NewCodedInput).
- /// If you want to read several messages from a single CodedInputStream, you
- /// can call ResetSizeCounter() after each message to avoid hitting the
- /// size limit.
- /// </remarks>
- public int SetSizeLimit(int limit)
- {
- if (limit < 0)
- {
- throw new ArgumentOutOfRangeException("Size limit cannot be negative: " + limit);
- }
- int oldLimit = sizeLimit;
- sizeLimit = limit;
- return oldLimit;
+ return (long)(n >> 1) ^ -(long)(n & 1);
}
+ #endregion
#region Internal reading and buffer management
/// <summary>
- /// Resets the current size counter to zero (see SetSizeLimit).
- /// </summary>
- public void ResetSizeCounter()
- {
- totalBytesRetired = 0;
- }
-
- /// <summary>
/// Sets currentLimit to (current position) + byteLimit. This is called
/// when descending into a length-delimited embedded message. The previous
/// limit is returned.
/// </summary>
/// <returns>The old limit.</returns>
- public int PushLimit(int byteLimit)
+ internal int PushLimit(int byteLimit)
{
if (byteLimit < 0)
{
@@ -1073,7 +835,7 @@ namespace Google.Protobuf /// <summary>
/// Discards the current limit, returning the previous limit.
/// </summary>
- public void PopLimit(int oldLimit)
+ internal void PopLimit(int oldLimit)
{
currentLimit = oldLimit;
RecomputeBufferSizeAfterLimit();
@@ -1083,7 +845,7 @@ namespace Google.Protobuf /// Returns whether or not all the data before the limit has been read.
/// </summary>
/// <returns></returns>
- public bool ReachedLimit
+ internal bool ReachedLimit
{
get
{
@@ -1173,7 +935,7 @@ namespace Google.Protobuf /// <exception cref="InvalidProtocolBufferException">
/// the end of the stream or the current limit was reached
/// </exception>
- public byte ReadRawByte()
+ internal byte ReadRawByte()
{
if (bufferPos == bufferSize)
{
@@ -1183,12 +945,12 @@ namespace Google.Protobuf }
/// <summary>
- /// Read a fixed size of bytes from the input.
+ /// Reads a fixed size of bytes from the input.
/// </summary>
/// <exception cref="InvalidProtocolBufferException">
/// the end of the stream or the current limit was reached
/// </exception>
- public byte[] ReadRawBytes(int size)
+ internal byte[] ReadRawBytes(int size)
{
if (size < 0)
{
@@ -1197,7 +959,8 @@ namespace Google.Protobuf if (totalBytesRetired + bufferPos + size > currentLimit)
{
- // Read to the end of the stream anyway.
+ // Read to the end of the stream (up to the current limit) anyway.
+ // TODO(jonskeet): This is the only usage of SkipRawBytes. Do we really need to do it?
SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
// Then fail.
throw InvalidProtocolBufferException.TruncatedMessage();
@@ -1302,62 +1065,11 @@ namespace Google.Protobuf }
/// <summary>
- /// Reads and discards a single field, given its tag value.
- /// </summary>
- /// <returns>false if the tag is an end-group tag, in which case
- /// nothing is skipped. Otherwise, returns true.</returns>
- public bool SkipField()
- {
- uint tag = lastTag;
- switch (WireFormat.GetTagWireType(tag))
- {
- case WireFormat.WireType.Varint:
- ReadRawVarint64();
- return true;
- case WireFormat.WireType.Fixed64:
- ReadRawLittleEndian64();
- return true;
- case WireFormat.WireType.LengthDelimited:
- SkipRawBytes((int) ReadRawVarint32());
- return true;
- case WireFormat.WireType.StartGroup:
- SkipMessage();
- CheckLastTagWas(
- WireFormat.MakeTag(WireFormat.GetTagFieldNumber(tag),
- WireFormat.WireType.EndGroup));
- return true;
- case WireFormat.WireType.EndGroup:
- return false;
- case WireFormat.WireType.Fixed32:
- ReadRawLittleEndian32();
- return true;
- default:
- throw InvalidProtocolBufferException.InvalidWireType();
- }
- }
-
- /// <summary>
- /// Reads and discards an entire message. This will read either until EOF
- /// or until an endgroup tag, whichever comes first.
- /// </summary>
- public void SkipMessage()
- {
- uint tag;
- while (ReadTag(out tag))
- {
- if (!SkipField())
- {
- return;
- }
- }
- }
-
- /// <summary>
/// Reads and discards <paramref name="size"/> bytes.
/// </summary>
/// <exception cref="InvalidProtocolBufferException">the end of the stream
/// or the current limit was reached</exception>
- public void SkipRawBytes(int size)
+ private void SkipRawBytes(int size)
{
if (size < 0)
{
diff --git a/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs b/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs index ef1f4c0c..82aba51b 100644 --- a/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs +++ b/csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs @@ -50,7 +50,7 @@ namespace Google.Protobuf private const int LittleEndian32Size = 4;
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// double field, including the tag.
/// </summary>
public static int ComputeDoubleSize(double value)
@@ -59,7 +59,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// float field, including the tag.
/// </summary>
public static int ComputeFloatSize(float value)
@@ -68,7 +68,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// uint64 field, including the tag.
/// </summary>
public static int ComputeUInt64Size(ulong value)
@@ -77,7 +77,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode an
+ /// Computes the number of bytes that would be needed to encode an
/// int64 field, including the tag.
/// </summary>
public static int ComputeInt64Size(long value)
@@ -86,7 +86,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode an
+ /// Computes the number of bytes that would be needed to encode an
/// int32 field, including the tag.
/// </summary>
public static int ComputeInt32Size(int value)
@@ -103,7 +103,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// fixed64 field, including the tag.
/// </summary>
public static int ComputeFixed64Size(ulong value)
@@ -112,7 +112,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// fixed32 field, including the tag.
/// </summary>
public static int ComputeFixed32Size(uint value)
@@ -121,7 +121,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// bool field, including the tag.
/// </summary>
public static int ComputeBoolSize(bool value)
@@ -130,7 +130,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// string field, including the tag.
/// </summary>
public static int ComputeStringSize(String value)
@@ -141,7 +141,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// group field, including the tag.
/// </summary>
public static int ComputeGroupSize(IMessage value)
@@ -150,7 +150,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode an
+ /// Computes the number of bytes that would be needed to encode an
/// embedded message field, including the tag.
/// </summary>
public static int ComputeMessageSize(IMessage value)
@@ -160,7 +160,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// bytes field, including the tag.
/// </summary>
public static int ComputeBytesSize(ByteString value)
@@ -170,7 +170,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// uint32 field, including the tag.
/// </summary>
public static int ComputeUInt32Size(uint value)
@@ -179,7 +179,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a
+ /// Computes the number of bytes that would be needed to encode a
/// enum field, including the tag. The caller is responsible for
/// converting the enum value to its numeric value.
/// </summary>
@@ -190,7 +190,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode an
+ /// Computes the number of bytes that would be needed to encode an
/// sfixed32 field, including the tag.
/// </summary>
public static int ComputeSFixed32Size(int value)
@@ -199,7 +199,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode an
+ /// Computes the number of bytes that would be needed to encode an
/// sfixed64 field, including the tag.
/// </summary>
public static int ComputeSFixed64Size(long value)
@@ -208,7 +208,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode an
+ /// Computes the number of bytes that would be needed to encode an
/// sint32 field, including the tag.
/// </summary>
public static int ComputeSInt32Size(int value)
@@ -217,7 +217,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode an
+ /// Computes the number of bytes that would be needed to encode an
/// sint64 field, including the tag.
/// </summary>
public static int ComputeSInt64Size(long value)
@@ -226,7 +226,16 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a varint.
+ /// Computes the number of bytes that would be needed to encode a length,
+ /// as written by <see cref="WriteLength"/>.
+ /// </summary>
+ public static int ComputeLengthSize(int length)
+ {
+ return ComputeRawVarint32Size((uint) length);
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a varint.
/// </summary>
public static int ComputeRawVarint32Size(uint value)
{
@@ -250,7 +259,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a varint.
+ /// Computes the number of bytes that would be needed to encode a varint.
/// </summary>
public static int ComputeRawVarint64Size(ulong value)
{
@@ -294,7 +303,7 @@ namespace Google.Protobuf }
/// <summary>
- /// Compute the number of bytes that would be needed to encode a tag.
+ /// Computes the number of bytes that would be needed to encode a tag.
/// </summary>
public static int ComputeTagSize(int fieldNumber)
{
diff --git a/csharp/src/ProtocolBuffers/CodedOutputStream.cs b/csharp/src/ProtocolBuffers/CodedOutputStream.cs index def874c0..161f48f4 100644 --- a/csharp/src/ProtocolBuffers/CodedOutputStream.cs +++ b/csharp/src/ProtocolBuffers/CodedOutputStream.cs @@ -37,7 +37,6 @@ using System;
using System.IO;
using System.Text;
-using Google.Protobuf.Collections;
namespace Google.Protobuf
{
@@ -141,11 +140,12 @@ namespace Google.Protobuf }
}
- #region Writing of values without tags
+ #region Writing of values (not including tags)
/// <summary>
- /// Writes a double field value, including tag, to the stream.
+ /// Writes a double field value, without a tag, to the stream.
/// </summary>
+ /// <param name="value">The value to write</param>
public void WriteDouble(double value)
{
WriteRawLittleEndian64((ulong)BitConverter.DoubleToInt64Bits(value));
@@ -154,6 +154,7 @@ namespace Google.Protobuf /// <summary>
/// Writes a float field value, without a tag, to the stream.
/// </summary>
+ /// <param name="value">The value to write</param>
public void WriteFloat(float value)
{
byte[] rawBytes = BitConverter.GetBytes(value);
@@ -178,6 +179,7 @@ namespace Google.Protobuf /// <summary>
/// Writes a uint64 field value, without a tag, to the stream.
/// </summary>
+ /// <param name="value">The value to write</param>
public void WriteUInt64(ulong value)
{
WriteRawVarint64(value);
@@ -186,6 +188,7 @@ namespace Google.Protobuf /// <summary>
/// Writes an int64 field value, without a tag, to the stream.
/// </summary>
+ /// <param name="value">The value to write</param>
public void WriteInt64(long value)
{
WriteRawVarint64((ulong) value);
@@ -194,6 +197,7 @@ namespace Google.Protobuf /// <summary>
/// Writes an int32 field value, without a tag, to the stream.
/// </summary>
+ /// <param name="value">The value to write</param>
public void WriteInt32(int value)
{
if (value >= 0)
@@ -210,6 +214,7 @@ namespace Google.Protobuf /// <summary>
/// Writes a fixed64 field value, without a tag, to the stream.
/// </summary>
+ /// <param name="value">The value to write</param>
public void WriteFixed64(ulong value)
{
WriteRawLittleEndian64(value);
@@ -218,6 +223,7 @@ namespace Google.Protobuf /// <summary>
/// Writes a fixed32 field value, without a tag, to the stream.
/// </summary>
+ /// <param name="value">The value to write</param>
public void WriteFixed32(uint value)
{
WriteRawLittleEndian32(value);
@@ -226,6 +232,7 @@ namespace Google.Protobuf /// <summary>
/// Writes a bool field value, without a tag, to the stream.
/// </summary>
+ /// <param name="value">The value to write</param>
public void WriteBool(bool value)
{
WriteRawByte(value ? (byte) 1 : (byte) 0);
@@ -233,13 +240,15 @@ namespace Google.Protobuf /// <summary>
/// Writes a string field value, without a tag, to the stream.
+ /// The data is length-prefixed.
/// </summary>
+ /// <param name="value">The value to write</param>
public void WriteString(string value)
{
// Optimise the case where we have enough space to write
// the string directly to the buffer, which should be common.
int length = Utf8Encoding.GetByteCount(value);
- WriteRawVarint32((uint)length);
+ WriteLength(length);
if (limit - position >= length)
{
if (length == value.Length) // Must be all ASCII...
@@ -262,23 +271,41 @@ namespace Google.Protobuf }
}
+ /// <summary>
+ /// Writes a message, without a tag, to the stream.
+ /// The data is length-prefixed.
+ /// </summary>
+ /// <param name="value">The value to write</param>
public void WriteMessage(IMessage value)
{
WriteRawVarint32((uint) value.CalculateSize());
value.WriteTo(this);
}
+ /// <summary>
+ /// Write a byte string, without a tag, to the stream.
+ /// The data is length-prefixed.
+ /// </summary>
+ /// <param name="value">The value to write</param>
public void WriteBytes(ByteString value)
{
WriteRawVarint32((uint) value.Length);
value.WriteRawBytesTo(this);
}
+ /// <summary>
+ /// Writes a uint32 value, without a tag, to the stream.
+ /// </summary>
+ /// <param name="value">The value to write</param>
public void WriteUInt32(uint value)
{
WriteRawVarint32(value);
}
+ /// <summary>
+ /// Writes an enum value, without a tag, to the stream.
+ /// </summary>
+ /// <param name="value">The value to write</param>
public void WriteEnum(int value)
{
WriteInt32(value);
@@ -289,179 +316,43 @@ namespace Google.Protobuf WriteRawLittleEndian32((uint) value);
}
+ /// <summary>
+ /// Writes an sfixed64 value, without a tag, to the stream.
+ /// </summary>
+ /// <param name="value">The value to write</param>
public void WriteSFixed64(long value)
{
WriteRawLittleEndian64((ulong) value);
}
+ /// <summary>
+ /// Writes an sint32 value, without a tag, to the stream.
+ /// </summary>
+ /// <param name="value">The value to write</param>
public void WriteSInt32(int value)
{
WriteRawVarint32(EncodeZigZag32(value));
}
+ /// <summary>
+ /// Writes an sint64 value, without a tag, to the stream.
+ /// </summary>
+ /// <param name="value">The value to write</param>
public void WriteSInt64(long value)
{
WriteRawVarint64(EncodeZigZag64(value));
}
- #endregion
-
- #region Write array members, with fields.
- public void WriteMessageArray<T>(int fieldNumber, RepeatedField<T> list)
- where T : IMessage
- {
- foreach (T value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
- WriteMessage(value);
- }
- }
-
- public void WriteStringArray(int fieldNumber, RepeatedField<string> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
- WriteString(value);
- }
- }
-
- public void WriteBytesArray(int fieldNumber, RepeatedField<ByteString> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
- WriteBytes(value);
- }
- }
-
- public void WriteBoolArray(int fieldNumber, RepeatedField<bool> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Varint);
- WriteBool(value);
- }
- }
-
- public void WriteInt32Array(int fieldNumber, RepeatedField<int> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Varint);
- WriteInt32(value);
- }
- }
-
- public void WriteSInt32Array(int fieldNumber, RepeatedField<int> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Varint);
- WriteSInt32(value);
- }
- }
-
- public void WriteUInt32Array(int fieldNumber, RepeatedField<uint> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Varint);
- WriteUInt32(value);
- }
- }
-
- public void WriteFixed32Array(int fieldNumber, RepeatedField<uint> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
- WriteFixed32(value);
- }
- }
-
- public void WriteSFixed32Array(int fieldNumber, RepeatedField<int> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
- WriteSFixed32(value);
- }
- }
-
- public void WriteInt64Array(int fieldNumber, RepeatedField<long> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
- WriteInt64(value);
- }
- }
-
- public void WriteSInt64Array(int fieldNumber, RepeatedField<long> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Varint);
- WriteSInt64(value);
- }
- }
-
- public void WriteUInt64Array(int fieldNumber, RepeatedField<ulong> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Varint);
- WriteUInt64(value);
- }
- }
-
- public void WriteFixed64Array(int fieldNumber, RepeatedField<ulong> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
- WriteFixed64(value);
- }
- }
-
- public void WriteSFixed64Array(int fieldNumber, RepeatedField<long> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
- WriteSFixed64(value);
- }
- }
-
- public void WriteDoubleArray(int fieldNumber, RepeatedField<double> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
- WriteDouble(value);
- }
- }
-
- public void WriteFloatArray(int fieldNumber, RepeatedField<float> list)
- {
- foreach (var value in list)
- {
- WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
- WriteFloat(value);
- }
- }
-
- public void WriteEnumArray<T>(int fieldNumber, RepeatedField<T> list)
- where T : struct, IComparable, IFormattable
+ /// <summary>
+ /// Writes a length (in bytes) for length-delimited data.
+ /// </summary>
+ /// <remarks>
+ /// This method simply writes a rawint, but exists for clarity in calling code.
+ /// </remarks>
+ /// <param name="length">Length value, in bytes.</param>
+ public void WriteLength(int length)
{
- // Bit of a hack, to access the values as ints
- var iterator = list.GetInt32Enumerator();
- while (iterator.MoveNext())
- {
- WriteTag(fieldNumber, WireFormat.WireType.Varint);
- WriteEnum(iterator.Current);
- }
+ WriteRawVarint32((uint) length);
}
#endregion
@@ -470,6 +361,8 @@ namespace Google.Protobuf /// <summary>
/// Encodes and writes a tag.
/// </summary>
+ /// <param name="fieldNumber">The number of the field to write the tag for</param>
+ /// <param name="type">The wire format type of the tag to write</param>
public void WriteTag(int fieldNumber, WireFormat.WireType type)
{
WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type));
@@ -478,6 +371,7 @@ namespace Google.Protobuf /// <summary>
/// Writes an already-encoded tag.
/// </summary>
+ /// <param name="tag">The encoded tag</param>
public void WriteTag(uint tag)
{
WriteRawVarint32(tag);
@@ -486,6 +380,7 @@ namespace Google.Protobuf /// <summary>
/// Writes the given single-byte tag directly to the stream.
/// </summary>
+ /// <param name="b1">The encoded tag</param>
public void WriteRawTag(byte b1)
{
WriteRawByte(b1);
@@ -494,6 +389,8 @@ namespace Google.Protobuf /// <summary>
/// Writes the given two-byte tag directly to the stream.
/// </summary>
+ /// <param name="b1">The first byte of the encoded tag</param>
+ /// <param name="b2">The second byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2)
{
WriteRawByte(b1);
@@ -503,6 +400,9 @@ namespace Google.Protobuf /// <summary>
/// Writes the given three-byte tag directly to the stream.
/// </summary>
+ /// <param name="b1">The first byte of the encoded tag</param>
+ /// <param name="b2">The second byte of the encoded tag</param>
+ /// <param name="b3">The third byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3)
{
WriteRawByte(b1);
@@ -513,6 +413,10 @@ namespace Google.Protobuf /// <summary>
/// Writes the given four-byte tag directly to the stream.
/// </summary>
+ /// <param name="b1">The first byte of the encoded tag</param>
+ /// <param name="b2">The second byte of the encoded tag</param>
+ /// <param name="b3">The third byte of the encoded tag</param>
+ /// <param name="b4">The fourth byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3, byte b4)
{
WriteRawByte(b1);
@@ -524,6 +428,11 @@ namespace Google.Protobuf /// <summary>
/// Writes the given five-byte tag directly to the stream.
/// </summary>
+ /// <param name="b1">The first byte of the encoded tag</param>
+ /// <param name="b2">The second byte of the encoded tag</param>
+ /// <param name="b3">The third byte of the encoded tag</param>
+ /// <param name="b4">The fourth byte of the encoded tag</param>
+ /// <param name="b5">The fifth byte of the encoded tag</param>
public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5)
{
WriteRawByte(b1);
@@ -534,178 +443,13 @@ namespace Google.Protobuf }
#endregion
- #region Write packed array members
- // TODO(jonskeet): A lot of these are really inefficient, due to method group conversions. Fix!
- // (Alternatively, add extension methods to RepeatedField, accepting the Write* methods via delegates too.)
- public void WritePackedBoolArray(RepeatedField<bool> list)
- {
- uint size = (uint)list.Count;
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteBool(value);
- }
- }
-
- public void WritePackedInt32Array(RepeatedField<int> list)
- {
- uint size = list.CalculateSize(ComputeInt32Size);
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteInt32(value);
- }
- }
-
- public void WritePackedSInt32Array(RepeatedField<int> list)
- {
- uint size = list.CalculateSize(ComputeSInt32Size);
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteSInt32(value);
- }
- }
-
- public void WritePackedUInt32Array(RepeatedField<uint> list)
- {
- uint size = list.CalculateSize(ComputeUInt32Size);
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteUInt32(value);
- }
- }
-
- public void WritePackedFixed32Array(RepeatedField<uint> list)
- {
- uint size = (uint) list.Count * 4;
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteFixed32(value);
- }
- }
-
- public void WritePackedSFixed32Array(RepeatedField<int> list)
- {
- uint size = (uint) list.Count * 4;
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteSFixed32(value);
- }
- }
-
- public void WritePackedInt64Array(RepeatedField<long> list)
- {
- uint size = list.CalculateSize(ComputeInt64Size);
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteInt64(value);
- }
- }
-
- public void WritePackedSInt64Array(RepeatedField<long> list)
- {
- uint size = list.CalculateSize(ComputeSInt64Size);
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteSInt64(value);
- }
- }
-
- public void WritePackedUInt64Array(RepeatedField<ulong> list)
- {
- if (list.Count == 0)
- {
- return;
- }
- uint size = list.CalculateSize(ComputeUInt64Size);
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteUInt64(value);
- }
- }
-
- public void WritePackedFixed64Array(RepeatedField<ulong> list)
- {
- uint size = (uint) list.Count * 8;
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteFixed64(value);
- }
- }
-
- public void WritePackedSFixed64Array(RepeatedField<long> list)
- {
- uint size = (uint) list.Count * 8;
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteSFixed64(value);
- }
- }
-
- public void WritePackedDoubleArray(RepeatedField<double> list)
- {
- uint size = (uint) list.Count * 8;
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteDouble(value);
- }
- }
-
- public void WritePackedFloatArray(RepeatedField<float> list)
- {
- if (list.Count == 0)
- {
- return;
- }
- uint size = (uint) list.Count * 4;
- WriteRawVarint32(size);
- foreach (var value in list)
- {
- WriteFloat(value);
- }
- }
-
- public void WritePackedEnumArray<T>(RepeatedField<T> list)
- where T : struct, IComparable, IFormattable
- {
- if (list.Count == 0)
- {
- return;
- }
- // Bit of a hack, to access the values as ints
- var iterator = list.GetInt32Enumerator();
- uint size = 0;
- while (iterator.MoveNext())
- {
- size += (uint) ComputeEnumSize(iterator.Current);
- }
- iterator.Reset();
- WriteRawVarint32(size);
- while (iterator.MoveNext())
- {
- WriteEnum(iterator.Current);
- }
- }
-
- #endregion
-
#region Underlying writing primitives
/// <summary>
/// Writes a 32 bit value as a varint. The fast route is taken when
/// there's enough buffer space left to whizz through without checking
/// for each byte; otherwise, we resort to calling WriteRawByte each time.
/// </summary>
- public void WriteRawVarint32(uint value)
+ internal void WriteRawVarint32(uint value)
{
// Optimize for the common case of a single byte value
if (value < 128 && position < limit)
@@ -734,7 +478,7 @@ namespace Google.Protobuf }
}
- public void WriteRawVarint64(ulong value)
+ internal void WriteRawVarint64(ulong value)
{
while (value > 127 && position < limit)
{
@@ -756,7 +500,7 @@ namespace Google.Protobuf }
}
- public void WriteRawLittleEndian32(uint value)
+ internal void WriteRawLittleEndian32(uint value)
{
if (position + 4 > limit)
{
@@ -774,7 +518,7 @@ namespace Google.Protobuf }
}
- public void WriteRawLittleEndian64(ulong value)
+ internal void WriteRawLittleEndian64(ulong value)
{
if (position + 8 > limit)
{
@@ -800,7 +544,7 @@ namespace Google.Protobuf }
}
- public void WriteRawByte(byte value)
+ internal void WriteRawByte(byte value)
{
if (position == limit)
{
@@ -810,7 +554,7 @@ namespace Google.Protobuf buffer[position++] = value;
}
- public void WriteRawByte(uint value)
+ internal void WriteRawByte(uint value)
{
WriteRawByte((byte) value);
}
@@ -818,7 +562,7 @@ namespace Google.Protobuf /// <summary>
/// Writes out an array of bytes.
/// </summary>
- public void WriteRawBytes(byte[] value)
+ internal void WriteRawBytes(byte[] value)
{
WriteRawBytes(value, 0, value.Length);
}
@@ -826,7 +570,7 @@ namespace Google.Protobuf /// <summary>
/// Writes out part of an array of bytes.
/// </summary>
- public void WriteRawBytes(byte[] value, int offset, int length)
+ internal void WriteRawBytes(byte[] value, int offset, int length)
{
if (limit - position >= length)
{
@@ -873,7 +617,7 @@ namespace Google.Protobuf /// sign-extended to 64 bits to be varint encoded, thus always taking
/// 10 bytes on the wire.)
/// </remarks>
- public static uint EncodeZigZag32(int n)
+ internal static uint EncodeZigZag32(int n)
{
// Note: the right-shift must be arithmetic
return (uint) ((n << 1) ^ (n >> 31));
@@ -888,7 +632,7 @@ namespace Google.Protobuf /// sign-extended to 64 bits to be varint encoded, thus always taking
/// 10 bytes on the wire.)
/// </remarks>
- public static ulong EncodeZigZag64(long n)
+ internal static ulong EncodeZigZag64(long n)
{
return (ulong) ((n << 1) ^ (n >> 63));
}
diff --git a/csharp/src/ProtocolBuffers/Collections/MapField.cs b/csharp/src/ProtocolBuffers/Collections/MapField.cs index 9eed833f..6d1097a6 100644 --- a/csharp/src/ProtocolBuffers/Collections/MapField.cs +++ b/csharp/src/ProtocolBuffers/Collections/MapField.cs @@ -334,6 +334,10 @@ namespace Google.Protobuf.Collections public int CalculateSize(Codec codec) { + if (Count == 0) + { + return 0; + } var message = new Codec.MessageAdapter(codec); int size = 0; foreach (var entry in list) @@ -419,13 +423,13 @@ namespace Google.Protobuf.Collections public void WriteTo(CodedOutputStream output) { - codec.keyCodec.Write(output, Key); - codec.valueCodec.Write(output, Value); + codec.keyCodec.WriteTagAndValue(output, Key); + codec.valueCodec.WriteTagAndValue(output, Value); } public int CalculateSize() { - return codec.keyCodec.CalculateSize(Key) + codec.valueCodec.CalculateSize(Value); + return codec.keyCodec.CalculateSizeWithTag(Key) + codec.valueCodec.CalculateSizeWithTag(Value); } } } diff --git a/csharp/src/ProtocolBuffers/Collections/ReadOnlyDictionary.cs b/csharp/src/ProtocolBuffers/Collections/ReadOnlyDictionary.cs index 031ebd02..cf3ff83c 100644 --- a/csharp/src/ProtocolBuffers/Collections/ReadOnlyDictionary.cs +++ b/csharp/src/ProtocolBuffers/Collections/ReadOnlyDictionary.cs @@ -38,7 +38,7 @@ namespace Google.Protobuf.Collections /// <summary>
/// Read-only wrapper around another dictionary.
/// </summary>
- public sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
+ internal sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private readonly IDictionary<TKey, TValue> wrapped;
diff --git a/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs b/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs index 39d4f351..0d82e3bc 100644 --- a/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs +++ b/csharp/src/ProtocolBuffers/Collections/RepeatedField.cs @@ -49,6 +49,113 @@ namespace Google.Protobuf.Collections return clone; } + public void AddEntriesFrom(CodedInputStream input, FieldCodec<T> codec) + { + // TODO: Inline some of the Add code, so we can avoid checking the size on every + // iteration and the mutability. + uint tag = input.LastTag; + var reader = codec.ValueReader; + // Value types can be packed or not. + if (typeof(T).IsValueType && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited) + { + int length = input.ReadLength(); + if (length > 0) + { + int oldLimit = input.PushLimit(length); + while (!input.ReachedLimit) + { + Add(reader(input)); + } + input.PopLimit(oldLimit); + } + // Empty packed field. Odd, but valid - just ignore. + } + else + { + // Not packed... (possibly not packable) + do + { + Add(reader(input)); + } while (input.MaybeConsumeTag(tag)); + } + } + + public int CalculateSize(FieldCodec<T> codec) + { + if (count == 0) + { + return 0; + } + uint tag = codec.Tag; + if (typeof(T).IsValueType && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited) + { + int dataSize = CalculatePackedDataSize(codec); + return CodedOutputStream.ComputeRawVarint32Size(tag) + + CodedOutputStream.ComputeRawVarint32Size((uint)dataSize) + + dataSize; + } + else + { + var sizeCalculator = codec.ValueSizeCalculator; + int size = count * CodedOutputStream.ComputeRawVarint32Size(tag); + for (int i = 0; i < count; i++) + { + size += sizeCalculator(array[i]); + } + return size; + } + } + + private int CalculatePackedDataSize(FieldCodec<T> codec) + { + int fixedSize = codec.FixedSize; + if (fixedSize == 0) + { + var calculator = codec.ValueSizeCalculator; + int tmp = 0; + for (int i = 0; i < count; i++) + { + tmp += calculator(array[i]); + } + return tmp; + } + else + { + return fixedSize * Count; + } + } + + public void WriteTo(CodedOutputStream output, FieldCodec<T> codec) + { + if (count == 0) + { + return; + } + var writer = codec.ValueWriter; + var tag = codec.Tag; + if (typeof(T).IsValueType && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited) + { + // Packed primitive type + uint size = (uint)CalculatePackedDataSize(codec); + output.WriteTag(tag); + output.WriteRawVarint32(size); + for (int i = 0; i < count; i++) + { + writer(output, array[i]); + } + } + else + { + // Not packed: a simple tag/value pair for each value. + // Can't use codec.WriteTagAndValue, as that omits default values. + for (int i = 0; i < count; i++) + { + output.WriteTag(tag); + writer(output, array[i]); + } + } + } + public bool IsFrozen { get { return frozen; } } public void Freeze() @@ -66,9 +173,9 @@ namespace Google.Protobuf.Collections private void EnsureSize(int size) { - size = Math.Max(size, MinArraySize); if (array.Length < size) { + size = Math.Max(size, MinArraySize); int newSize = Math.Max(array.Length * 2, size); var tmp = new T[newSize]; Array.Copy(array, 0, tmp, 0, array.Length); @@ -87,18 +194,6 @@ namespace Google.Protobuf.Collections array[count++] = item; } - /// <summary> - /// Hack to allow us to add enums easily... will only work with int-based types. - /// </summary> - /// <param name="readEnum"></param> - internal void AddInt32(int item) - { - this.CheckMutable(); - EnsureSize(count + 1); - int[] castArray = (int[]) (object) array; - castArray[count++] = item; - } - public void Clear() { this.CheckMutable(); @@ -180,16 +275,7 @@ namespace Google.Protobuf.Collections IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); - } - - /// <summary> - /// Returns an enumerator of the values in this list as integers. - /// Used for enum types. - /// </summary> - internal Int32Enumerator GetInt32Enumerator() - { - return new Int32Enumerator((int[])(object)array, count); - } + } public override int GetHashCode() { @@ -297,17 +383,7 @@ namespace Google.Protobuf.Collections array[index] = value; } } - - internal uint CalculateSize(Func<T, int> sizeComputer) - { - int size = 0; - for (int i = 0; i < count; i++) - { - size += sizeComputer(array[i]); - } - return (uint)size; - } - + public struct Enumerator : IEnumerator<T> { private int index; @@ -355,46 +431,5 @@ namespace Google.Protobuf.Collections { } } - - internal struct Int32Enumerator : IEnumerator<int> - { - private int index; - private readonly int[] array; - private readonly int count; - - public Int32Enumerator(int[] array, int count) - { - this.array = array; - this.index = -1; - this.count = count; - } - - public bool MoveNext() - { - if (index + 1 >= count) - { - return false; - } - index++; - return true; - } - - public void Reset() - { - index = -1; - } - - // No guard here, as we're only going to use this internally... - public int Current { get { return array[index]; } } - - object IEnumerator.Current - { - get { return Current; } - } - - public void Dispose() - { - } - } } } diff --git a/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs b/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs index bc0419b0..80166a34 100644 --- a/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs +++ b/csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs @@ -314,6 +314,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int FileFieldNumber = 1; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.FileDescriptorProto> _repeated_file_codec + = pb::FieldCodec.ForMessage(10, global::Google.Protobuf.DescriptorProtos.FileDescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FileDescriptorProto> file_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FileDescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FileDescriptorProto> File { get { return file_; } @@ -341,19 +343,12 @@ namespace Google.Protobuf.DescriptorProtos { } public void WriteTo(pb::CodedOutputStream output) { - if (file_.Count > 0) { - output.WriteMessageArray(1, file_); - } + file_.WriteTo(output, _repeated_file_codec); } public int CalculateSize() { int size = 0; - if (file_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.FileDescriptorProto element in file_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * file_.Count; - } + size += file_.CalculateSize(_repeated_file_codec); return size; } @@ -376,7 +371,7 @@ namespace Google.Protobuf.DescriptorProtos { } break; case 10: { - input.ReadMessageArray(file_, global::Google.Protobuf.DescriptorProtos.FileDescriptorProto.Parser); + file_.AddEntriesFrom(input, _repeated_file_codec); break; } } @@ -461,42 +456,56 @@ namespace Google.Protobuf.DescriptorProtos { } public const int DependencyFieldNumber = 3; + private static readonly pb::FieldCodec<string> _repeated_dependency_codec + = pb::FieldCodec.ForString(26); private readonly pbc::RepeatedField<string> dependency_ = new pbc::RepeatedField<string>(); public pbc::RepeatedField<string> Dependency { get { return dependency_; } } public const int PublicDependencyFieldNumber = 10; + private static readonly pb::FieldCodec<int> _repeated_publicDependency_codec + = pb::FieldCodec.ForInt32(80); private readonly pbc::RepeatedField<int> publicDependency_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> PublicDependency { get { return publicDependency_; } } public const int WeakDependencyFieldNumber = 11; + private static readonly pb::FieldCodec<int> _repeated_weakDependency_codec + = pb::FieldCodec.ForInt32(88); private readonly pbc::RepeatedField<int> weakDependency_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> WeakDependency { get { return weakDependency_; } } public const int MessageTypeFieldNumber = 4; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.DescriptorProto> _repeated_messageType_codec + = pb::FieldCodec.ForMessage(34, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto> messageType_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto> MessageType { get { return messageType_; } } public const int EnumTypeFieldNumber = 5; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto> _repeated_enumType_codec + = pb::FieldCodec.ForMessage(42, global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto> enumType_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto> EnumType { get { return enumType_; } } public const int ServiceFieldNumber = 6; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.ServiceDescriptorProto> _repeated_service_codec + = pb::FieldCodec.ForMessage(50, global::Google.Protobuf.DescriptorProtos.ServiceDescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.ServiceDescriptorProto> service_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.ServiceDescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.ServiceDescriptorProto> Service { get { return service_; } } public const int ExtensionFieldNumber = 7; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto> _repeated_extension_codec + = pb::FieldCodec.ForMessage(58, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto> extension_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto> Extension { get { return extension_; } @@ -584,21 +593,11 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(18); output.WriteString(Package); } - if (dependency_.Count > 0) { - output.WriteStringArray(3, dependency_); - } - if (messageType_.Count > 0) { - output.WriteMessageArray(4, messageType_); - } - if (enumType_.Count > 0) { - output.WriteMessageArray(5, enumType_); - } - if (service_.Count > 0) { - output.WriteMessageArray(6, service_); - } - if (extension_.Count > 0) { - output.WriteMessageArray(7, extension_); - } + dependency_.WriteTo(output, _repeated_dependency_codec); + messageType_.WriteTo(output, _repeated_messageType_codec); + enumType_.WriteTo(output, _repeated_enumType_codec); + service_.WriteTo(output, _repeated_service_codec); + extension_.WriteTo(output, _repeated_extension_codec); if (options_ != null) { output.WriteRawTag(66); output.WriteMessage(Options); @@ -607,12 +606,8 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(74); output.WriteMessage(SourceCodeInfo); } - if (publicDependency_.Count > 0) { - output.WriteInt32Array(10, publicDependency_); - } - if (weakDependency_.Count > 0) { - output.WriteInt32Array(11, weakDependency_); - } + publicDependency_.WriteTo(output, _repeated_publicDependency_codec); + weakDependency_.WriteTo(output, _repeated_weakDependency_codec); if (Syntax.Length != 0) { output.WriteRawTag(98); output.WriteString(Syntax); @@ -627,54 +622,13 @@ namespace Google.Protobuf.DescriptorProtos { if (Package.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Package); } - if (dependency_.Count > 0) { - int dataSize = 0; - foreach (string element in dependency_) { - dataSize += pb::CodedOutputStream.ComputeStringSize(element); - } - size += dataSize; - size += 1 * dependency_.Count; - } - if (publicDependency_.Count > 0) { - int dataSize = 0; - foreach (int element in publicDependency_) { - dataSize += pb::CodedOutputStream.ComputeInt32Size(element); - } - size += dataSize; - size += 1 * publicDependency_.Count; - } - if (weakDependency_.Count > 0) { - int dataSize = 0; - foreach (int element in weakDependency_) { - dataSize += pb::CodedOutputStream.ComputeInt32Size(element); - } - size += dataSize; - size += 1 * weakDependency_.Count; - } - if (messageType_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.DescriptorProto element in messageType_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * messageType_.Count; - } - if (enumType_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto element in enumType_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * enumType_.Count; - } - if (service_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.ServiceDescriptorProto element in service_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * service_.Count; - } - if (extension_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto element in extension_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * extension_.Count; - } + size += dependency_.CalculateSize(_repeated_dependency_codec); + size += publicDependency_.CalculateSize(_repeated_publicDependency_codec); + size += weakDependency_.CalculateSize(_repeated_weakDependency_codec); + size += messageType_.CalculateSize(_repeated_messageType_codec); + size += enumType_.CalculateSize(_repeated_enumType_codec); + size += service_.CalculateSize(_repeated_service_codec); + size += extension_.CalculateSize(_repeated_extension_codec); if (options_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options); } @@ -741,23 +695,23 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 26: { - input.ReadStringArray(dependency_); + dependency_.AddEntriesFrom(input, _repeated_dependency_codec); break; } case 34: { - input.ReadMessageArray(messageType_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Parser); + messageType_.AddEntriesFrom(input, _repeated_messageType_codec); break; } case 42: { - input.ReadMessageArray(enumType_, global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto.Parser); + enumType_.AddEntriesFrom(input, _repeated_enumType_codec); break; } case 50: { - input.ReadMessageArray(service_, global::Google.Protobuf.DescriptorProtos.ServiceDescriptorProto.Parser); + service_.AddEntriesFrom(input, _repeated_service_codec); break; } case 58: { - input.ReadMessageArray(extension_, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser); + extension_.AddEntriesFrom(input, _repeated_extension_codec); break; } case 66: { @@ -776,12 +730,12 @@ namespace Google.Protobuf.DescriptorProtos { } case 82: case 80: { - input.ReadInt32Array(publicDependency_); + publicDependency_.AddEntriesFrom(input, _repeated_publicDependency_codec); break; } case 90: case 88: { - input.ReadInt32Array(weakDependency_); + weakDependency_.AddEntriesFrom(input, _repeated_weakDependency_codec); break; } case 98: { @@ -858,36 +812,48 @@ namespace Google.Protobuf.DescriptorProtos { } public const int FieldFieldNumber = 2; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto> _repeated_field_codec + = pb::FieldCodec.ForMessage(18, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto> field_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto> Field { get { return field_; } } public const int ExtensionFieldNumber = 6; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto> _repeated_extension_codec + = pb::FieldCodec.ForMessage(50, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto> extension_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto> Extension { get { return extension_; } } public const int NestedTypeFieldNumber = 3; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.DescriptorProto> _repeated_nestedType_codec + = pb::FieldCodec.ForMessage(26, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto> nestedType_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto> NestedType { get { return nestedType_; } } public const int EnumTypeFieldNumber = 4; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto> _repeated_enumType_codec + = pb::FieldCodec.ForMessage(34, global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto> enumType_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto> EnumType { get { return enumType_; } } public const int ExtensionRangeFieldNumber = 5; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ExtensionRange> _repeated_extensionRange_codec + = pb::FieldCodec.ForMessage(42, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ExtensionRange> extensionRange_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ExtensionRange>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ExtensionRange> ExtensionRange { get { return extensionRange_; } } public const int OneofDeclFieldNumber = 8; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.OneofDescriptorProto> _repeated_oneofDecl_codec + = pb::FieldCodec.ForMessage(66, global::Google.Protobuf.DescriptorProtos.OneofDescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.OneofDescriptorProto> oneofDecl_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.OneofDescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.OneofDescriptorProto> OneofDecl { get { return oneofDecl_; } @@ -904,12 +870,16 @@ namespace Google.Protobuf.DescriptorProtos { } public const int ReservedRangeFieldNumber = 9; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ReservedRange> _repeated_reservedRange_codec + = pb::FieldCodec.ForMessage(74, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ReservedRange.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ReservedRange> reservedRange_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ReservedRange>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ReservedRange> ReservedRange { get { return reservedRange_; } } public const int ReservedNameFieldNumber = 10; + private static readonly pb::FieldCodec<string> _repeated_reservedName_codec + = pb::FieldCodec.ForString(82); private readonly pbc::RepeatedField<string> reservedName_ = new pbc::RepeatedField<string>(); public pbc::RepeatedField<string> ReservedName { get { return reservedName_; } @@ -959,34 +929,18 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(10); output.WriteString(Name); } - if (field_.Count > 0) { - output.WriteMessageArray(2, field_); - } - if (nestedType_.Count > 0) { - output.WriteMessageArray(3, nestedType_); - } - if (enumType_.Count > 0) { - output.WriteMessageArray(4, enumType_); - } - if (extensionRange_.Count > 0) { - output.WriteMessageArray(5, extensionRange_); - } - if (extension_.Count > 0) { - output.WriteMessageArray(6, extension_); - } + field_.WriteTo(output, _repeated_field_codec); + nestedType_.WriteTo(output, _repeated_nestedType_codec); + enumType_.WriteTo(output, _repeated_enumType_codec); + extensionRange_.WriteTo(output, _repeated_extensionRange_codec); + extension_.WriteTo(output, _repeated_extension_codec); if (options_ != null) { output.WriteRawTag(58); output.WriteMessage(Options); } - if (oneofDecl_.Count > 0) { - output.WriteMessageArray(8, oneofDecl_); - } - if (reservedRange_.Count > 0) { - output.WriteMessageArray(9, reservedRange_); - } - if (reservedName_.Count > 0) { - output.WriteStringArray(10, reservedName_); - } + oneofDecl_.WriteTo(output, _repeated_oneofDecl_codec); + reservedRange_.WriteTo(output, _repeated_reservedRange_codec); + reservedName_.WriteTo(output, _repeated_reservedName_codec); } public int CalculateSize() { @@ -994,59 +948,17 @@ namespace Google.Protobuf.DescriptorProtos { if (Name.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); } - if (field_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto element in field_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * field_.Count; - } - if (extension_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto element in extension_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * extension_.Count; - } - if (nestedType_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.DescriptorProto element in nestedType_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * nestedType_.Count; - } - if (enumType_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto element in enumType_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * enumType_.Count; - } - if (extensionRange_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ExtensionRange element in extensionRange_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * extensionRange_.Count; - } - if (oneofDecl_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.OneofDescriptorProto element in oneofDecl_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * oneofDecl_.Count; - } + size += field_.CalculateSize(_repeated_field_codec); + size += extension_.CalculateSize(_repeated_extension_codec); + size += nestedType_.CalculateSize(_repeated_nestedType_codec); + size += enumType_.CalculateSize(_repeated_enumType_codec); + size += extensionRange_.CalculateSize(_repeated_extensionRange_codec); + size += oneofDecl_.CalculateSize(_repeated_oneofDecl_codec); if (options_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options); } - if (reservedRange_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ReservedRange element in reservedRange_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * reservedRange_.Count; - } - if (reservedName_.Count > 0) { - int dataSize = 0; - foreach (string element in reservedName_) { - dataSize += pb::CodedOutputStream.ComputeStringSize(element); - } - size += dataSize; - size += 1 * reservedName_.Count; - } + size += reservedRange_.CalculateSize(_repeated_reservedRange_codec); + size += reservedName_.CalculateSize(_repeated_reservedName_codec); return size; } @@ -1089,23 +1001,23 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 18: { - input.ReadMessageArray(field_, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser); + field_.AddEntriesFrom(input, _repeated_field_codec); break; } case 26: { - input.ReadMessageArray(nestedType_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Parser); + nestedType_.AddEntriesFrom(input, _repeated_nestedType_codec); break; } case 34: { - input.ReadMessageArray(enumType_, global::Google.Protobuf.DescriptorProtos.EnumDescriptorProto.Parser); + enumType_.AddEntriesFrom(input, _repeated_enumType_codec); break; } case 42: { - input.ReadMessageArray(extensionRange_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Parser); + extensionRange_.AddEntriesFrom(input, _repeated_extensionRange_codec); break; } case 50: { - input.ReadMessageArray(extension_, global::Google.Protobuf.DescriptorProtos.FieldDescriptorProto.Parser); + extension_.AddEntriesFrom(input, _repeated_extension_codec); break; } case 58: { @@ -1116,15 +1028,15 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 66: { - input.ReadMessageArray(oneofDecl_, global::Google.Protobuf.DescriptorProtos.OneofDescriptorProto.Parser); + oneofDecl_.AddEntriesFrom(input, _repeated_oneofDecl_codec); break; } case 74: { - input.ReadMessageArray(reservedRange_, global::Google.Protobuf.DescriptorProtos.DescriptorProto.Types.ReservedRange.Parser); + reservedRange_.AddEntriesFrom(input, _repeated_reservedRange_codec); break; } case 82: { - input.ReadStringArray(reservedName_); + reservedName_.AddEntriesFrom(input, _repeated_reservedName_codec); break; } } @@ -1943,6 +1855,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int ValueFieldNumber = 2; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.EnumValueDescriptorProto> _repeated_value_codec + = pb::FieldCodec.ForMessage(18, global::Google.Protobuf.DescriptorProtos.EnumValueDescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.EnumValueDescriptorProto> value_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.EnumValueDescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.EnumValueDescriptorProto> Value { get { return value_; } @@ -1988,9 +1902,7 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(10); output.WriteString(Name); } - if (value_.Count > 0) { - output.WriteMessageArray(2, value_); - } + value_.WriteTo(output, _repeated_value_codec); if (options_ != null) { output.WriteRawTag(26); output.WriteMessage(Options); @@ -2002,12 +1914,7 @@ namespace Google.Protobuf.DescriptorProtos { if (Name.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); } - if (value_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.EnumValueDescriptorProto element in value_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * value_.Count; - } + size += value_.CalculateSize(_repeated_value_codec); if (options_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options); } @@ -2046,7 +1953,7 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 18: { - input.ReadMessageArray(value_, global::Google.Protobuf.DescriptorProtos.EnumValueDescriptorProto.Parser); + value_.AddEntriesFrom(input, _repeated_value_codec); break; } case 26: { @@ -2284,6 +2191,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int MethodFieldNumber = 2; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.MethodDescriptorProto> _repeated_method_codec + = pb::FieldCodec.ForMessage(18, global::Google.Protobuf.DescriptorProtos.MethodDescriptorProto.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.MethodDescriptorProto> method_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.MethodDescriptorProto>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.MethodDescriptorProto> Method { get { return method_; } @@ -2329,9 +2238,7 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(10); output.WriteString(Name); } - if (method_.Count > 0) { - output.WriteMessageArray(2, method_); - } + method_.WriteTo(output, _repeated_method_codec); if (options_ != null) { output.WriteRawTag(26); output.WriteMessage(Options); @@ -2343,12 +2250,7 @@ namespace Google.Protobuf.DescriptorProtos { if (Name.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); } - if (method_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.MethodDescriptorProto element in method_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * method_.Count; - } + size += method_.CalculateSize(_repeated_method_codec); if (options_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options); } @@ -2387,7 +2289,7 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 18: { - input.ReadMessageArray(method_, global::Google.Protobuf.DescriptorProtos.MethodDescriptorProto.Parser); + method_.AddEntriesFrom(input, _repeated_method_codec); break; } case 26: { @@ -2847,6 +2749,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int UninterpretedOptionFieldNumber = 999; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> _repeated_uninterpretedOption_codec + = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> UninterpretedOption { get { return uninterpretedOption_; } @@ -2958,9 +2862,7 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(170, 2); output.WriteString(CsharpNamespace); } - if (uninterpretedOption_.Count > 0) { - output.WriteMessageArray(999, uninterpretedOption_); - } + uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); } public int CalculateSize() { @@ -3007,12 +2909,7 @@ namespace Google.Protobuf.DescriptorProtos { if (CsharpNamespace.Length != 0) { size += 2 + pb::CodedOutputStream.ComputeStringSize(CsharpNamespace); } - if (uninterpretedOption_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.UninterpretedOption element in uninterpretedOption_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * uninterpretedOption_.Count; - } + size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); return size; } @@ -3133,7 +3030,7 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 7994: { - input.ReadMessageArray(uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); + uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); break; } } @@ -3235,6 +3132,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int UninterpretedOptionFieldNumber = 999; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> _repeated_uninterpretedOption_codec + = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> UninterpretedOption { get { return uninterpretedOption_; } @@ -3286,9 +3185,7 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(56); output.WriteBool(MapEntry); } - if (uninterpretedOption_.Count > 0) { - output.WriteMessageArray(999, uninterpretedOption_); - } + uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); } public int CalculateSize() { @@ -3305,12 +3202,7 @@ namespace Google.Protobuf.DescriptorProtos { if (MapEntry != false) { size += 1 + 1; } - if (uninterpretedOption_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.UninterpretedOption element in uninterpretedOption_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * uninterpretedOption_.Count; - } + size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); return size; } @@ -3361,7 +3253,7 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 7994: { - input.ReadMessageArray(uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); + uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); break; } } @@ -3473,6 +3365,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int UninterpretedOptionFieldNumber = 999; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> _repeated_uninterpretedOption_codec + = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> UninterpretedOption { get { return uninterpretedOption_; } @@ -3536,9 +3430,7 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(80); output.WriteBool(Weak); } - if (uninterpretedOption_.Count > 0) { - output.WriteMessageArray(999, uninterpretedOption_); - } + uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); } public int CalculateSize() { @@ -3561,12 +3453,7 @@ namespace Google.Protobuf.DescriptorProtos { if (Weak != false) { size += 1 + 1; } - if (uninterpretedOption_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.UninterpretedOption element in uninterpretedOption_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * uninterpretedOption_.Count; - } + size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); return size; } @@ -3631,7 +3518,7 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 7994: { - input.ReadMessageArray(uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); + uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); break; } } @@ -3717,6 +3604,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int UninterpretedOptionFieldNumber = 999; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> _repeated_uninterpretedOption_codec + = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> UninterpretedOption { get { return uninterpretedOption_; } @@ -3756,9 +3645,7 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(24); output.WriteBool(Deprecated); } - if (uninterpretedOption_.Count > 0) { - output.WriteMessageArray(999, uninterpretedOption_); - } + uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); } public int CalculateSize() { @@ -3769,12 +3656,7 @@ namespace Google.Protobuf.DescriptorProtos { if (Deprecated != false) { size += 1 + 1; } - if (uninterpretedOption_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.UninterpretedOption element in uninterpretedOption_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * uninterpretedOption_.Count; - } + size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); return size; } @@ -3811,7 +3693,7 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 7994: { - input.ReadMessageArray(uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); + uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); break; } } @@ -3868,6 +3750,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int UninterpretedOptionFieldNumber = 999; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> _repeated_uninterpretedOption_codec + = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> UninterpretedOption { get { return uninterpretedOption_; } @@ -3901,9 +3785,7 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(8); output.WriteBool(Deprecated); } - if (uninterpretedOption_.Count > 0) { - output.WriteMessageArray(999, uninterpretedOption_); - } + uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); } public int CalculateSize() { @@ -3911,12 +3793,7 @@ namespace Google.Protobuf.DescriptorProtos { if (Deprecated != false) { size += 1 + 1; } - if (uninterpretedOption_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.UninterpretedOption element in uninterpretedOption_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * uninterpretedOption_.Count; - } + size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); return size; } @@ -3946,7 +3823,7 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 7994: { - input.ReadMessageArray(uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); + uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); break; } } @@ -4003,6 +3880,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int UninterpretedOptionFieldNumber = 999; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> _repeated_uninterpretedOption_codec + = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> UninterpretedOption { get { return uninterpretedOption_; } @@ -4036,9 +3915,7 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(136, 2); output.WriteBool(Deprecated); } - if (uninterpretedOption_.Count > 0) { - output.WriteMessageArray(999, uninterpretedOption_); - } + uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); } public int CalculateSize() { @@ -4046,12 +3923,7 @@ namespace Google.Protobuf.DescriptorProtos { if (Deprecated != false) { size += 2 + 1; } - if (uninterpretedOption_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.UninterpretedOption element in uninterpretedOption_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * uninterpretedOption_.Count; - } + size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); return size; } @@ -4081,7 +3953,7 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 7994: { - input.ReadMessageArray(uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); + uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); break; } } @@ -4138,6 +4010,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int UninterpretedOptionFieldNumber = 999; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> _repeated_uninterpretedOption_codec + = pb::FieldCodec.ForMessage(7994, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> uninterpretedOption_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption> UninterpretedOption { get { return uninterpretedOption_; } @@ -4171,9 +4045,7 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(136, 2); output.WriteBool(Deprecated); } - if (uninterpretedOption_.Count > 0) { - output.WriteMessageArray(999, uninterpretedOption_); - } + uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); } public int CalculateSize() { @@ -4181,12 +4053,7 @@ namespace Google.Protobuf.DescriptorProtos { if (Deprecated != false) { size += 2 + 1; } - if (uninterpretedOption_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.UninterpretedOption element in uninterpretedOption_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 2 * uninterpretedOption_.Count; - } + size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec); return size; } @@ -4216,7 +4083,7 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 7994: { - input.ReadMessageArray(uninterpretedOption_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Parser); + uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); break; } } @@ -4268,6 +4135,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int NameFieldNumber = 2; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Types.NamePart> _repeated_name_codec + = pb::FieldCodec.ForMessage(18, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Types.NamePart.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Types.NamePart> name_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Types.NamePart>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Types.NamePart> Name { get { return name_; } @@ -4367,9 +4236,7 @@ namespace Google.Protobuf.DescriptorProtos { } public void WriteTo(pb::CodedOutputStream output) { - if (name_.Count > 0) { - output.WriteMessageArray(2, name_); - } + name_.WriteTo(output, _repeated_name_codec); if (IdentifierValue.Length != 0) { output.WriteRawTag(26); output.WriteString(IdentifierValue); @@ -4398,12 +4265,7 @@ namespace Google.Protobuf.DescriptorProtos { public int CalculateSize() { int size = 0; - if (name_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Types.NamePart element in name_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * name_.Count; - } + size += name_.CalculateSize(_repeated_name_codec); if (IdentifierValue.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(IdentifierValue); } @@ -4462,7 +4324,7 @@ namespace Google.Protobuf.DescriptorProtos { } break; case 18: { - input.ReadMessageArray(name_, global::Google.Protobuf.DescriptorProtos.UninterpretedOption.Types.NamePart.Parser); + name_.AddEntriesFrom(input, _repeated_name_codec); break; } case 26: { @@ -4676,6 +4538,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int LocationFieldNumber = 1; + private static readonly pb::FieldCodec<global::Google.Protobuf.DescriptorProtos.SourceCodeInfo.Types.Location> _repeated_location_codec + = pb::FieldCodec.ForMessage(10, global::Google.Protobuf.DescriptorProtos.SourceCodeInfo.Types.Location.Parser); private readonly pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.SourceCodeInfo.Types.Location> location_ = new pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.SourceCodeInfo.Types.Location>(); public pbc::RepeatedField<global::Google.Protobuf.DescriptorProtos.SourceCodeInfo.Types.Location> Location { get { return location_; } @@ -4703,19 +4567,12 @@ namespace Google.Protobuf.DescriptorProtos { } public void WriteTo(pb::CodedOutputStream output) { - if (location_.Count > 0) { - output.WriteMessageArray(1, location_); - } + location_.WriteTo(output, _repeated_location_codec); } public int CalculateSize() { int size = 0; - if (location_.Count > 0) { - foreach (global::Google.Protobuf.DescriptorProtos.SourceCodeInfo.Types.Location element in location_) { - size += pb::CodedOutputStream.ComputeMessageSize(element); - } - size += 1 * location_.Count; - } + size += location_.CalculateSize(_repeated_location_codec); return size; } @@ -4738,7 +4595,7 @@ namespace Google.Protobuf.DescriptorProtos { } break; case 10: { - input.ReadMessageArray(location_, global::Google.Protobuf.DescriptorProtos.SourceCodeInfo.Types.Location.Parser); + location_.AddEntriesFrom(input, _repeated_location_codec); break; } } @@ -4791,12 +4648,16 @@ namespace Google.Protobuf.DescriptorProtos { } public const int PathFieldNumber = 1; + private static readonly pb::FieldCodec<int> _repeated_path_codec + = pb::FieldCodec.ForInt32(10); private readonly pbc::RepeatedField<int> path_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> Path { get { return path_; } } public const int SpanFieldNumber = 2; + private static readonly pb::FieldCodec<int> _repeated_span_codec + = pb::FieldCodec.ForInt32(18); private readonly pbc::RepeatedField<int> span_ = new pbc::RepeatedField<int>(); public pbc::RepeatedField<int> Span { get { return span_; } @@ -4823,6 +4684,8 @@ namespace Google.Protobuf.DescriptorProtos { } public const int LeadingDetachedCommentsFieldNumber = 6; + private static readonly pb::FieldCodec<string> _repeated_leadingDetachedComments_codec + = pb::FieldCodec.ForString(50); private readonly pbc::RepeatedField<string> leadingDetachedComments_ = new pbc::RepeatedField<string>(); public pbc::RepeatedField<string> LeadingDetachedComments { get { return leadingDetachedComments_; } @@ -4858,14 +4721,8 @@ namespace Google.Protobuf.DescriptorProtos { } public void WriteTo(pb::CodedOutputStream output) { - if (path_.Count > 0) { - output.WriteRawTag(10); - output.WritePackedInt32Array(path_); - } - if (span_.Count > 0) { - output.WriteRawTag(18); - output.WritePackedInt32Array(span_); - } + path_.WriteTo(output, _repeated_path_codec); + span_.WriteTo(output, _repeated_span_codec); if (LeadingComments.Length != 0) { output.WriteRawTag(26); output.WriteString(LeadingComments); @@ -4874,43 +4731,20 @@ namespace Google.Protobuf.DescriptorProtos { output.WriteRawTag(34); output.WriteString(TrailingComments); } - if (leadingDetachedComments_.Count > 0) { - output.WriteStringArray(6, leadingDetachedComments_); - } + leadingDetachedComments_.WriteTo(output, _repeated_leadingDetachedComments_codec); } public int CalculateSize() { int size = 0; - if (path_.Count > 0) { - int dataSize = 0; - foreach (int element in path_) { - dataSize += pb::CodedOutputStream.ComputeInt32Size(element); - } - size += dataSize; - size += 1 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } - if (span_.Count > 0) { - int dataSize = 0; - foreach (int element in span_) { - dataSize += pb::CodedOutputStream.ComputeInt32Size(element); - } - size += dataSize; - size += 1 + pb::CodedOutputStream.ComputeInt32Size(dataSize); - } + size += path_.CalculateSize(_repeated_path_codec); + size += span_.CalculateSize(_repeated_span_codec); if (LeadingComments.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(LeadingComments); } if (TrailingComments.Length != 0) { size += 1 + pb::CodedOutputStream.ComputeStringSize(TrailingComments); } - if (leadingDetachedComments_.Count > 0) { - int dataSize = 0; - foreach (string element in leadingDetachedComments_) { - dataSize += pb::CodedOutputStream.ComputeStringSize(element); - } - size += dataSize; - size += 1 * leadingDetachedComments_.Count; - } + size += leadingDetachedComments_.CalculateSize(_repeated_leadingDetachedComments_codec); return size; } @@ -4942,12 +4776,12 @@ namespace Google.Protobuf.DescriptorProtos { break; case 10: case 8: { - input.ReadInt32Array(path_); + path_.AddEntriesFrom(input, _repeated_path_codec); break; } case 18: case 16: { - input.ReadInt32Array(span_); + span_.AddEntriesFrom(input, _repeated_span_codec); break; } case 26: { @@ -4959,7 +4793,7 @@ namespace Google.Protobuf.DescriptorProtos { break; } case 50: { - input.ReadStringArray(leadingDetachedComments_); + leadingDetachedComments_.AddEntriesFrom(input, _repeated_leadingDetachedComments_codec); break; } } diff --git a/csharp/src/ProtocolBuffers/FieldCodec.cs b/csharp/src/ProtocolBuffers/FieldCodec.cs index 4cab9cc4..f075dbbf 100644 --- a/csharp/src/ProtocolBuffers/FieldCodec.cs +++ b/csharp/src/ProtocolBuffers/FieldCodec.cs @@ -8,6 +8,7 @@ namespace Google.Protobuf /// </summary> public static class FieldCodec { + // TODO: Avoid the "dual hit" of lambda expressions: create open delegates instead. (At least test...) public static FieldCodec<string> ForString(uint tag) { return new FieldCodec<string>(input => input.ReadString(), (output, value) => output.WriteString(value), CodedOutputStream.ComputeStringSize, tag); @@ -84,7 +85,7 @@ namespace Google.Protobuf } // Enums are tricky. We can probably use expression trees to build these delegates automatically, - // but it's easy to generate the code fdor it. + // but it's easy to generate the code for it. public static FieldCodec<T> ForEnum<T>(uint tag, Func<T, int> toInt32, Func<int, T> fromInt32) { return new FieldCodec<T>(input => fromInt32( @@ -145,28 +146,68 @@ namespace Google.Protobuf private readonly Func<CodedInputStream, T> reader; private readonly Action<CodedOutputStream, T> writer; - private readonly Func<T, int> sizeComputer; + private readonly Func<T, int> sizeCalculator; private readonly uint tag; private readonly int tagSize; + private readonly int fixedSize; internal FieldCodec( Func<CodedInputStream, T> reader, Action<CodedOutputStream, T> writer, - Func<T, int> sizeComputer, + Func<T, int> sizeCalculator, uint tag) { this.reader = reader; this.writer = writer; - this.sizeComputer = sizeComputer; + this.sizeCalculator = sizeCalculator; + this.fixedSize = 0; this.tag = tag; tagSize = CodedOutputStream.ComputeRawVarint32Size(tag); } + internal FieldCodec( + Func<CodedInputStream, T> reader, + Action<CodedOutputStream, T> writer, + int fixedSize, + uint tag) + { + this.reader = reader; + this.writer = writer; + this.sizeCalculator = _ => fixedSize; + this.fixedSize = fixedSize; + this.tag = tag; + tagSize = CodedOutputStream.ComputeRawVarint32Size(tag); + } + + /// <summary> + /// Returns the size calculator for just a value. + /// </summary> + internal Func<T, int> ValueSizeCalculator { get { return sizeCalculator; } } + + /// <summary> + /// Returns a delegate to write a value (unconditionally) to a coded output stream. + /// </summary> + internal Action<CodedOutputStream, T> ValueWriter { get { return writer; } } + + /// <summary> + /// Returns a delegate to read a value from a coded input stream. It is assumed that + /// the stream is already positioned on the appropriate tag. + /// </summary> + internal Func<CodedInputStream, T> ValueReader { get { return reader; } } + + /// <summary> + /// Returns the fixed size for an entry, or 0 if sizes vary. + /// </summary> + internal int FixedSize { get { return fixedSize; } } + public uint Tag { get { return tag; } } public T DefaultValue { get { return Default; } } - public void Write(CodedOutputStream output, T value) + /// <summary> + /// Write a tag and the given value, *if* the value is not the default. + /// </summary> + public void WriteTagAndValue(CodedOutputStream output, T value) { if (!IsDefault(value)) { @@ -180,9 +221,13 @@ namespace Google.Protobuf return reader(input); } - public int CalculateSize(T value) + /// <summary> + /// Calculates the size required to write the given value, with a tag, + /// if the value is not the default. + /// </summary> + public int CalculateSizeWithTag(T value) { - return IsDefault(value) ? 0 : sizeComputer(value) + CodedOutputStream.ComputeRawVarint32Size(tag); + return IsDefault(value) ? 0 : sizeCalculator(value) + tagSize; } } } diff --git a/csharp/src/ProtocolBuffers/MessageExtensions.cs b/csharp/src/ProtocolBuffers/MessageExtensions.cs index 57cecfd4..253c18ae 100644 --- a/csharp/src/ProtocolBuffers/MessageExtensions.cs +++ b/csharp/src/ProtocolBuffers/MessageExtensions.cs @@ -38,7 +38,7 @@ namespace Google.Protobuf { ThrowHelper.ThrowIfNull(message, "message"); ThrowHelper.ThrowIfNull(input, "input"); - int size = (int)CodedInputStream.ReadRawVarint32(input); + int size = (int) CodedInputStream.ReadRawVarint32(input); Stream limitedStream = new LimitedInputStream(input, size); message.MergeFrom(limitedStream); } diff --git a/csharp/src/ProtocolBuffers/Properties/AssemblyInfo.cs b/csharp/src/ProtocolBuffers/Properties/AssemblyInfo.cs index 806bd5d5..27ccddbc 100644 --- a/csharp/src/ProtocolBuffers/Properties/AssemblyInfo.cs +++ b/csharp/src/ProtocolBuffers/Properties/AssemblyInfo.cs @@ -61,6 +61,13 @@ using System.Security; [assembly: AssemblyVersion("2.4.1.555")]
+[assembly: InternalsVisibleTo("Google.Protobuf.Test, PublicKey=" +
+ "00240000048000009400000006020000002400005253413100040000110000003b4611704c5379" +
+ "39c3e0fbe9447dd6fa5462507f9dd4fd9fbf0712457e415b037da6d2c4eb5d2c7d29c86380af68" +
+ "7cf400401bb183f2a70bd3b631c1fcb7db8aa66c766694a9fb53fa765df6303104da8c978f3b6d" +
+ "53909cd30685b8bc9922c726cd82b5995e9e2cfca6df7a2d189d851492e49f4b76f269ce6dfd08" +
+ "c34a7d98")]
+
#if !NOFILEVERSION
[assembly: AssemblyFileVersion("2.4.1.555")]
#endif
diff --git a/csharp/src/ProtocolBuffers/WireFormat.cs b/csharp/src/ProtocolBuffers/WireFormat.cs index 221ffef6..974665f1 100644 --- a/csharp/src/ProtocolBuffers/WireFormat.cs +++ b/csharp/src/ProtocolBuffers/WireFormat.cs @@ -53,13 +53,13 @@ namespace Google.Protobuf #region Fixed sizes.
// TODO(jonskeet): Move these somewhere else. They're messy. Consider making FieldType a smarter kind of enum
- public const int Fixed32Size = 4;
- public const int Fixed64Size = 8;
- public const int SFixed32Size = 4;
- public const int SFixed64Size = 8;
- public const int FloatSize = 4;
- public const int DoubleSize = 8;
- public const int BoolSize = 1;
+ internal const int Fixed32Size = 4;
+ internal const int Fixed64Size = 8;
+ internal const int SFixed32Size = 4;
+ internal const int SFixed64Size = 8;
+ internal const int FloatSize = 4;
+ internal const int DoubleSize = 8;
+ internal const int BoolSize = 1;
#endregion
@@ -72,22 +72,7 @@ namespace Google.Protobuf EndGroup = 4,
Fixed32 = 5
}
-
- internal static class MessageSetField
- {
- internal const int Item = 1;
- internal const int TypeID = 2;
- internal const int Message = 3;
- }
-
- internal static class MessageSetTag
- {
- internal static readonly uint ItemStart = MakeTag(MessageSetField.Item, WireType.StartGroup);
- internal static readonly uint ItemEnd = MakeTag(MessageSetField.Item, WireType.EndGroup);
- internal static readonly uint TypeID = MakeTag(MessageSetField.TypeID, WireType.Varint);
- internal static readonly uint Message = MakeTag(MessageSetField.Message, WireType.LengthDelimited);
- }
-
+
private const int TagTypeBits = 3;
private const uint TagTypeMask = (1 << TagTypeBits) - 1;
@@ -120,7 +105,6 @@ namespace Google.Protobuf return (uint) (fieldNumber << TagTypeBits) | (uint) wireType;
}
-#if !LITE
public static uint MakeTag(FieldDescriptor field)
{
return MakeTag(field.FieldNumber, GetWireType(field));
@@ -135,8 +119,6 @@ namespace Google.Protobuf return descriptor.IsPacked ? WireType.LengthDelimited : GetWireType(descriptor.FieldType);
}
-#endif
-
/// <summary>
/// Converts a field type to its wire type. Done with a switch for the sake
/// of speed - this is significantly faster than a dictionary lookup.
@@ -177,7 +159,7 @@ namespace Google.Protobuf case FieldType.Enum:
return WireType.Varint;
default:
- throw new ArgumentOutOfRangeException("No such field type");
+ throw new ArgumentOutOfRangeException("fieldType", "No such field type");
}
}
}
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc index d223273c..4445c281 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc @@ -49,7 +49,6 @@ namespace csharp { RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( const FieldDescriptor* descriptor, int fieldOrdinal) : FieldGeneratorBase(descriptor, fieldOrdinal) { - variables_["packed"] = descriptor->is_packed() ? "Packed" : ""; } RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() { @@ -57,6 +56,10 @@ RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() { } void RepeatedEnumFieldGenerator::GenerateMembers(io::Printer* printer) { + printer->Print( + variables_, + "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n" + " = pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x);"); printer->Print(variables_, "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); AddDeprecatedFlag(printer); @@ -76,53 +79,19 @@ void RepeatedEnumFieldGenerator::GenerateMergingCode(io::Printer* printer) { void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer) { printer->Print( variables_, - "input.ReadEnumArray<$type_name$>($name$_);\n"); + "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); } void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) { printer->Print( variables_, - "if ($name$_.Count > 0) {\n"); - printer->Indent(); - if (descriptor_->is_packed()) { - printer->Print( - variables_, - "output.WriteRawTag($tag_bytes$);\n" - "output.WritePackedEnumArray($name$_);\n"); - } else { - printer->Print( - variables_, - "output.Write$capitalized_type_name$Array($number$, $name$_);\n"); - } - printer->Outdent(); - printer->Print("}\n"); + "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); } -void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { - // TODO(jonskeet): Move all this code into CodedOutputStream? It's a lot to repeat everywhere... - printer->Print( - variables_, - "if ($name$_.Count > 0) {\n"); - printer->Indent(); - printer->Print("int dataSize = 0;\n"); +void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { printer->Print( variables_, - "foreach ($type_name$ element in $name$_) {\n" - " dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element);\n" - "}\n" - "size += dataSize;\n"); - int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()); - if (descriptor_->is_packed()) { - printer->Print( - "size += $tag_size$ + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);\n", - "tag_size", SimpleItoa(tagSize)); - } else { - printer->Print( - "size += $tag_size$ * $name$_.Count;\n", - "tag_size", SimpleItoa(tagSize), "name", name()); - } - printer->Outdent(); - printer->Print("}\n"); + "size += $name$_.CalculateSize(_repeated_$name$_codec);\n"); } void RepeatedEnumFieldGenerator::WriteHash(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc index 400f0e4f..c74e5d0d 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -57,6 +57,10 @@ RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() { void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, + "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n" + " = pb::FieldCodec.ForMessage($tag$, $type_name$.Parser);\n"); + printer->Print( + variables_, "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); AddDeprecatedFlag(printer); printer->Print( @@ -75,28 +79,19 @@ void RepeatedMessageFieldGenerator::GenerateMergingCode(io::Printer* printer) { void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer) { printer->Print( variables_, - "input.ReadMessageArray($name$_, $type_name$.Parser);\n"); + "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); } void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) { - // TODO(jonskeet): Bake the foreach loop into the generated code? We lose the - // advantage of knowing the tag bytes this way :( printer->Print( variables_, - "if ($name$_.Count > 0) {\n" - " output.WriteMessageArray($number$, $name$_);\n" - "}\n"); + "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); } void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { printer->Print( variables_, - "if ($name$_.Count > 0) {\n" - " foreach ($type_name$ element in $name$_) {\n" - " size += pb::CodedOutputStream.ComputeMessageSize(element);\n" - " }\n" - " size += $tag_size$ * $name$_.Count;\n" - "}\n"); + "size += $name$_.CalculateSize(_repeated_$name$_codec);\n"); } void RepeatedMessageFieldGenerator::WriteHash(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc index a78a74c0..a3014da8 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc @@ -49,7 +49,6 @@ namespace csharp { RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( const FieldDescriptor* descriptor, int fieldOrdinal) : FieldGeneratorBase(descriptor, fieldOrdinal) { - variables_["packed"] = descriptor->is_packed() ? "Packed" : ""; } RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() { @@ -57,6 +56,10 @@ RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() { } void RepeatedPrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) { + printer->Print( + variables_, + "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n" + " = pb::FieldCodec.For$capitalized_type_name$($tag$);\n"); printer->Print(variables_, "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); AddDeprecatedFlag(printer); @@ -74,63 +77,21 @@ void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) } void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) { - printer->Print(variables_, - "input.Read$capitalized_type_name$Array($name$_);\n"); + printer->Print( + variables_, + "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); } -void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode( - io::Printer* printer) { +void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer) { printer->Print( variables_, - "if ($name$_.Count > 0) {\n"); - printer->Indent(); - if (descriptor_->is_packed()) { - printer->Print( - variables_, - "output.WriteRawTag($tag_bytes$);\n" - "output.WritePacked$capitalized_type_name$Array($name$_);\n"); - } else { - printer->Print( - variables_, - "output.Write$capitalized_type_name$Array($number$, $name$_);\n"); - } - printer->Outdent(); - printer->Print("}\n"); + "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); } -void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode( - io::Printer* printer) { - // TODO(jonskeet): Do this in the runtime if possible. It's a pain, but it must be feasible... +void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { printer->Print( - "if ($name$_.Count > 0) {\n", - "name", name()); - printer->Indent(); - printer->Print("int dataSize = 0;\n"); - int fixedSize = GetFixedSize(descriptor_->type()); - if (fixedSize == -1) { - printer->Print( - variables_, - "foreach ($type_name$ element in $name$_) {\n" - " dataSize += pb::CodedOutputStream.Compute$capitalized_type_name$Size(element);\n" - "}\n"); - } else { - printer->Print( - "dataSize = $size$ * $name$_.Count;\n", - "size", SimpleItoa(fixedSize), "name", name()); - } - printer->Print("size += dataSize;\n"); - int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()); - if (descriptor_->is_packed()) { - printer->Print( - "size += $tag_size$ + pb::CodedOutputStream.ComputeInt32Size(dataSize);\n", - "tag_size", SimpleItoa(tagSize)); - } else { - printer->Print( - "size += $tag_size$ * $name$_.Count;\n", - "tag_size", SimpleItoa(tagSize), "name", name()); - } - printer->Outdent(); - printer->Print("}\n"); + variables_, + "size += $name$_.CalculateSize(_repeated_$name$_codec);\n"); } void RepeatedPrimitiveFieldGenerator::WriteHash(io::Printer* printer) { |