aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/protobuf
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2017-12-20 04:34:12 +0100
committerGravatar Laszlo Csomor <laszlocsomor@google.com>2017-12-20 13:42:22 +0100
commit87dd180cbb10be3cafbdad27fadc80a8502503e8 (patch)
tree30018ac824a582238b7ee1f54c3d4a20db8b3d2b /third_party/protobuf
parent5c16ab2378befcd8000bf4f95da596ada04ae8c6 (diff)
@AutoCodec features.
* Adds PUBLIC_FIELDS strategy, which can be used to generate codecs for FragmentOptions. * Support for boolean, enum, Void, String and List types. PiperOrigin-RevId: 179636138
Diffstat (limited to 'third_party/protobuf')
-rw-r--r--third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/ByteStringTest.cs340
-rw-r--r--third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs1194
-rw-r--r--third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs836
-rw-r--r--third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/DeprecatedMemberTest.cs110
-rw-r--r--third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/GeneratedMessageTest.cs1444
-rw-r--r--third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/IssuesTest.cs164
-rw-r--r--third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/TestCornerCases.cs124
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/AddressBook/AddPerson.cs262
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/AddressBook/ListPeople.cs196
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/AddressBook/Program.cs188
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/AddressBook/SampleUsage.cs144
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.JsonDump/Program.cs144
-rwxr-xr-xthird_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/ByteStringTest.cs472
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs1208
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs850
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs110
-rwxr-xr-xthird_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs2
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs1444
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/IssuesTest.cs164
-rwxr-xr-xthird_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/Program.cs2
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/TestCornerCases.cs124
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.sln90
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/ByteArray.cs156
-rwxr-xr-xthird_party/protobuf/3.4.0/csharp/src/Google.Protobuf/ByteString.cs800
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedInputStream.cs2550
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs606
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedOutputStream.cs1522
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs292
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/FrameworkPortability.cs96
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/IMessage.cs174
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs256
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs98
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Reflection/PartialClasses.cs116
-rw-r--r--third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/WireFormat.cs206
34 files changed, 8242 insertions, 8242 deletions
diff --git a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/ByteStringTest.cs b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/ByteStringTest.cs
index 685e130a74..8935b7829d 100644
--- a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/ByteStringTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/ByteStringTest.cs
@@ -1,171 +1,171 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.Text;
-using NUnit.Framework;
-
-namespace Google.Protobuf
-{
- public class ByteStringTest
- {
- [Test]
- public void Equality()
- {
- ByteString b1 = ByteString.CopyFrom(1, 2, 3);
- ByteString b2 = ByteString.CopyFrom(1, 2, 3);
- ByteString b3 = ByteString.CopyFrom(1, 2, 4);
- ByteString b4 = ByteString.CopyFrom(1, 2, 3, 4);
- EqualityTester.AssertEquality(b1, b1);
- EqualityTester.AssertEquality(b1, b2);
- EqualityTester.AssertInequality(b1, b3);
- EqualityTester.AssertInequality(b1, b4);
- EqualityTester.AssertInequality(b1, null);
-#pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1)
- Assert.IsTrue(b1 == b1);
- Assert.IsTrue(b1 == b2);
- Assert.IsFalse(b1 == b3);
- Assert.IsFalse(b1 == b4);
- Assert.IsFalse(b1 == null);
- Assert.IsTrue((ByteString) null == null);
- Assert.IsFalse(b1 != b1);
- Assert.IsFalse(b1 != b2);
-#pragma warning disable 1718
- Assert.IsTrue(b1 != b3);
- Assert.IsTrue(b1 != b4);
- Assert.IsTrue(b1 != null);
- Assert.IsFalse((ByteString) null != null);
- }
-
- [Test]
- public void EmptyByteStringHasZeroSize()
- {
- Assert.AreEqual(0, ByteString.Empty.Length);
- }
-
- [Test]
- public void CopyFromStringWithExplicitEncoding()
- {
- ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
- Assert.AreEqual(4, bs.Length);
- Assert.AreEqual(65, bs[0]);
- Assert.AreEqual(0, bs[1]);
- Assert.AreEqual(66, bs[2]);
- Assert.AreEqual(0, bs[3]);
- }
-
- [Test]
- public void IsEmptyWhenEmpty()
- {
- Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
- }
-
- [Test]
- public void IsEmptyWhenNotEmpty()
- {
- Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
- }
-
- [Test]
- public void CopyFromByteArrayCopiesContents()
- {
- byte[] data = new byte[1];
- data[0] = 10;
- ByteString bs = ByteString.CopyFrom(data);
- Assert.AreEqual(10, bs[0]);
- data[0] = 5;
- Assert.AreEqual(10, bs[0]);
- }
-
- [Test]
- public void ToByteArrayCopiesContents()
- {
- ByteString bs = ByteString.CopyFromUtf8("Hello");
- byte[] data = bs.ToByteArray();
- Assert.AreEqual((byte)'H', data[0]);
- Assert.AreEqual((byte)'H', bs[0]);
- data[0] = 0;
- Assert.AreEqual(0, data[0]);
- Assert.AreEqual((byte)'H', bs[0]);
- }
-
- [Test]
- public void CopyFromUtf8UsesUtf8()
- {
- ByteString bs = ByteString.CopyFromUtf8("\u20ac");
- Assert.AreEqual(3, bs.Length);
- Assert.AreEqual(0xe2, bs[0]);
- Assert.AreEqual(0x82, bs[1]);
- Assert.AreEqual(0xac, bs[2]);
- }
-
- [Test]
- public void CopyFromPortion()
- {
- byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
- ByteString bs = ByteString.CopyFrom(data, 2, 3);
- Assert.AreEqual(3, bs.Length);
- Assert.AreEqual(2, bs[0]);
- Assert.AreEqual(3, bs[1]);
- }
-
- [Test]
- public void ToStringUtf8()
- {
- ByteString bs = ByteString.CopyFromUtf8("\u20ac");
- Assert.AreEqual("\u20ac", bs.ToStringUtf8());
- }
-
- [Test]
- public void ToStringWithExplicitEncoding()
- {
- ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
- Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
- }
-
- [Test]
- public void FromBase64_WithText()
- {
- byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
- string base64 = Convert.ToBase64String(data);
- ByteString bs = ByteString.FromBase64(base64);
- Assert.AreEqual(data, bs.ToByteArray());
- }
-
- [Test]
- public void FromBase64_Empty()
- {
- // Optimization which also fixes issue 61.
- Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.Text;
+using NUnit.Framework;
+
+namespace Google.Protobuf
+{
+ public class ByteStringTest
+ {
+ [Test]
+ public void Equality()
+ {
+ ByteString b1 = ByteString.CopyFrom(1, 2, 3);
+ ByteString b2 = ByteString.CopyFrom(1, 2, 3);
+ ByteString b3 = ByteString.CopyFrom(1, 2, 4);
+ ByteString b4 = ByteString.CopyFrom(1, 2, 3, 4);
+ EqualityTester.AssertEquality(b1, b1);
+ EqualityTester.AssertEquality(b1, b2);
+ EqualityTester.AssertInequality(b1, b3);
+ EqualityTester.AssertInequality(b1, b4);
+ EqualityTester.AssertInequality(b1, null);
+#pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1)
+ Assert.IsTrue(b1 == b1);
+ Assert.IsTrue(b1 == b2);
+ Assert.IsFalse(b1 == b3);
+ Assert.IsFalse(b1 == b4);
+ Assert.IsFalse(b1 == null);
+ Assert.IsTrue((ByteString) null == null);
+ Assert.IsFalse(b1 != b1);
+ Assert.IsFalse(b1 != b2);
+#pragma warning disable 1718
+ Assert.IsTrue(b1 != b3);
+ Assert.IsTrue(b1 != b4);
+ Assert.IsTrue(b1 != null);
+ Assert.IsFalse((ByteString) null != null);
+ }
+
+ [Test]
+ public void EmptyByteStringHasZeroSize()
+ {
+ Assert.AreEqual(0, ByteString.Empty.Length);
+ }
+
+ [Test]
+ public void CopyFromStringWithExplicitEncoding()
+ {
+ ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
+ Assert.AreEqual(4, bs.Length);
+ Assert.AreEqual(65, bs[0]);
+ Assert.AreEqual(0, bs[1]);
+ Assert.AreEqual(66, bs[2]);
+ Assert.AreEqual(0, bs[3]);
+ }
+
+ [Test]
+ public void IsEmptyWhenEmpty()
+ {
+ Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
+ }
+
+ [Test]
+ public void IsEmptyWhenNotEmpty()
+ {
+ Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
+ }
+
+ [Test]
+ public void CopyFromByteArrayCopiesContents()
+ {
+ byte[] data = new byte[1];
+ data[0] = 10;
+ ByteString bs = ByteString.CopyFrom(data);
+ Assert.AreEqual(10, bs[0]);
+ data[0] = 5;
+ Assert.AreEqual(10, bs[0]);
+ }
+
+ [Test]
+ public void ToByteArrayCopiesContents()
+ {
+ ByteString bs = ByteString.CopyFromUtf8("Hello");
+ byte[] data = bs.ToByteArray();
+ Assert.AreEqual((byte)'H', data[0]);
+ Assert.AreEqual((byte)'H', bs[0]);
+ data[0] = 0;
+ Assert.AreEqual(0, data[0]);
+ Assert.AreEqual((byte)'H', bs[0]);
+ }
+
+ [Test]
+ public void CopyFromUtf8UsesUtf8()
+ {
+ ByteString bs = ByteString.CopyFromUtf8("\u20ac");
+ Assert.AreEqual(3, bs.Length);
+ Assert.AreEqual(0xe2, bs[0]);
+ Assert.AreEqual(0x82, bs[1]);
+ Assert.AreEqual(0xac, bs[2]);
+ }
+
+ [Test]
+ public void CopyFromPortion()
+ {
+ byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
+ ByteString bs = ByteString.CopyFrom(data, 2, 3);
+ Assert.AreEqual(3, bs.Length);
+ Assert.AreEqual(2, bs[0]);
+ Assert.AreEqual(3, bs[1]);
+ }
+
+ [Test]
+ public void ToStringUtf8()
+ {
+ ByteString bs = ByteString.CopyFromUtf8("\u20ac");
+ Assert.AreEqual("\u20ac", bs.ToStringUtf8());
+ }
+
+ [Test]
+ public void ToStringWithExplicitEncoding()
+ {
+ ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
+ Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
+ }
+
+ [Test]
+ public void FromBase64_WithText()
+ {
+ byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
+ string base64 = Convert.ToBase64String(data);
+ ByteString bs = ByteString.FromBase64(base64);
+ Assert.AreEqual(data, bs.ToByteArray());
+ }
+
+ [Test]
+ public void FromBase64_Empty()
+ {
+ // Optimization which also fixes issue 61.
+ Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs
index ff44895c06..db0a180949 100644
--- a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs
@@ -1,598 +1,598 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.IO;
-using Google.Protobuf.TestProtos;
-using NUnit.Framework;
-
-namespace Google.Protobuf
-{
- public class CodedInputStreamTest
- {
- /// <summary>
- /// Helper to construct a byte array from a bunch of bytes. The inputs are
- /// actually ints so that I can use hex notation and not get stupid errors
- /// about precision.
- /// </summary>
- private static byte[] Bytes(params int[] bytesAsInts)
- {
- byte[] bytes = new byte[bytesAsInts.Length];
- for (int i = 0; i < bytesAsInts.Length; i++)
- {
- bytes[i] = (byte) bytesAsInts[i];
- }
- return bytes;
- }
-
- /// <summary>
- /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64()
- /// </summary>
- private static void AssertReadVarint(byte[] data, ulong value)
- {
- CodedInputStream input = new CodedInputStream(data);
- Assert.AreEqual((uint) value, input.ReadRawVarint32());
-
- input = new CodedInputStream(data);
- Assert.AreEqual(value, input.ReadRawVarint64());
- Assert.IsTrue(input.IsAtEnd);
-
- // Try different block sizes.
- for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
- {
- input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
- Assert.AreEqual((uint) value, input.ReadRawVarint32());
-
- input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
- Assert.AreEqual(value, input.ReadRawVarint64());
- Assert.IsTrue(input.IsAtEnd);
- }
-
- // Try reading directly from a MemoryStream. We want to verify that it
- // doesn't read past the end of the input, so write an extra byte - this
- // lets us test the position at the end.
- MemoryStream memoryStream = new MemoryStream();
- memoryStream.Write(data, 0, data.Length);
- memoryStream.WriteByte(0);
- memoryStream.Position = 0;
- Assert.AreEqual((uint) value, CodedInputStream.ReadRawVarint32(memoryStream));
- Assert.AreEqual(data.Length, memoryStream.Position);
- }
-
- /// <summary>
- /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
- /// expects them to fail with an InvalidProtocolBufferException whose
- /// description matches the given one.
- /// </summary>
- private static void AssertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data)
- {
- CodedInputStream input = new CodedInputStream(data);
- var exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint32());
- Assert.AreEqual(expected.Message, exception.Message);
-
- input = new CodedInputStream(data);
- exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint64());
- Assert.AreEqual(expected.Message, exception.Message);
-
- // Make sure we get the same error when reading directly from a Stream.
- exception = Assert.Throws<InvalidProtocolBufferException>(() => CodedInputStream.ReadRawVarint32(new MemoryStream(data)));
- Assert.AreEqual(expected.Message, exception.Message);
- }
-
- [Test]
- public void ReadVarint()
- {
- AssertReadVarint(Bytes(0x00), 0);
- AssertReadVarint(Bytes(0x01), 1);
- AssertReadVarint(Bytes(0x7f), 127);
- // 14882
- AssertReadVarint(Bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
- // 2961488830
- AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
- (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
- (0x0bL << 28));
-
- // 64-bit
- // 7256456126
- AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
- (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
- (0x1bL << 28));
- // 41256202580718336
- AssertReadVarint(Bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
- (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
- (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
- // 11964378330978735131
- AssertReadVarint(Bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
- (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
- (0x3bUL << 28) | (0x56UL << 35) | (0x00UL << 42) |
- (0x05UL << 49) | (0x26UL << 56) | (0x01UL << 63));
-
- // Failures
- AssertReadVarintFailure(
- InvalidProtocolBufferException.MalformedVarint(),
- Bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x00));
- AssertReadVarintFailure(
- InvalidProtocolBufferException.TruncatedMessage(),
- Bytes(0x80));
- }
-
- /// <summary>
- /// Parses the given bytes using ReadRawLittleEndian32() and checks
- /// that the result matches the given value.
- /// </summary>
- private static void AssertReadLittleEndian32(byte[] data, uint value)
- {
- CodedInputStream input = new CodedInputStream(data);
- Assert.AreEqual(value, input.ReadRawLittleEndian32());
- Assert.IsTrue(input.IsAtEnd);
-
- // Try different block sizes.
- for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
- {
- input = new CodedInputStream(
- new SmallBlockInputStream(data, blockSize));
- Assert.AreEqual(value, input.ReadRawLittleEndian32());
- Assert.IsTrue(input.IsAtEnd);
- }
- }
-
- /// <summary>
- /// Parses the given bytes using ReadRawLittleEndian64() and checks
- /// that the result matches the given value.
- /// </summary>
- private static void AssertReadLittleEndian64(byte[] data, ulong value)
- {
- CodedInputStream input = new CodedInputStream(data);
- Assert.AreEqual(value, input.ReadRawLittleEndian64());
- Assert.IsTrue(input.IsAtEnd);
-
- // Try different block sizes.
- for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
- {
- input = new CodedInputStream(
- new SmallBlockInputStream(data, blockSize));
- Assert.AreEqual(value, input.ReadRawLittleEndian64());
- Assert.IsTrue(input.IsAtEnd);
- }
- }
-
- [Test]
- public void ReadLittleEndian()
- {
- AssertReadLittleEndian32(Bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
- AssertReadLittleEndian32(Bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
-
- AssertReadLittleEndian64(Bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
- 0x123456789abcdef0L);
- AssertReadLittleEndian64(
- Bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef012345678UL);
- }
-
- [Test]
- public void DecodeZigZag32()
- {
- Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(0));
- Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(1));
- Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(2));
- Assert.AreEqual(-2, CodedInputStream.DecodeZigZag32(3));
- Assert.AreEqual(0x3FFFFFFF, CodedInputStream.DecodeZigZag32(0x7FFFFFFE));
- Assert.AreEqual(unchecked((int) 0xC0000000), CodedInputStream.DecodeZigZag32(0x7FFFFFFF));
- Assert.AreEqual(0x7FFFFFFF, CodedInputStream.DecodeZigZag32(0xFFFFFFFE));
- Assert.AreEqual(unchecked((int) 0x80000000), CodedInputStream.DecodeZigZag32(0xFFFFFFFF));
- }
-
- [Test]
- public void DecodeZigZag64()
- {
- Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(0));
- Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(1));
- Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(2));
- Assert.AreEqual(-2, CodedInputStream.DecodeZigZag64(3));
- Assert.AreEqual(0x000000003FFFFFFFL, CodedInputStream.DecodeZigZag64(0x000000007FFFFFFEL));
- Assert.AreEqual(unchecked((long) 0xFFFFFFFFC0000000L), CodedInputStream.DecodeZigZag64(0x000000007FFFFFFFL));
- Assert.AreEqual(0x000000007FFFFFFFL, CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFEL));
- Assert.AreEqual(unchecked((long) 0xFFFFFFFF80000000L), CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFFL));
- Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL));
- Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL));
- }
-
- [Test]
- public void ReadWholeMessage_VaryingBlockSizes()
- {
- TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
-
- byte[] rawBytes = message.ToByteArray();
- 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.Parser.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize));
- Assert.AreEqual(message, message2);
- }
- }
-
- [Test]
- public void ReadHugeBlob()
- {
- // Allocate and initialize a 1MB blob.
- byte[] blob = new byte[1 << 20];
- for (int i = 0; i < blob.Length; i++)
- {
- blob[i] = (byte) i;
- }
-
- // Make a message containing it.
- 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.Parser.ParseFrom(message.ToByteString());
-
- Assert.AreEqual(message, message2);
- }
-
- [Test]
- public void ReadMaliciouslyLargeBlob()
- {
- MemoryStream ms = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(ms);
-
- uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteRawVarint32(tag);
- output.WriteRawVarint32(0x7FFFFFFF);
- output.WriteRawBytes(new byte[32]); // Pad with a few random bytes.
- output.Flush();
- ms.Position = 0;
-
- CodedInputStream input = new CodedInputStream(ms);
- Assert.AreEqual(tag, input.ReadTag());
-
- Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
- }
-
- internal static TestRecursiveMessage MakeRecursiveMessage(int depth)
- {
- if (depth == 0)
- {
- return new TestRecursiveMessage { I = 5 };
- }
- else
- {
- return new TestRecursiveMessage { A = MakeRecursiveMessage(depth - 1) };
- }
- }
-
- internal static void AssertMessageDepth(TestRecursiveMessage message, int depth)
- {
- if (depth == 0)
- {
- Assert.IsNull(message.A);
- Assert.AreEqual(5, message.I);
- }
- else
- {
- Assert.IsNotNull(message.A);
- AssertMessageDepth(message.A, depth - 1);
- }
- }
-
- [Test]
- public void MaliciousRecursion()
- {
- ByteString data64 = MakeRecursiveMessage(64).ToByteString();
- ByteString data65 = MakeRecursiveMessage(65).ToByteString();
-
- AssertMessageDepth(TestRecursiveMessage.Parser.ParseFrom(data64), 64);
-
- Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(data65));
-
- CodedInputStream input = CodedInputStream.CreateWithLimits(new MemoryStream(data64.ToByteArray()), 1000000, 63);
- Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(input));
- }
-
- [Test]
- public void SizeLimit()
- {
- // Have to use a Stream rather than ByteString.CreateCodedInput as SizeLimit doesn't
- // apply to the latter case.
- MemoryStream ms = new MemoryStream(SampleMessages.CreateFullTestAllTypes().ToByteArray());
- CodedInputStream input = CodedInputStream.CreateWithLimits(ms, 16, 100);
- Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(input));
- }
-
- /// <summary>
- /// Tests that if we read an string that contains invalid UTF-8, no exception
- /// is thrown. Instead, the invalid bytes are replaced with the Unicode
- /// "replacement character" U+FFFD.
- /// </summary>
- [Test]
- public void ReadInvalidUtf8()
- {
- MemoryStream ms = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(ms);
-
- uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteRawVarint32(tag);
- output.WriteRawVarint32(1);
- output.WriteRawBytes(new byte[] {0x80});
- output.Flush();
- ms.Position = 0;
-
- CodedInputStream input = new CodedInputStream(ms);
-
- Assert.AreEqual(tag, input.ReadTag());
- string text = input.ReadString();
- Assert.AreEqual('\ufffd', text[0]);
- }
-
- /// <summary>
- /// A stream which limits the number of bytes it reads at a time.
- /// We use this to make sure that CodedInputStream doesn't screw up when
- /// reading in small blocks.
- /// </summary>
- private sealed class SmallBlockInputStream : MemoryStream
- {
- private readonly int blockSize;
-
- public SmallBlockInputStream(byte[] data, int blockSize)
- : base(data)
- {
- this.blockSize = blockSize;
- }
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- return base.Read(buffer, offset, Math.Min(count, blockSize));
- }
- }
-
- [Test]
- public void TestNegativeEnum()
- {
- byte[] bytes = { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };
- CodedInputStream input = new CodedInputStream(bytes);
- Assert.AreEqual((int)SampleEnum.NegativeValue, input.ReadEnum());
- Assert.IsTrue(input.IsAtEnd);
- }
-
- //Issue 71: CodedInputStream.ReadBytes go to slow path unnecessarily
- [Test]
- public void TestSlowPathAvoidance()
- {
- using (var ms = new MemoryStream())
- {
- CodedOutputStream output = new CodedOutputStream(ms);
- output.WriteTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteBytes(ByteString.CopyFrom(new byte[100]));
- output.WriteTag(2, WireFormat.WireType.LengthDelimited);
- output.WriteBytes(ByteString.CopyFrom(new byte[100]));
- output.Flush();
-
- ms.Position = 0;
- CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);
-
- uint tag = input.ReadTag();
- Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
- Assert.AreEqual(100, input.ReadBytes().Length);
-
- tag = input.ReadTag();
- Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
- Assert.AreEqual(100, input.ReadBytes().Length);
- }
- }
-
- [Test]
- public void Tag0Throws()
- {
- var input = new CodedInputStream(new byte[] { 0 });
- Assert.Throws<InvalidProtocolBufferException>(() => input.ReadTag());
- }
-
- [Test]
- public void SkipGroup()
- {
- // Create an output stream with a group in:
- // Field 1: string "field 1"
- // Field 2: group containing:
- // Field 1: fixed int32 value 100
- // Field 2: string "ignore me"
- // Field 3: nested group containing
- // Field 1: fixed int64 value 1000
- // Field 3: string "field 3"
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- output.WriteTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteString("field 1");
-
- // The outer group...
- output.WriteTag(2, WireFormat.WireType.StartGroup);
- output.WriteTag(1, WireFormat.WireType.Fixed32);
- output.WriteFixed32(100);
- output.WriteTag(2, WireFormat.WireType.LengthDelimited);
- output.WriteString("ignore me");
- // The nested group...
- output.WriteTag(3, WireFormat.WireType.StartGroup);
- output.WriteTag(1, WireFormat.WireType.Fixed64);
- output.WriteFixed64(1000);
- // Note: Not sure the field number is relevant for end group...
- output.WriteTag(3, WireFormat.WireType.EndGroup);
-
- // End the outer group
- output.WriteTag(2, WireFormat.WireType.EndGroup);
-
- output.WriteTag(3, WireFormat.WireType.LengthDelimited);
- output.WriteString("field 3");
- output.Flush();
- stream.Position = 0;
-
- // Now act like a generated client
- var input = new CodedInputStream(stream);
- Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
- Assert.AreEqual("field 1", input.ReadString());
- Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
- input.SkipLastField(); // Should consume the whole group, including the nested one.
- Assert.AreEqual(WireFormat.MakeTag(3, WireFormat.WireType.LengthDelimited), input.ReadTag());
- Assert.AreEqual("field 3", input.ReadString());
- }
-
- [Test]
- public void SkipGroup_WrongEndGroupTag()
- {
- // Create an output stream with:
- // Field 1: string "field 1"
- // Start group 2
- // Field 3: fixed int32
- // End group 4 (should give an error)
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- output.WriteTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteString("field 1");
-
- // The outer group...
- output.WriteTag(2, WireFormat.WireType.StartGroup);
- output.WriteTag(3, WireFormat.WireType.Fixed32);
- output.WriteFixed32(100);
- output.WriteTag(4, WireFormat.WireType.EndGroup);
- output.Flush();
- stream.Position = 0;
-
- // Now act like a generated client
- var input = new CodedInputStream(stream);
- Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
- Assert.AreEqual("field 1", input.ReadString());
- Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
- Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
- }
-
- [Test]
- public void RogueEndGroupTag()
- {
- // If we have an end-group tag without a leading start-group tag, generated
- // code will just call SkipLastField... so that should fail.
-
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- output.WriteTag(1, WireFormat.WireType.EndGroup);
- output.Flush();
- stream.Position = 0;
-
- var input = new CodedInputStream(stream);
- Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.EndGroup), input.ReadTag());
- Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
- }
-
- [Test]
- public void EndOfStreamReachedWhileSkippingGroup()
- {
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- output.WriteTag(1, WireFormat.WireType.StartGroup);
- output.WriteTag(2, WireFormat.WireType.StartGroup);
- output.WriteTag(2, WireFormat.WireType.EndGroup);
-
- output.Flush();
- stream.Position = 0;
-
- // Now act like a generated client
- var input = new CodedInputStream(stream);
- input.ReadTag();
- Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
- }
-
- [Test]
- public void RecursionLimitAppliedWhileSkippingGroup()
- {
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
- {
- output.WriteTag(1, WireFormat.WireType.StartGroup);
- }
- for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
- {
- output.WriteTag(1, WireFormat.WireType.EndGroup);
- }
- output.Flush();
- stream.Position = 0;
-
- // Now act like a generated client
- var input = new CodedInputStream(stream);
- Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.StartGroup), input.ReadTag());
- Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
- }
-
- [Test]
- public void Construction_Invalid()
- {
- Assert.Throws<ArgumentNullException>(() => new CodedInputStream((byte[]) null));
- Assert.Throws<ArgumentNullException>(() => new CodedInputStream(null, 0, 0));
- Assert.Throws<ArgumentNullException>(() => new CodedInputStream((Stream) null));
- Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 100, 0));
- Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 5, 10));
- }
-
- [Test]
- public void CreateWithLimits_InvalidLimits()
- {
- var stream = new MemoryStream();
- Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 0, 1));
- Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 1, 0));
- }
-
- [Test]
- public void Dispose_DisposesUnderlyingStream()
- {
- var memoryStream = new MemoryStream();
- Assert.IsTrue(memoryStream.CanRead);
- using (var cis = new CodedInputStream(memoryStream))
- {
- }
- Assert.IsFalse(memoryStream.CanRead); // Disposed
- }
-
- [Test]
- public void Dispose_WithLeaveOpen()
- {
- var memoryStream = new MemoryStream();
- Assert.IsTrue(memoryStream.CanRead);
- using (var cis = new CodedInputStream(memoryStream, true))
- {
- }
- Assert.IsTrue(memoryStream.CanRead); // We left the stream open
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.IO;
+using Google.Protobuf.TestProtos;
+using NUnit.Framework;
+
+namespace Google.Protobuf
+{
+ public class CodedInputStreamTest
+ {
+ /// <summary>
+ /// Helper to construct a byte array from a bunch of bytes. The inputs are
+ /// actually ints so that I can use hex notation and not get stupid errors
+ /// about precision.
+ /// </summary>
+ private static byte[] Bytes(params int[] bytesAsInts)
+ {
+ byte[] bytes = new byte[bytesAsInts.Length];
+ for (int i = 0; i < bytesAsInts.Length; i++)
+ {
+ bytes[i] = (byte) bytesAsInts[i];
+ }
+ return bytes;
+ }
+
+ /// <summary>
+ /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64()
+ /// </summary>
+ private static void AssertReadVarint(byte[] data, ulong value)
+ {
+ CodedInputStream input = new CodedInputStream(data);
+ Assert.AreEqual((uint) value, input.ReadRawVarint32());
+
+ input = new CodedInputStream(data);
+ Assert.AreEqual(value, input.ReadRawVarint64());
+ Assert.IsTrue(input.IsAtEnd);
+
+ // Try different block sizes.
+ for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
+ {
+ input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
+ Assert.AreEqual((uint) value, input.ReadRawVarint32());
+
+ input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
+ Assert.AreEqual(value, input.ReadRawVarint64());
+ Assert.IsTrue(input.IsAtEnd);
+ }
+
+ // Try reading directly from a MemoryStream. We want to verify that it
+ // doesn't read past the end of the input, so write an extra byte - this
+ // lets us test the position at the end.
+ MemoryStream memoryStream = new MemoryStream();
+ memoryStream.Write(data, 0, data.Length);
+ memoryStream.WriteByte(0);
+ memoryStream.Position = 0;
+ Assert.AreEqual((uint) value, CodedInputStream.ReadRawVarint32(memoryStream));
+ Assert.AreEqual(data.Length, memoryStream.Position);
+ }
+
+ /// <summary>
+ /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
+ /// expects them to fail with an InvalidProtocolBufferException whose
+ /// description matches the given one.
+ /// </summary>
+ private static void AssertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data)
+ {
+ CodedInputStream input = new CodedInputStream(data);
+ var exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint32());
+ Assert.AreEqual(expected.Message, exception.Message);
+
+ input = new CodedInputStream(data);
+ exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint64());
+ Assert.AreEqual(expected.Message, exception.Message);
+
+ // Make sure we get the same error when reading directly from a Stream.
+ exception = Assert.Throws<InvalidProtocolBufferException>(() => CodedInputStream.ReadRawVarint32(new MemoryStream(data)));
+ Assert.AreEqual(expected.Message, exception.Message);
+ }
+
+ [Test]
+ public void ReadVarint()
+ {
+ AssertReadVarint(Bytes(0x00), 0);
+ AssertReadVarint(Bytes(0x01), 1);
+ AssertReadVarint(Bytes(0x7f), 127);
+ // 14882
+ AssertReadVarint(Bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
+ // 2961488830
+ AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x0bL << 28));
+
+ // 64-bit
+ // 7256456126
+ AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x1bL << 28));
+ // 41256202580718336
+ AssertReadVarint(Bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
+ (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+ (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
+ // 11964378330978735131
+ AssertReadVarint(Bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
+ (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+ (0x3bUL << 28) | (0x56UL << 35) | (0x00UL << 42) |
+ (0x05UL << 49) | (0x26UL << 56) | (0x01UL << 63));
+
+ // Failures
+ AssertReadVarintFailure(
+ InvalidProtocolBufferException.MalformedVarint(),
+ Bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x00));
+ AssertReadVarintFailure(
+ InvalidProtocolBufferException.TruncatedMessage(),
+ Bytes(0x80));
+ }
+
+ /// <summary>
+ /// Parses the given bytes using ReadRawLittleEndian32() and checks
+ /// that the result matches the given value.
+ /// </summary>
+ private static void AssertReadLittleEndian32(byte[] data, uint value)
+ {
+ CodedInputStream input = new CodedInputStream(data);
+ Assert.AreEqual(value, input.ReadRawLittleEndian32());
+ Assert.IsTrue(input.IsAtEnd);
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
+ {
+ input = new CodedInputStream(
+ new SmallBlockInputStream(data, blockSize));
+ Assert.AreEqual(value, input.ReadRawLittleEndian32());
+ Assert.IsTrue(input.IsAtEnd);
+ }
+ }
+
+ /// <summary>
+ /// Parses the given bytes using ReadRawLittleEndian64() and checks
+ /// that the result matches the given value.
+ /// </summary>
+ private static void AssertReadLittleEndian64(byte[] data, ulong value)
+ {
+ CodedInputStream input = new CodedInputStream(data);
+ Assert.AreEqual(value, input.ReadRawLittleEndian64());
+ Assert.IsTrue(input.IsAtEnd);
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
+ {
+ input = new CodedInputStream(
+ new SmallBlockInputStream(data, blockSize));
+ Assert.AreEqual(value, input.ReadRawLittleEndian64());
+ Assert.IsTrue(input.IsAtEnd);
+ }
+ }
+
+ [Test]
+ public void ReadLittleEndian()
+ {
+ AssertReadLittleEndian32(Bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
+ AssertReadLittleEndian32(Bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
+
+ AssertReadLittleEndian64(Bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
+ 0x123456789abcdef0L);
+ AssertReadLittleEndian64(
+ Bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef012345678UL);
+ }
+
+ [Test]
+ public void DecodeZigZag32()
+ {
+ Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(0));
+ Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(1));
+ Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(2));
+ Assert.AreEqual(-2, CodedInputStream.DecodeZigZag32(3));
+ Assert.AreEqual(0x3FFFFFFF, CodedInputStream.DecodeZigZag32(0x7FFFFFFE));
+ Assert.AreEqual(unchecked((int) 0xC0000000), CodedInputStream.DecodeZigZag32(0x7FFFFFFF));
+ Assert.AreEqual(0x7FFFFFFF, CodedInputStream.DecodeZigZag32(0xFFFFFFFE));
+ Assert.AreEqual(unchecked((int) 0x80000000), CodedInputStream.DecodeZigZag32(0xFFFFFFFF));
+ }
+
+ [Test]
+ public void DecodeZigZag64()
+ {
+ Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(0));
+ Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(1));
+ Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(2));
+ Assert.AreEqual(-2, CodedInputStream.DecodeZigZag64(3));
+ Assert.AreEqual(0x000000003FFFFFFFL, CodedInputStream.DecodeZigZag64(0x000000007FFFFFFEL));
+ Assert.AreEqual(unchecked((long) 0xFFFFFFFFC0000000L), CodedInputStream.DecodeZigZag64(0x000000007FFFFFFFL));
+ Assert.AreEqual(0x000000007FFFFFFFL, CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFEL));
+ Assert.AreEqual(unchecked((long) 0xFFFFFFFF80000000L), CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFFL));
+ Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL));
+ Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL));
+ }
+
+ [Test]
+ public void ReadWholeMessage_VaryingBlockSizes()
+ {
+ TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
+
+ byte[] rawBytes = message.ToByteArray();
+ 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.Parser.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize));
+ Assert.AreEqual(message, message2);
+ }
+ }
+
+ [Test]
+ public void ReadHugeBlob()
+ {
+ // Allocate and initialize a 1MB blob.
+ byte[] blob = new byte[1 << 20];
+ for (int i = 0; i < blob.Length; i++)
+ {
+ blob[i] = (byte) i;
+ }
+
+ // Make a message containing it.
+ 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.Parser.ParseFrom(message.ToByteString());
+
+ Assert.AreEqual(message, message2);
+ }
+
+ [Test]
+ public void ReadMaliciouslyLargeBlob()
+ {
+ MemoryStream ms = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(ms);
+
+ uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteRawVarint32(tag);
+ output.WriteRawVarint32(0x7FFFFFFF);
+ output.WriteRawBytes(new byte[32]); // Pad with a few random bytes.
+ output.Flush();
+ ms.Position = 0;
+
+ CodedInputStream input = new CodedInputStream(ms);
+ Assert.AreEqual(tag, input.ReadTag());
+
+ Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
+ }
+
+ internal static TestRecursiveMessage MakeRecursiveMessage(int depth)
+ {
+ if (depth == 0)
+ {
+ return new TestRecursiveMessage { I = 5 };
+ }
+ else
+ {
+ return new TestRecursiveMessage { A = MakeRecursiveMessage(depth - 1) };
+ }
+ }
+
+ internal static void AssertMessageDepth(TestRecursiveMessage message, int depth)
+ {
+ if (depth == 0)
+ {
+ Assert.IsNull(message.A);
+ Assert.AreEqual(5, message.I);
+ }
+ else
+ {
+ Assert.IsNotNull(message.A);
+ AssertMessageDepth(message.A, depth - 1);
+ }
+ }
+
+ [Test]
+ public void MaliciousRecursion()
+ {
+ ByteString data64 = MakeRecursiveMessage(64).ToByteString();
+ ByteString data65 = MakeRecursiveMessage(65).ToByteString();
+
+ AssertMessageDepth(TestRecursiveMessage.Parser.ParseFrom(data64), 64);
+
+ Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(data65));
+
+ CodedInputStream input = CodedInputStream.CreateWithLimits(new MemoryStream(data64.ToByteArray()), 1000000, 63);
+ Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(input));
+ }
+
+ [Test]
+ public void SizeLimit()
+ {
+ // Have to use a Stream rather than ByteString.CreateCodedInput as SizeLimit doesn't
+ // apply to the latter case.
+ MemoryStream ms = new MemoryStream(SampleMessages.CreateFullTestAllTypes().ToByteArray());
+ CodedInputStream input = CodedInputStream.CreateWithLimits(ms, 16, 100);
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(input));
+ }
+
+ /// <summary>
+ /// Tests that if we read an string that contains invalid UTF-8, no exception
+ /// is thrown. Instead, the invalid bytes are replaced with the Unicode
+ /// "replacement character" U+FFFD.
+ /// </summary>
+ [Test]
+ public void ReadInvalidUtf8()
+ {
+ MemoryStream ms = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(ms);
+
+ uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteRawVarint32(tag);
+ output.WriteRawVarint32(1);
+ output.WriteRawBytes(new byte[] {0x80});
+ output.Flush();
+ ms.Position = 0;
+
+ CodedInputStream input = new CodedInputStream(ms);
+
+ Assert.AreEqual(tag, input.ReadTag());
+ string text = input.ReadString();
+ Assert.AreEqual('\ufffd', text[0]);
+ }
+
+ /// <summary>
+ /// A stream which limits the number of bytes it reads at a time.
+ /// We use this to make sure that CodedInputStream doesn't screw up when
+ /// reading in small blocks.
+ /// </summary>
+ private sealed class SmallBlockInputStream : MemoryStream
+ {
+ private readonly int blockSize;
+
+ public SmallBlockInputStream(byte[] data, int blockSize)
+ : base(data)
+ {
+ this.blockSize = blockSize;
+ }
+
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ return base.Read(buffer, offset, Math.Min(count, blockSize));
+ }
+ }
+
+ [Test]
+ public void TestNegativeEnum()
+ {
+ byte[] bytes = { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };
+ CodedInputStream input = new CodedInputStream(bytes);
+ Assert.AreEqual((int)SampleEnum.NegativeValue, input.ReadEnum());
+ Assert.IsTrue(input.IsAtEnd);
+ }
+
+ //Issue 71: CodedInputStream.ReadBytes go to slow path unnecessarily
+ [Test]
+ public void TestSlowPathAvoidance()
+ {
+ using (var ms = new MemoryStream())
+ {
+ CodedOutputStream output = new CodedOutputStream(ms);
+ output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteBytes(ByteString.CopyFrom(new byte[100]));
+ output.WriteTag(2, WireFormat.WireType.LengthDelimited);
+ output.WriteBytes(ByteString.CopyFrom(new byte[100]));
+ output.Flush();
+
+ ms.Position = 0;
+ CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);
+
+ uint tag = input.ReadTag();
+ Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
+ Assert.AreEqual(100, input.ReadBytes().Length);
+
+ tag = input.ReadTag();
+ Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
+ Assert.AreEqual(100, input.ReadBytes().Length);
+ }
+ }
+
+ [Test]
+ public void Tag0Throws()
+ {
+ var input = new CodedInputStream(new byte[] { 0 });
+ Assert.Throws<InvalidProtocolBufferException>(() => input.ReadTag());
+ }
+
+ [Test]
+ public void SkipGroup()
+ {
+ // Create an output stream with a group in:
+ // Field 1: string "field 1"
+ // Field 2: group containing:
+ // Field 1: fixed int32 value 100
+ // Field 2: string "ignore me"
+ // Field 3: nested group containing
+ // Field 1: fixed int64 value 1000
+ // Field 3: string "field 3"
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteString("field 1");
+
+ // The outer group...
+ output.WriteTag(2, WireFormat.WireType.StartGroup);
+ output.WriteTag(1, WireFormat.WireType.Fixed32);
+ output.WriteFixed32(100);
+ output.WriteTag(2, WireFormat.WireType.LengthDelimited);
+ output.WriteString("ignore me");
+ // The nested group...
+ output.WriteTag(3, WireFormat.WireType.StartGroup);
+ output.WriteTag(1, WireFormat.WireType.Fixed64);
+ output.WriteFixed64(1000);
+ // Note: Not sure the field number is relevant for end group...
+ output.WriteTag(3, WireFormat.WireType.EndGroup);
+
+ // End the outer group
+ output.WriteTag(2, WireFormat.WireType.EndGroup);
+
+ output.WriteTag(3, WireFormat.WireType.LengthDelimited);
+ output.WriteString("field 3");
+ output.Flush();
+ stream.Position = 0;
+
+ // Now act like a generated client
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
+ Assert.AreEqual("field 1", input.ReadString());
+ Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
+ input.SkipLastField(); // Should consume the whole group, including the nested one.
+ Assert.AreEqual(WireFormat.MakeTag(3, WireFormat.WireType.LengthDelimited), input.ReadTag());
+ Assert.AreEqual("field 3", input.ReadString());
+ }
+
+ [Test]
+ public void SkipGroup_WrongEndGroupTag()
+ {
+ // Create an output stream with:
+ // Field 1: string "field 1"
+ // Start group 2
+ // Field 3: fixed int32
+ // End group 4 (should give an error)
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteString("field 1");
+
+ // The outer group...
+ output.WriteTag(2, WireFormat.WireType.StartGroup);
+ output.WriteTag(3, WireFormat.WireType.Fixed32);
+ output.WriteFixed32(100);
+ output.WriteTag(4, WireFormat.WireType.EndGroup);
+ output.Flush();
+ stream.Position = 0;
+
+ // Now act like a generated client
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
+ Assert.AreEqual("field 1", input.ReadString());
+ Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
+ public void RogueEndGroupTag()
+ {
+ // If we have an end-group tag without a leading start-group tag, generated
+ // code will just call SkipLastField... so that should fail.
+
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.EndGroup);
+ output.Flush();
+ stream.Position = 0;
+
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.EndGroup), input.ReadTag());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
+ public void EndOfStreamReachedWhileSkippingGroup()
+ {
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.StartGroup);
+ output.WriteTag(2, WireFormat.WireType.StartGroup);
+ output.WriteTag(2, WireFormat.WireType.EndGroup);
+
+ output.Flush();
+ stream.Position = 0;
+
+ // Now act like a generated client
+ var input = new CodedInputStream(stream);
+ input.ReadTag();
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
+ public void RecursionLimitAppliedWhileSkippingGroup()
+ {
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
+ {
+ output.WriteTag(1, WireFormat.WireType.StartGroup);
+ }
+ for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
+ {
+ output.WriteTag(1, WireFormat.WireType.EndGroup);
+ }
+ output.Flush();
+ stream.Position = 0;
+
+ // Now act like a generated client
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.StartGroup), input.ReadTag());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
+ public void Construction_Invalid()
+ {
+ Assert.Throws<ArgumentNullException>(() => new CodedInputStream((byte[]) null));
+ Assert.Throws<ArgumentNullException>(() => new CodedInputStream(null, 0, 0));
+ Assert.Throws<ArgumentNullException>(() => new CodedInputStream((Stream) null));
+ Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 100, 0));
+ Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 5, 10));
+ }
+
+ [Test]
+ public void CreateWithLimits_InvalidLimits()
+ {
+ var stream = new MemoryStream();
+ Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 0, 1));
+ Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 1, 0));
+ }
+
+ [Test]
+ public void Dispose_DisposesUnderlyingStream()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanRead);
+ using (var cis = new CodedInputStream(memoryStream))
+ {
+ }
+ Assert.IsFalse(memoryStream.CanRead); // Disposed
+ }
+
+ [Test]
+ public void Dispose_WithLeaveOpen()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanRead);
+ using (var cis = new CodedInputStream(memoryStream, true))
+ {
+ }
+ Assert.IsTrue(memoryStream.CanRead); // We left the stream open
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
index 01bd3218f3..3653d4f337 100644
--- a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
@@ -1,419 +1,419 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.IO;
-using Google.Protobuf.TestProtos;
-using NUnit.Framework;
-
-namespace Google.Protobuf
-{
- public class CodedOutputStreamTest
- {
- /// <summary>
- /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
- /// checks that the result matches the given bytes
- /// </summary>
- private static void AssertWriteVarint(byte[] data, ulong value)
- {
- // Only do 32-bit write if the value fits in 32 bits.
- if ((value >> 32) == 0)
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput);
- output.WriteRawVarint32((uint) value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
- // Also try computing size.
- Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
- }
-
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput);
- output.WriteRawVarint64(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
-
- // Also try computing size.
- Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
- }
-
- // Try different buffer sizes.
- for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
- {
- // Only do 32-bit write if the value fits in 32 bits.
- if ((value >> 32) == 0)
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output =
- new CodedOutputStream(rawOutput, bufferSize);
- output.WriteRawVarint32((uint) value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
- }
-
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput, bufferSize);
- output.WriteRawVarint64(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
- }
- }
- }
-
- /// <summary>
- /// Tests WriteRawVarint32() and WriteRawVarint64()
- /// </summary>
- [Test]
- public void WriteVarint()
- {
- AssertWriteVarint(new byte[] {0x00}, 0);
- AssertWriteVarint(new byte[] {0x01}, 1);
- AssertWriteVarint(new byte[] {0x7f}, 127);
- // 14882
- AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
- // 2961488830
- AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
- (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
- (0x0bL << 28));
-
- // 64-bit
- // 7256456126
- AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
- (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
- (0x1bL << 28));
- // 41256202580718336
- AssertWriteVarint(
- new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
- (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
- (0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
- // 11964378330978735131
- AssertWriteVarint(
- new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
- unchecked((ulong)
- ((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
- (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
- (0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
- }
-
- /// <summary>
- /// Parses the given bytes using WriteRawLittleEndian32() and checks
- /// that the result matches the given value.
- /// </summary>
- private static void AssertWriteLittleEndian32(byte[] data, uint value)
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput);
- output.WriteRawLittleEndian32(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
-
- // Try different buffer sizes.
- for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
- {
- rawOutput = new MemoryStream();
- output = new CodedOutputStream(rawOutput, bufferSize);
- output.WriteRawLittleEndian32(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
- }
- }
-
- /// <summary>
- /// Parses the given bytes using WriteRawLittleEndian64() and checks
- /// that the result matches the given value.
- /// </summary>
- private static void AssertWriteLittleEndian64(byte[] data, ulong value)
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput);
- output.WriteRawLittleEndian64(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
-
- // Try different block sizes.
- for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
- {
- rawOutput = new MemoryStream();
- output = new CodedOutputStream(rawOutput, blockSize);
- output.WriteRawLittleEndian64(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
- }
- }
-
- /// <summary>
- /// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
- /// </summary>
- [Test]
- public void WriteLittleEndian()
- {
- AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
- AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
-
- AssertWriteLittleEndian64(
- new byte[] {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
- 0x123456789abcdef0L);
- AssertWriteLittleEndian64(
- new byte[] {0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
- 0x9abcdef012345678UL);
- }
-
- [Test]
- public void WriteWholeMessage_VaryingBlockSizes()
- {
- TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
-
- byte[] rawBytes = message.ToByteArray();
-
- // Try different block sizes.
- for (int blockSize = 1; blockSize < 256; blockSize *= 2)
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput, blockSize);
- message.WriteTo(output);
- output.Flush();
- Assert.AreEqual(rawBytes, rawOutput.ToArray());
- }
- }
-
- [Test]
- public void EncodeZigZag32()
- {
- Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag32(0));
- Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag32(-1));
- Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag32(1));
- Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag32(-2));
- Assert.AreEqual(0x7FFFFFFEu, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
- Assert.AreEqual(0x7FFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000)));
- Assert.AreEqual(0xFFFFFFFEu, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
- Assert.AreEqual(0xFFFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000)));
- }
-
- [Test]
- public void EncodeZigZag64()
- {
- Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag64(0));
- Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag64(-1));
- Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag64(1));
- Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag64(-2));
- Assert.AreEqual(0x000000007FFFFFFEuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
- Assert.AreEqual(0x000000007FFFFFFFuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
- Assert.AreEqual(0x00000000FFFFFFFEuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
- Assert.AreEqual(0x00000000FFFFFFFFuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
- Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
- Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
- }
-
- [Test]
- public void RoundTripZigZag32()
- {
- // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
- // were chosen semi-randomly via keyboard bashing.
- Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
- Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
- Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
- Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
- Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
- }
-
- [Test]
- public void RoundTripZigZag64()
- {
- Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
- Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
- Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
- Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
- Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
-
- Assert.AreEqual(856912304801416L,
- CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
- Assert.AreEqual(-75123905439571256L,
- CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
- }
-
- [Test]
- public void TestNegativeEnumNoTag()
- {
- Assert.AreEqual(10, CodedOutputStream.ComputeInt32Size(-2));
- Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) SampleEnum.NegativeValue));
-
- byte[] bytes = new byte[10];
- CodedOutputStream output = new CodedOutputStream(bytes);
- 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));
- }
-
- [Test]
- public void TestCodedInputOutputPosition()
- {
- byte[] content = new byte[110];
- for (int i = 0; i < content.Length; i++)
- content[i] = (byte)i;
-
- byte[] child = new byte[120];
- {
- MemoryStream ms = new MemoryStream(child);
- CodedOutputStream cout = new CodedOutputStream(ms, 20);
- // Field 11: numeric value: 500
- cout.WriteTag(11, WireFormat.WireType.Varint);
- Assert.AreEqual(1, cout.Position);
- cout.WriteInt32(500);
- Assert.AreEqual(3, cout.Position);
- //Field 12: length delimited 120 bytes
- cout.WriteTag(12, WireFormat.WireType.LengthDelimited);
- Assert.AreEqual(4, cout.Position);
- cout.WriteBytes(ByteString.CopyFrom(content));
- Assert.AreEqual(115, cout.Position);
- // Field 13: fixed numeric value: 501
- cout.WriteTag(13, WireFormat.WireType.Fixed32);
- Assert.AreEqual(116, cout.Position);
- cout.WriteSFixed32(501);
- Assert.AreEqual(120, cout.Position);
- cout.Flush();
- }
-
- byte[] bytes = new byte[130];
- {
- CodedOutputStream cout = new CodedOutputStream(bytes);
- // Field 1: numeric value: 500
- cout.WriteTag(1, WireFormat.WireType.Varint);
- Assert.AreEqual(1, cout.Position);
- cout.WriteInt32(500);
- Assert.AreEqual(3, cout.Position);
- //Field 2: length delimited 120 bytes
- cout.WriteTag(2, WireFormat.WireType.LengthDelimited);
- Assert.AreEqual(4, cout.Position);
- cout.WriteBytes(ByteString.CopyFrom(child));
- Assert.AreEqual(125, cout.Position);
- // Field 3: fixed numeric value: 500
- cout.WriteTag(3, WireFormat.WireType.Fixed32);
- Assert.AreEqual(126, cout.Position);
- cout.WriteSFixed32(501);
- Assert.AreEqual(130, cout.Position);
- cout.Flush();
- }
- // Now test Input stream:
- {
- CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0, false);
- Assert.AreEqual(0, cin.Position);
- // Field 1:
- uint tag = cin.ReadTag();
- Assert.AreEqual(1, tag >> 3);
- Assert.AreEqual(1, cin.Position);
- Assert.AreEqual(500, cin.ReadInt32());
- Assert.AreEqual(3, cin.Position);
- //Field 2:
- tag = cin.ReadTag();
- Assert.AreEqual(2, tag >> 3);
- Assert.AreEqual(4, cin.Position);
- int childlen = cin.ReadLength();
- Assert.AreEqual(120, childlen);
- Assert.AreEqual(5, cin.Position);
- int oldlimit = cin.PushLimit((int)childlen);
- Assert.AreEqual(5, cin.Position);
- // Now we are reading child message
- {
- // Field 11: numeric value: 500
- tag = cin.ReadTag();
- Assert.AreEqual(11, tag >> 3);
- Assert.AreEqual(6, cin.Position);
- Assert.AreEqual(500, cin.ReadInt32());
- Assert.AreEqual(8, cin.Position);
- //Field 12: length delimited 120 bytes
- tag = cin.ReadTag();
- Assert.AreEqual(12, tag >> 3);
- Assert.AreEqual(9, cin.Position);
- ByteString bstr = cin.ReadBytes();
- Assert.AreEqual(110, bstr.Length);
- Assert.AreEqual((byte) 109, bstr[109]);
- Assert.AreEqual(120, cin.Position);
- // Field 13: fixed numeric value: 501
- tag = cin.ReadTag();
- Assert.AreEqual(13, tag >> 3);
- // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
- Assert.AreEqual(121, cin.Position);
- Assert.AreEqual(501, cin.ReadSFixed32());
- Assert.AreEqual(125, cin.Position);
- Assert.IsTrue(cin.IsAtEnd);
- }
- cin.PopLimit(oldlimit);
- Assert.AreEqual(125, cin.Position);
- // Field 3: fixed numeric value: 501
- tag = cin.ReadTag();
- Assert.AreEqual(3, tag >> 3);
- Assert.AreEqual(126, cin.Position);
- Assert.AreEqual(501, cin.ReadSFixed32());
- Assert.AreEqual(130, cin.Position);
- Assert.IsTrue(cin.IsAtEnd);
- }
- }
-
- [Test]
- public void Dispose_DisposesUnderlyingStream()
- {
- var memoryStream = new MemoryStream();
- Assert.IsTrue(memoryStream.CanWrite);
- using (var cos = new CodedOutputStream(memoryStream))
- {
- cos.WriteRawByte(0);
- Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
- }
- Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
- Assert.IsFalse(memoryStream.CanWrite); // Disposed
- }
-
- [Test]
- public void Dispose_WithLeaveOpen()
- {
- var memoryStream = new MemoryStream();
- Assert.IsTrue(memoryStream.CanWrite);
- using (var cos = new CodedOutputStream(memoryStream, true))
- {
- cos.WriteRawByte(0);
- Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
- }
- Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream
- Assert.IsTrue(memoryStream.CanWrite); // We left the stream open
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.IO;
+using Google.Protobuf.TestProtos;
+using NUnit.Framework;
+
+namespace Google.Protobuf
+{
+ public class CodedOutputStreamTest
+ {
+ /// <summary>
+ /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
+ /// checks that the result matches the given bytes
+ /// </summary>
+ private static void AssertWriteVarint(byte[] data, ulong value)
+ {
+ // Only do 32-bit write if the value fits in 32 bits.
+ if ((value >> 32) == 0)
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput);
+ output.WriteRawVarint32((uint) value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+ // Also try computing size.
+ Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
+ }
+
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput);
+ output.WriteRawVarint64(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+
+ // Also try computing size.
+ Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
+ }
+
+ // Try different buffer sizes.
+ for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
+ {
+ // Only do 32-bit write if the value fits in 32 bits.
+ if ((value >> 32) == 0)
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output =
+ new CodedOutputStream(rawOutput, bufferSize);
+ output.WriteRawVarint32((uint) value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+ }
+
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput, bufferSize);
+ output.WriteRawVarint64(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+ }
+ }
+ }
+
+ /// <summary>
+ /// Tests WriteRawVarint32() and WriteRawVarint64()
+ /// </summary>
+ [Test]
+ public void WriteVarint()
+ {
+ AssertWriteVarint(new byte[] {0x00}, 0);
+ AssertWriteVarint(new byte[] {0x01}, 1);
+ AssertWriteVarint(new byte[] {0x7f}, 127);
+ // 14882
+ AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
+ // 2961488830
+ AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x0bL << 28));
+
+ // 64-bit
+ // 7256456126
+ AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x1bL << 28));
+ // 41256202580718336
+ AssertWriteVarint(
+ new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
+ (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+ (0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
+ // 11964378330978735131
+ AssertWriteVarint(
+ new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
+ unchecked((ulong)
+ ((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+ (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
+ (0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
+ }
+
+ /// <summary>
+ /// Parses the given bytes using WriteRawLittleEndian32() and checks
+ /// that the result matches the given value.
+ /// </summary>
+ private static void AssertWriteLittleEndian32(byte[] data, uint value)
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput);
+ output.WriteRawLittleEndian32(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+
+ // Try different buffer sizes.
+ for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
+ {
+ rawOutput = new MemoryStream();
+ output = new CodedOutputStream(rawOutput, bufferSize);
+ output.WriteRawLittleEndian32(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+ }
+ }
+
+ /// <summary>
+ /// Parses the given bytes using WriteRawLittleEndian64() and checks
+ /// that the result matches the given value.
+ /// </summary>
+ private static void AssertWriteLittleEndian64(byte[] data, ulong value)
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput);
+ output.WriteRawLittleEndian64(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
+ {
+ rawOutput = new MemoryStream();
+ output = new CodedOutputStream(rawOutput, blockSize);
+ output.WriteRawLittleEndian64(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+ }
+ }
+
+ /// <summary>
+ /// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
+ /// </summary>
+ [Test]
+ public void WriteLittleEndian()
+ {
+ AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
+ AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
+
+ AssertWriteLittleEndian64(
+ new byte[] {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
+ 0x123456789abcdef0L);
+ AssertWriteLittleEndian64(
+ new byte[] {0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
+ 0x9abcdef012345678UL);
+ }
+
+ [Test]
+ public void WriteWholeMessage_VaryingBlockSizes()
+ {
+ TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
+
+ byte[] rawBytes = message.ToByteArray();
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize < 256; blockSize *= 2)
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput, blockSize);
+ message.WriteTo(output);
+ output.Flush();
+ Assert.AreEqual(rawBytes, rawOutput.ToArray());
+ }
+ }
+
+ [Test]
+ public void EncodeZigZag32()
+ {
+ Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag32(0));
+ Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag32(-1));
+ Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag32(1));
+ Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag32(-2));
+ Assert.AreEqual(0x7FFFFFFEu, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
+ Assert.AreEqual(0x7FFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000)));
+ Assert.AreEqual(0xFFFFFFFEu, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
+ Assert.AreEqual(0xFFFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000)));
+ }
+
+ [Test]
+ public void EncodeZigZag64()
+ {
+ Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag64(0));
+ Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag64(-1));
+ Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag64(1));
+ Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag64(-2));
+ Assert.AreEqual(0x000000007FFFFFFEuL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
+ Assert.AreEqual(0x000000007FFFFFFFuL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
+ Assert.AreEqual(0x00000000FFFFFFFEuL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
+ Assert.AreEqual(0x00000000FFFFFFFFuL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
+ Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
+ Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
+ }
+
+ [Test]
+ public void RoundTripZigZag32()
+ {
+ // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
+ // were chosen semi-randomly via keyboard bashing.
+ Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
+ Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
+ Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
+ Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
+ Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
+ }
+
+ [Test]
+ public void RoundTripZigZag64()
+ {
+ Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
+ Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
+ Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
+ Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
+ Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
+
+ Assert.AreEqual(856912304801416L,
+ CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
+ Assert.AreEqual(-75123905439571256L,
+ CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
+ }
+
+ [Test]
+ public void TestNegativeEnumNoTag()
+ {
+ Assert.AreEqual(10, CodedOutputStream.ComputeInt32Size(-2));
+ Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) SampleEnum.NegativeValue));
+
+ byte[] bytes = new byte[10];
+ CodedOutputStream output = new CodedOutputStream(bytes);
+ 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));
+ }
+
+ [Test]
+ public void TestCodedInputOutputPosition()
+ {
+ byte[] content = new byte[110];
+ for (int i = 0; i < content.Length; i++)
+ content[i] = (byte)i;
+
+ byte[] child = new byte[120];
+ {
+ MemoryStream ms = new MemoryStream(child);
+ CodedOutputStream cout = new CodedOutputStream(ms, 20);
+ // Field 11: numeric value: 500
+ cout.WriteTag(11, WireFormat.WireType.Varint);
+ Assert.AreEqual(1, cout.Position);
+ cout.WriteInt32(500);
+ Assert.AreEqual(3, cout.Position);
+ //Field 12: length delimited 120 bytes
+ cout.WriteTag(12, WireFormat.WireType.LengthDelimited);
+ Assert.AreEqual(4, cout.Position);
+ cout.WriteBytes(ByteString.CopyFrom(content));
+ Assert.AreEqual(115, cout.Position);
+ // Field 13: fixed numeric value: 501
+ cout.WriteTag(13, WireFormat.WireType.Fixed32);
+ Assert.AreEqual(116, cout.Position);
+ cout.WriteSFixed32(501);
+ Assert.AreEqual(120, cout.Position);
+ cout.Flush();
+ }
+
+ byte[] bytes = new byte[130];
+ {
+ CodedOutputStream cout = new CodedOutputStream(bytes);
+ // Field 1: numeric value: 500
+ cout.WriteTag(1, WireFormat.WireType.Varint);
+ Assert.AreEqual(1, cout.Position);
+ cout.WriteInt32(500);
+ Assert.AreEqual(3, cout.Position);
+ //Field 2: length delimited 120 bytes
+ cout.WriteTag(2, WireFormat.WireType.LengthDelimited);
+ Assert.AreEqual(4, cout.Position);
+ cout.WriteBytes(ByteString.CopyFrom(child));
+ Assert.AreEqual(125, cout.Position);
+ // Field 3: fixed numeric value: 500
+ cout.WriteTag(3, WireFormat.WireType.Fixed32);
+ Assert.AreEqual(126, cout.Position);
+ cout.WriteSFixed32(501);
+ Assert.AreEqual(130, cout.Position);
+ cout.Flush();
+ }
+ // Now test Input stream:
+ {
+ CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0, false);
+ Assert.AreEqual(0, cin.Position);
+ // Field 1:
+ uint tag = cin.ReadTag();
+ Assert.AreEqual(1, tag >> 3);
+ Assert.AreEqual(1, cin.Position);
+ Assert.AreEqual(500, cin.ReadInt32());
+ Assert.AreEqual(3, cin.Position);
+ //Field 2:
+ tag = cin.ReadTag();
+ Assert.AreEqual(2, tag >> 3);
+ Assert.AreEqual(4, cin.Position);
+ int childlen = cin.ReadLength();
+ Assert.AreEqual(120, childlen);
+ Assert.AreEqual(5, cin.Position);
+ int oldlimit = cin.PushLimit((int)childlen);
+ Assert.AreEqual(5, cin.Position);
+ // Now we are reading child message
+ {
+ // Field 11: numeric value: 500
+ tag = cin.ReadTag();
+ Assert.AreEqual(11, tag >> 3);
+ Assert.AreEqual(6, cin.Position);
+ Assert.AreEqual(500, cin.ReadInt32());
+ Assert.AreEqual(8, cin.Position);
+ //Field 12: length delimited 120 bytes
+ tag = cin.ReadTag();
+ Assert.AreEqual(12, tag >> 3);
+ Assert.AreEqual(9, cin.Position);
+ ByteString bstr = cin.ReadBytes();
+ Assert.AreEqual(110, bstr.Length);
+ Assert.AreEqual((byte) 109, bstr[109]);
+ Assert.AreEqual(120, cin.Position);
+ // Field 13: fixed numeric value: 501
+ tag = cin.ReadTag();
+ Assert.AreEqual(13, tag >> 3);
+ // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
+ Assert.AreEqual(121, cin.Position);
+ Assert.AreEqual(501, cin.ReadSFixed32());
+ Assert.AreEqual(125, cin.Position);
+ Assert.IsTrue(cin.IsAtEnd);
+ }
+ cin.PopLimit(oldlimit);
+ Assert.AreEqual(125, cin.Position);
+ // Field 3: fixed numeric value: 501
+ tag = cin.ReadTag();
+ Assert.AreEqual(3, tag >> 3);
+ Assert.AreEqual(126, cin.Position);
+ Assert.AreEqual(501, cin.ReadSFixed32());
+ Assert.AreEqual(130, cin.Position);
+ Assert.IsTrue(cin.IsAtEnd);
+ }
+ }
+
+ [Test]
+ public void Dispose_DisposesUnderlyingStream()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanWrite);
+ using (var cos = new CodedOutputStream(memoryStream))
+ {
+ cos.WriteRawByte(0);
+ Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
+ }
+ Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
+ Assert.IsFalse(memoryStream.CanWrite); // Disposed
+ }
+
+ [Test]
+ public void Dispose_WithLeaveOpen()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanWrite);
+ using (var cos = new CodedOutputStream(memoryStream, true))
+ {
+ cos.WriteRawByte(0);
+ Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
+ }
+ Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream
+ Assert.IsTrue(memoryStream.CanWrite); // We left the stream open
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/DeprecatedMemberTest.cs b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
index 34d5b9f98c..8dfad8b331 100644
--- a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
@@ -1,55 +1,55 @@
-#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.Reflection;
-using Google.Protobuf.TestProtos;
-using NUnit.Framework;
-
-namespace Google.Protobuf
-{
- public class DeprecatedMemberTest
- {
- private static void AssertIsDeprecated(MemberInfo member)
- {
- Assert.NotNull(member);
- Assert.IsTrue(member.IsDefined(typeof(ObsoleteAttribute), false), "Member not obsolete: " + member);
- }
-
- [Test]
- public void TestDepreatedPrimitiveValue()
- {
- AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty("DeprecatedInt32"));
- }
-
- }
-}
+#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.Reflection;
+using Google.Protobuf.TestProtos;
+using NUnit.Framework;
+
+namespace Google.Protobuf
+{
+ public class DeprecatedMemberTest
+ {
+ private static void AssertIsDeprecated(MemberInfo member)
+ {
+ Assert.NotNull(member);
+ Assert.IsTrue(member.IsDefined(typeof(ObsoleteAttribute), false), "Member not obsolete: " + member);
+ }
+
+ [Test]
+ public void TestDepreatedPrimitiveValue()
+ {
+ AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty("DeprecatedInt32"));
+ }
+
+ }
+}
diff --git a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/GeneratedMessageTest.cs
index 8b153d691f..b029551c0b 100644
--- a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/GeneratedMessageTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/GeneratedMessageTest.cs
@@ -1,723 +1,723 @@
-#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.IO;
-using Google.Protobuf.TestProtos;
-using NUnit.Framework;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using Google.Protobuf.WellKnownTypes;
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Tests around the generated TestAllTypes message.
- /// </summary>
- public class GeneratedMessageTest
- {
- [Test]
- public void EmptyMessageFieldDistinctFromMissingMessageField()
- {
- // This demonstrates what we're really interested in...
- var message1 = new TestAllTypes { SingleForeignMessage = new ForeignMessage() };
- var message2 = new TestAllTypes(); // SingleForeignMessage is null
- EqualityTester.AssertInequality(message1, message2);
- }
-
- [Test]
- public void DefaultValues()
- {
- // Single fields
- var message = new TestAllTypes();
- Assert.AreEqual(false, message.SingleBool);
- Assert.AreEqual(ByteString.Empty, message.SingleBytes);
- Assert.AreEqual(0.0, message.SingleDouble);
- Assert.AreEqual(0, message.SingleFixed32);
- Assert.AreEqual(0L, message.SingleFixed64);
- Assert.AreEqual(0.0f, message.SingleFloat);
- Assert.AreEqual(ForeignEnum.ForeignUnspecified, message.SingleForeignEnum);
- Assert.IsNull(message.SingleForeignMessage);
- Assert.AreEqual(ImportEnum.Unspecified, message.SingleImportEnum);
- Assert.IsNull(message.SingleImportMessage);
- Assert.AreEqual(0, message.SingleInt32);
- Assert.AreEqual(0L, message.SingleInt64);
- Assert.AreEqual(TestAllTypes.Types.NestedEnum.Unspecified, message.SingleNestedEnum);
- Assert.IsNull(message.SingleNestedMessage);
- Assert.IsNull(message.SinglePublicImportMessage);
- Assert.AreEqual(0, message.SingleSfixed32);
- Assert.AreEqual(0L, message.SingleSfixed64);
- Assert.AreEqual(0, message.SingleSint32);
- Assert.AreEqual(0L, message.SingleSint64);
- Assert.AreEqual("", message.SingleString);
- Assert.AreEqual(0U, message.SingleUint32);
- Assert.AreEqual(0UL, message.SingleUint64);
-
- // Repeated fields
- Assert.AreEqual(0, message.RepeatedBool.Count);
- Assert.AreEqual(0, message.RepeatedBytes.Count);
- Assert.AreEqual(0, message.RepeatedDouble.Count);
- Assert.AreEqual(0, message.RepeatedFixed32.Count);
- Assert.AreEqual(0, message.RepeatedFixed64.Count);
- Assert.AreEqual(0, message.RepeatedFloat.Count);
- Assert.AreEqual(0, message.RepeatedForeignEnum.Count);
- Assert.AreEqual(0, message.RepeatedForeignMessage.Count);
- Assert.AreEqual(0, message.RepeatedImportEnum.Count);
- Assert.AreEqual(0, message.RepeatedImportMessage.Count);
- Assert.AreEqual(0, message.RepeatedNestedEnum.Count);
- Assert.AreEqual(0, message.RepeatedNestedMessage.Count);
- Assert.AreEqual(0, message.RepeatedPublicImportMessage.Count);
- Assert.AreEqual(0, message.RepeatedSfixed32.Count);
- Assert.AreEqual(0, message.RepeatedSfixed64.Count);
- Assert.AreEqual(0, message.RepeatedSint32.Count);
- Assert.AreEqual(0, message.RepeatedSint64.Count);
- Assert.AreEqual(0, message.RepeatedString.Count);
- Assert.AreEqual(0, message.RepeatedUint32.Count);
- Assert.AreEqual(0, message.RepeatedUint64.Count);
-
- // Oneof fields
- Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
- Assert.AreEqual(0, message.OneofUint32);
- Assert.AreEqual("", message.OneofString);
- Assert.AreEqual(ByteString.Empty, message.OneofBytes);
- Assert.IsNull(message.OneofNestedMessage);
- }
-
- [Test]
- public void NullStringAndBytesRejected()
- {
- var message = new TestAllTypes();
- Assert.Throws<ArgumentNullException>(() => message.SingleString = null);
- Assert.Throws<ArgumentNullException>(() => message.OneofString = null);
- Assert.Throws<ArgumentNullException>(() => message.SingleBytes = null);
- Assert.Throws<ArgumentNullException>(() => message.OneofBytes = null);
- }
-
- [Test]
- public void RoundTrip_Empty()
- {
- var message = new TestAllTypes();
- // Without setting any values, there's nothing to write.
- byte[] bytes = message.ToByteArray();
- Assert.AreEqual(0, bytes.Length);
- TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
- Assert.AreEqual(message, parsed);
- }
-
- [Test]
- public void RoundTrip_SingleValues()
- {
- var message = new TestAllTypes
- {
- SingleBool = true,
- SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
- SingleDouble = 23.5,
- SingleFixed32 = 23,
- SingleFixed64 = 1234567890123,
- SingleFloat = 12.25f,
- SingleForeignEnum = ForeignEnum.ForeignBar,
- SingleForeignMessage = new ForeignMessage { C = 10 },
- SingleImportEnum = ImportEnum.ImportBaz,
- 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
- };
-
- byte[] bytes = message.ToByteArray();
- TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
- Assert.AreEqual(message, parsed);
- }
-
- [Test]
- public void RoundTrip_RepeatedValues()
- {
- var message = new TestAllTypes
- {
- RepeatedBool = { true, false },
- RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
- RepeatedDouble = { -12.25, 23.5 },
- RepeatedFixed32 = { uint.MaxValue, 23 },
- RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
- RepeatedFloat = { 100f, 12.25f },
- RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
- RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
- RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.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 }
- };
-
- byte[] bytes = message.ToByteArray();
- TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
- Assert.AreEqual(message, parsed);
- }
-
- // Note that not every map within map_unittest_proto3 is used. They all go through very
- // similar code paths. The fact that all maps are present is validation that we have codecs
- // for every type.
- [Test]
- public void RoundTrip_Maps()
- {
- var message = new TestMap
- {
- MapBoolBool = {
- { false, true },
- { true, false }
- },
- MapInt32Bytes = {
- { 5, ByteString.CopyFrom(6, 7, 8) },
- { 25, ByteString.CopyFrom(1, 2, 3, 4, 5) },
- { 10, ByteString.Empty }
- },
- MapInt32ForeignMessage = {
- { 0, new ForeignMessage { C = 10 } },
- { 5, new ForeignMessage() },
- },
- MapInt32Enum = {
- { 1, MapEnum.Bar },
- { 2000, MapEnum.Foo }
- }
- };
-
- byte[] bytes = message.ToByteArray();
- TestMap parsed = TestMap.Parser.ParseFrom(bytes);
- Assert.AreEqual(message, parsed);
- }
-
- [Test]
- public void MapWithEmptyEntry()
- {
- var message = new TestMap
- {
- MapInt32Bytes = { { 0, ByteString.Empty } }
- };
-
- byte[] bytes = message.ToByteArray();
- Assert.AreEqual(2, bytes.Length); // Tag for field entry (1 byte), length of entry (0; 1 byte)
-
- var parsed = TestMap.Parser.ParseFrom(bytes);
- Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
- Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
- }
-
- [Test]
- public void MapWithOnlyValue()
- {
- // Hand-craft the stream to contain a single entry with just a value.
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
- output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
- var nestedMessage = new ForeignMessage { C = 20 };
- // Size of the entry (tag, size written by WriteMessage, data written by WriteMessage)
- output.WriteLength(2 + nestedMessage.CalculateSize());
- output.WriteTag(2, WireFormat.WireType.LengthDelimited);
- output.WriteMessage(nestedMessage);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(nestedMessage, parsed.MapInt32ForeignMessage[0]);
- }
-
- [Test]
- public void MapWithOnlyKey_PrimitiveValue()
- {
- // Hand-craft the stream to contain a single entry with just a key.
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
- output.WriteTag(TestMap.MapInt32DoubleFieldNumber, WireFormat.WireType.LengthDelimited);
- int key = 10;
- output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(0.0, parsed.MapInt32Double[key]);
- }
-
- [Test]
- public void MapWithOnlyKey_MessageValue()
- {
- // Hand-craft the stream to contain a single entry with just a key.
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
- output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
- int key = 10;
- output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]);
- }
-
- [Test]
- public void MapIgnoresExtraFieldsWithinEntryMessages()
- {
- // Hand-craft the stream to contain a single entry with three fields
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
-
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
-
- var key = 10; // Field 1
- var value = 20; // Field 2
- var extra = 30; // Field 3
-
- // Each field can be represented in a single byte, with a single byte tag.
- // Total message size: 6 bytes.
- output.WriteLength(6);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value);
- output.WriteTag(3, WireFormat.WireType.Varint);
- output.WriteInt32(extra);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(value, parsed.MapInt32Int32[key]);
- }
-
- [Test]
- public void MapFieldOrderIsIrrelevant()
- {
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
-
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
-
- var key = 10;
- var value = 20;
-
- // Each field can be represented in a single byte, with a single byte tag.
- // Total message size: 4 bytes.
- output.WriteLength(4);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(value, parsed.MapInt32Int32[key]);
- }
-
- [Test]
- public void MapNonContiguousEntries()
- {
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
-
- // Message structure:
- // Entry for MapInt32Int32
- // Entry for MapStringString
- // Entry for MapInt32Int32
-
- // First entry
- var key1 = 10;
- var value1 = 20;
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteLength(4);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key1);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value1);
-
- // Second entry
- var key2 = "a";
- var value2 = "b";
- output.WriteTag(TestMap.MapStringStringFieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteLength(6); // 3 bytes per entry: tag, size, character
- output.WriteTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteString(key2);
- output.WriteTag(2, WireFormat.WireType.LengthDelimited);
- output.WriteString(value2);
-
- // Third entry
- var key3 = 15;
- var value3 = 25;
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteLength(4);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key3);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value3);
-
- output.Flush();
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- var expected = new TestMap
- {
- MapInt32Int32 = { { key1, value1 }, { key3, value3 } },
- MapStringString = { { key2, value2 } }
- };
- Assert.AreEqual(expected, parsed);
- }
-
- [Test]
- public void DuplicateKeys_LastEntryWins()
- {
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
-
- var key = 10;
- var value1 = 20;
- var value2 = 30;
-
- // First entry
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteLength(4);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value1);
-
- // Second entry - same key, different value
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteLength(4);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value2);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(value2, parsed.MapInt32Int32[key]);
- }
-
- [Test]
- public void CloneSingleNonMessageValues()
- {
- var original = new TestAllTypes
- {
- SingleBool = true,
- SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
- SingleDouble = 23.5,
- SingleFixed32 = 23,
- SingleFixed64 = 1234567890123,
- SingleFloat = 12.25f,
- SingleInt32 = 100,
- SingleInt64 = 3210987654321,
- SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
- SingleSfixed32 = -123,
- SingleSfixed64 = -12345678901234,
- SingleSint32 = -456,
- SingleSint64 = -12345678901235,
- SingleString = "test",
- SingleUint32 = uint.MaxValue,
- SingleUint64 = ulong.MaxValue
- };
- var clone = original.Clone();
- Assert.AreNotSame(original, clone);
- Assert.AreEqual(original, clone);
- // Just as a single example
- clone.SingleInt32 = 150;
- Assert.AreNotEqual(original, clone);
- }
-
- [Test]
- public void CloneRepeatedNonMessageValues()
- {
- var original = new TestAllTypes
- {
- RepeatedBool = { true, false },
- RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
- RepeatedDouble = { -12.25, 23.5 },
- RepeatedFixed32 = { uint.MaxValue, 23 },
- RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
- RepeatedFloat = { 100f, 12.25f },
- RepeatedInt32 = { 100, 200 },
- RepeatedInt64 = { 3210987654321, long.MaxValue },
- RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
- 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 }
- };
-
- var clone = original.Clone();
- Assert.AreNotSame(original, clone);
- Assert.AreEqual(original, clone);
- // Just as a single example
- clone.RepeatedDouble.Add(25.5);
- Assert.AreNotEqual(original, clone);
- }
-
- [Test]
- public void CloneSingleMessageField()
- {
- var original = new TestAllTypes
- {
- SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
- };
-
- var clone = original.Clone();
- Assert.AreNotSame(original, clone);
- Assert.AreNotSame(original.SingleNestedMessage, clone.SingleNestedMessage);
- Assert.AreEqual(original, clone);
-
- clone.SingleNestedMessage.Bb = 30;
- Assert.AreNotEqual(original, clone);
- }
-
- [Test]
- public void CloneRepeatedMessageField()
- {
- var original = new TestAllTypes
- {
- RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 20 } }
- };
-
- var clone = original.Clone();
- Assert.AreNotSame(original, clone);
- Assert.AreNotSame(original.RepeatedNestedMessage, clone.RepeatedNestedMessage);
- Assert.AreNotSame(original.RepeatedNestedMessage[0], clone.RepeatedNestedMessage[0]);
- Assert.AreEqual(original, clone);
-
- clone.RepeatedNestedMessage[0].Bb = 30;
- Assert.AreNotEqual(original, clone);
- }
-
- [Test]
- public void CloneOneofField()
- {
- var original = new TestAllTypes
- {
- OneofNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
- };
-
- var clone = original.Clone();
- Assert.AreNotSame(original, clone);
- Assert.AreEqual(original, clone);
-
- // We should have cloned the message
- original.OneofNestedMessage.Bb = 30;
- Assert.AreNotEqual(original, clone);
- }
-
- [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 Oneof_DefaultValuesNotEqual()
- {
- var message1 = new TestAllTypes { OneofString = "" };
- var message2 = new TestAllTypes { OneofUint32 = 0 };
- Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message1.OneofFieldCase);
- Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
- Assert.AreNotEqual(message1, message2);
- }
-
- [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);
- }
-
- [Test]
- public void IgnoreUnknownFields_RealDataStillRead()
- {
- var message = SampleMessages.CreateFullTestAllTypes();
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- var unusedFieldNumber = 23456;
- Assert.IsFalse(TestAllTypes.Descriptor.Fields.InDeclarationOrder().Select(x => x.FieldNumber).Contains(unusedFieldNumber));
- output.WriteTag(unusedFieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteString("ignore me");
- message.WriteTo(output);
- output.Flush();
-
- stream.Position = 0;
- var parsed = TestAllTypes.Parser.ParseFrom(stream);
- Assert.AreEqual(message, parsed);
- }
-
- [Test]
- public void IgnoreUnknownFields_AllTypes()
- {
- // Simple way of ensuring we can skip all kinds of fields.
- var data = SampleMessages.CreateFullTestAllTypes().ToByteArray();
- var empty = Empty.Parser.ParseFrom(data);
- Assert.AreEqual(new Empty(), empty);
- }
-
- // This was originally seen as a conformance test failure.
- [Test]
- public void TruncatedMessageFieldThrows()
- {
- // 130, 3 is the message tag
- // 1 is the data length - but there's no data.
- var data = new byte[] { 130, 3, 1 };
- Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(data));
- }
-
- /// <summary>
- /// Demonstrates current behaviour with an extraneous end group tag - see issue 688
- /// for details; we may want to change this.
- /// </summary>
- [Test]
- public void ExtraEndGroupThrows()
- {
- var message = SampleMessages.CreateFullTestAllTypes();
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
-
- output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32);
- output.WriteFixed32(123);
- output.WriteTag(100, WireFormat.WireType.EndGroup);
-
- output.Flush();
-
- stream.Position = 0;
- Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream));
- }
-
- [Test]
- public void CustomDiagnosticMessage_DirectToStringCall()
- {
- var message = new ForeignMessage { C = 31 };
- Assert.AreEqual("{ \"c\": 31, \"@cInHex\": \"1f\" }", message.ToString());
- Assert.AreEqual("{ \"c\": 31 }", JsonFormatter.Default.Format(message));
- }
-
- [Test]
- public void CustomDiagnosticMessage_Nested()
- {
- var message = new TestAllTypes { SingleForeignMessage = new ForeignMessage { C = 16 } };
- Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16, \"@cInHex\": \"10\" } }", message.ToString());
- Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16 } }", JsonFormatter.Default.Format(message));
- }
-
- [Test]
- public void CustomDiagnosticMessage_DirectToTextWriterCall()
- {
- var message = new ForeignMessage { C = 31 };
- var writer = new StringWriter();
- JsonFormatter.Default.Format(message, writer);
- Assert.AreEqual("{ \"c\": 31 }", writer.ToString());
- }
- }
+#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.IO;
+using Google.Protobuf.TestProtos;
+using NUnit.Framework;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using Google.Protobuf.WellKnownTypes;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Tests around the generated TestAllTypes message.
+ /// </summary>
+ public class GeneratedMessageTest
+ {
+ [Test]
+ public void EmptyMessageFieldDistinctFromMissingMessageField()
+ {
+ // This demonstrates what we're really interested in...
+ var message1 = new TestAllTypes { SingleForeignMessage = new ForeignMessage() };
+ var message2 = new TestAllTypes(); // SingleForeignMessage is null
+ EqualityTester.AssertInequality(message1, message2);
+ }
+
+ [Test]
+ public void DefaultValues()
+ {
+ // Single fields
+ var message = new TestAllTypes();
+ Assert.AreEqual(false, message.SingleBool);
+ Assert.AreEqual(ByteString.Empty, message.SingleBytes);
+ Assert.AreEqual(0.0, message.SingleDouble);
+ Assert.AreEqual(0, message.SingleFixed32);
+ Assert.AreEqual(0L, message.SingleFixed64);
+ Assert.AreEqual(0.0f, message.SingleFloat);
+ Assert.AreEqual(ForeignEnum.ForeignUnspecified, message.SingleForeignEnum);
+ Assert.IsNull(message.SingleForeignMessage);
+ Assert.AreEqual(ImportEnum.Unspecified, message.SingleImportEnum);
+ Assert.IsNull(message.SingleImportMessage);
+ Assert.AreEqual(0, message.SingleInt32);
+ Assert.AreEqual(0L, message.SingleInt64);
+ Assert.AreEqual(TestAllTypes.Types.NestedEnum.Unspecified, message.SingleNestedEnum);
+ Assert.IsNull(message.SingleNestedMessage);
+ Assert.IsNull(message.SinglePublicImportMessage);
+ Assert.AreEqual(0, message.SingleSfixed32);
+ Assert.AreEqual(0L, message.SingleSfixed64);
+ Assert.AreEqual(0, message.SingleSint32);
+ Assert.AreEqual(0L, message.SingleSint64);
+ Assert.AreEqual("", message.SingleString);
+ Assert.AreEqual(0U, message.SingleUint32);
+ Assert.AreEqual(0UL, message.SingleUint64);
+
+ // Repeated fields
+ Assert.AreEqual(0, message.RepeatedBool.Count);
+ Assert.AreEqual(0, message.RepeatedBytes.Count);
+ Assert.AreEqual(0, message.RepeatedDouble.Count);
+ Assert.AreEqual(0, message.RepeatedFixed32.Count);
+ Assert.AreEqual(0, message.RepeatedFixed64.Count);
+ Assert.AreEqual(0, message.RepeatedFloat.Count);
+ Assert.AreEqual(0, message.RepeatedForeignEnum.Count);
+ Assert.AreEqual(0, message.RepeatedForeignMessage.Count);
+ Assert.AreEqual(0, message.RepeatedImportEnum.Count);
+ Assert.AreEqual(0, message.RepeatedImportMessage.Count);
+ Assert.AreEqual(0, message.RepeatedNestedEnum.Count);
+ Assert.AreEqual(0, message.RepeatedNestedMessage.Count);
+ Assert.AreEqual(0, message.RepeatedPublicImportMessage.Count);
+ Assert.AreEqual(0, message.RepeatedSfixed32.Count);
+ Assert.AreEqual(0, message.RepeatedSfixed64.Count);
+ Assert.AreEqual(0, message.RepeatedSint32.Count);
+ Assert.AreEqual(0, message.RepeatedSint64.Count);
+ Assert.AreEqual(0, message.RepeatedString.Count);
+ Assert.AreEqual(0, message.RepeatedUint32.Count);
+ Assert.AreEqual(0, message.RepeatedUint64.Count);
+
+ // Oneof fields
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
+ Assert.AreEqual(0, message.OneofUint32);
+ Assert.AreEqual("", message.OneofString);
+ Assert.AreEqual(ByteString.Empty, message.OneofBytes);
+ Assert.IsNull(message.OneofNestedMessage);
+ }
+
+ [Test]
+ public void NullStringAndBytesRejected()
+ {
+ var message = new TestAllTypes();
+ Assert.Throws<ArgumentNullException>(() => message.SingleString = null);
+ Assert.Throws<ArgumentNullException>(() => message.OneofString = null);
+ Assert.Throws<ArgumentNullException>(() => message.SingleBytes = null);
+ Assert.Throws<ArgumentNullException>(() => message.OneofBytes = null);
+ }
+
+ [Test]
+ public void RoundTrip_Empty()
+ {
+ var message = new TestAllTypes();
+ // Without setting any values, there's nothing to write.
+ byte[] bytes = message.ToByteArray();
+ Assert.AreEqual(0, bytes.Length);
+ TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
+ Assert.AreEqual(message, parsed);
+ }
+
+ [Test]
+ public void RoundTrip_SingleValues()
+ {
+ var message = new TestAllTypes
+ {
+ SingleBool = true,
+ SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
+ SingleDouble = 23.5,
+ SingleFixed32 = 23,
+ SingleFixed64 = 1234567890123,
+ SingleFloat = 12.25f,
+ SingleForeignEnum = ForeignEnum.ForeignBar,
+ SingleForeignMessage = new ForeignMessage { C = 10 },
+ SingleImportEnum = ImportEnum.ImportBaz,
+ 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
+ };
+
+ byte[] bytes = message.ToByteArray();
+ TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
+ Assert.AreEqual(message, parsed);
+ }
+
+ [Test]
+ public void RoundTrip_RepeatedValues()
+ {
+ var message = new TestAllTypes
+ {
+ RepeatedBool = { true, false },
+ RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
+ RepeatedDouble = { -12.25, 23.5 },
+ RepeatedFixed32 = { uint.MaxValue, 23 },
+ RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
+ RepeatedFloat = { 100f, 12.25f },
+ RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
+ RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
+ RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.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 }
+ };
+
+ byte[] bytes = message.ToByteArray();
+ TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
+ Assert.AreEqual(message, parsed);
+ }
+
+ // Note that not every map within map_unittest_proto3 is used. They all go through very
+ // similar code paths. The fact that all maps are present is validation that we have codecs
+ // for every type.
+ [Test]
+ public void RoundTrip_Maps()
+ {
+ var message = new TestMap
+ {
+ MapBoolBool = {
+ { false, true },
+ { true, false }
+ },
+ MapInt32Bytes = {
+ { 5, ByteString.CopyFrom(6, 7, 8) },
+ { 25, ByteString.CopyFrom(1, 2, 3, 4, 5) },
+ { 10, ByteString.Empty }
+ },
+ MapInt32ForeignMessage = {
+ { 0, new ForeignMessage { C = 10 } },
+ { 5, new ForeignMessage() },
+ },
+ MapInt32Enum = {
+ { 1, MapEnum.Bar },
+ { 2000, MapEnum.Foo }
+ }
+ };
+
+ byte[] bytes = message.ToByteArray();
+ TestMap parsed = TestMap.Parser.ParseFrom(bytes);
+ Assert.AreEqual(message, parsed);
+ }
+
+ [Test]
+ public void MapWithEmptyEntry()
+ {
+ var message = new TestMap
+ {
+ MapInt32Bytes = { { 0, ByteString.Empty } }
+ };
+
+ byte[] bytes = message.ToByteArray();
+ Assert.AreEqual(2, bytes.Length); // Tag for field entry (1 byte), length of entry (0; 1 byte)
+
+ var parsed = TestMap.Parser.ParseFrom(bytes);
+ Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
+ Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
+ }
+
+ [Test]
+ public void MapWithOnlyValue()
+ {
+ // Hand-craft the stream to contain a single entry with just a value.
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+ output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
+ var nestedMessage = new ForeignMessage { C = 20 };
+ // Size of the entry (tag, size written by WriteMessage, data written by WriteMessage)
+ output.WriteLength(2 + nestedMessage.CalculateSize());
+ output.WriteTag(2, WireFormat.WireType.LengthDelimited);
+ output.WriteMessage(nestedMessage);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(nestedMessage, parsed.MapInt32ForeignMessage[0]);
+ }
+
+ [Test]
+ public void MapWithOnlyKey_PrimitiveValue()
+ {
+ // Hand-craft the stream to contain a single entry with just a key.
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+ output.WriteTag(TestMap.MapInt32DoubleFieldNumber, WireFormat.WireType.LengthDelimited);
+ int key = 10;
+ output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(0.0, parsed.MapInt32Double[key]);
+ }
+
+ [Test]
+ public void MapWithOnlyKey_MessageValue()
+ {
+ // Hand-craft the stream to contain a single entry with just a key.
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+ output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
+ int key = 10;
+ output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]);
+ }
+
+ [Test]
+ public void MapIgnoresExtraFieldsWithinEntryMessages()
+ {
+ // Hand-craft the stream to contain a single entry with three fields
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+
+ var key = 10; // Field 1
+ var value = 20; // Field 2
+ var extra = 30; // Field 3
+
+ // Each field can be represented in a single byte, with a single byte tag.
+ // Total message size: 6 bytes.
+ output.WriteLength(6);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value);
+ output.WriteTag(3, WireFormat.WireType.Varint);
+ output.WriteInt32(extra);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(value, parsed.MapInt32Int32[key]);
+ }
+
+ [Test]
+ public void MapFieldOrderIsIrrelevant()
+ {
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+
+ var key = 10;
+ var value = 20;
+
+ // Each field can be represented in a single byte, with a single byte tag.
+ // Total message size: 4 bytes.
+ output.WriteLength(4);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(value, parsed.MapInt32Int32[key]);
+ }
+
+ [Test]
+ public void MapNonContiguousEntries()
+ {
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+
+ // Message structure:
+ // Entry for MapInt32Int32
+ // Entry for MapStringString
+ // Entry for MapInt32Int32
+
+ // First entry
+ var key1 = 10;
+ var value1 = 20;
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(4);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key1);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value1);
+
+ // Second entry
+ var key2 = "a";
+ var value2 = "b";
+ output.WriteTag(TestMap.MapStringStringFieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(6); // 3 bytes per entry: tag, size, character
+ output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteString(key2);
+ output.WriteTag(2, WireFormat.WireType.LengthDelimited);
+ output.WriteString(value2);
+
+ // Third entry
+ var key3 = 15;
+ var value3 = 25;
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(4);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key3);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value3);
+
+ output.Flush();
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ var expected = new TestMap
+ {
+ MapInt32Int32 = { { key1, value1 }, { key3, value3 } },
+ MapStringString = { { key2, value2 } }
+ };
+ Assert.AreEqual(expected, parsed);
+ }
+
+ [Test]
+ public void DuplicateKeys_LastEntryWins()
+ {
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+
+ var key = 10;
+ var value1 = 20;
+ var value2 = 30;
+
+ // First entry
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(4);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value1);
+
+ // Second entry - same key, different value
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(4);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value2);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(value2, parsed.MapInt32Int32[key]);
+ }
+
+ [Test]
+ public void CloneSingleNonMessageValues()
+ {
+ var original = new TestAllTypes
+ {
+ SingleBool = true,
+ SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
+ SingleDouble = 23.5,
+ SingleFixed32 = 23,
+ SingleFixed64 = 1234567890123,
+ SingleFloat = 12.25f,
+ SingleInt32 = 100,
+ SingleInt64 = 3210987654321,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
+ SingleSfixed32 = -123,
+ SingleSfixed64 = -12345678901234,
+ SingleSint32 = -456,
+ SingleSint64 = -12345678901235,
+ SingleString = "test",
+ SingleUint32 = uint.MaxValue,
+ SingleUint64 = ulong.MaxValue
+ };
+ var clone = original.Clone();
+ Assert.AreNotSame(original, clone);
+ Assert.AreEqual(original, clone);
+ // Just as a single example
+ clone.SingleInt32 = 150;
+ Assert.AreNotEqual(original, clone);
+ }
+
+ [Test]
+ public void CloneRepeatedNonMessageValues()
+ {
+ var original = new TestAllTypes
+ {
+ RepeatedBool = { true, false },
+ RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
+ RepeatedDouble = { -12.25, 23.5 },
+ RepeatedFixed32 = { uint.MaxValue, 23 },
+ RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
+ RepeatedFloat = { 100f, 12.25f },
+ RepeatedInt32 = { 100, 200 },
+ RepeatedInt64 = { 3210987654321, long.MaxValue },
+ RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
+ 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 }
+ };
+
+ var clone = original.Clone();
+ Assert.AreNotSame(original, clone);
+ Assert.AreEqual(original, clone);
+ // Just as a single example
+ clone.RepeatedDouble.Add(25.5);
+ Assert.AreNotEqual(original, clone);
+ }
+
+ [Test]
+ public void CloneSingleMessageField()
+ {
+ var original = new TestAllTypes
+ {
+ SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
+ };
+
+ var clone = original.Clone();
+ Assert.AreNotSame(original, clone);
+ Assert.AreNotSame(original.SingleNestedMessage, clone.SingleNestedMessage);
+ Assert.AreEqual(original, clone);
+
+ clone.SingleNestedMessage.Bb = 30;
+ Assert.AreNotEqual(original, clone);
+ }
+
+ [Test]
+ public void CloneRepeatedMessageField()
+ {
+ var original = new TestAllTypes
+ {
+ RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 20 } }
+ };
+
+ var clone = original.Clone();
+ Assert.AreNotSame(original, clone);
+ Assert.AreNotSame(original.RepeatedNestedMessage, clone.RepeatedNestedMessage);
+ Assert.AreNotSame(original.RepeatedNestedMessage[0], clone.RepeatedNestedMessage[0]);
+ Assert.AreEqual(original, clone);
+
+ clone.RepeatedNestedMessage[0].Bb = 30;
+ Assert.AreNotEqual(original, clone);
+ }
+
+ [Test]
+ public void CloneOneofField()
+ {
+ var original = new TestAllTypes
+ {
+ OneofNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
+ };
+
+ var clone = original.Clone();
+ Assert.AreNotSame(original, clone);
+ Assert.AreEqual(original, clone);
+
+ // We should have cloned the message
+ original.OneofNestedMessage.Bb = 30;
+ Assert.AreNotEqual(original, clone);
+ }
+
+ [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 Oneof_DefaultValuesNotEqual()
+ {
+ var message1 = new TestAllTypes { OneofString = "" };
+ var message2 = new TestAllTypes { OneofUint32 = 0 };
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message1.OneofFieldCase);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
+ Assert.AreNotEqual(message1, message2);
+ }
+
+ [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);
+ }
+
+ [Test]
+ public void IgnoreUnknownFields_RealDataStillRead()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ var unusedFieldNumber = 23456;
+ Assert.IsFalse(TestAllTypes.Descriptor.Fields.InDeclarationOrder().Select(x => x.FieldNumber).Contains(unusedFieldNumber));
+ output.WriteTag(unusedFieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteString("ignore me");
+ message.WriteTo(output);
+ output.Flush();
+
+ stream.Position = 0;
+ var parsed = TestAllTypes.Parser.ParseFrom(stream);
+ Assert.AreEqual(message, parsed);
+ }
+
+ [Test]
+ public void IgnoreUnknownFields_AllTypes()
+ {
+ // Simple way of ensuring we can skip all kinds of fields.
+ var data = SampleMessages.CreateFullTestAllTypes().ToByteArray();
+ var empty = Empty.Parser.ParseFrom(data);
+ Assert.AreEqual(new Empty(), empty);
+ }
+
+ // This was originally seen as a conformance test failure.
+ [Test]
+ public void TruncatedMessageFieldThrows()
+ {
+ // 130, 3 is the message tag
+ // 1 is the data length - but there's no data.
+ var data = new byte[] { 130, 3, 1 };
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(data));
+ }
+
+ /// <summary>
+ /// Demonstrates current behaviour with an extraneous end group tag - see issue 688
+ /// for details; we may want to change this.
+ /// </summary>
+ [Test]
+ public void ExtraEndGroupThrows()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+
+ output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32);
+ output.WriteFixed32(123);
+ output.WriteTag(100, WireFormat.WireType.EndGroup);
+
+ output.Flush();
+
+ stream.Position = 0;
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_DirectToStringCall()
+ {
+ var message = new ForeignMessage { C = 31 };
+ Assert.AreEqual("{ \"c\": 31, \"@cInHex\": \"1f\" }", message.ToString());
+ Assert.AreEqual("{ \"c\": 31 }", JsonFormatter.Default.Format(message));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_Nested()
+ {
+ var message = new TestAllTypes { SingleForeignMessage = new ForeignMessage { C = 16 } };
+ Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16, \"@cInHex\": \"10\" } }", message.ToString());
+ Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16 } }", JsonFormatter.Default.Format(message));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_DirectToTextWriterCall()
+ {
+ var message = new ForeignMessage { C = 31 };
+ var writer = new StringWriter();
+ JsonFormatter.Default.Format(message, writer);
+ Assert.AreEqual("{ \"c\": 31 }", writer.ToString());
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/IssuesTest.cs b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/IssuesTest.cs
index a38d6b08b5..ddb23aa685 100644
--- a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/IssuesTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/IssuesTest.cs
@@ -1,82 +1,82 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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 Google.Protobuf.Reflection;
-using UnitTest.Issues.TestProtos;
-using NUnit.Framework;
-
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Tests for issues which aren't easily compartmentalized into other unit tests.
- /// </summary>
- public class IssuesTest
- {
- // Issue 45
- [Test]
- public void FieldCalledItem()
- {
- ItemField message = new ItemField { Item = 3 };
- FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item");
- Assert.NotNull(field);
- Assert.AreEqual(3, (int)field.Accessor.GetValue(message));
- }
-
- [Test]
- public void ReservedNames()
- {
- var message = new ReservedNames { Types_ = 10, Descriptor_ = 20 };
- // Underscores aren't reflected in the JSON.
- Assert.AreEqual("{ \"types\": 10, \"descriptor\": 20 }", message.ToString());
- }
-
- [Test]
- public void JsonNameParseTest()
- {
- var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
- var parser = new JsonParser(settings);
-
- // It is safe to use either original field name or explicitly specified json_name
- Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
- parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
- }
-
- [Test]
- public void JsonNameFormatTest()
- {
- var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
- Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
- JsonFormatter.Default.Format(message));
- }
- }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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 Google.Protobuf.Reflection;
+using UnitTest.Issues.TestProtos;
+using NUnit.Framework;
+
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Tests for issues which aren't easily compartmentalized into other unit tests.
+ /// </summary>
+ public class IssuesTest
+ {
+ // Issue 45
+ [Test]
+ public void FieldCalledItem()
+ {
+ ItemField message = new ItemField { Item = 3 };
+ FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item");
+ Assert.NotNull(field);
+ Assert.AreEqual(3, (int)field.Accessor.GetValue(message));
+ }
+
+ [Test]
+ public void ReservedNames()
+ {
+ var message = new ReservedNames { Types_ = 10, Descriptor_ = 20 };
+ // Underscores aren't reflected in the JSON.
+ Assert.AreEqual("{ \"types\": 10, \"descriptor\": 20 }", message.ToString());
+ }
+
+ [Test]
+ public void JsonNameParseTest()
+ {
+ var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
+ var parser = new JsonParser(settings);
+
+ // It is safe to use either original field name or explicitly specified json_name
+ Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
+ parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
+ }
+
+ [Test]
+ public void JsonNameFormatTest()
+ {
+ var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
+ Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
+ JsonFormatter.Default.Format(message));
+ }
+ }
+}
diff --git a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/TestCornerCases.cs b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/TestCornerCases.cs
index 248f5fa913..fd75b19f42 100644
--- a/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/TestCornerCases.cs
+++ b/third_party/protobuf/3.4.0/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/TestCornerCases.cs
@@ -1,62 +1,62 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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 UnitTest.Issues.TestProtos;
-using NUnit.Framework;
-
-namespace Google.Protobuf
-{
- public class TestCornerCases
- {
- [Test]
- public void TestRoundTripNegativeEnums()
- {
- NegativeEnumMessage msg = new NegativeEnumMessage
- {
- Value = NegativeEnum.MinusOne,
- Values = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
- PackedValues = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
- };
-
- Assert.AreEqual(58, msg.CalculateSize());
-
- byte[] bytes = new byte[58];
- CodedOutputStream output = new CodedOutputStream(bytes);
-
- msg.WriteTo(output);
- Assert.AreEqual(0, output.SpaceLeft);
-
- NegativeEnumMessage copy = NegativeEnumMessage.Parser.ParseFrom(bytes);
- Assert.AreEqual(msg, copy);
- }
- }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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 UnitTest.Issues.TestProtos;
+using NUnit.Framework;
+
+namespace Google.Protobuf
+{
+ public class TestCornerCases
+ {
+ [Test]
+ public void TestRoundTripNegativeEnums()
+ {
+ NegativeEnumMessage msg = new NegativeEnumMessage
+ {
+ Value = NegativeEnum.MinusOne,
+ Values = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
+ PackedValues = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
+ };
+
+ Assert.AreEqual(58, msg.CalculateSize());
+
+ byte[] bytes = new byte[58];
+ CodedOutputStream output = new CodedOutputStream(bytes);
+
+ msg.WriteTo(output);
+ Assert.AreEqual(0, output.SpaceLeft);
+
+ NegativeEnumMessage copy = NegativeEnumMessage.Parser.ParseFrom(bytes);
+ Assert.AreEqual(msg, copy);
+ }
+ }
+}
diff --git a/third_party/protobuf/3.4.0/csharp/src/AddressBook/AddPerson.cs b/third_party/protobuf/3.4.0/csharp/src/AddressBook/AddPerson.cs
index 62d1788d55..484f1ea25d 100644
--- a/third_party/protobuf/3.4.0/csharp/src/AddressBook/AddPerson.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/AddressBook/AddPerson.cs
@@ -1,132 +1,132 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.IO;
-
-namespace Google.Protobuf.Examples.AddressBook
-{
- internal class AddPerson
- {
- /// <summary>
- /// Builds a person based on user input
- /// </summary>
- private static Person PromptForAddress(TextReader input, TextWriter output)
- {
- Person person = new Person();
-
- output.Write("Enter person ID: ");
- person.Id = int.Parse(input.ReadLine());
-
- output.Write("Enter name: ");
- person.Name = input.ReadLine();
-
- output.Write("Enter email address (blank for none): ");
- string email = input.ReadLine();
- if (email.Length > 0)
- {
- person.Email = email;
- }
-
- while (true)
- {
- output.Write("Enter a phone number (or leave blank to finish): ");
- string number = input.ReadLine();
- if (number.Length == 0)
- {
- break;
- }
-
- Person.Types.PhoneNumber phoneNumber = new Person.Types.PhoneNumber { Number = number };
-
- output.Write("Is this a mobile, home, or work phone? ");
- String type = input.ReadLine();
- switch (type)
- {
- case "mobile":
- phoneNumber.Type = Person.Types.PhoneType.Mobile;
- break;
- case "home":
- phoneNumber.Type = Person.Types.PhoneType.Home;
- break;
- case "work":
- phoneNumber.Type = Person.Types.PhoneType.Work;
- break;
- default:
- output.Write("Unknown phone type. Using default.");
- break;
- }
-
- person.Phones.Add(phoneNumber);
- }
- return person;
- }
-
- /// <summary>
- /// Entry point - loads an existing addressbook or creates a new one,
- /// then writes it back to the file.
- /// </summary>
- public static int Main(string[] args)
- {
- if (args.Length != 1)
- {
- Console.Error.WriteLine("Usage: AddPerson ADDRESS_BOOK_FILE");
- return -1;
- }
-
- AddressBook addressBook;
-
- if (File.Exists(args[0]))
- {
- using (Stream file = File.OpenRead(args[0]))
- {
- addressBook = AddressBook.Parser.ParseFrom(file);
- }
- }
- else
- {
- Console.WriteLine("{0}: File not found. Creating a new file.", args[0]);
- addressBook = new AddressBook();
- }
-
- // Add an address.
- addressBook.People.Add(PromptForAddress(Console.In, Console.Out));
-
- // Write the new address book back to disk.
- using (Stream output = File.OpenWrite(args[0]))
- {
- addressBook.WriteTo(output);
- }
- return 0;
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.IO;
+
+namespace Google.Protobuf.Examples.AddressBook
+{
+ internal class AddPerson
+ {
+ /// <summary>
+ /// Builds a person based on user input
+ /// </summary>
+ private static Person PromptForAddress(TextReader input, TextWriter output)
+ {
+ Person person = new Person();
+
+ output.Write("Enter person ID: ");
+ person.Id = int.Parse(input.ReadLine());
+
+ output.Write("Enter name: ");
+ person.Name = input.ReadLine();
+
+ output.Write("Enter email address (blank for none): ");
+ string email = input.ReadLine();
+ if (email.Length > 0)
+ {
+ person.Email = email;
+ }
+
+ while (true)
+ {
+ output.Write("Enter a phone number (or leave blank to finish): ");
+ string number = input.ReadLine();
+ if (number.Length == 0)
+ {
+ break;
+ }
+
+ Person.Types.PhoneNumber phoneNumber = new Person.Types.PhoneNumber { Number = number };
+
+ output.Write("Is this a mobile, home, or work phone? ");
+ String type = input.ReadLine();
+ switch (type)
+ {
+ case "mobile":
+ phoneNumber.Type = Person.Types.PhoneType.Mobile;
+ break;
+ case "home":
+ phoneNumber.Type = Person.Types.PhoneType.Home;
+ break;
+ case "work":
+ phoneNumber.Type = Person.Types.PhoneType.Work;
+ break;
+ default:
+ output.Write("Unknown phone type. Using default.");
+ break;
+ }
+
+ person.Phones.Add(phoneNumber);
+ }
+ return person;
+ }
+
+ /// <summary>
+ /// Entry point - loads an existing addressbook or creates a new one,
+ /// then writes it back to the file.
+ /// </summary>
+ public static int Main(string[] args)
+ {
+ if (args.Length != 1)
+ {
+ Console.Error.WriteLine("Usage: AddPerson ADDRESS_BOOK_FILE");
+ return -1;
+ }
+
+ AddressBook addressBook;
+
+ if (File.Exists(args[0]))
+ {
+ using (Stream file = File.OpenRead(args[0]))
+ {
+ addressBook = AddressBook.Parser.ParseFrom(file);
+ }
+ }
+ else
+ {
+ Console.WriteLine("{0}: File not found. Creating a new file.", args[0]);
+ addressBook = new AddressBook();
+ }
+
+ // Add an address.
+ addressBook.People.Add(PromptForAddress(Console.In, Console.Out));
+
+ // Write the new address book back to disk.
+ using (Stream output = File.OpenWrite(args[0]))
+ {
+ addressBook.WriteTo(output);
+ }
+ return 0;
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/AddressBook/ListPeople.cs b/third_party/protobuf/3.4.0/csharp/src/AddressBook/ListPeople.cs
index 3758c1bce5..71572289d4 100644
--- a/third_party/protobuf/3.4.0/csharp/src/AddressBook/ListPeople.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/AddressBook/ListPeople.cs
@@ -1,99 +1,99 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.IO;
-
-namespace Google.Protobuf.Examples.AddressBook
-{
- internal class ListPeople
- {
- /// <summary>
- /// Iterates though all people in the AddressBook and prints info about them.
- /// </summary>
- private static void Print(AddressBook addressBook)
- {
- foreach (Person person in addressBook.People)
- {
- Console.WriteLine("Person ID: {0}", person.Id);
- Console.WriteLine(" Name: {0}", person.Name);
- if (person.Email != "")
- {
- Console.WriteLine(" E-mail address: {0}", person.Email);
- }
-
- foreach (Person.Types.PhoneNumber phoneNumber in person.Phones)
- {
- switch (phoneNumber.Type)
- {
- case Person.Types.PhoneType.Mobile:
- Console.Write(" Mobile phone #: ");
- break;
- case Person.Types.PhoneType.Home:
- Console.Write(" Home phone #: ");
- break;
- case Person.Types.PhoneType.Work:
- Console.Write(" Work phone #: ");
- break;
- }
- Console.WriteLine(phoneNumber.Number);
- }
- }
- }
-
- /// <summary>
- /// Entry point - loads the addressbook and then displays it.
- /// </summary>
- public static int Main(string[] args)
- {
- if (args.Length != 1)
- {
- Console.Error.WriteLine("Usage: ListPeople ADDRESS_BOOK_FILE");
- return 1;
- }
-
- if (!File.Exists(args[0]))
- {
- Console.WriteLine("{0} doesn't exist. Add a person to create the file first.", args[0]);
- return 0;
- }
-
- // Read the existing address book.
- using (Stream stream = File.OpenRead(args[0]))
- {
- AddressBook addressBook = AddressBook.Parser.ParseFrom(stream);
- Print(addressBook);
- }
- return 0;
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.IO;
+
+namespace Google.Protobuf.Examples.AddressBook
+{
+ internal class ListPeople
+ {
+ /// <summary>
+ /// Iterates though all people in the AddressBook and prints info about them.
+ /// </summary>
+ private static void Print(AddressBook addressBook)
+ {
+ foreach (Person person in addressBook.People)
+ {
+ Console.WriteLine("Person ID: {0}", person.Id);
+ Console.WriteLine(" Name: {0}", person.Name);
+ if (person.Email != "")
+ {
+ Console.WriteLine(" E-mail address: {0}", person.Email);
+ }
+
+ foreach (Person.Types.PhoneNumber phoneNumber in person.Phones)
+ {
+ switch (phoneNumber.Type)
+ {
+ case Person.Types.PhoneType.Mobile:
+ Console.Write(" Mobile phone #: ");
+ break;
+ case Person.Types.PhoneType.Home:
+ Console.Write(" Home phone #: ");
+ break;
+ case Person.Types.PhoneType.Work:
+ Console.Write(" Work phone #: ");
+ break;
+ }
+ Console.WriteLine(phoneNumber.Number);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Entry point - loads the addressbook and then displays it.
+ /// </summary>
+ public static int Main(string[] args)
+ {
+ if (args.Length != 1)
+ {
+ Console.Error.WriteLine("Usage: ListPeople ADDRESS_BOOK_FILE");
+ return 1;
+ }
+
+ if (!File.Exists(args[0]))
+ {
+ Console.WriteLine("{0} doesn't exist. Add a person to create the file first.", args[0]);
+ return 0;
+ }
+
+ // Read the existing address book.
+ using (Stream stream = File.OpenRead(args[0]))
+ {
+ AddressBook addressBook = AddressBook.Parser.ParseFrom(stream);
+ Print(addressBook);
+ }
+ return 0;
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/AddressBook/Program.cs b/third_party/protobuf/3.4.0/csharp/src/AddressBook/Program.cs
index ff7b9c085e..8164f44179 100644
--- a/third_party/protobuf/3.4.0/csharp/src/AddressBook/Program.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/AddressBook/Program.cs
@@ -1,95 +1,95 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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;
-
-namespace Google.Protobuf.Examples.AddressBook
-{
- /// <summary>
- /// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour
- /// to individual actions. Each action has its own Main method, so that it can be used as an
- /// invidual complete program.
- /// </summary>
- internal class Program
- {
- private static int Main(string[] args)
- {
- if (args.Length > 1)
- {
- Console.Error.WriteLine("Usage: AddressBook [file]");
- Console.Error.WriteLine("If the filename isn't specified, \"addressbook.data\" is used instead.");
- return 1;
- }
- string addressBookFile = args.Length > 0 ? args[0] : "addressbook.data";
-
- bool stopping = false;
- while (!stopping)
- {
- Console.WriteLine("Options:");
- Console.WriteLine(" L: List contents");
- Console.WriteLine(" A: Add new person");
- Console.WriteLine(" Q: Quit");
- Console.Write("Action? ");
- Console.Out.Flush();
- char choice = Console.ReadKey().KeyChar;
- Console.WriteLine();
- try
- {
- switch (choice)
- {
- case 'A':
- case 'a':
- AddPerson.Main(new string[] {addressBookFile});
- break;
- case 'L':
- case 'l':
- ListPeople.Main(new string[] {addressBookFile});
- break;
- case 'Q':
- case 'q':
- stopping = true;
- break;
- default:
- Console.WriteLine("Unknown option: {0}", choice);
- break;
- }
- }
- catch (Exception e)
- {
- Console.WriteLine("Exception executing action: {0}", e);
- }
- Console.WriteLine();
- }
- return 0;
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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;
+
+namespace Google.Protobuf.Examples.AddressBook
+{
+ /// <summary>
+ /// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour
+ /// to individual actions. Each action has its own Main method, so that it can be used as an
+ /// invidual complete program.
+ /// </summary>
+ internal class Program
+ {
+ private static int Main(string[] args)
+ {
+ if (args.Length > 1)
+ {
+ Console.Error.WriteLine("Usage: AddressBook [file]");
+ Console.Error.WriteLine("If the filename isn't specified, \"addressbook.data\" is used instead.");
+ return 1;
+ }
+ string addressBookFile = args.Length > 0 ? args[0] : "addressbook.data";
+
+ bool stopping = false;
+ while (!stopping)
+ {
+ Console.WriteLine("Options:");
+ Console.WriteLine(" L: List contents");
+ Console.WriteLine(" A: Add new person");
+ Console.WriteLine(" Q: Quit");
+ Console.Write("Action? ");
+ Console.Out.Flush();
+ char choice = Console.ReadKey().KeyChar;
+ Console.WriteLine();
+ try
+ {
+ switch (choice)
+ {
+ case 'A':
+ case 'a':
+ AddPerson.Main(new string[] {addressBookFile});
+ break;
+ case 'L':
+ case 'l':
+ ListPeople.Main(new string[] {addressBookFile});
+ break;
+ case 'Q':
+ case 'q':
+ stopping = true;
+ break;
+ default:
+ Console.WriteLine("Unknown option: {0}", choice);
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Exception executing action: {0}", e);
+ }
+ Console.WriteLine();
+ }
+ return 0;
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/AddressBook/SampleUsage.cs b/third_party/protobuf/3.4.0/csharp/src/AddressBook/SampleUsage.cs
index 941d865aa4..b4ab8d8f36 100644
--- a/third_party/protobuf/3.4.0/csharp/src/AddressBook/SampleUsage.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/AddressBook/SampleUsage.cs
@@ -1,73 +1,73 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.IO;
-
-namespace Google.Protobuf.Examples.AddressBook
-{
- internal class SampleUsage
- {
- private static void Main()
- {
- byte[] bytes;
- // Create a new person
- Person person = new Person
- {
- Id = 1,
- Name = "Foo",
- Email = "foo@bar",
- Phones = { new Person.Types.PhoneNumber { Number = "555-1212" } }
- };
- using (MemoryStream stream = new MemoryStream())
- {
- // Save the person to a stream
- person.WriteTo(stream);
- bytes = stream.ToArray();
- }
- Person copy = Person.Parser.ParseFrom(bytes);
-
- AddressBook book = new AddressBook
- {
- People = { copy }
- };
- bytes = book.ToByteArray();
- // And read the address book back again
- AddressBook restored = AddressBook.Parser.ParseFrom(bytes);
- // The message performs a deep-comparison on equality:
- if (restored.People.Count != 1 || !person.Equals(restored.People[0]))
- {
- throw new Exception("There is a bad person in here!");
- }
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.IO;
+
+namespace Google.Protobuf.Examples.AddressBook
+{
+ internal class SampleUsage
+ {
+ private static void Main()
+ {
+ byte[] bytes;
+ // Create a new person
+ Person person = new Person
+ {
+ Id = 1,
+ Name = "Foo",
+ Email = "foo@bar",
+ Phones = { new Person.Types.PhoneNumber { Number = "555-1212" } }
+ };
+ using (MemoryStream stream = new MemoryStream())
+ {
+ // Save the person to a stream
+ person.WriteTo(stream);
+ bytes = stream.ToArray();
+ }
+ Person copy = Person.Parser.ParseFrom(bytes);
+
+ AddressBook book = new AddressBook
+ {
+ People = { copy }
+ };
+ bytes = book.ToByteArray();
+ // And read the address book back again
+ AddressBook restored = AddressBook.Parser.ParseFrom(bytes);
+ // The message performs a deep-comparison on equality:
+ if (restored.People.Count != 1 || !person.Equals(restored.People[0]))
+ {
+ throw new Exception("There is a bad person in here!");
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.JsonDump/Program.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.JsonDump/Program.cs
index 296b2f3f1e..56e32ad86e 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.JsonDump/Program.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.JsonDump/Program.cs
@@ -1,73 +1,73 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.IO;
-using System.Reflection;
-
-namespace Google.Protobuf.ProtoDump
-{
- /// <summary>
- /// Small utility to load a binary message and dump it in JSON format.
- /// </summary>
- internal class Program
- {
- private static int Main(string[] args)
- {
- if (args.Length != 2)
- {
- Console.Error.WriteLine("Usage: Google.Protobuf.JsonDump <descriptor type name> <input data>");
- Console.Error.WriteLine("The descriptor type name is the fully-qualified message name,");
- Console.Error.WriteLine("including assembly e.g. ProjectNamespace.Message,Company.Project");
- return 1;
- }
- Type type = Type.GetType(args[0]);
- if (type == null)
- {
- Console.Error.WriteLine("Unable to load type {0}.", args[0]);
- return 1;
- }
- if (!typeof(IMessage).GetTypeInfo().IsAssignableFrom(type))
- {
- Console.Error.WriteLine("Type {0} doesn't implement IMessage.", args[0]);
- return 1;
- }
- IMessage message = (IMessage) Activator.CreateInstance(type);
- using (var input = File.OpenRead(args[1]))
- {
- message.MergeFrom(input);
- }
- Console.WriteLine(message);
- return 0;
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.IO;
+using System.Reflection;
+
+namespace Google.Protobuf.ProtoDump
+{
+ /// <summary>
+ /// Small utility to load a binary message and dump it in JSON format.
+ /// </summary>
+ internal class Program
+ {
+ private static int Main(string[] args)
+ {
+ if (args.Length != 2)
+ {
+ Console.Error.WriteLine("Usage: Google.Protobuf.JsonDump <descriptor type name> <input data>");
+ Console.Error.WriteLine("The descriptor type name is the fully-qualified message name,");
+ Console.Error.WriteLine("including assembly e.g. ProjectNamespace.Message,Company.Project");
+ return 1;
+ }
+ Type type = Type.GetType(args[0]);
+ if (type == null)
+ {
+ Console.Error.WriteLine("Unable to load type {0}.", args[0]);
+ return 1;
+ }
+ if (!typeof(IMessage).GetTypeInfo().IsAssignableFrom(type))
+ {
+ Console.Error.WriteLine("Type {0} doesn't implement IMessage.", args[0]);
+ return 1;
+ }
+ IMessage message = (IMessage) Activator.CreateInstance(type);
+ using (var input = File.OpenRead(args[1]))
+ {
+ message.MergeFrom(input);
+ }
+ Console.WriteLine(message);
+ return 0;
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/ByteStringTest.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/ByteStringTest.cs
index afdd491f36..da467ce519 100755
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/ByteStringTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/ByteStringTest.cs
@@ -1,237 +1,237 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.Text;
-using NUnit.Framework;
-using System.IO;
-#if !NET35
-using System.Threading.Tasks;
-#endif
-
-namespace Google.Protobuf
-{
- public class ByteStringTest
- {
- [Test]
- public void Equality()
- {
- ByteString b1 = ByteString.CopyFrom(1, 2, 3);
- ByteString b2 = ByteString.CopyFrom(1, 2, 3);
- ByteString b3 = ByteString.CopyFrom(1, 2, 4);
- ByteString b4 = ByteString.CopyFrom(1, 2, 3, 4);
- EqualityTester.AssertEquality(b1, b1);
- EqualityTester.AssertEquality(b1, b2);
- EqualityTester.AssertInequality(b1, b3);
- EqualityTester.AssertInequality(b1, b4);
- EqualityTester.AssertInequality(b1, null);
-#pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1)
- Assert.IsTrue(b1 == b1);
- Assert.IsTrue(b1 == b2);
- Assert.IsFalse(b1 == b3);
- Assert.IsFalse(b1 == b4);
- Assert.IsFalse(b1 == null);
- Assert.IsTrue((ByteString) null == null);
- Assert.IsFalse(b1 != b1);
- Assert.IsFalse(b1 != b2);
-#pragma warning disable 1718
- Assert.IsTrue(b1 != b3);
- Assert.IsTrue(b1 != b4);
- Assert.IsTrue(b1 != null);
- Assert.IsFalse((ByteString) null != null);
- }
-
- [Test]
- public void EmptyByteStringHasZeroSize()
- {
- Assert.AreEqual(0, ByteString.Empty.Length);
- }
-
- [Test]
- public void CopyFromStringWithExplicitEncoding()
- {
- ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
- Assert.AreEqual(4, bs.Length);
- Assert.AreEqual(65, bs[0]);
- Assert.AreEqual(0, bs[1]);
- Assert.AreEqual(66, bs[2]);
- Assert.AreEqual(0, bs[3]);
- }
-
- [Test]
- public void IsEmptyWhenEmpty()
- {
- Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
- }
-
- [Test]
- public void IsEmptyWhenNotEmpty()
- {
- Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
- }
-
- [Test]
- public void CopyFromByteArrayCopiesContents()
- {
- byte[] data = new byte[1];
- data[0] = 10;
- ByteString bs = ByteString.CopyFrom(data);
- Assert.AreEqual(10, bs[0]);
- data[0] = 5;
- Assert.AreEqual(10, bs[0]);
- }
-
- [Test]
- public void ToByteArrayCopiesContents()
- {
- ByteString bs = ByteString.CopyFromUtf8("Hello");
- byte[] data = bs.ToByteArray();
- Assert.AreEqual((byte)'H', data[0]);
- Assert.AreEqual((byte)'H', bs[0]);
- data[0] = 0;
- Assert.AreEqual(0, data[0]);
- Assert.AreEqual((byte)'H', bs[0]);
- }
-
- [Test]
- public void CopyFromUtf8UsesUtf8()
- {
- ByteString bs = ByteString.CopyFromUtf8("\u20ac");
- Assert.AreEqual(3, bs.Length);
- Assert.AreEqual(0xe2, bs[0]);
- Assert.AreEqual(0x82, bs[1]);
- Assert.AreEqual(0xac, bs[2]);
- }
-
- [Test]
- public void CopyFromPortion()
- {
- byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
- ByteString bs = ByteString.CopyFrom(data, 2, 3);
- Assert.AreEqual(3, bs.Length);
- Assert.AreEqual(2, bs[0]);
- Assert.AreEqual(3, bs[1]);
- }
-
- [Test]
- public void ToStringUtf8()
- {
- ByteString bs = ByteString.CopyFromUtf8("\u20ac");
- Assert.AreEqual("\u20ac", bs.ToStringUtf8());
- }
-
- [Test]
- public void ToStringWithExplicitEncoding()
- {
- ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
- Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
- }
-
- [Test]
- public void FromBase64_WithText()
- {
- byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
- string base64 = Convert.ToBase64String(data);
- ByteString bs = ByteString.FromBase64(base64);
- Assert.AreEqual(data, bs.ToByteArray());
- }
-
- [Test]
- public void FromBase64_Empty()
- {
- // Optimization which also fixes issue 61.
- Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
- }
-
- [Test]
- public void FromStream_Seekable()
- {
- var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
- // Consume the first byte, just to test that it's "from current position"
- stream.ReadByte();
- var actual = ByteString.FromStream(stream);
- ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
- Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
- }
-
- [Test]
- public void FromStream_NotSeekable()
- {
- var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
- // Consume the first byte, just to test that it's "from current position"
- stream.ReadByte();
- // Wrap the original stream in LimitedInputStream, which has CanSeek=false
- var limitedStream = new LimitedInputStream(stream, 3);
- var actual = ByteString.FromStream(limitedStream);
- ByteString expected = ByteString.CopyFrom(2, 3, 4);
- Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
- }
-
-#if !NET35
- [Test]
- public async Task FromStreamAsync_Seekable()
- {
- var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
- // Consume the first byte, just to test that it's "from current position"
- stream.ReadByte();
- var actual = await ByteString.FromStreamAsync(stream);
- ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
- Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
- }
-
- [Test]
- public async Task FromStreamAsync_NotSeekable()
- {
- var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
- // Consume the first byte, just to test that it's "from current position"
- stream.ReadByte();
- // Wrap the original stream in LimitedInputStream, which has CanSeek=false
- var limitedStream = new LimitedInputStream(stream, 3);
- var actual = await ByteString.FromStreamAsync(limitedStream);
- ByteString expected = ByteString.CopyFrom(2, 3, 4);
- Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
- }
-#endif
-
- [Test]
- public void GetHashCode_Regression()
- {
- // We used to have an awful hash algorithm where only the last four
- // bytes were relevant. This is a regression test for
- // https://github.com/google/protobuf/issues/2511
-
- ByteString b1 = ByteString.CopyFrom(100, 1, 2, 3, 4);
- ByteString b2 = ByteString.CopyFrom(200, 1, 2, 3, 4);
- Assert.AreNotEqual(b1.GetHashCode(), b2.GetHashCode());
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.Text;
+using NUnit.Framework;
+using System.IO;
+#if !NET35
+using System.Threading.Tasks;
+#endif
+
+namespace Google.Protobuf
+{
+ public class ByteStringTest
+ {
+ [Test]
+ public void Equality()
+ {
+ ByteString b1 = ByteString.CopyFrom(1, 2, 3);
+ ByteString b2 = ByteString.CopyFrom(1, 2, 3);
+ ByteString b3 = ByteString.CopyFrom(1, 2, 4);
+ ByteString b4 = ByteString.CopyFrom(1, 2, 3, 4);
+ EqualityTester.AssertEquality(b1, b1);
+ EqualityTester.AssertEquality(b1, b2);
+ EqualityTester.AssertInequality(b1, b3);
+ EqualityTester.AssertInequality(b1, b4);
+ EqualityTester.AssertInequality(b1, null);
+#pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1)
+ Assert.IsTrue(b1 == b1);
+ Assert.IsTrue(b1 == b2);
+ Assert.IsFalse(b1 == b3);
+ Assert.IsFalse(b1 == b4);
+ Assert.IsFalse(b1 == null);
+ Assert.IsTrue((ByteString) null == null);
+ Assert.IsFalse(b1 != b1);
+ Assert.IsFalse(b1 != b2);
+#pragma warning disable 1718
+ Assert.IsTrue(b1 != b3);
+ Assert.IsTrue(b1 != b4);
+ Assert.IsTrue(b1 != null);
+ Assert.IsFalse((ByteString) null != null);
+ }
+
+ [Test]
+ public void EmptyByteStringHasZeroSize()
+ {
+ Assert.AreEqual(0, ByteString.Empty.Length);
+ }
+
+ [Test]
+ public void CopyFromStringWithExplicitEncoding()
+ {
+ ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
+ Assert.AreEqual(4, bs.Length);
+ Assert.AreEqual(65, bs[0]);
+ Assert.AreEqual(0, bs[1]);
+ Assert.AreEqual(66, bs[2]);
+ Assert.AreEqual(0, bs[3]);
+ }
+
+ [Test]
+ public void IsEmptyWhenEmpty()
+ {
+ Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
+ }
+
+ [Test]
+ public void IsEmptyWhenNotEmpty()
+ {
+ Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
+ }
+
+ [Test]
+ public void CopyFromByteArrayCopiesContents()
+ {
+ byte[] data = new byte[1];
+ data[0] = 10;
+ ByteString bs = ByteString.CopyFrom(data);
+ Assert.AreEqual(10, bs[0]);
+ data[0] = 5;
+ Assert.AreEqual(10, bs[0]);
+ }
+
+ [Test]
+ public void ToByteArrayCopiesContents()
+ {
+ ByteString bs = ByteString.CopyFromUtf8("Hello");
+ byte[] data = bs.ToByteArray();
+ Assert.AreEqual((byte)'H', data[0]);
+ Assert.AreEqual((byte)'H', bs[0]);
+ data[0] = 0;
+ Assert.AreEqual(0, data[0]);
+ Assert.AreEqual((byte)'H', bs[0]);
+ }
+
+ [Test]
+ public void CopyFromUtf8UsesUtf8()
+ {
+ ByteString bs = ByteString.CopyFromUtf8("\u20ac");
+ Assert.AreEqual(3, bs.Length);
+ Assert.AreEqual(0xe2, bs[0]);
+ Assert.AreEqual(0x82, bs[1]);
+ Assert.AreEqual(0xac, bs[2]);
+ }
+
+ [Test]
+ public void CopyFromPortion()
+ {
+ byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
+ ByteString bs = ByteString.CopyFrom(data, 2, 3);
+ Assert.AreEqual(3, bs.Length);
+ Assert.AreEqual(2, bs[0]);
+ Assert.AreEqual(3, bs[1]);
+ }
+
+ [Test]
+ public void ToStringUtf8()
+ {
+ ByteString bs = ByteString.CopyFromUtf8("\u20ac");
+ Assert.AreEqual("\u20ac", bs.ToStringUtf8());
+ }
+
+ [Test]
+ public void ToStringWithExplicitEncoding()
+ {
+ ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
+ Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
+ }
+
+ [Test]
+ public void FromBase64_WithText()
+ {
+ byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
+ string base64 = Convert.ToBase64String(data);
+ ByteString bs = ByteString.FromBase64(base64);
+ Assert.AreEqual(data, bs.ToByteArray());
+ }
+
+ [Test]
+ public void FromBase64_Empty()
+ {
+ // Optimization which also fixes issue 61.
+ Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
+ }
+
+ [Test]
+ public void FromStream_Seekable()
+ {
+ var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
+ // Consume the first byte, just to test that it's "from current position"
+ stream.ReadByte();
+ var actual = ByteString.FromStream(stream);
+ ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
+ Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
+ }
+
+ [Test]
+ public void FromStream_NotSeekable()
+ {
+ var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
+ // Consume the first byte, just to test that it's "from current position"
+ stream.ReadByte();
+ // Wrap the original stream in LimitedInputStream, which has CanSeek=false
+ var limitedStream = new LimitedInputStream(stream, 3);
+ var actual = ByteString.FromStream(limitedStream);
+ ByteString expected = ByteString.CopyFrom(2, 3, 4);
+ Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
+ }
+
+#if !NET35
+ [Test]
+ public async Task FromStreamAsync_Seekable()
+ {
+ var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
+ // Consume the first byte, just to test that it's "from current position"
+ stream.ReadByte();
+ var actual = await ByteString.FromStreamAsync(stream);
+ ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
+ Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
+ }
+
+ [Test]
+ public async Task FromStreamAsync_NotSeekable()
+ {
+ var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
+ // Consume the first byte, just to test that it's "from current position"
+ stream.ReadByte();
+ // Wrap the original stream in LimitedInputStream, which has CanSeek=false
+ var limitedStream = new LimitedInputStream(stream, 3);
+ var actual = await ByteString.FromStreamAsync(limitedStream);
+ ByteString expected = ByteString.CopyFrom(2, 3, 4);
+ Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
+ }
+#endif
+
+ [Test]
+ public void GetHashCode_Regression()
+ {
+ // We used to have an awful hash algorithm where only the last four
+ // bytes were relevant. This is a regression test for
+ // https://github.com/google/protobuf/issues/2511
+
+ ByteString b1 = ByteString.CopyFrom(100, 1, 2, 3, 4);
+ ByteString b2 = ByteString.CopyFrom(200, 1, 2, 3, 4);
+ Assert.AreNotEqual(b1.GetHashCode(), b2.GetHashCode());
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
index e719d2a090..65bc871a50 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
@@ -1,605 +1,605 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.IO;
-using Google.Protobuf.TestProtos;
-using NUnit.Framework;
-
-namespace Google.Protobuf
-{
- public class CodedInputStreamTest
- {
- /// <summary>
- /// Helper to construct a byte array from a bunch of bytes. The inputs are
- /// actually ints so that I can use hex notation and not get stupid errors
- /// about precision.
- /// </summary>
- private static byte[] Bytes(params int[] bytesAsInts)
- {
- byte[] bytes = new byte[bytesAsInts.Length];
- for (int i = 0; i < bytesAsInts.Length; i++)
- {
- bytes[i] = (byte) bytesAsInts[i];
- }
- return bytes;
- }
-
- /// <summary>
- /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64()
- /// </summary>
- private static void AssertReadVarint(byte[] data, ulong value)
- {
- CodedInputStream input = new CodedInputStream(data);
- Assert.AreEqual((uint) value, input.ReadRawVarint32());
-
- input = new CodedInputStream(data);
- Assert.AreEqual(value, input.ReadRawVarint64());
- Assert.IsTrue(input.IsAtEnd);
-
- // Try different block sizes.
- for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
- {
- input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
- Assert.AreEqual((uint) value, input.ReadRawVarint32());
-
- input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
- Assert.AreEqual(value, input.ReadRawVarint64());
- Assert.IsTrue(input.IsAtEnd);
- }
-
- // Try reading directly from a MemoryStream. We want to verify that it
- // doesn't read past the end of the input, so write an extra byte - this
- // lets us test the position at the end.
- MemoryStream memoryStream = new MemoryStream();
- memoryStream.Write(data, 0, data.Length);
- memoryStream.WriteByte(0);
- memoryStream.Position = 0;
- Assert.AreEqual((uint) value, CodedInputStream.ReadRawVarint32(memoryStream));
- Assert.AreEqual(data.Length, memoryStream.Position);
- }
-
- /// <summary>
- /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
- /// expects them to fail with an InvalidProtocolBufferException whose
- /// description matches the given one.
- /// </summary>
- private static void AssertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data)
- {
- CodedInputStream input = new CodedInputStream(data);
- var exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint32());
- Assert.AreEqual(expected.Message, exception.Message);
-
- input = new CodedInputStream(data);
- exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint64());
- Assert.AreEqual(expected.Message, exception.Message);
-
- // Make sure we get the same error when reading directly from a Stream.
- exception = Assert.Throws<InvalidProtocolBufferException>(() => CodedInputStream.ReadRawVarint32(new MemoryStream(data)));
- Assert.AreEqual(expected.Message, exception.Message);
- }
-
- [Test]
- public void ReadVarint()
- {
- AssertReadVarint(Bytes(0x00), 0);
- AssertReadVarint(Bytes(0x01), 1);
- AssertReadVarint(Bytes(0x7f), 127);
- // 14882
- AssertReadVarint(Bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
- // 2961488830
- AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
- (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
- (0x0bL << 28));
-
- // 64-bit
- // 7256456126
- AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
- (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
- (0x1bL << 28));
- // 41256202580718336
- AssertReadVarint(Bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
- (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
- (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
- // 11964378330978735131
- AssertReadVarint(Bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
- (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
- (0x3bUL << 28) | (0x56UL << 35) | (0x00UL << 42) |
- (0x05UL << 49) | (0x26UL << 56) | (0x01UL << 63));
-
- // Failures
- AssertReadVarintFailure(
- InvalidProtocolBufferException.MalformedVarint(),
- Bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x00));
- AssertReadVarintFailure(
- InvalidProtocolBufferException.TruncatedMessage(),
- Bytes(0x80));
- }
-
- /// <summary>
- /// Parses the given bytes using ReadRawLittleEndian32() and checks
- /// that the result matches the given value.
- /// </summary>
- private static void AssertReadLittleEndian32(byte[] data, uint value)
- {
- CodedInputStream input = new CodedInputStream(data);
- Assert.AreEqual(value, input.ReadRawLittleEndian32());
- Assert.IsTrue(input.IsAtEnd);
-
- // Try different block sizes.
- for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
- {
- input = new CodedInputStream(
- new SmallBlockInputStream(data, blockSize));
- Assert.AreEqual(value, input.ReadRawLittleEndian32());
- Assert.IsTrue(input.IsAtEnd);
- }
- }
-
- /// <summary>
- /// Parses the given bytes using ReadRawLittleEndian64() and checks
- /// that the result matches the given value.
- /// </summary>
- private static void AssertReadLittleEndian64(byte[] data, ulong value)
- {
- CodedInputStream input = new CodedInputStream(data);
- Assert.AreEqual(value, input.ReadRawLittleEndian64());
- Assert.IsTrue(input.IsAtEnd);
-
- // Try different block sizes.
- for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
- {
- input = new CodedInputStream(
- new SmallBlockInputStream(data, blockSize));
- Assert.AreEqual(value, input.ReadRawLittleEndian64());
- Assert.IsTrue(input.IsAtEnd);
- }
- }
-
- [Test]
- public void ReadLittleEndian()
- {
- AssertReadLittleEndian32(Bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
- AssertReadLittleEndian32(Bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
-
- AssertReadLittleEndian64(Bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
- 0x123456789abcdef0L);
- AssertReadLittleEndian64(
- Bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef012345678UL);
- }
-
- [Test]
- public void DecodeZigZag32()
- {
- Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(0));
- Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(1));
- Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(2));
- Assert.AreEqual(-2, CodedInputStream.DecodeZigZag32(3));
- Assert.AreEqual(0x3FFFFFFF, CodedInputStream.DecodeZigZag32(0x7FFFFFFE));
- Assert.AreEqual(unchecked((int) 0xC0000000), CodedInputStream.DecodeZigZag32(0x7FFFFFFF));
- Assert.AreEqual(0x7FFFFFFF, CodedInputStream.DecodeZigZag32(0xFFFFFFFE));
- Assert.AreEqual(unchecked((int) 0x80000000), CodedInputStream.DecodeZigZag32(0xFFFFFFFF));
- }
-
- [Test]
- public void DecodeZigZag64()
- {
- Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(0));
- Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(1));
- Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(2));
- Assert.AreEqual(-2, CodedInputStream.DecodeZigZag64(3));
- Assert.AreEqual(0x000000003FFFFFFFL, CodedInputStream.DecodeZigZag64(0x000000007FFFFFFEL));
- Assert.AreEqual(unchecked((long) 0xFFFFFFFFC0000000L), CodedInputStream.DecodeZigZag64(0x000000007FFFFFFFL));
- Assert.AreEqual(0x000000007FFFFFFFL, CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFEL));
- Assert.AreEqual(unchecked((long) 0xFFFFFFFF80000000L), CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFFL));
- Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL));
- Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL));
- }
-
- [Test]
- public void ReadWholeMessage_VaryingBlockSizes()
- {
- TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
-
- byte[] rawBytes = message.ToByteArray();
- 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.Parser.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize));
- Assert.AreEqual(message, message2);
- }
- }
-
- [Test]
- public void ReadHugeBlob()
- {
- // Allocate and initialize a 1MB blob.
- byte[] blob = new byte[1 << 20];
- for (int i = 0; i < blob.Length; i++)
- {
- blob[i] = (byte) i;
- }
-
- // Make a message containing it.
- 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.Parser.ParseFrom(message.ToByteString());
-
- Assert.AreEqual(message, message2);
- }
-
- [Test]
- public void ReadMaliciouslyLargeBlob()
- {
- MemoryStream ms = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(ms);
-
- uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteRawVarint32(tag);
- output.WriteRawVarint32(0x7FFFFFFF);
- output.WriteRawBytes(new byte[32]); // Pad with a few random bytes.
- output.Flush();
- ms.Position = 0;
-
- CodedInputStream input = new CodedInputStream(ms);
- Assert.AreEqual(tag, input.ReadTag());
-
- Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
- }
-
- internal static TestRecursiveMessage MakeRecursiveMessage(int depth)
- {
- if (depth == 0)
- {
- return new TestRecursiveMessage { I = 5 };
- }
- else
- {
- return new TestRecursiveMessage { A = MakeRecursiveMessage(depth - 1) };
- }
- }
-
- internal static void AssertMessageDepth(TestRecursiveMessage message, int depth)
- {
- if (depth == 0)
- {
- Assert.IsNull(message.A);
- Assert.AreEqual(5, message.I);
- }
- else
- {
- Assert.IsNotNull(message.A);
- AssertMessageDepth(message.A, depth - 1);
- }
- }
-
- [Test]
- public void MaliciousRecursion()
- {
- ByteString data64 = MakeRecursiveMessage(64).ToByteString();
- ByteString data65 = MakeRecursiveMessage(65).ToByteString();
-
- AssertMessageDepth(TestRecursiveMessage.Parser.ParseFrom(data64), 64);
-
- Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(data65));
-
- CodedInputStream input = CodedInputStream.CreateWithLimits(new MemoryStream(data64.ToByteArray()), 1000000, 63);
- Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(input));
- }
-
- [Test]
- public void SizeLimit()
- {
- // Have to use a Stream rather than ByteString.CreateCodedInput as SizeLimit doesn't
- // apply to the latter case.
- MemoryStream ms = new MemoryStream(SampleMessages.CreateFullTestAllTypes().ToByteArray());
- CodedInputStream input = CodedInputStream.CreateWithLimits(ms, 16, 100);
- Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(input));
- }
-
- /// <summary>
- /// Tests that if we read an string that contains invalid UTF-8, no exception
- /// is thrown. Instead, the invalid bytes are replaced with the Unicode
- /// "replacement character" U+FFFD.
- /// </summary>
- [Test]
- public void ReadInvalidUtf8()
- {
- MemoryStream ms = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(ms);
-
- uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteRawVarint32(tag);
- output.WriteRawVarint32(1);
- output.WriteRawBytes(new byte[] {0x80});
- output.Flush();
- ms.Position = 0;
-
- CodedInputStream input = new CodedInputStream(ms);
-
- Assert.AreEqual(tag, input.ReadTag());
- string text = input.ReadString();
- Assert.AreEqual('\ufffd', text[0]);
- }
-
- /// <summary>
- /// A stream which limits the number of bytes it reads at a time.
- /// We use this to make sure that CodedInputStream doesn't screw up when
- /// reading in small blocks.
- /// </summary>
- private sealed class SmallBlockInputStream : MemoryStream
- {
- private readonly int blockSize;
-
- public SmallBlockInputStream(byte[] data, int blockSize)
- : base(data)
- {
- this.blockSize = blockSize;
- }
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- return base.Read(buffer, offset, Math.Min(count, blockSize));
- }
- }
-
- [Test]
- public void TestNegativeEnum()
- {
- byte[] bytes = { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };
- CodedInputStream input = new CodedInputStream(bytes);
- Assert.AreEqual((int)SampleEnum.NegativeValue, input.ReadEnum());
- Assert.IsTrue(input.IsAtEnd);
- }
-
- //Issue 71: CodedInputStream.ReadBytes go to slow path unnecessarily
- [Test]
- public void TestSlowPathAvoidance()
- {
- using (var ms = new MemoryStream())
- {
- CodedOutputStream output = new CodedOutputStream(ms);
- output.WriteTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteBytes(ByteString.CopyFrom(new byte[100]));
- output.WriteTag(2, WireFormat.WireType.LengthDelimited);
- output.WriteBytes(ByteString.CopyFrom(new byte[100]));
- output.Flush();
-
- ms.Position = 0;
- CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);
-
- uint tag = input.ReadTag();
- Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
- Assert.AreEqual(100, input.ReadBytes().Length);
-
- tag = input.ReadTag();
- Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
- Assert.AreEqual(100, input.ReadBytes().Length);
- }
- }
-
- [Test]
- public void Tag0Throws()
- {
- var input = new CodedInputStream(new byte[] { 0 });
- Assert.Throws<InvalidProtocolBufferException>(() => input.ReadTag());
- }
-
- [Test]
- public void SkipGroup()
- {
- // Create an output stream with a group in:
- // Field 1: string "field 1"
- // Field 2: group containing:
- // Field 1: fixed int32 value 100
- // Field 2: string "ignore me"
- // Field 3: nested group containing
- // Field 1: fixed int64 value 1000
- // Field 3: string "field 3"
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- output.WriteTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteString("field 1");
-
- // The outer group...
- output.WriteTag(2, WireFormat.WireType.StartGroup);
- output.WriteTag(1, WireFormat.WireType.Fixed32);
- output.WriteFixed32(100);
- output.WriteTag(2, WireFormat.WireType.LengthDelimited);
- output.WriteString("ignore me");
- // The nested group...
- output.WriteTag(3, WireFormat.WireType.StartGroup);
- output.WriteTag(1, WireFormat.WireType.Fixed64);
- output.WriteFixed64(1000);
- // Note: Not sure the field number is relevant for end group...
- output.WriteTag(3, WireFormat.WireType.EndGroup);
-
- // End the outer group
- output.WriteTag(2, WireFormat.WireType.EndGroup);
-
- output.WriteTag(3, WireFormat.WireType.LengthDelimited);
- output.WriteString("field 3");
- output.Flush();
- stream.Position = 0;
-
- // Now act like a generated client
- var input = new CodedInputStream(stream);
- Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
- Assert.AreEqual("field 1", input.ReadString());
- Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
- input.SkipLastField(); // Should consume the whole group, including the nested one.
- Assert.AreEqual(WireFormat.MakeTag(3, WireFormat.WireType.LengthDelimited), input.ReadTag());
- Assert.AreEqual("field 3", input.ReadString());
- }
-
- [Test]
- public void SkipGroup_WrongEndGroupTag()
- {
- // Create an output stream with:
- // Field 1: string "field 1"
- // Start group 2
- // Field 3: fixed int32
- // End group 4 (should give an error)
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- output.WriteTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteString("field 1");
-
- // The outer group...
- output.WriteTag(2, WireFormat.WireType.StartGroup);
- output.WriteTag(3, WireFormat.WireType.Fixed32);
- output.WriteFixed32(100);
- output.WriteTag(4, WireFormat.WireType.EndGroup);
- output.Flush();
- stream.Position = 0;
-
- // Now act like a generated client
- var input = new CodedInputStream(stream);
- Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
- Assert.AreEqual("field 1", input.ReadString());
- Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
- Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
- }
-
- [Test]
- public void RogueEndGroupTag()
- {
- // If we have an end-group tag without a leading start-group tag, generated
- // code will just call SkipLastField... so that should fail.
-
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- output.WriteTag(1, WireFormat.WireType.EndGroup);
- output.Flush();
- stream.Position = 0;
-
- var input = new CodedInputStream(stream);
- Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.EndGroup), input.ReadTag());
- Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
- }
-
- [Test]
- public void EndOfStreamReachedWhileSkippingGroup()
- {
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- output.WriteTag(1, WireFormat.WireType.StartGroup);
- output.WriteTag(2, WireFormat.WireType.StartGroup);
- output.WriteTag(2, WireFormat.WireType.EndGroup);
-
- output.Flush();
- stream.Position = 0;
-
- // Now act like a generated client
- var input = new CodedInputStream(stream);
- input.ReadTag();
- Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
- }
-
- [Test]
- public void RecursionLimitAppliedWhileSkippingGroup()
- {
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
- {
- output.WriteTag(1, WireFormat.WireType.StartGroup);
- }
- for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
- {
- output.WriteTag(1, WireFormat.WireType.EndGroup);
- }
- output.Flush();
- stream.Position = 0;
-
- // Now act like a generated client
- var input = new CodedInputStream(stream);
- Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.StartGroup), input.ReadTag());
- Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
- }
-
- [Test]
- public void Construction_Invalid()
- {
- Assert.Throws<ArgumentNullException>(() => new CodedInputStream((byte[]) null));
- Assert.Throws<ArgumentNullException>(() => new CodedInputStream(null, 0, 0));
- Assert.Throws<ArgumentNullException>(() => new CodedInputStream((Stream) null));
- Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 100, 0));
- Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 5, 10));
- }
-
- [Test]
- public void CreateWithLimits_InvalidLimits()
- {
- var stream = new MemoryStream();
- Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 0, 1));
- Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 1, 0));
- }
-
- [Test]
- public void Dispose_DisposesUnderlyingStream()
- {
- var memoryStream = new MemoryStream();
- Assert.IsTrue(memoryStream.CanRead);
- using (var cis = new CodedInputStream(memoryStream))
- {
- }
- Assert.IsFalse(memoryStream.CanRead); // Disposed
- }
-
- [Test]
- public void Dispose_WithLeaveOpen()
- {
- var memoryStream = new MemoryStream();
- Assert.IsTrue(memoryStream.CanRead);
- using (var cis = new CodedInputStream(memoryStream, true))
- {
- }
- Assert.IsTrue(memoryStream.CanRead); // We left the stream open
- }
-
- [Test]
- public void Dispose_FromByteArray()
- {
- var stream = new CodedInputStream(new byte[10]);
- stream.Dispose();
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.IO;
+using Google.Protobuf.TestProtos;
+using NUnit.Framework;
+
+namespace Google.Protobuf
+{
+ public class CodedInputStreamTest
+ {
+ /// <summary>
+ /// Helper to construct a byte array from a bunch of bytes. The inputs are
+ /// actually ints so that I can use hex notation and not get stupid errors
+ /// about precision.
+ /// </summary>
+ private static byte[] Bytes(params int[] bytesAsInts)
+ {
+ byte[] bytes = new byte[bytesAsInts.Length];
+ for (int i = 0; i < bytesAsInts.Length; i++)
+ {
+ bytes[i] = (byte) bytesAsInts[i];
+ }
+ return bytes;
+ }
+
+ /// <summary>
+ /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64()
+ /// </summary>
+ private static void AssertReadVarint(byte[] data, ulong value)
+ {
+ CodedInputStream input = new CodedInputStream(data);
+ Assert.AreEqual((uint) value, input.ReadRawVarint32());
+
+ input = new CodedInputStream(data);
+ Assert.AreEqual(value, input.ReadRawVarint64());
+ Assert.IsTrue(input.IsAtEnd);
+
+ // Try different block sizes.
+ for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
+ {
+ input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
+ Assert.AreEqual((uint) value, input.ReadRawVarint32());
+
+ input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize));
+ Assert.AreEqual(value, input.ReadRawVarint64());
+ Assert.IsTrue(input.IsAtEnd);
+ }
+
+ // Try reading directly from a MemoryStream. We want to verify that it
+ // doesn't read past the end of the input, so write an extra byte - this
+ // lets us test the position at the end.
+ MemoryStream memoryStream = new MemoryStream();
+ memoryStream.Write(data, 0, data.Length);
+ memoryStream.WriteByte(0);
+ memoryStream.Position = 0;
+ Assert.AreEqual((uint) value, CodedInputStream.ReadRawVarint32(memoryStream));
+ Assert.AreEqual(data.Length, memoryStream.Position);
+ }
+
+ /// <summary>
+ /// Parses the given bytes using ReadRawVarint32() and ReadRawVarint64() and
+ /// expects them to fail with an InvalidProtocolBufferException whose
+ /// description matches the given one.
+ /// </summary>
+ private static void AssertReadVarintFailure(InvalidProtocolBufferException expected, byte[] data)
+ {
+ CodedInputStream input = new CodedInputStream(data);
+ var exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint32());
+ Assert.AreEqual(expected.Message, exception.Message);
+
+ input = new CodedInputStream(data);
+ exception = Assert.Throws<InvalidProtocolBufferException>(() => input.ReadRawVarint64());
+ Assert.AreEqual(expected.Message, exception.Message);
+
+ // Make sure we get the same error when reading directly from a Stream.
+ exception = Assert.Throws<InvalidProtocolBufferException>(() => CodedInputStream.ReadRawVarint32(new MemoryStream(data)));
+ Assert.AreEqual(expected.Message, exception.Message);
+ }
+
+ [Test]
+ public void ReadVarint()
+ {
+ AssertReadVarint(Bytes(0x00), 0);
+ AssertReadVarint(Bytes(0x01), 1);
+ AssertReadVarint(Bytes(0x7f), 127);
+ // 14882
+ AssertReadVarint(Bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
+ // 2961488830
+ AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x0bL << 28));
+
+ // 64-bit
+ // 7256456126
+ AssertReadVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x1bL << 28));
+ // 41256202580718336
+ AssertReadVarint(Bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
+ (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+ (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
+ // 11964378330978735131
+ AssertReadVarint(Bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
+ (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+ (0x3bUL << 28) | (0x56UL << 35) | (0x00UL << 42) |
+ (0x05UL << 49) | (0x26UL << 56) | (0x01UL << 63));
+
+ // Failures
+ AssertReadVarintFailure(
+ InvalidProtocolBufferException.MalformedVarint(),
+ Bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x00));
+ AssertReadVarintFailure(
+ InvalidProtocolBufferException.TruncatedMessage(),
+ Bytes(0x80));
+ }
+
+ /// <summary>
+ /// Parses the given bytes using ReadRawLittleEndian32() and checks
+ /// that the result matches the given value.
+ /// </summary>
+ private static void AssertReadLittleEndian32(byte[] data, uint value)
+ {
+ CodedInputStream input = new CodedInputStream(data);
+ Assert.AreEqual(value, input.ReadRawLittleEndian32());
+ Assert.IsTrue(input.IsAtEnd);
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
+ {
+ input = new CodedInputStream(
+ new SmallBlockInputStream(data, blockSize));
+ Assert.AreEqual(value, input.ReadRawLittleEndian32());
+ Assert.IsTrue(input.IsAtEnd);
+ }
+ }
+
+ /// <summary>
+ /// Parses the given bytes using ReadRawLittleEndian64() and checks
+ /// that the result matches the given value.
+ /// </summary>
+ private static void AssertReadLittleEndian64(byte[] data, ulong value)
+ {
+ CodedInputStream input = new CodedInputStream(data);
+ Assert.AreEqual(value, input.ReadRawLittleEndian64());
+ Assert.IsTrue(input.IsAtEnd);
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
+ {
+ input = new CodedInputStream(
+ new SmallBlockInputStream(data, blockSize));
+ Assert.AreEqual(value, input.ReadRawLittleEndian64());
+ Assert.IsTrue(input.IsAtEnd);
+ }
+ }
+
+ [Test]
+ public void ReadLittleEndian()
+ {
+ AssertReadLittleEndian32(Bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
+ AssertReadLittleEndian32(Bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
+
+ AssertReadLittleEndian64(Bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
+ 0x123456789abcdef0L);
+ AssertReadLittleEndian64(
+ Bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef012345678UL);
+ }
+
+ [Test]
+ public void DecodeZigZag32()
+ {
+ Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(0));
+ Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(1));
+ Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(2));
+ Assert.AreEqual(-2, CodedInputStream.DecodeZigZag32(3));
+ Assert.AreEqual(0x3FFFFFFF, CodedInputStream.DecodeZigZag32(0x7FFFFFFE));
+ Assert.AreEqual(unchecked((int) 0xC0000000), CodedInputStream.DecodeZigZag32(0x7FFFFFFF));
+ Assert.AreEqual(0x7FFFFFFF, CodedInputStream.DecodeZigZag32(0xFFFFFFFE));
+ Assert.AreEqual(unchecked((int) 0x80000000), CodedInputStream.DecodeZigZag32(0xFFFFFFFF));
+ }
+
+ [Test]
+ public void DecodeZigZag64()
+ {
+ Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(0));
+ Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(1));
+ Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(2));
+ Assert.AreEqual(-2, CodedInputStream.DecodeZigZag64(3));
+ Assert.AreEqual(0x000000003FFFFFFFL, CodedInputStream.DecodeZigZag64(0x000000007FFFFFFEL));
+ Assert.AreEqual(unchecked((long) 0xFFFFFFFFC0000000L), CodedInputStream.DecodeZigZag64(0x000000007FFFFFFFL));
+ Assert.AreEqual(0x000000007FFFFFFFL, CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFEL));
+ Assert.AreEqual(unchecked((long) 0xFFFFFFFF80000000L), CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFFL));
+ Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL));
+ Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL));
+ }
+
+ [Test]
+ public void ReadWholeMessage_VaryingBlockSizes()
+ {
+ TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
+
+ byte[] rawBytes = message.ToByteArray();
+ 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.Parser.ParseFrom(new SmallBlockInputStream(rawBytes, blockSize));
+ Assert.AreEqual(message, message2);
+ }
+ }
+
+ [Test]
+ public void ReadHugeBlob()
+ {
+ // Allocate and initialize a 1MB blob.
+ byte[] blob = new byte[1 << 20];
+ for (int i = 0; i < blob.Length; i++)
+ {
+ blob[i] = (byte) i;
+ }
+
+ // Make a message containing it.
+ 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.Parser.ParseFrom(message.ToByteString());
+
+ Assert.AreEqual(message, message2);
+ }
+
+ [Test]
+ public void ReadMaliciouslyLargeBlob()
+ {
+ MemoryStream ms = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(ms);
+
+ uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteRawVarint32(tag);
+ output.WriteRawVarint32(0x7FFFFFFF);
+ output.WriteRawBytes(new byte[32]); // Pad with a few random bytes.
+ output.Flush();
+ ms.Position = 0;
+
+ CodedInputStream input = new CodedInputStream(ms);
+ Assert.AreEqual(tag, input.ReadTag());
+
+ Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
+ }
+
+ internal static TestRecursiveMessage MakeRecursiveMessage(int depth)
+ {
+ if (depth == 0)
+ {
+ return new TestRecursiveMessage { I = 5 };
+ }
+ else
+ {
+ return new TestRecursiveMessage { A = MakeRecursiveMessage(depth - 1) };
+ }
+ }
+
+ internal static void AssertMessageDepth(TestRecursiveMessage message, int depth)
+ {
+ if (depth == 0)
+ {
+ Assert.IsNull(message.A);
+ Assert.AreEqual(5, message.I);
+ }
+ else
+ {
+ Assert.IsNotNull(message.A);
+ AssertMessageDepth(message.A, depth - 1);
+ }
+ }
+
+ [Test]
+ public void MaliciousRecursion()
+ {
+ ByteString data64 = MakeRecursiveMessage(64).ToByteString();
+ ByteString data65 = MakeRecursiveMessage(65).ToByteString();
+
+ AssertMessageDepth(TestRecursiveMessage.Parser.ParseFrom(data64), 64);
+
+ Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(data65));
+
+ CodedInputStream input = CodedInputStream.CreateWithLimits(new MemoryStream(data64.ToByteArray()), 1000000, 63);
+ Assert.Throws<InvalidProtocolBufferException>(() => TestRecursiveMessage.Parser.ParseFrom(input));
+ }
+
+ [Test]
+ public void SizeLimit()
+ {
+ // Have to use a Stream rather than ByteString.CreateCodedInput as SizeLimit doesn't
+ // apply to the latter case.
+ MemoryStream ms = new MemoryStream(SampleMessages.CreateFullTestAllTypes().ToByteArray());
+ CodedInputStream input = CodedInputStream.CreateWithLimits(ms, 16, 100);
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(input));
+ }
+
+ /// <summary>
+ /// Tests that if we read an string that contains invalid UTF-8, no exception
+ /// is thrown. Instead, the invalid bytes are replaced with the Unicode
+ /// "replacement character" U+FFFD.
+ /// </summary>
+ [Test]
+ public void ReadInvalidUtf8()
+ {
+ MemoryStream ms = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(ms);
+
+ uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteRawVarint32(tag);
+ output.WriteRawVarint32(1);
+ output.WriteRawBytes(new byte[] {0x80});
+ output.Flush();
+ ms.Position = 0;
+
+ CodedInputStream input = new CodedInputStream(ms);
+
+ Assert.AreEqual(tag, input.ReadTag());
+ string text = input.ReadString();
+ Assert.AreEqual('\ufffd', text[0]);
+ }
+
+ /// <summary>
+ /// A stream which limits the number of bytes it reads at a time.
+ /// We use this to make sure that CodedInputStream doesn't screw up when
+ /// reading in small blocks.
+ /// </summary>
+ private sealed class SmallBlockInputStream : MemoryStream
+ {
+ private readonly int blockSize;
+
+ public SmallBlockInputStream(byte[] data, int blockSize)
+ : base(data)
+ {
+ this.blockSize = blockSize;
+ }
+
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ return base.Read(buffer, offset, Math.Min(count, blockSize));
+ }
+ }
+
+ [Test]
+ public void TestNegativeEnum()
+ {
+ byte[] bytes = { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };
+ CodedInputStream input = new CodedInputStream(bytes);
+ Assert.AreEqual((int)SampleEnum.NegativeValue, input.ReadEnum());
+ Assert.IsTrue(input.IsAtEnd);
+ }
+
+ //Issue 71: CodedInputStream.ReadBytes go to slow path unnecessarily
+ [Test]
+ public void TestSlowPathAvoidance()
+ {
+ using (var ms = new MemoryStream())
+ {
+ CodedOutputStream output = new CodedOutputStream(ms);
+ output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteBytes(ByteString.CopyFrom(new byte[100]));
+ output.WriteTag(2, WireFormat.WireType.LengthDelimited);
+ output.WriteBytes(ByteString.CopyFrom(new byte[100]));
+ output.Flush();
+
+ ms.Position = 0;
+ CodedInputStream input = new CodedInputStream(ms, new byte[ms.Length / 2], 0, 0, false);
+
+ uint tag = input.ReadTag();
+ Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
+ Assert.AreEqual(100, input.ReadBytes().Length);
+
+ tag = input.ReadTag();
+ Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
+ Assert.AreEqual(100, input.ReadBytes().Length);
+ }
+ }
+
+ [Test]
+ public void Tag0Throws()
+ {
+ var input = new CodedInputStream(new byte[] { 0 });
+ Assert.Throws<InvalidProtocolBufferException>(() => input.ReadTag());
+ }
+
+ [Test]
+ public void SkipGroup()
+ {
+ // Create an output stream with a group in:
+ // Field 1: string "field 1"
+ // Field 2: group containing:
+ // Field 1: fixed int32 value 100
+ // Field 2: string "ignore me"
+ // Field 3: nested group containing
+ // Field 1: fixed int64 value 1000
+ // Field 3: string "field 3"
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteString("field 1");
+
+ // The outer group...
+ output.WriteTag(2, WireFormat.WireType.StartGroup);
+ output.WriteTag(1, WireFormat.WireType.Fixed32);
+ output.WriteFixed32(100);
+ output.WriteTag(2, WireFormat.WireType.LengthDelimited);
+ output.WriteString("ignore me");
+ // The nested group...
+ output.WriteTag(3, WireFormat.WireType.StartGroup);
+ output.WriteTag(1, WireFormat.WireType.Fixed64);
+ output.WriteFixed64(1000);
+ // Note: Not sure the field number is relevant for end group...
+ output.WriteTag(3, WireFormat.WireType.EndGroup);
+
+ // End the outer group
+ output.WriteTag(2, WireFormat.WireType.EndGroup);
+
+ output.WriteTag(3, WireFormat.WireType.LengthDelimited);
+ output.WriteString("field 3");
+ output.Flush();
+ stream.Position = 0;
+
+ // Now act like a generated client
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
+ Assert.AreEqual("field 1", input.ReadString());
+ Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
+ input.SkipLastField(); // Should consume the whole group, including the nested one.
+ Assert.AreEqual(WireFormat.MakeTag(3, WireFormat.WireType.LengthDelimited), input.ReadTag());
+ Assert.AreEqual("field 3", input.ReadString());
+ }
+
+ [Test]
+ public void SkipGroup_WrongEndGroupTag()
+ {
+ // Create an output stream with:
+ // Field 1: string "field 1"
+ // Start group 2
+ // Field 3: fixed int32
+ // End group 4 (should give an error)
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteString("field 1");
+
+ // The outer group...
+ output.WriteTag(2, WireFormat.WireType.StartGroup);
+ output.WriteTag(3, WireFormat.WireType.Fixed32);
+ output.WriteFixed32(100);
+ output.WriteTag(4, WireFormat.WireType.EndGroup);
+ output.Flush();
+ stream.Position = 0;
+
+ // Now act like a generated client
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
+ Assert.AreEqual("field 1", input.ReadString());
+ Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
+ public void RogueEndGroupTag()
+ {
+ // If we have an end-group tag without a leading start-group tag, generated
+ // code will just call SkipLastField... so that should fail.
+
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.EndGroup);
+ output.Flush();
+ stream.Position = 0;
+
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.EndGroup), input.ReadTag());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
+ public void EndOfStreamReachedWhileSkippingGroup()
+ {
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.StartGroup);
+ output.WriteTag(2, WireFormat.WireType.StartGroup);
+ output.WriteTag(2, WireFormat.WireType.EndGroup);
+
+ output.Flush();
+ stream.Position = 0;
+
+ // Now act like a generated client
+ var input = new CodedInputStream(stream);
+ input.ReadTag();
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
+ public void RecursionLimitAppliedWhileSkippingGroup()
+ {
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
+ {
+ output.WriteTag(1, WireFormat.WireType.StartGroup);
+ }
+ for (int i = 0; i < CodedInputStream.DefaultRecursionLimit + 1; i++)
+ {
+ output.WriteTag(1, WireFormat.WireType.EndGroup);
+ }
+ output.Flush();
+ stream.Position = 0;
+
+ // Now act like a generated client
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.StartGroup), input.ReadTag());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
+ public void Construction_Invalid()
+ {
+ Assert.Throws<ArgumentNullException>(() => new CodedInputStream((byte[]) null));
+ Assert.Throws<ArgumentNullException>(() => new CodedInputStream(null, 0, 0));
+ Assert.Throws<ArgumentNullException>(() => new CodedInputStream((Stream) null));
+ Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 100, 0));
+ Assert.Throws<ArgumentOutOfRangeException>(() => new CodedInputStream(new byte[10], 5, 10));
+ }
+
+ [Test]
+ public void CreateWithLimits_InvalidLimits()
+ {
+ var stream = new MemoryStream();
+ Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 0, 1));
+ Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 1, 0));
+ }
+
+ [Test]
+ public void Dispose_DisposesUnderlyingStream()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanRead);
+ using (var cis = new CodedInputStream(memoryStream))
+ {
+ }
+ Assert.IsFalse(memoryStream.CanRead); // Disposed
+ }
+
+ [Test]
+ public void Dispose_WithLeaveOpen()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanRead);
+ using (var cis = new CodedInputStream(memoryStream, true))
+ {
+ }
+ Assert.IsTrue(memoryStream.CanRead); // We left the stream open
+ }
+
+ [Test]
+ public void Dispose_FromByteArray()
+ {
+ var stream = new CodedInputStream(new byte[10]);
+ stream.Dispose();
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
index 98cabd55ad..32926e930f 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
@@ -1,426 +1,426 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.IO;
-using Google.Protobuf.TestProtos;
-using NUnit.Framework;
-
-namespace Google.Protobuf
-{
- public class CodedOutputStreamTest
- {
- /// <summary>
- /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
- /// checks that the result matches the given bytes
- /// </summary>
- private static void AssertWriteVarint(byte[] data, ulong value)
- {
- // Only do 32-bit write if the value fits in 32 bits.
- if ((value >> 32) == 0)
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput);
- output.WriteRawVarint32((uint) value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
- // Also try computing size.
- Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
- }
-
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput);
- output.WriteRawVarint64(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
-
- // Also try computing size.
- Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
- }
-
- // Try different buffer sizes.
- for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
- {
- // Only do 32-bit write if the value fits in 32 bits.
- if ((value >> 32) == 0)
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output =
- new CodedOutputStream(rawOutput, bufferSize);
- output.WriteRawVarint32((uint) value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
- }
-
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput, bufferSize);
- output.WriteRawVarint64(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
- }
- }
- }
-
- /// <summary>
- /// Tests WriteRawVarint32() and WriteRawVarint64()
- /// </summary>
- [Test]
- public void WriteVarint()
- {
- AssertWriteVarint(new byte[] {0x00}, 0);
- AssertWriteVarint(new byte[] {0x01}, 1);
- AssertWriteVarint(new byte[] {0x7f}, 127);
- // 14882
- AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
- // 2961488830
- AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
- (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
- (0x0bL << 28));
-
- // 64-bit
- // 7256456126
- AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
- (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
- (0x1bL << 28));
- // 41256202580718336
- AssertWriteVarint(
- new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
- (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
- (0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
- // 11964378330978735131
- AssertWriteVarint(
- new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
- unchecked((ulong)
- ((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
- (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
- (0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
- }
-
- /// <summary>
- /// Parses the given bytes using WriteRawLittleEndian32() and checks
- /// that the result matches the given value.
- /// </summary>
- private static void AssertWriteLittleEndian32(byte[] data, uint value)
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput);
- output.WriteRawLittleEndian32(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
-
- // Try different buffer sizes.
- for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
- {
- rawOutput = new MemoryStream();
- output = new CodedOutputStream(rawOutput, bufferSize);
- output.WriteRawLittleEndian32(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
- }
- }
-
- /// <summary>
- /// Parses the given bytes using WriteRawLittleEndian64() and checks
- /// that the result matches the given value.
- /// </summary>
- private static void AssertWriteLittleEndian64(byte[] data, ulong value)
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput);
- output.WriteRawLittleEndian64(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
-
- // Try different block sizes.
- for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
- {
- rawOutput = new MemoryStream();
- output = new CodedOutputStream(rawOutput, blockSize);
- output.WriteRawLittleEndian64(value);
- output.Flush();
- Assert.AreEqual(data, rawOutput.ToArray());
- }
- }
-
- /// <summary>
- /// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
- /// </summary>
- [Test]
- public void WriteLittleEndian()
- {
- AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
- AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
-
- AssertWriteLittleEndian64(
- new byte[] {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
- 0x123456789abcdef0L);
- AssertWriteLittleEndian64(
- new byte[] {0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
- 0x9abcdef012345678UL);
- }
-
- [Test]
- public void WriteWholeMessage_VaryingBlockSizes()
- {
- TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
-
- byte[] rawBytes = message.ToByteArray();
-
- // Try different block sizes.
- for (int blockSize = 1; blockSize < 256; blockSize *= 2)
- {
- MemoryStream rawOutput = new MemoryStream();
- CodedOutputStream output = new CodedOutputStream(rawOutput, blockSize);
- message.WriteTo(output);
- output.Flush();
- Assert.AreEqual(rawBytes, rawOutput.ToArray());
- }
- }
-
- [Test]
- public void EncodeZigZag32()
- {
- Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag32(0));
- Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag32(-1));
- Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag32(1));
- Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag32(-2));
- Assert.AreEqual(0x7FFFFFFEu, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
- Assert.AreEqual(0x7FFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000)));
- Assert.AreEqual(0xFFFFFFFEu, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
- Assert.AreEqual(0xFFFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000)));
- }
-
- [Test]
- public void EncodeZigZag64()
- {
- Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag64(0));
- Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag64(-1));
- Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag64(1));
- Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag64(-2));
- Assert.AreEqual(0x000000007FFFFFFEuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
- Assert.AreEqual(0x000000007FFFFFFFuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
- Assert.AreEqual(0x00000000FFFFFFFEuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
- Assert.AreEqual(0x00000000FFFFFFFFuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
- Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
- Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
- }
-
- [Test]
- public void RoundTripZigZag32()
- {
- // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
- // were chosen semi-randomly via keyboard bashing.
- Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
- Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
- Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
- Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
- Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
- }
-
- [Test]
- public void RoundTripZigZag64()
- {
- Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
- Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
- Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
- Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
- Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
-
- Assert.AreEqual(856912304801416L,
- CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
- Assert.AreEqual(-75123905439571256L,
- CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
- }
-
- [Test]
- public void TestNegativeEnumNoTag()
- {
- Assert.AreEqual(10, CodedOutputStream.ComputeInt32Size(-2));
- Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) SampleEnum.NegativeValue));
-
- byte[] bytes = new byte[10];
- CodedOutputStream output = new CodedOutputStream(bytes);
- 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));
- }
-
- [Test]
- public void TestCodedInputOutputPosition()
- {
- byte[] content = new byte[110];
- for (int i = 0; i < content.Length; i++)
- content[i] = (byte)i;
-
- byte[] child = new byte[120];
- {
- MemoryStream ms = new MemoryStream(child);
- CodedOutputStream cout = new CodedOutputStream(ms, 20);
- // Field 11: numeric value: 500
- cout.WriteTag(11, WireFormat.WireType.Varint);
- Assert.AreEqual(1, cout.Position);
- cout.WriteInt32(500);
- Assert.AreEqual(3, cout.Position);
- //Field 12: length delimited 120 bytes
- cout.WriteTag(12, WireFormat.WireType.LengthDelimited);
- Assert.AreEqual(4, cout.Position);
- cout.WriteBytes(ByteString.CopyFrom(content));
- Assert.AreEqual(115, cout.Position);
- // Field 13: fixed numeric value: 501
- cout.WriteTag(13, WireFormat.WireType.Fixed32);
- Assert.AreEqual(116, cout.Position);
- cout.WriteSFixed32(501);
- Assert.AreEqual(120, cout.Position);
- cout.Flush();
- }
-
- byte[] bytes = new byte[130];
- {
- CodedOutputStream cout = new CodedOutputStream(bytes);
- // Field 1: numeric value: 500
- cout.WriteTag(1, WireFormat.WireType.Varint);
- Assert.AreEqual(1, cout.Position);
- cout.WriteInt32(500);
- Assert.AreEqual(3, cout.Position);
- //Field 2: length delimited 120 bytes
- cout.WriteTag(2, WireFormat.WireType.LengthDelimited);
- Assert.AreEqual(4, cout.Position);
- cout.WriteBytes(ByteString.CopyFrom(child));
- Assert.AreEqual(125, cout.Position);
- // Field 3: fixed numeric value: 500
- cout.WriteTag(3, WireFormat.WireType.Fixed32);
- Assert.AreEqual(126, cout.Position);
- cout.WriteSFixed32(501);
- Assert.AreEqual(130, cout.Position);
- cout.Flush();
- }
- // Now test Input stream:
- {
- CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0, false);
- Assert.AreEqual(0, cin.Position);
- // Field 1:
- uint tag = cin.ReadTag();
- Assert.AreEqual(1, tag >> 3);
- Assert.AreEqual(1, cin.Position);
- Assert.AreEqual(500, cin.ReadInt32());
- Assert.AreEqual(3, cin.Position);
- //Field 2:
- tag = cin.ReadTag();
- Assert.AreEqual(2, tag >> 3);
- Assert.AreEqual(4, cin.Position);
- int childlen = cin.ReadLength();
- Assert.AreEqual(120, childlen);
- Assert.AreEqual(5, cin.Position);
- int oldlimit = cin.PushLimit((int)childlen);
- Assert.AreEqual(5, cin.Position);
- // Now we are reading child message
- {
- // Field 11: numeric value: 500
- tag = cin.ReadTag();
- Assert.AreEqual(11, tag >> 3);
- Assert.AreEqual(6, cin.Position);
- Assert.AreEqual(500, cin.ReadInt32());
- Assert.AreEqual(8, cin.Position);
- //Field 12: length delimited 120 bytes
- tag = cin.ReadTag();
- Assert.AreEqual(12, tag >> 3);
- Assert.AreEqual(9, cin.Position);
- ByteString bstr = cin.ReadBytes();
- Assert.AreEqual(110, bstr.Length);
- Assert.AreEqual((byte) 109, bstr[109]);
- Assert.AreEqual(120, cin.Position);
- // Field 13: fixed numeric value: 501
- tag = cin.ReadTag();
- Assert.AreEqual(13, tag >> 3);
- // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
- Assert.AreEqual(121, cin.Position);
- Assert.AreEqual(501, cin.ReadSFixed32());
- Assert.AreEqual(125, cin.Position);
- Assert.IsTrue(cin.IsAtEnd);
- }
- cin.PopLimit(oldlimit);
- Assert.AreEqual(125, cin.Position);
- // Field 3: fixed numeric value: 501
- tag = cin.ReadTag();
- Assert.AreEqual(3, tag >> 3);
- Assert.AreEqual(126, cin.Position);
- Assert.AreEqual(501, cin.ReadSFixed32());
- Assert.AreEqual(130, cin.Position);
- Assert.IsTrue(cin.IsAtEnd);
- }
- }
-
- [Test]
- public void Dispose_DisposesUnderlyingStream()
- {
- var memoryStream = new MemoryStream();
- Assert.IsTrue(memoryStream.CanWrite);
- using (var cos = new CodedOutputStream(memoryStream))
- {
- cos.WriteRawByte(0);
- Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
- }
- Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
- Assert.IsFalse(memoryStream.CanWrite); // Disposed
- }
-
- [Test]
- public void Dispose_WithLeaveOpen()
- {
- var memoryStream = new MemoryStream();
- Assert.IsTrue(memoryStream.CanWrite);
- using (var cos = new CodedOutputStream(memoryStream, true))
- {
- cos.WriteRawByte(0);
- Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
- }
- Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream
- Assert.IsTrue(memoryStream.CanWrite); // We left the stream open
- }
-
- [Test]
- public void Dispose_FromByteArray()
- {
- var stream = new CodedOutputStream(new byte[10]);
- stream.Dispose();
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.IO;
+using Google.Protobuf.TestProtos;
+using NUnit.Framework;
+
+namespace Google.Protobuf
+{
+ public class CodedOutputStreamTest
+ {
+ /// <summary>
+ /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
+ /// checks that the result matches the given bytes
+ /// </summary>
+ private static void AssertWriteVarint(byte[] data, ulong value)
+ {
+ // Only do 32-bit write if the value fits in 32 bits.
+ if ((value >> 32) == 0)
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput);
+ output.WriteRawVarint32((uint) value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+ // Also try computing size.
+ Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
+ }
+
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput);
+ output.WriteRawVarint64(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+
+ // Also try computing size.
+ Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
+ }
+
+ // Try different buffer sizes.
+ for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
+ {
+ // Only do 32-bit write if the value fits in 32 bits.
+ if ((value >> 32) == 0)
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output =
+ new CodedOutputStream(rawOutput, bufferSize);
+ output.WriteRawVarint32((uint) value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+ }
+
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput, bufferSize);
+ output.WriteRawVarint64(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+ }
+ }
+ }
+
+ /// <summary>
+ /// Tests WriteRawVarint32() and WriteRawVarint64()
+ /// </summary>
+ [Test]
+ public void WriteVarint()
+ {
+ AssertWriteVarint(new byte[] {0x00}, 0);
+ AssertWriteVarint(new byte[] {0x01}, 1);
+ AssertWriteVarint(new byte[] {0x7f}, 127);
+ // 14882
+ AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
+ // 2961488830
+ AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x0bL << 28));
+
+ // 64-bit
+ // 7256456126
+ AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
+ (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+ (0x1bL << 28));
+ // 41256202580718336
+ AssertWriteVarint(
+ new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
+ (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+ (0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
+ // 11964378330978735131
+ AssertWriteVarint(
+ new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
+ unchecked((ulong)
+ ((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+ (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
+ (0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
+ }
+
+ /// <summary>
+ /// Parses the given bytes using WriteRawLittleEndian32() and checks
+ /// that the result matches the given value.
+ /// </summary>
+ private static void AssertWriteLittleEndian32(byte[] data, uint value)
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput);
+ output.WriteRawLittleEndian32(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+
+ // Try different buffer sizes.
+ for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
+ {
+ rawOutput = new MemoryStream();
+ output = new CodedOutputStream(rawOutput, bufferSize);
+ output.WriteRawLittleEndian32(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+ }
+ }
+
+ /// <summary>
+ /// Parses the given bytes using WriteRawLittleEndian64() and checks
+ /// that the result matches the given value.
+ /// </summary>
+ private static void AssertWriteLittleEndian64(byte[] data, ulong value)
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput);
+ output.WriteRawLittleEndian64(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
+ {
+ rawOutput = new MemoryStream();
+ output = new CodedOutputStream(rawOutput, blockSize);
+ output.WriteRawLittleEndian64(value);
+ output.Flush();
+ Assert.AreEqual(data, rawOutput.ToArray());
+ }
+ }
+
+ /// <summary>
+ /// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
+ /// </summary>
+ [Test]
+ public void WriteLittleEndian()
+ {
+ AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
+ AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
+
+ AssertWriteLittleEndian64(
+ new byte[] {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
+ 0x123456789abcdef0L);
+ AssertWriteLittleEndian64(
+ new byte[] {0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
+ 0x9abcdef012345678UL);
+ }
+
+ [Test]
+ public void WriteWholeMessage_VaryingBlockSizes()
+ {
+ TestAllTypes message = SampleMessages.CreateFullTestAllTypes();
+
+ byte[] rawBytes = message.ToByteArray();
+
+ // Try different block sizes.
+ for (int blockSize = 1; blockSize < 256; blockSize *= 2)
+ {
+ MemoryStream rawOutput = new MemoryStream();
+ CodedOutputStream output = new CodedOutputStream(rawOutput, blockSize);
+ message.WriteTo(output);
+ output.Flush();
+ Assert.AreEqual(rawBytes, rawOutput.ToArray());
+ }
+ }
+
+ [Test]
+ public void EncodeZigZag32()
+ {
+ Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag32(0));
+ Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag32(-1));
+ Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag32(1));
+ Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag32(-2));
+ Assert.AreEqual(0x7FFFFFFEu, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
+ Assert.AreEqual(0x7FFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000)));
+ Assert.AreEqual(0xFFFFFFFEu, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
+ Assert.AreEqual(0xFFFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000)));
+ }
+
+ [Test]
+ public void EncodeZigZag64()
+ {
+ Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag64(0));
+ Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag64(-1));
+ Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag64(1));
+ Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag64(-2));
+ Assert.AreEqual(0x000000007FFFFFFEuL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
+ Assert.AreEqual(0x000000007FFFFFFFuL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
+ Assert.AreEqual(0x00000000FFFFFFFEuL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
+ Assert.AreEqual(0x00000000FFFFFFFFuL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
+ Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
+ Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
+ CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
+ }
+
+ [Test]
+ public void RoundTripZigZag32()
+ {
+ // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
+ // were chosen semi-randomly via keyboard bashing.
+ Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
+ Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
+ Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
+ Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
+ Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
+ }
+
+ [Test]
+ public void RoundTripZigZag64()
+ {
+ Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
+ Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
+ Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
+ Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
+ Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
+
+ Assert.AreEqual(856912304801416L,
+ CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
+ Assert.AreEqual(-75123905439571256L,
+ CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
+ }
+
+ [Test]
+ public void TestNegativeEnumNoTag()
+ {
+ Assert.AreEqual(10, CodedOutputStream.ComputeInt32Size(-2));
+ Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) SampleEnum.NegativeValue));
+
+ byte[] bytes = new byte[10];
+ CodedOutputStream output = new CodedOutputStream(bytes);
+ 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));
+ }
+
+ [Test]
+ public void TestCodedInputOutputPosition()
+ {
+ byte[] content = new byte[110];
+ for (int i = 0; i < content.Length; i++)
+ content[i] = (byte)i;
+
+ byte[] child = new byte[120];
+ {
+ MemoryStream ms = new MemoryStream(child);
+ CodedOutputStream cout = new CodedOutputStream(ms, 20);
+ // Field 11: numeric value: 500
+ cout.WriteTag(11, WireFormat.WireType.Varint);
+ Assert.AreEqual(1, cout.Position);
+ cout.WriteInt32(500);
+ Assert.AreEqual(3, cout.Position);
+ //Field 12: length delimited 120 bytes
+ cout.WriteTag(12, WireFormat.WireType.LengthDelimited);
+ Assert.AreEqual(4, cout.Position);
+ cout.WriteBytes(ByteString.CopyFrom(content));
+ Assert.AreEqual(115, cout.Position);
+ // Field 13: fixed numeric value: 501
+ cout.WriteTag(13, WireFormat.WireType.Fixed32);
+ Assert.AreEqual(116, cout.Position);
+ cout.WriteSFixed32(501);
+ Assert.AreEqual(120, cout.Position);
+ cout.Flush();
+ }
+
+ byte[] bytes = new byte[130];
+ {
+ CodedOutputStream cout = new CodedOutputStream(bytes);
+ // Field 1: numeric value: 500
+ cout.WriteTag(1, WireFormat.WireType.Varint);
+ Assert.AreEqual(1, cout.Position);
+ cout.WriteInt32(500);
+ Assert.AreEqual(3, cout.Position);
+ //Field 2: length delimited 120 bytes
+ cout.WriteTag(2, WireFormat.WireType.LengthDelimited);
+ Assert.AreEqual(4, cout.Position);
+ cout.WriteBytes(ByteString.CopyFrom(child));
+ Assert.AreEqual(125, cout.Position);
+ // Field 3: fixed numeric value: 500
+ cout.WriteTag(3, WireFormat.WireType.Fixed32);
+ Assert.AreEqual(126, cout.Position);
+ cout.WriteSFixed32(501);
+ Assert.AreEqual(130, cout.Position);
+ cout.Flush();
+ }
+ // Now test Input stream:
+ {
+ CodedInputStream cin = new CodedInputStream(new MemoryStream(bytes), new byte[50], 0, 0, false);
+ Assert.AreEqual(0, cin.Position);
+ // Field 1:
+ uint tag = cin.ReadTag();
+ Assert.AreEqual(1, tag >> 3);
+ Assert.AreEqual(1, cin.Position);
+ Assert.AreEqual(500, cin.ReadInt32());
+ Assert.AreEqual(3, cin.Position);
+ //Field 2:
+ tag = cin.ReadTag();
+ Assert.AreEqual(2, tag >> 3);
+ Assert.AreEqual(4, cin.Position);
+ int childlen = cin.ReadLength();
+ Assert.AreEqual(120, childlen);
+ Assert.AreEqual(5, cin.Position);
+ int oldlimit = cin.PushLimit((int)childlen);
+ Assert.AreEqual(5, cin.Position);
+ // Now we are reading child message
+ {
+ // Field 11: numeric value: 500
+ tag = cin.ReadTag();
+ Assert.AreEqual(11, tag >> 3);
+ Assert.AreEqual(6, cin.Position);
+ Assert.AreEqual(500, cin.ReadInt32());
+ Assert.AreEqual(8, cin.Position);
+ //Field 12: length delimited 120 bytes
+ tag = cin.ReadTag();
+ Assert.AreEqual(12, tag >> 3);
+ Assert.AreEqual(9, cin.Position);
+ ByteString bstr = cin.ReadBytes();
+ Assert.AreEqual(110, bstr.Length);
+ Assert.AreEqual((byte) 109, bstr[109]);
+ Assert.AreEqual(120, cin.Position);
+ // Field 13: fixed numeric value: 501
+ tag = cin.ReadTag();
+ Assert.AreEqual(13, tag >> 3);
+ // ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
+ Assert.AreEqual(121, cin.Position);
+ Assert.AreEqual(501, cin.ReadSFixed32());
+ Assert.AreEqual(125, cin.Position);
+ Assert.IsTrue(cin.IsAtEnd);
+ }
+ cin.PopLimit(oldlimit);
+ Assert.AreEqual(125, cin.Position);
+ // Field 3: fixed numeric value: 501
+ tag = cin.ReadTag();
+ Assert.AreEqual(3, tag >> 3);
+ Assert.AreEqual(126, cin.Position);
+ Assert.AreEqual(501, cin.ReadSFixed32());
+ Assert.AreEqual(130, cin.Position);
+ Assert.IsTrue(cin.IsAtEnd);
+ }
+ }
+
+ [Test]
+ public void Dispose_DisposesUnderlyingStream()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanWrite);
+ using (var cos = new CodedOutputStream(memoryStream))
+ {
+ cos.WriteRawByte(0);
+ Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
+ }
+ Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
+ Assert.IsFalse(memoryStream.CanWrite); // Disposed
+ }
+
+ [Test]
+ public void Dispose_WithLeaveOpen()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanWrite);
+ using (var cos = new CodedOutputStream(memoryStream, true))
+ {
+ cos.WriteRawByte(0);
+ Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
+ }
+ Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream
+ Assert.IsTrue(memoryStream.CanWrite); // We left the stream open
+ }
+
+ [Test]
+ public void Dispose_FromByteArray()
+ {
+ var stream = new CodedOutputStream(new byte[10]);
+ stream.Dispose();
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
index 34d5b9f98c..8dfad8b331 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs
@@ -1,55 +1,55 @@
-#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.Reflection;
-using Google.Protobuf.TestProtos;
-using NUnit.Framework;
-
-namespace Google.Protobuf
-{
- public class DeprecatedMemberTest
- {
- private static void AssertIsDeprecated(MemberInfo member)
- {
- Assert.NotNull(member);
- Assert.IsTrue(member.IsDefined(typeof(ObsoleteAttribute), false), "Member not obsolete: " + member);
- }
-
- [Test]
- public void TestDepreatedPrimitiveValue()
- {
- AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty("DeprecatedInt32"));
- }
-
- }
-}
+#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.Reflection;
+using Google.Protobuf.TestProtos;
+using NUnit.Framework;
+
+namespace Google.Protobuf
+{
+ public class DeprecatedMemberTest
+ {
+ private static void AssertIsDeprecated(MemberInfo member)
+ {
+ Assert.NotNull(member);
+ Assert.IsTrue(member.IsDefined(typeof(ObsoleteAttribute), false), "Member not obsolete: " + member);
+ }
+
+ [Test]
+ public void TestDepreatedPrimitiveValue()
+ {
+ AssertIsDeprecated(typeof(TestDeprecatedFields).GetProperty("DeprecatedInt32"));
+ }
+
+ }
+}
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
index 77641163c0..3c5e32d2e0 100755
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
@@ -158,7 +158,7 @@ namespace Google.Protobuf
{
// WriteTagAndValue ignores default values
var stream = new MemoryStream();
- CodedOutputStream codedOutput;
+ CodedOutputStream codedOutput;
#if !NET35
codedOutput = new CodedOutputStream(stream);
codec.WriteTagAndValue(codedOutput, codec.DefaultValue);
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
index 8b153d691f..b029551c0b 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
@@ -1,723 +1,723 @@
-#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.IO;
-using Google.Protobuf.TestProtos;
-using NUnit.Framework;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using Google.Protobuf.WellKnownTypes;
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Tests around the generated TestAllTypes message.
- /// </summary>
- public class GeneratedMessageTest
- {
- [Test]
- public void EmptyMessageFieldDistinctFromMissingMessageField()
- {
- // This demonstrates what we're really interested in...
- var message1 = new TestAllTypes { SingleForeignMessage = new ForeignMessage() };
- var message2 = new TestAllTypes(); // SingleForeignMessage is null
- EqualityTester.AssertInequality(message1, message2);
- }
-
- [Test]
- public void DefaultValues()
- {
- // Single fields
- var message = new TestAllTypes();
- Assert.AreEqual(false, message.SingleBool);
- Assert.AreEqual(ByteString.Empty, message.SingleBytes);
- Assert.AreEqual(0.0, message.SingleDouble);
- Assert.AreEqual(0, message.SingleFixed32);
- Assert.AreEqual(0L, message.SingleFixed64);
- Assert.AreEqual(0.0f, message.SingleFloat);
- Assert.AreEqual(ForeignEnum.ForeignUnspecified, message.SingleForeignEnum);
- Assert.IsNull(message.SingleForeignMessage);
- Assert.AreEqual(ImportEnum.Unspecified, message.SingleImportEnum);
- Assert.IsNull(message.SingleImportMessage);
- Assert.AreEqual(0, message.SingleInt32);
- Assert.AreEqual(0L, message.SingleInt64);
- Assert.AreEqual(TestAllTypes.Types.NestedEnum.Unspecified, message.SingleNestedEnum);
- Assert.IsNull(message.SingleNestedMessage);
- Assert.IsNull(message.SinglePublicImportMessage);
- Assert.AreEqual(0, message.SingleSfixed32);
- Assert.AreEqual(0L, message.SingleSfixed64);
- Assert.AreEqual(0, message.SingleSint32);
- Assert.AreEqual(0L, message.SingleSint64);
- Assert.AreEqual("", message.SingleString);
- Assert.AreEqual(0U, message.SingleUint32);
- Assert.AreEqual(0UL, message.SingleUint64);
-
- // Repeated fields
- Assert.AreEqual(0, message.RepeatedBool.Count);
- Assert.AreEqual(0, message.RepeatedBytes.Count);
- Assert.AreEqual(0, message.RepeatedDouble.Count);
- Assert.AreEqual(0, message.RepeatedFixed32.Count);
- Assert.AreEqual(0, message.RepeatedFixed64.Count);
- Assert.AreEqual(0, message.RepeatedFloat.Count);
- Assert.AreEqual(0, message.RepeatedForeignEnum.Count);
- Assert.AreEqual(0, message.RepeatedForeignMessage.Count);
- Assert.AreEqual(0, message.RepeatedImportEnum.Count);
- Assert.AreEqual(0, message.RepeatedImportMessage.Count);
- Assert.AreEqual(0, message.RepeatedNestedEnum.Count);
- Assert.AreEqual(0, message.RepeatedNestedMessage.Count);
- Assert.AreEqual(0, message.RepeatedPublicImportMessage.Count);
- Assert.AreEqual(0, message.RepeatedSfixed32.Count);
- Assert.AreEqual(0, message.RepeatedSfixed64.Count);
- Assert.AreEqual(0, message.RepeatedSint32.Count);
- Assert.AreEqual(0, message.RepeatedSint64.Count);
- Assert.AreEqual(0, message.RepeatedString.Count);
- Assert.AreEqual(0, message.RepeatedUint32.Count);
- Assert.AreEqual(0, message.RepeatedUint64.Count);
-
- // Oneof fields
- Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
- Assert.AreEqual(0, message.OneofUint32);
- Assert.AreEqual("", message.OneofString);
- Assert.AreEqual(ByteString.Empty, message.OneofBytes);
- Assert.IsNull(message.OneofNestedMessage);
- }
-
- [Test]
- public void NullStringAndBytesRejected()
- {
- var message = new TestAllTypes();
- Assert.Throws<ArgumentNullException>(() => message.SingleString = null);
- Assert.Throws<ArgumentNullException>(() => message.OneofString = null);
- Assert.Throws<ArgumentNullException>(() => message.SingleBytes = null);
- Assert.Throws<ArgumentNullException>(() => message.OneofBytes = null);
- }
-
- [Test]
- public void RoundTrip_Empty()
- {
- var message = new TestAllTypes();
- // Without setting any values, there's nothing to write.
- byte[] bytes = message.ToByteArray();
- Assert.AreEqual(0, bytes.Length);
- TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
- Assert.AreEqual(message, parsed);
- }
-
- [Test]
- public void RoundTrip_SingleValues()
- {
- var message = new TestAllTypes
- {
- SingleBool = true,
- SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
- SingleDouble = 23.5,
- SingleFixed32 = 23,
- SingleFixed64 = 1234567890123,
- SingleFloat = 12.25f,
- SingleForeignEnum = ForeignEnum.ForeignBar,
- SingleForeignMessage = new ForeignMessage { C = 10 },
- SingleImportEnum = ImportEnum.ImportBaz,
- 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
- };
-
- byte[] bytes = message.ToByteArray();
- TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
- Assert.AreEqual(message, parsed);
- }
-
- [Test]
- public void RoundTrip_RepeatedValues()
- {
- var message = new TestAllTypes
- {
- RepeatedBool = { true, false },
- RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
- RepeatedDouble = { -12.25, 23.5 },
- RepeatedFixed32 = { uint.MaxValue, 23 },
- RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
- RepeatedFloat = { 100f, 12.25f },
- RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
- RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
- RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.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 }
- };
-
- byte[] bytes = message.ToByteArray();
- TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
- Assert.AreEqual(message, parsed);
- }
-
- // Note that not every map within map_unittest_proto3 is used. They all go through very
- // similar code paths. The fact that all maps are present is validation that we have codecs
- // for every type.
- [Test]
- public void RoundTrip_Maps()
- {
- var message = new TestMap
- {
- MapBoolBool = {
- { false, true },
- { true, false }
- },
- MapInt32Bytes = {
- { 5, ByteString.CopyFrom(6, 7, 8) },
- { 25, ByteString.CopyFrom(1, 2, 3, 4, 5) },
- { 10, ByteString.Empty }
- },
- MapInt32ForeignMessage = {
- { 0, new ForeignMessage { C = 10 } },
- { 5, new ForeignMessage() },
- },
- MapInt32Enum = {
- { 1, MapEnum.Bar },
- { 2000, MapEnum.Foo }
- }
- };
-
- byte[] bytes = message.ToByteArray();
- TestMap parsed = TestMap.Parser.ParseFrom(bytes);
- Assert.AreEqual(message, parsed);
- }
-
- [Test]
- public void MapWithEmptyEntry()
- {
- var message = new TestMap
- {
- MapInt32Bytes = { { 0, ByteString.Empty } }
- };
-
- byte[] bytes = message.ToByteArray();
- Assert.AreEqual(2, bytes.Length); // Tag for field entry (1 byte), length of entry (0; 1 byte)
-
- var parsed = TestMap.Parser.ParseFrom(bytes);
- Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
- Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
- }
-
- [Test]
- public void MapWithOnlyValue()
- {
- // Hand-craft the stream to contain a single entry with just a value.
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
- output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
- var nestedMessage = new ForeignMessage { C = 20 };
- // Size of the entry (tag, size written by WriteMessage, data written by WriteMessage)
- output.WriteLength(2 + nestedMessage.CalculateSize());
- output.WriteTag(2, WireFormat.WireType.LengthDelimited);
- output.WriteMessage(nestedMessage);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(nestedMessage, parsed.MapInt32ForeignMessage[0]);
- }
-
- [Test]
- public void MapWithOnlyKey_PrimitiveValue()
- {
- // Hand-craft the stream to contain a single entry with just a key.
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
- output.WriteTag(TestMap.MapInt32DoubleFieldNumber, WireFormat.WireType.LengthDelimited);
- int key = 10;
- output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(0.0, parsed.MapInt32Double[key]);
- }
-
- [Test]
- public void MapWithOnlyKey_MessageValue()
- {
- // Hand-craft the stream to contain a single entry with just a key.
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
- output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
- int key = 10;
- output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]);
- }
-
- [Test]
- public void MapIgnoresExtraFieldsWithinEntryMessages()
- {
- // Hand-craft the stream to contain a single entry with three fields
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
-
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
-
- var key = 10; // Field 1
- var value = 20; // Field 2
- var extra = 30; // Field 3
-
- // Each field can be represented in a single byte, with a single byte tag.
- // Total message size: 6 bytes.
- output.WriteLength(6);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value);
- output.WriteTag(3, WireFormat.WireType.Varint);
- output.WriteInt32(extra);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(value, parsed.MapInt32Int32[key]);
- }
-
- [Test]
- public void MapFieldOrderIsIrrelevant()
- {
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
-
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
-
- var key = 10;
- var value = 20;
-
- // Each field can be represented in a single byte, with a single byte tag.
- // Total message size: 4 bytes.
- output.WriteLength(4);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(value, parsed.MapInt32Int32[key]);
- }
-
- [Test]
- public void MapNonContiguousEntries()
- {
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
-
- // Message structure:
- // Entry for MapInt32Int32
- // Entry for MapStringString
- // Entry for MapInt32Int32
-
- // First entry
- var key1 = 10;
- var value1 = 20;
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteLength(4);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key1);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value1);
-
- // Second entry
- var key2 = "a";
- var value2 = "b";
- output.WriteTag(TestMap.MapStringStringFieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteLength(6); // 3 bytes per entry: tag, size, character
- output.WriteTag(1, WireFormat.WireType.LengthDelimited);
- output.WriteString(key2);
- output.WriteTag(2, WireFormat.WireType.LengthDelimited);
- output.WriteString(value2);
-
- // Third entry
- var key3 = 15;
- var value3 = 25;
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteLength(4);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key3);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value3);
-
- output.Flush();
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- var expected = new TestMap
- {
- MapInt32Int32 = { { key1, value1 }, { key3, value3 } },
- MapStringString = { { key2, value2 } }
- };
- Assert.AreEqual(expected, parsed);
- }
-
- [Test]
- public void DuplicateKeys_LastEntryWins()
- {
- var memoryStream = new MemoryStream();
- var output = new CodedOutputStream(memoryStream);
-
- var key = 10;
- var value1 = 20;
- var value2 = 30;
-
- // First entry
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteLength(4);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value1);
-
- // Second entry - same key, different value
- output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteLength(4);
- output.WriteTag(1, WireFormat.WireType.Varint);
- output.WriteInt32(key);
- output.WriteTag(2, WireFormat.WireType.Varint);
- output.WriteInt32(value2);
- output.Flush();
-
- var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
- Assert.AreEqual(value2, parsed.MapInt32Int32[key]);
- }
-
- [Test]
- public void CloneSingleNonMessageValues()
- {
- var original = new TestAllTypes
- {
- SingleBool = true,
- SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
- SingleDouble = 23.5,
- SingleFixed32 = 23,
- SingleFixed64 = 1234567890123,
- SingleFloat = 12.25f,
- SingleInt32 = 100,
- SingleInt64 = 3210987654321,
- SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
- SingleSfixed32 = -123,
- SingleSfixed64 = -12345678901234,
- SingleSint32 = -456,
- SingleSint64 = -12345678901235,
- SingleString = "test",
- SingleUint32 = uint.MaxValue,
- SingleUint64 = ulong.MaxValue
- };
- var clone = original.Clone();
- Assert.AreNotSame(original, clone);
- Assert.AreEqual(original, clone);
- // Just as a single example
- clone.SingleInt32 = 150;
- Assert.AreNotEqual(original, clone);
- }
-
- [Test]
- public void CloneRepeatedNonMessageValues()
- {
- var original = new TestAllTypes
- {
- RepeatedBool = { true, false },
- RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
- RepeatedDouble = { -12.25, 23.5 },
- RepeatedFixed32 = { uint.MaxValue, 23 },
- RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
- RepeatedFloat = { 100f, 12.25f },
- RepeatedInt32 = { 100, 200 },
- RepeatedInt64 = { 3210987654321, long.MaxValue },
- RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
- 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 }
- };
-
- var clone = original.Clone();
- Assert.AreNotSame(original, clone);
- Assert.AreEqual(original, clone);
- // Just as a single example
- clone.RepeatedDouble.Add(25.5);
- Assert.AreNotEqual(original, clone);
- }
-
- [Test]
- public void CloneSingleMessageField()
- {
- var original = new TestAllTypes
- {
- SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
- };
-
- var clone = original.Clone();
- Assert.AreNotSame(original, clone);
- Assert.AreNotSame(original.SingleNestedMessage, clone.SingleNestedMessage);
- Assert.AreEqual(original, clone);
-
- clone.SingleNestedMessage.Bb = 30;
- Assert.AreNotEqual(original, clone);
- }
-
- [Test]
- public void CloneRepeatedMessageField()
- {
- var original = new TestAllTypes
- {
- RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 20 } }
- };
-
- var clone = original.Clone();
- Assert.AreNotSame(original, clone);
- Assert.AreNotSame(original.RepeatedNestedMessage, clone.RepeatedNestedMessage);
- Assert.AreNotSame(original.RepeatedNestedMessage[0], clone.RepeatedNestedMessage[0]);
- Assert.AreEqual(original, clone);
-
- clone.RepeatedNestedMessage[0].Bb = 30;
- Assert.AreNotEqual(original, clone);
- }
-
- [Test]
- public void CloneOneofField()
- {
- var original = new TestAllTypes
- {
- OneofNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
- };
-
- var clone = original.Clone();
- Assert.AreNotSame(original, clone);
- Assert.AreEqual(original, clone);
-
- // We should have cloned the message
- original.OneofNestedMessage.Bb = 30;
- Assert.AreNotEqual(original, clone);
- }
-
- [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 Oneof_DefaultValuesNotEqual()
- {
- var message1 = new TestAllTypes { OneofString = "" };
- var message2 = new TestAllTypes { OneofUint32 = 0 };
- Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message1.OneofFieldCase);
- Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
- Assert.AreNotEqual(message1, message2);
- }
-
- [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);
- }
-
- [Test]
- public void IgnoreUnknownFields_RealDataStillRead()
- {
- var message = SampleMessages.CreateFullTestAllTypes();
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
- var unusedFieldNumber = 23456;
- Assert.IsFalse(TestAllTypes.Descriptor.Fields.InDeclarationOrder().Select(x => x.FieldNumber).Contains(unusedFieldNumber));
- output.WriteTag(unusedFieldNumber, WireFormat.WireType.LengthDelimited);
- output.WriteString("ignore me");
- message.WriteTo(output);
- output.Flush();
-
- stream.Position = 0;
- var parsed = TestAllTypes.Parser.ParseFrom(stream);
- Assert.AreEqual(message, parsed);
- }
-
- [Test]
- public void IgnoreUnknownFields_AllTypes()
- {
- // Simple way of ensuring we can skip all kinds of fields.
- var data = SampleMessages.CreateFullTestAllTypes().ToByteArray();
- var empty = Empty.Parser.ParseFrom(data);
- Assert.AreEqual(new Empty(), empty);
- }
-
- // This was originally seen as a conformance test failure.
- [Test]
- public void TruncatedMessageFieldThrows()
- {
- // 130, 3 is the message tag
- // 1 is the data length - but there's no data.
- var data = new byte[] { 130, 3, 1 };
- Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(data));
- }
-
- /// <summary>
- /// Demonstrates current behaviour with an extraneous end group tag - see issue 688
- /// for details; we may want to change this.
- /// </summary>
- [Test]
- public void ExtraEndGroupThrows()
- {
- var message = SampleMessages.CreateFullTestAllTypes();
- var stream = new MemoryStream();
- var output = new CodedOutputStream(stream);
-
- output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32);
- output.WriteFixed32(123);
- output.WriteTag(100, WireFormat.WireType.EndGroup);
-
- output.Flush();
-
- stream.Position = 0;
- Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream));
- }
-
- [Test]
- public void CustomDiagnosticMessage_DirectToStringCall()
- {
- var message = new ForeignMessage { C = 31 };
- Assert.AreEqual("{ \"c\": 31, \"@cInHex\": \"1f\" }", message.ToString());
- Assert.AreEqual("{ \"c\": 31 }", JsonFormatter.Default.Format(message));
- }
-
- [Test]
- public void CustomDiagnosticMessage_Nested()
- {
- var message = new TestAllTypes { SingleForeignMessage = new ForeignMessage { C = 16 } };
- Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16, \"@cInHex\": \"10\" } }", message.ToString());
- Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16 } }", JsonFormatter.Default.Format(message));
- }
-
- [Test]
- public void CustomDiagnosticMessage_DirectToTextWriterCall()
- {
- var message = new ForeignMessage { C = 31 };
- var writer = new StringWriter();
- JsonFormatter.Default.Format(message, writer);
- Assert.AreEqual("{ \"c\": 31 }", writer.ToString());
- }
- }
+#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.IO;
+using Google.Protobuf.TestProtos;
+using NUnit.Framework;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using Google.Protobuf.WellKnownTypes;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Tests around the generated TestAllTypes message.
+ /// </summary>
+ public class GeneratedMessageTest
+ {
+ [Test]
+ public void EmptyMessageFieldDistinctFromMissingMessageField()
+ {
+ // This demonstrates what we're really interested in...
+ var message1 = new TestAllTypes { SingleForeignMessage = new ForeignMessage() };
+ var message2 = new TestAllTypes(); // SingleForeignMessage is null
+ EqualityTester.AssertInequality(message1, message2);
+ }
+
+ [Test]
+ public void DefaultValues()
+ {
+ // Single fields
+ var message = new TestAllTypes();
+ Assert.AreEqual(false, message.SingleBool);
+ Assert.AreEqual(ByteString.Empty, message.SingleBytes);
+ Assert.AreEqual(0.0, message.SingleDouble);
+ Assert.AreEqual(0, message.SingleFixed32);
+ Assert.AreEqual(0L, message.SingleFixed64);
+ Assert.AreEqual(0.0f, message.SingleFloat);
+ Assert.AreEqual(ForeignEnum.ForeignUnspecified, message.SingleForeignEnum);
+ Assert.IsNull(message.SingleForeignMessage);
+ Assert.AreEqual(ImportEnum.Unspecified, message.SingleImportEnum);
+ Assert.IsNull(message.SingleImportMessage);
+ Assert.AreEqual(0, message.SingleInt32);
+ Assert.AreEqual(0L, message.SingleInt64);
+ Assert.AreEqual(TestAllTypes.Types.NestedEnum.Unspecified, message.SingleNestedEnum);
+ Assert.IsNull(message.SingleNestedMessage);
+ Assert.IsNull(message.SinglePublicImportMessage);
+ Assert.AreEqual(0, message.SingleSfixed32);
+ Assert.AreEqual(0L, message.SingleSfixed64);
+ Assert.AreEqual(0, message.SingleSint32);
+ Assert.AreEqual(0L, message.SingleSint64);
+ Assert.AreEqual("", message.SingleString);
+ Assert.AreEqual(0U, message.SingleUint32);
+ Assert.AreEqual(0UL, message.SingleUint64);
+
+ // Repeated fields
+ Assert.AreEqual(0, message.RepeatedBool.Count);
+ Assert.AreEqual(0, message.RepeatedBytes.Count);
+ Assert.AreEqual(0, message.RepeatedDouble.Count);
+ Assert.AreEqual(0, message.RepeatedFixed32.Count);
+ Assert.AreEqual(0, message.RepeatedFixed64.Count);
+ Assert.AreEqual(0, message.RepeatedFloat.Count);
+ Assert.AreEqual(0, message.RepeatedForeignEnum.Count);
+ Assert.AreEqual(0, message.RepeatedForeignMessage.Count);
+ Assert.AreEqual(0, message.RepeatedImportEnum.Count);
+ Assert.AreEqual(0, message.RepeatedImportMessage.Count);
+ Assert.AreEqual(0, message.RepeatedNestedEnum.Count);
+ Assert.AreEqual(0, message.RepeatedNestedMessage.Count);
+ Assert.AreEqual(0, message.RepeatedPublicImportMessage.Count);
+ Assert.AreEqual(0, message.RepeatedSfixed32.Count);
+ Assert.AreEqual(0, message.RepeatedSfixed64.Count);
+ Assert.AreEqual(0, message.RepeatedSint32.Count);
+ Assert.AreEqual(0, message.RepeatedSint64.Count);
+ Assert.AreEqual(0, message.RepeatedString.Count);
+ Assert.AreEqual(0, message.RepeatedUint32.Count);
+ Assert.AreEqual(0, message.RepeatedUint64.Count);
+
+ // Oneof fields
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
+ Assert.AreEqual(0, message.OneofUint32);
+ Assert.AreEqual("", message.OneofString);
+ Assert.AreEqual(ByteString.Empty, message.OneofBytes);
+ Assert.IsNull(message.OneofNestedMessage);
+ }
+
+ [Test]
+ public void NullStringAndBytesRejected()
+ {
+ var message = new TestAllTypes();
+ Assert.Throws<ArgumentNullException>(() => message.SingleString = null);
+ Assert.Throws<ArgumentNullException>(() => message.OneofString = null);
+ Assert.Throws<ArgumentNullException>(() => message.SingleBytes = null);
+ Assert.Throws<ArgumentNullException>(() => message.OneofBytes = null);
+ }
+
+ [Test]
+ public void RoundTrip_Empty()
+ {
+ var message = new TestAllTypes();
+ // Without setting any values, there's nothing to write.
+ byte[] bytes = message.ToByteArray();
+ Assert.AreEqual(0, bytes.Length);
+ TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
+ Assert.AreEqual(message, parsed);
+ }
+
+ [Test]
+ public void RoundTrip_SingleValues()
+ {
+ var message = new TestAllTypes
+ {
+ SingleBool = true,
+ SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
+ SingleDouble = 23.5,
+ SingleFixed32 = 23,
+ SingleFixed64 = 1234567890123,
+ SingleFloat = 12.25f,
+ SingleForeignEnum = ForeignEnum.ForeignBar,
+ SingleForeignMessage = new ForeignMessage { C = 10 },
+ SingleImportEnum = ImportEnum.ImportBaz,
+ 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
+ };
+
+ byte[] bytes = message.ToByteArray();
+ TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
+ Assert.AreEqual(message, parsed);
+ }
+
+ [Test]
+ public void RoundTrip_RepeatedValues()
+ {
+ var message = new TestAllTypes
+ {
+ RepeatedBool = { true, false },
+ RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
+ RepeatedDouble = { -12.25, 23.5 },
+ RepeatedFixed32 = { uint.MaxValue, 23 },
+ RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
+ RepeatedFloat = { 100f, 12.25f },
+ RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
+ RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
+ RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.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 }
+ };
+
+ byte[] bytes = message.ToByteArray();
+ TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes);
+ Assert.AreEqual(message, parsed);
+ }
+
+ // Note that not every map within map_unittest_proto3 is used. They all go through very
+ // similar code paths. The fact that all maps are present is validation that we have codecs
+ // for every type.
+ [Test]
+ public void RoundTrip_Maps()
+ {
+ var message = new TestMap
+ {
+ MapBoolBool = {
+ { false, true },
+ { true, false }
+ },
+ MapInt32Bytes = {
+ { 5, ByteString.CopyFrom(6, 7, 8) },
+ { 25, ByteString.CopyFrom(1, 2, 3, 4, 5) },
+ { 10, ByteString.Empty }
+ },
+ MapInt32ForeignMessage = {
+ { 0, new ForeignMessage { C = 10 } },
+ { 5, new ForeignMessage() },
+ },
+ MapInt32Enum = {
+ { 1, MapEnum.Bar },
+ { 2000, MapEnum.Foo }
+ }
+ };
+
+ byte[] bytes = message.ToByteArray();
+ TestMap parsed = TestMap.Parser.ParseFrom(bytes);
+ Assert.AreEqual(message, parsed);
+ }
+
+ [Test]
+ public void MapWithEmptyEntry()
+ {
+ var message = new TestMap
+ {
+ MapInt32Bytes = { { 0, ByteString.Empty } }
+ };
+
+ byte[] bytes = message.ToByteArray();
+ Assert.AreEqual(2, bytes.Length); // Tag for field entry (1 byte), length of entry (0; 1 byte)
+
+ var parsed = TestMap.Parser.ParseFrom(bytes);
+ Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
+ Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
+ }
+
+ [Test]
+ public void MapWithOnlyValue()
+ {
+ // Hand-craft the stream to contain a single entry with just a value.
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+ output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
+ var nestedMessage = new ForeignMessage { C = 20 };
+ // Size of the entry (tag, size written by WriteMessage, data written by WriteMessage)
+ output.WriteLength(2 + nestedMessage.CalculateSize());
+ output.WriteTag(2, WireFormat.WireType.LengthDelimited);
+ output.WriteMessage(nestedMessage);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(nestedMessage, parsed.MapInt32ForeignMessage[0]);
+ }
+
+ [Test]
+ public void MapWithOnlyKey_PrimitiveValue()
+ {
+ // Hand-craft the stream to contain a single entry with just a key.
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+ output.WriteTag(TestMap.MapInt32DoubleFieldNumber, WireFormat.WireType.LengthDelimited);
+ int key = 10;
+ output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(0.0, parsed.MapInt32Double[key]);
+ }
+
+ [Test]
+ public void MapWithOnlyKey_MessageValue()
+ {
+ // Hand-craft the stream to contain a single entry with just a key.
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+ output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
+ int key = 10;
+ output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]);
+ }
+
+ [Test]
+ public void MapIgnoresExtraFieldsWithinEntryMessages()
+ {
+ // Hand-craft the stream to contain a single entry with three fields
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+
+ var key = 10; // Field 1
+ var value = 20; // Field 2
+ var extra = 30; // Field 3
+
+ // Each field can be represented in a single byte, with a single byte tag.
+ // Total message size: 6 bytes.
+ output.WriteLength(6);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value);
+ output.WriteTag(3, WireFormat.WireType.Varint);
+ output.WriteInt32(extra);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(value, parsed.MapInt32Int32[key]);
+ }
+
+ [Test]
+ public void MapFieldOrderIsIrrelevant()
+ {
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+
+ var key = 10;
+ var value = 20;
+
+ // Each field can be represented in a single byte, with a single byte tag.
+ // Total message size: 4 bytes.
+ output.WriteLength(4);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(value, parsed.MapInt32Int32[key]);
+ }
+
+ [Test]
+ public void MapNonContiguousEntries()
+ {
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+
+ // Message structure:
+ // Entry for MapInt32Int32
+ // Entry for MapStringString
+ // Entry for MapInt32Int32
+
+ // First entry
+ var key1 = 10;
+ var value1 = 20;
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(4);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key1);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value1);
+
+ // Second entry
+ var key2 = "a";
+ var value2 = "b";
+ output.WriteTag(TestMap.MapStringStringFieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(6); // 3 bytes per entry: tag, size, character
+ output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteString(key2);
+ output.WriteTag(2, WireFormat.WireType.LengthDelimited);
+ output.WriteString(value2);
+
+ // Third entry
+ var key3 = 15;
+ var value3 = 25;
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(4);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key3);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value3);
+
+ output.Flush();
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ var expected = new TestMap
+ {
+ MapInt32Int32 = { { key1, value1 }, { key3, value3 } },
+ MapStringString = { { key2, value2 } }
+ };
+ Assert.AreEqual(expected, parsed);
+ }
+
+ [Test]
+ public void DuplicateKeys_LastEntryWins()
+ {
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+
+ var key = 10;
+ var value1 = 20;
+ var value2 = 30;
+
+ // First entry
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(4);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value1);
+
+ // Second entry - same key, different value
+ output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(4);
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.WriteTag(2, WireFormat.WireType.Varint);
+ output.WriteInt32(value2);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(value2, parsed.MapInt32Int32[key]);
+ }
+
+ [Test]
+ public void CloneSingleNonMessageValues()
+ {
+ var original = new TestAllTypes
+ {
+ SingleBool = true,
+ SingleBytes = ByteString.CopyFrom(1, 2, 3, 4),
+ SingleDouble = 23.5,
+ SingleFixed32 = 23,
+ SingleFixed64 = 1234567890123,
+ SingleFloat = 12.25f,
+ SingleInt32 = 100,
+ SingleInt64 = 3210987654321,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
+ SingleSfixed32 = -123,
+ SingleSfixed64 = -12345678901234,
+ SingleSint32 = -456,
+ SingleSint64 = -12345678901235,
+ SingleString = "test",
+ SingleUint32 = uint.MaxValue,
+ SingleUint64 = ulong.MaxValue
+ };
+ var clone = original.Clone();
+ Assert.AreNotSame(original, clone);
+ Assert.AreEqual(original, clone);
+ // Just as a single example
+ clone.SingleInt32 = 150;
+ Assert.AreNotEqual(original, clone);
+ }
+
+ [Test]
+ public void CloneRepeatedNonMessageValues()
+ {
+ var original = new TestAllTypes
+ {
+ RepeatedBool = { true, false },
+ RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
+ RepeatedDouble = { -12.25, 23.5 },
+ RepeatedFixed32 = { uint.MaxValue, 23 },
+ RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
+ RepeatedFloat = { 100f, 12.25f },
+ RepeatedInt32 = { 100, 200 },
+ RepeatedInt64 = { 3210987654321, long.MaxValue },
+ RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
+ 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 }
+ };
+
+ var clone = original.Clone();
+ Assert.AreNotSame(original, clone);
+ Assert.AreEqual(original, clone);
+ // Just as a single example
+ clone.RepeatedDouble.Add(25.5);
+ Assert.AreNotEqual(original, clone);
+ }
+
+ [Test]
+ public void CloneSingleMessageField()
+ {
+ var original = new TestAllTypes
+ {
+ SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
+ };
+
+ var clone = original.Clone();
+ Assert.AreNotSame(original, clone);
+ Assert.AreNotSame(original.SingleNestedMessage, clone.SingleNestedMessage);
+ Assert.AreEqual(original, clone);
+
+ clone.SingleNestedMessage.Bb = 30;
+ Assert.AreNotEqual(original, clone);
+ }
+
+ [Test]
+ public void CloneRepeatedMessageField()
+ {
+ var original = new TestAllTypes
+ {
+ RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 20 } }
+ };
+
+ var clone = original.Clone();
+ Assert.AreNotSame(original, clone);
+ Assert.AreNotSame(original.RepeatedNestedMessage, clone.RepeatedNestedMessage);
+ Assert.AreNotSame(original.RepeatedNestedMessage[0], clone.RepeatedNestedMessage[0]);
+ Assert.AreEqual(original, clone);
+
+ clone.RepeatedNestedMessage[0].Bb = 30;
+ Assert.AreNotEqual(original, clone);
+ }
+
+ [Test]
+ public void CloneOneofField()
+ {
+ var original = new TestAllTypes
+ {
+ OneofNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 }
+ };
+
+ var clone = original.Clone();
+ Assert.AreNotSame(original, clone);
+ Assert.AreEqual(original, clone);
+
+ // We should have cloned the message
+ original.OneofNestedMessage.Bb = 30;
+ Assert.AreNotEqual(original, clone);
+ }
+
+ [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 Oneof_DefaultValuesNotEqual()
+ {
+ var message1 = new TestAllTypes { OneofString = "" };
+ var message2 = new TestAllTypes { OneofUint32 = 0 };
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message1.OneofFieldCase);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
+ Assert.AreNotEqual(message1, message2);
+ }
+
+ [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);
+ }
+
+ [Test]
+ public void IgnoreUnknownFields_RealDataStillRead()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ var unusedFieldNumber = 23456;
+ Assert.IsFalse(TestAllTypes.Descriptor.Fields.InDeclarationOrder().Select(x => x.FieldNumber).Contains(unusedFieldNumber));
+ output.WriteTag(unusedFieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteString("ignore me");
+ message.WriteTo(output);
+ output.Flush();
+
+ stream.Position = 0;
+ var parsed = TestAllTypes.Parser.ParseFrom(stream);
+ Assert.AreEqual(message, parsed);
+ }
+
+ [Test]
+ public void IgnoreUnknownFields_AllTypes()
+ {
+ // Simple way of ensuring we can skip all kinds of fields.
+ var data = SampleMessages.CreateFullTestAllTypes().ToByteArray();
+ var empty = Empty.Parser.ParseFrom(data);
+ Assert.AreEqual(new Empty(), empty);
+ }
+
+ // This was originally seen as a conformance test failure.
+ [Test]
+ public void TruncatedMessageFieldThrows()
+ {
+ // 130, 3 is the message tag
+ // 1 is the data length - but there's no data.
+ var data = new byte[] { 130, 3, 1 };
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(data));
+ }
+
+ /// <summary>
+ /// Demonstrates current behaviour with an extraneous end group tag - see issue 688
+ /// for details; we may want to change this.
+ /// </summary>
+ [Test]
+ public void ExtraEndGroupThrows()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+
+ output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32);
+ output.WriteFixed32(123);
+ output.WriteTag(100, WireFormat.WireType.EndGroup);
+
+ output.Flush();
+
+ stream.Position = 0;
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_DirectToStringCall()
+ {
+ var message = new ForeignMessage { C = 31 };
+ Assert.AreEqual("{ \"c\": 31, \"@cInHex\": \"1f\" }", message.ToString());
+ Assert.AreEqual("{ \"c\": 31 }", JsonFormatter.Default.Format(message));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_Nested()
+ {
+ var message = new TestAllTypes { SingleForeignMessage = new ForeignMessage { C = 16 } };
+ Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16, \"@cInHex\": \"10\" } }", message.ToString());
+ Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16 } }", JsonFormatter.Default.Format(message));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_DirectToTextWriterCall()
+ {
+ var message = new ForeignMessage { C = 31 };
+ var writer = new StringWriter();
+ JsonFormatter.Default.Format(message, writer);
+ Assert.AreEqual("{ \"c\": 31 }", writer.ToString());
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/IssuesTest.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/IssuesTest.cs
index a38d6b08b5..ddb23aa685 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/IssuesTest.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/IssuesTest.cs
@@ -1,82 +1,82 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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 Google.Protobuf.Reflection;
-using UnitTest.Issues.TestProtos;
-using NUnit.Framework;
-
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Tests for issues which aren't easily compartmentalized into other unit tests.
- /// </summary>
- public class IssuesTest
- {
- // Issue 45
- [Test]
- public void FieldCalledItem()
- {
- ItemField message = new ItemField { Item = 3 };
- FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item");
- Assert.NotNull(field);
- Assert.AreEqual(3, (int)field.Accessor.GetValue(message));
- }
-
- [Test]
- public void ReservedNames()
- {
- var message = new ReservedNames { Types_ = 10, Descriptor_ = 20 };
- // Underscores aren't reflected in the JSON.
- Assert.AreEqual("{ \"types\": 10, \"descriptor\": 20 }", message.ToString());
- }
-
- [Test]
- public void JsonNameParseTest()
- {
- var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
- var parser = new JsonParser(settings);
-
- // It is safe to use either original field name or explicitly specified json_name
- Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
- parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
- }
-
- [Test]
- public void JsonNameFormatTest()
- {
- var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
- Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
- JsonFormatter.Default.Format(message));
- }
- }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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 Google.Protobuf.Reflection;
+using UnitTest.Issues.TestProtos;
+using NUnit.Framework;
+
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Tests for issues which aren't easily compartmentalized into other unit tests.
+ /// </summary>
+ public class IssuesTest
+ {
+ // Issue 45
+ [Test]
+ public void FieldCalledItem()
+ {
+ ItemField message = new ItemField { Item = 3 };
+ FieldDescriptor field = ItemField.Descriptor.FindFieldByName("item");
+ Assert.NotNull(field);
+ Assert.AreEqual(3, (int)field.Accessor.GetValue(message));
+ }
+
+ [Test]
+ public void ReservedNames()
+ {
+ var message = new ReservedNames { Types_ = 10, Descriptor_ = 20 };
+ // Underscores aren't reflected in the JSON.
+ Assert.AreEqual("{ \"types\": 10, \"descriptor\": 20 }", message.ToString());
+ }
+
+ [Test]
+ public void JsonNameParseTest()
+ {
+ var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
+ var parser = new JsonParser(settings);
+
+ // It is safe to use either original field name or explicitly specified json_name
+ Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
+ parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
+ }
+
+ [Test]
+ public void JsonNameFormatTest()
+ {
+ var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
+ Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
+ JsonFormatter.Default.Format(message));
+ }
+ }
+}
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/Program.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/Program.cs
index 954c02b5a2..254fb7b8ef 100755
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/Program.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/Program.cs
@@ -39,7 +39,7 @@ namespace Google.Protobuf.Test
public static int Main(string[] args)
{
#if NET35
- return new AutoRun(typeof(Program).Assembly).Execute(args);
+ return new AutoRun(typeof(Program).Assembly).Execute(args);
#else
return new AutoRun(typeof(Program).GetTypeInfo().Assembly).Execute(args);
#endif
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/TestCornerCases.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/TestCornerCases.cs
index 248f5fa913..fd75b19f42 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/TestCornerCases.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.Test/TestCornerCases.cs
@@ -1,62 +1,62 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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 UnitTest.Issues.TestProtos;
-using NUnit.Framework;
-
-namespace Google.Protobuf
-{
- public class TestCornerCases
- {
- [Test]
- public void TestRoundTripNegativeEnums()
- {
- NegativeEnumMessage msg = new NegativeEnumMessage
- {
- Value = NegativeEnum.MinusOne,
- Values = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
- PackedValues = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
- };
-
- Assert.AreEqual(58, msg.CalculateSize());
-
- byte[] bytes = new byte[58];
- CodedOutputStream output = new CodedOutputStream(bytes);
-
- msg.WriteTo(output);
- Assert.AreEqual(0, output.SpaceLeft);
-
- NegativeEnumMessage copy = NegativeEnumMessage.Parser.ParseFrom(bytes);
- Assert.AreEqual(msg, copy);
- }
- }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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 UnitTest.Issues.TestProtos;
+using NUnit.Framework;
+
+namespace Google.Protobuf
+{
+ public class TestCornerCases
+ {
+ [Test]
+ public void TestRoundTripNegativeEnums()
+ {
+ NegativeEnumMessage msg = new NegativeEnumMessage
+ {
+ Value = NegativeEnum.MinusOne,
+ Values = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
+ PackedValues = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
+ };
+
+ Assert.AreEqual(58, msg.CalculateSize());
+
+ byte[] bytes = new byte[58];
+ CodedOutputStream output = new CodedOutputStream(bytes);
+
+ msg.WriteTo(output);
+ Assert.AreEqual(0, output.SpaceLeft);
+
+ NegativeEnumMessage copy = NegativeEnumMessage.Parser.ParseFrom(bytes);
+ Assert.AreEqual(msg, copy);
+ }
+ }
+}
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.sln b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.sln
index 443ee3e93e..0c077cbbb1 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.sln
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf.sln
@@ -1,45 +1,45 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.26114.2
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressBook", "AddressBook\AddressBook.csproj", "{AFB63919-1E05-43B4-802A-8FB8C9B2F463}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.csproj", "{9B576380-726D-4142-8238-60A43AB0E35A}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.csproj", "{580EB013-D3C7-4578-B845-015F4A3B0591}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Conformance", "Google.Protobuf.Conformance\Google.Protobuf.Conformance.csproj", "{DDDC055B-E185-4181-BAB0-072F0F984569}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.csproj", "{9695E08F-9829-497D-B95C-B38F28D48690}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Release|Any CPU.Build.0 = Release|Any CPU
- {9B576380-726D-4142-8238-60A43AB0E35A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9B576380-726D-4142-8238-60A43AB0E35A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9B576380-726D-4142-8238-60A43AB0E35A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9B576380-726D-4142-8238-60A43AB0E35A}.Release|Any CPU.Build.0 = Release|Any CPU
- {580EB013-D3C7-4578-B845-015F4A3B0591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {580EB013-D3C7-4578-B845-015F4A3B0591}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {580EB013-D3C7-4578-B845-015F4A3B0591}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {580EB013-D3C7-4578-B845-015F4A3B0591}.Release|Any CPU.Build.0 = Release|Any CPU
- {DDDC055B-E185-4181-BAB0-072F0F984569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {DDDC055B-E185-4181-BAB0-072F0F984569}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {DDDC055B-E185-4181-BAB0-072F0F984569}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {DDDC055B-E185-4181-BAB0-072F0F984569}.Release|Any CPU.Build.0 = Release|Any CPU
- {9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26114.2
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressBook", "AddressBook\AddressBook.csproj", "{AFB63919-1E05-43B4-802A-8FB8C9B2F463}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.csproj", "{9B576380-726D-4142-8238-60A43AB0E35A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.csproj", "{580EB013-D3C7-4578-B845-015F4A3B0591}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Conformance", "Google.Protobuf.Conformance\Google.Protobuf.Conformance.csproj", "{DDDC055B-E185-4181-BAB0-072F0F984569}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.JsonDump", "Google.Protobuf.JsonDump\Google.Protobuf.JsonDump.csproj", "{9695E08F-9829-497D-B95C-B38F28D48690}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AFB63919-1E05-43B4-802A-8FB8C9B2F463}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9B576380-726D-4142-8238-60A43AB0E35A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9B576380-726D-4142-8238-60A43AB0E35A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9B576380-726D-4142-8238-60A43AB0E35A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9B576380-726D-4142-8238-60A43AB0E35A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {580EB013-D3C7-4578-B845-015F4A3B0591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {580EB013-D3C7-4578-B845-015F4A3B0591}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {580EB013-D3C7-4578-B845-015F4A3B0591}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {580EB013-D3C7-4578-B845-015F4A3B0591}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DDDC055B-E185-4181-BAB0-072F0F984569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DDDC055B-E185-4181-BAB0-072F0F984569}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DDDC055B-E185-4181-BAB0-072F0F984569}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DDDC055B-E185-4181-BAB0-072F0F984569}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9695E08F-9829-497D-B95C-B38F28D48690}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9695E08F-9829-497D-B95C-B38F28D48690}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/ByteArray.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/ByteArray.cs
index 69b6ef8d63..b19962794b 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/ByteArray.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/ByteArray.cs
@@ -1,79 +1,79 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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;
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Provides a utility routine to copy small arrays much more quickly than Buffer.BlockCopy
- /// </summary>
- internal static class ByteArray
- {
- /// <summary>
- /// The threshold above which you should use Buffer.BlockCopy rather than ByteArray.Copy
- /// </summary>
- private const int CopyThreshold = 12;
-
- /// <summary>
- /// Determines which copy routine to use based on the number of bytes to be copied.
- /// </summary>
- internal static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count)
- {
- if (count > CopyThreshold)
- {
- Buffer.BlockCopy(src, srcOffset, dst, dstOffset, count);
- }
- else
- {
- int stop = srcOffset + count;
- for (int i = srcOffset; i < stop; i++)
- {
- dst[dstOffset++] = src[i];
- }
- }
- }
-
- /// <summary>
- /// Reverses the order of bytes in the array
- /// </summary>
- internal static void Reverse(byte[] bytes)
- {
- for (int first = 0, last = bytes.Length - 1; first < last; first++, last--)
- {
- byte temp = bytes[first];
- bytes[first] = bytes[last];
- bytes[last] = temp;
- }
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Provides a utility routine to copy small arrays much more quickly than Buffer.BlockCopy
+ /// </summary>
+ internal static class ByteArray
+ {
+ /// <summary>
+ /// The threshold above which you should use Buffer.BlockCopy rather than ByteArray.Copy
+ /// </summary>
+ private const int CopyThreshold = 12;
+
+ /// <summary>
+ /// Determines which copy routine to use based on the number of bytes to be copied.
+ /// </summary>
+ internal static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count)
+ {
+ if (count > CopyThreshold)
+ {
+ Buffer.BlockCopy(src, srcOffset, dst, dstOffset, count);
+ }
+ else
+ {
+ int stop = srcOffset + count;
+ for (int i = srcOffset; i < stop; i++)
+ {
+ dst[dstOffset++] = src[i];
+ }
+ }
+ }
+
+ /// <summary>
+ /// Reverses the order of bytes in the array
+ /// </summary>
+ internal static void Reverse(byte[] bytes)
+ {
+ for (int first = 0, last = bytes.Length - 1; first < last; first++, last--)
+ {
+ byte temp = bytes[first];
+ bytes[first] = bytes[last];
+ bytes[last] = temp;
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/ByteString.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/ByteString.cs
index 4abdb7182c..c7f961e5ec 100755
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/ByteString.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/ByteString.cs
@@ -1,401 +1,401 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-#if !NET35
-using System.Threading;
-using System.Threading.Tasks;
-#endif
-#if NET35
-using Google.Protobuf.Compatibility;
-#endif
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Immutable array of bytes.
- /// </summary>
- public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString>
- {
- private static readonly ByteString empty = new ByteString(new byte[0]);
-
- private readonly byte[] bytes;
-
- /// <summary>
- /// Unsafe operations that can cause IO Failure and/or other catestrophic side-effects.
- /// </summary>
- internal static class Unsafe
- {
- /// <summary>
- /// Constructs a new ByteString from the given byte array. The array is
- /// *not* copied, and must not be modified after this constructor is called.
- /// </summary>
- internal static ByteString FromBytes(byte[] bytes)
- {
- return new ByteString(bytes);
- }
-
- /// <summary>
- /// Provides direct, unrestricted access to the bytes contained in this instance.
- /// You must not modify or resize the byte array returned by this method.
- /// </summary>
- internal static byte[] GetBuffer(ByteString bytes)
- {
- return bytes.bytes;
- }
- }
-
- /// <summary>
- /// Internal use only. Ensure that the provided array is not mutated and belongs to this instance.
- /// </summary>
- internal static ByteString AttachBytes(byte[] bytes)
- {
- return new ByteString(bytes);
- }
-
- /// <summary>
- /// Constructs a new ByteString from the given byte array. The array is
- /// *not* copied, and must not be modified after this constructor is called.
- /// </summary>
- private ByteString(byte[] bytes)
- {
- this.bytes = bytes;
- }
-
- /// <summary>
- /// Returns an empty ByteString.
- /// </summary>
- public static ByteString Empty
- {
- get { return empty; }
- }
-
- /// <summary>
- /// Returns the length of this ByteString in bytes.
- /// </summary>
- public int Length
- {
- get { return bytes.Length; }
- }
-
- /// <summary>
- /// Returns <c>true</c> if this byte string is empty, <c>false</c> otherwise.
- /// </summary>
- public bool IsEmpty
- {
- get { return Length == 0; }
- }
-
- /// <summary>
- /// Converts this <see cref="ByteString"/> into a byte array.
- /// </summary>
- /// <remarks>The data is copied - changes to the returned array will not be reflected in this <c>ByteString</c>.</remarks>
- /// <returns>A byte array with the same data as this <c>ByteString</c>.</returns>
- public byte[] ToByteArray()
- {
- return (byte[]) bytes.Clone();
- }
-
- /// <summary>
- /// Converts this <see cref="ByteString"/> into a standard base64 representation.
- /// </summary>
- /// <returns>A base64 representation of this <c>ByteString</c>.</returns>
- public string ToBase64()
- {
- return Convert.ToBase64String(bytes);
- }
-
- /// <summary>
- /// Constructs a <see cref="ByteString" /> from the Base64 Encoded String.
- /// </summary>
- public static ByteString FromBase64(string bytes)
- {
- // By handling the empty string explicitly, we not only optimize but we fix a
- // problem on CF 2.0. See issue 61 for details.
- return bytes == "" ? Empty : new ByteString(Convert.FromBase64String(bytes));
- }
-
- /// <summary>
- /// Constructs a <see cref="ByteString"/> from data in the given stream, synchronously.
- /// </summary>
- /// <remarks>If successful, <paramref name="stream"/> will be read completely, from the position
- /// at the start of the call.</remarks>
- /// <param name="stream">The stream to copy into a ByteString.</param>
- /// <returns>A ByteString with content read from the given stream.</returns>
- public static ByteString FromStream(Stream stream)
- {
- ProtoPreconditions.CheckNotNull(stream, nameof(stream));
- int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0;
- var memoryStream = new MemoryStream(capacity);
- stream.CopyTo(memoryStream);
-#if NETSTANDARD1_0
- byte[] bytes = memoryStream.ToArray();
-#else
- // Avoid an extra copy if we can.
- byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray();
-#endif
- return AttachBytes(bytes);
- }
-
-#if !NET35
- /// <summary>
- /// Constructs a <see cref="ByteString"/> from data in the given stream, asynchronously.
- /// </summary>
- /// <remarks>If successful, <paramref name="stream"/> will be read completely, from the position
- /// at the start of the call.</remarks>
- /// <param name="stream">The stream to copy into a ByteString.</param>
- /// <param name="cancellationToken">The cancellation token to use when reading from the stream, if any.</param>
- /// <returns>A ByteString with content read from the given stream.</returns>
- public async static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
- {
- ProtoPreconditions.CheckNotNull(stream, nameof(stream));
- int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0;
- var memoryStream = new MemoryStream(capacity);
- // We have to specify the buffer size here, as there's no overload accepting the cancellation token
- // alone. But it's documented to use 81920 by default if not specified.
- await stream.CopyToAsync(memoryStream, 81920, cancellationToken);
-#if NETSTANDARD1_0
- byte[] bytes = memoryStream.ToArray();
-#else
- // Avoid an extra copy if we can.
- byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray();
-#endif
- return AttachBytes(bytes);
- }
-#endif
-
- /// <summary>
- /// Constructs a <see cref="ByteString" /> from the given array. The contents
- /// are copied, so further modifications to the array will not
- /// be reflected in the returned ByteString.
- /// This method can also be invoked in <c>ByteString.CopyFrom(0xaa, 0xbb, ...)</c> form
- /// which is primarily useful for testing.
- /// </summary>
- public static ByteString CopyFrom(params byte[] bytes)
- {
- return new ByteString((byte[]) bytes.Clone());
- }
-
- /// <summary>
- /// Constructs a <see cref="ByteString" /> from a portion of a byte array.
- /// </summary>
- public static ByteString CopyFrom(byte[] bytes, int offset, int count)
- {
- byte[] portion = new byte[count];
- ByteArray.Copy(bytes, offset, portion, 0, count);
- return new ByteString(portion);
- }
-
- /// <summary>
- /// Creates a new <see cref="ByteString" /> by encoding the specified text with
- /// the given encoding.
- /// </summary>
- public static ByteString CopyFrom(string text, Encoding encoding)
- {
- return new ByteString(encoding.GetBytes(text));
- }
-
- /// <summary>
- /// Creates a new <see cref="ByteString" /> by encoding the specified text in UTF-8.
- /// </summary>
- public static ByteString CopyFromUtf8(string text)
- {
- return CopyFrom(text, Encoding.UTF8);
- }
-
- /// <summary>
- /// Retuns the byte at the given index.
- /// </summary>
- public byte this[int index]
- {
- get { return bytes[index]; }
- }
-
- /// <summary>
- /// Converts this <see cref="ByteString"/> into a string by applying the given encoding.
- /// </summary>
- /// <remarks>
- /// This method should only be used to convert binary data which was the result of encoding
- /// text with the given encoding.
- /// </remarks>
- /// <param name="encoding">The encoding to use to decode the binary data into text.</param>
- /// <returns>The result of decoding the binary data with the given decoding.</returns>
- public string ToString(Encoding encoding)
- {
- return encoding.GetString(bytes, 0, bytes.Length);
- }
-
- /// <summary>
- /// Converts this <see cref="ByteString"/> into a string by applying the UTF-8 encoding.
- /// </summary>
- /// <remarks>
- /// This method should only be used to convert binary data which was the result of encoding
- /// text with UTF-8.
- /// </remarks>
- /// <returns>The result of decoding the binary data with the given decoding.</returns>
- public string ToStringUtf8()
- {
- return ToString(Encoding.UTF8);
- }
-
- /// <summary>
- /// Returns an iterator over the bytes in this <see cref="ByteString"/>.
- /// </summary>
- /// <returns>An iterator over the bytes in this object.</returns>
- public IEnumerator<byte> GetEnumerator()
- {
- return ((IEnumerable<byte>) bytes).GetEnumerator();
- }
-
- /// <summary>
- /// Returns an iterator over the bytes in this <see cref="ByteString"/>.
- /// </summary>
- /// <returns>An iterator over the bytes in this object.</returns>
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- /// <summary>
- /// Creates a CodedInputStream from this ByteString's data.
- /// </summary>
- public CodedInputStream CreateCodedInput()
- {
- // We trust CodedInputStream not to reveal the provided byte array or modify it
- return new CodedInputStream(bytes);
- }
-
- /// <summary>
- /// Compares two byte strings for equality.
- /// </summary>
- /// <param name="lhs">The first byte string to compare.</param>
- /// <param name="rhs">The second byte string to compare.</param>
- /// <returns><c>true</c> if the byte strings are equal; false otherwise.</returns>
- public static bool operator ==(ByteString lhs, ByteString rhs)
- {
- if (ReferenceEquals(lhs, rhs))
- {
- return true;
- }
- if (ReferenceEquals(lhs, null) || ReferenceEquals(rhs, null))
- {
- return false;
- }
- if (lhs.bytes.Length != rhs.bytes.Length)
- {
- return false;
- }
- for (int i = 0; i < lhs.Length; i++)
- {
- if (rhs.bytes[i] != lhs.bytes[i])
- {
- return false;
- }
- }
- return true;
- }
-
- /// <summary>
- /// Compares two byte strings for inequality.
- /// </summary>
- /// <param name="lhs">The first byte string to compare.</param>
- /// <param name="rhs">The second byte string to compare.</param>
- /// <returns><c>false</c> if the byte strings are equal; true otherwise.</returns>
- public static bool operator !=(ByteString lhs, ByteString rhs)
- {
- return !(lhs == rhs);
- }
-
- /// <summary>
- /// Compares this byte string with another object.
- /// </summary>
- /// <param name="obj">The object to compare this with.</param>
- /// <returns><c>true</c> if <paramref name="obj"/> refers to an equal <see cref="ByteString"/>; <c>false</c> otherwise.</returns>
- public override bool Equals(object obj)
- {
- return this == (obj as ByteString);
- }
-
- /// <summary>
- /// Returns a hash code for this object. Two equal byte strings
- /// will return the same hash code.
- /// </summary>
- /// <returns>A hash code for this object.</returns>
- public override int GetHashCode()
- {
- int ret = 23;
- foreach (byte b in bytes)
- {
- ret = (ret * 31) + b;
- }
- return ret;
- }
-
- /// <summary>
- /// Compares this byte string with another.
- /// </summary>
- /// <param name="other">The <see cref="ByteString"/> to compare this with.</param>
- /// <returns><c>true</c> if <paramref name="other"/> refers to an equal byte string; <c>false</c> otherwise.</returns>
- public bool Equals(ByteString other)
- {
- return this == other;
- }
-
- /// <summary>
- /// Used internally by CodedOutputStream to avoid creating a copy for the write
- /// </summary>
- internal void WriteRawBytesTo(CodedOutputStream outputStream)
- {
- outputStream.WriteRawBytes(bytes, 0, bytes.Length);
- }
-
- /// <summary>
- /// Copies the entire byte array to the destination array provided at the offset specified.
- /// </summary>
- public void CopyTo(byte[] array, int position)
- {
- ByteArray.Copy(bytes, 0, array, position, bytes.Length);
- }
-
- /// <summary>
- /// Writes the entire byte array to the provided stream
- /// </summary>
- public void WriteTo(Stream outputStream)
- {
- outputStream.Write(bytes, 0, bytes.Length);
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+#if !NET35
+using System.Threading;
+using System.Threading.Tasks;
+#endif
+#if NET35
+using Google.Protobuf.Compatibility;
+#endif
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Immutable array of bytes.
+ /// </summary>
+ public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString>
+ {
+ private static readonly ByteString empty = new ByteString(new byte[0]);
+
+ private readonly byte[] bytes;
+
+ /// <summary>
+ /// Unsafe operations that can cause IO Failure and/or other catestrophic side-effects.
+ /// </summary>
+ internal static class Unsafe
+ {
+ /// <summary>
+ /// Constructs a new ByteString from the given byte array. The array is
+ /// *not* copied, and must not be modified after this constructor is called.
+ /// </summary>
+ internal static ByteString FromBytes(byte[] bytes)
+ {
+ return new ByteString(bytes);
+ }
+
+ /// <summary>
+ /// Provides direct, unrestricted access to the bytes contained in this instance.
+ /// You must not modify or resize the byte array returned by this method.
+ /// </summary>
+ internal static byte[] GetBuffer(ByteString bytes)
+ {
+ return bytes.bytes;
+ }
+ }
+
+ /// <summary>
+ /// Internal use only. Ensure that the provided array is not mutated and belongs to this instance.
+ /// </summary>
+ internal static ByteString AttachBytes(byte[] bytes)
+ {
+ return new ByteString(bytes);
+ }
+
+ /// <summary>
+ /// Constructs a new ByteString from the given byte array. The array is
+ /// *not* copied, and must not be modified after this constructor is called.
+ /// </summary>
+ private ByteString(byte[] bytes)
+ {
+ this.bytes = bytes;
+ }
+
+ /// <summary>
+ /// Returns an empty ByteString.
+ /// </summary>
+ public static ByteString Empty
+ {
+ get { return empty; }
+ }
+
+ /// <summary>
+ /// Returns the length of this ByteString in bytes.
+ /// </summary>
+ public int Length
+ {
+ get { return bytes.Length; }
+ }
+
+ /// <summary>
+ /// Returns <c>true</c> if this byte string is empty, <c>false</c> otherwise.
+ /// </summary>
+ public bool IsEmpty
+ {
+ get { return Length == 0; }
+ }
+
+ /// <summary>
+ /// Converts this <see cref="ByteString"/> into a byte array.
+ /// </summary>
+ /// <remarks>The data is copied - changes to the returned array will not be reflected in this <c>ByteString</c>.</remarks>
+ /// <returns>A byte array with the same data as this <c>ByteString</c>.</returns>
+ public byte[] ToByteArray()
+ {
+ return (byte[]) bytes.Clone();
+ }
+
+ /// <summary>
+ /// Converts this <see cref="ByteString"/> into a standard base64 representation.
+ /// </summary>
+ /// <returns>A base64 representation of this <c>ByteString</c>.</returns>
+ public string ToBase64()
+ {
+ return Convert.ToBase64String(bytes);
+ }
+
+ /// <summary>
+ /// Constructs a <see cref="ByteString" /> from the Base64 Encoded String.
+ /// </summary>
+ public static ByteString FromBase64(string bytes)
+ {
+ // By handling the empty string explicitly, we not only optimize but we fix a
+ // problem on CF 2.0. See issue 61 for details.
+ return bytes == "" ? Empty : new ByteString(Convert.FromBase64String(bytes));
+ }
+
+ /// <summary>
+ /// Constructs a <see cref="ByteString"/> from data in the given stream, synchronously.
+ /// </summary>
+ /// <remarks>If successful, <paramref name="stream"/> will be read completely, from the position
+ /// at the start of the call.</remarks>
+ /// <param name="stream">The stream to copy into a ByteString.</param>
+ /// <returns>A ByteString with content read from the given stream.</returns>
+ public static ByteString FromStream(Stream stream)
+ {
+ ProtoPreconditions.CheckNotNull(stream, nameof(stream));
+ int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0;
+ var memoryStream = new MemoryStream(capacity);
+ stream.CopyTo(memoryStream);
+#if NETSTANDARD1_0
+ byte[] bytes = memoryStream.ToArray();
+#else
+ // Avoid an extra copy if we can.
+ byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray();
+#endif
+ return AttachBytes(bytes);
+ }
+
+#if !NET35
+ /// <summary>
+ /// Constructs a <see cref="ByteString"/> from data in the given stream, asynchronously.
+ /// </summary>
+ /// <remarks>If successful, <paramref name="stream"/> will be read completely, from the position
+ /// at the start of the call.</remarks>
+ /// <param name="stream">The stream to copy into a ByteString.</param>
+ /// <param name="cancellationToken">The cancellation token to use when reading from the stream, if any.</param>
+ /// <returns>A ByteString with content read from the given stream.</returns>
+ public async static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ ProtoPreconditions.CheckNotNull(stream, nameof(stream));
+ int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0;
+ var memoryStream = new MemoryStream(capacity);
+ // We have to specify the buffer size here, as there's no overload accepting the cancellation token
+ // alone. But it's documented to use 81920 by default if not specified.
+ await stream.CopyToAsync(memoryStream, 81920, cancellationToken);
+#if NETSTANDARD1_0
+ byte[] bytes = memoryStream.ToArray();
+#else
+ // Avoid an extra copy if we can.
+ byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray();
+#endif
+ return AttachBytes(bytes);
+ }
+#endif
+
+ /// <summary>
+ /// Constructs a <see cref="ByteString" /> from the given array. The contents
+ /// are copied, so further modifications to the array will not
+ /// be reflected in the returned ByteString.
+ /// This method can also be invoked in <c>ByteString.CopyFrom(0xaa, 0xbb, ...)</c> form
+ /// which is primarily useful for testing.
+ /// </summary>
+ public static ByteString CopyFrom(params byte[] bytes)
+ {
+ return new ByteString((byte[]) bytes.Clone());
+ }
+
+ /// <summary>
+ /// Constructs a <see cref="ByteString" /> from a portion of a byte array.
+ /// </summary>
+ public static ByteString CopyFrom(byte[] bytes, int offset, int count)
+ {
+ byte[] portion = new byte[count];
+ ByteArray.Copy(bytes, offset, portion, 0, count);
+ return new ByteString(portion);
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="ByteString" /> by encoding the specified text with
+ /// the given encoding.
+ /// </summary>
+ public static ByteString CopyFrom(string text, Encoding encoding)
+ {
+ return new ByteString(encoding.GetBytes(text));
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="ByteString" /> by encoding the specified text in UTF-8.
+ /// </summary>
+ public static ByteString CopyFromUtf8(string text)
+ {
+ return CopyFrom(text, Encoding.UTF8);
+ }
+
+ /// <summary>
+ /// Retuns the byte at the given index.
+ /// </summary>
+ public byte this[int index]
+ {
+ get { return bytes[index]; }
+ }
+
+ /// <summary>
+ /// Converts this <see cref="ByteString"/> into a string by applying the given encoding.
+ /// </summary>
+ /// <remarks>
+ /// This method should only be used to convert binary data which was the result of encoding
+ /// text with the given encoding.
+ /// </remarks>
+ /// <param name="encoding">The encoding to use to decode the binary data into text.</param>
+ /// <returns>The result of decoding the binary data with the given decoding.</returns>
+ public string ToString(Encoding encoding)
+ {
+ return encoding.GetString(bytes, 0, bytes.Length);
+ }
+
+ /// <summary>
+ /// Converts this <see cref="ByteString"/> into a string by applying the UTF-8 encoding.
+ /// </summary>
+ /// <remarks>
+ /// This method should only be used to convert binary data which was the result of encoding
+ /// text with UTF-8.
+ /// </remarks>
+ /// <returns>The result of decoding the binary data with the given decoding.</returns>
+ public string ToStringUtf8()
+ {
+ return ToString(Encoding.UTF8);
+ }
+
+ /// <summary>
+ /// Returns an iterator over the bytes in this <see cref="ByteString"/>.
+ /// </summary>
+ /// <returns>An iterator over the bytes in this object.</returns>
+ public IEnumerator<byte> GetEnumerator()
+ {
+ return ((IEnumerable<byte>) bytes).GetEnumerator();
+ }
+
+ /// <summary>
+ /// Returns an iterator over the bytes in this <see cref="ByteString"/>.
+ /// </summary>
+ /// <returns>An iterator over the bytes in this object.</returns>
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ /// <summary>
+ /// Creates a CodedInputStream from this ByteString's data.
+ /// </summary>
+ public CodedInputStream CreateCodedInput()
+ {
+ // We trust CodedInputStream not to reveal the provided byte array or modify it
+ return new CodedInputStream(bytes);
+ }
+
+ /// <summary>
+ /// Compares two byte strings for equality.
+ /// </summary>
+ /// <param name="lhs">The first byte string to compare.</param>
+ /// <param name="rhs">The second byte string to compare.</param>
+ /// <returns><c>true</c> if the byte strings are equal; false otherwise.</returns>
+ public static bool operator ==(ByteString lhs, ByteString rhs)
+ {
+ if (ReferenceEquals(lhs, rhs))
+ {
+ return true;
+ }
+ if (ReferenceEquals(lhs, null) || ReferenceEquals(rhs, null))
+ {
+ return false;
+ }
+ if (lhs.bytes.Length != rhs.bytes.Length)
+ {
+ return false;
+ }
+ for (int i = 0; i < lhs.Length; i++)
+ {
+ if (rhs.bytes[i] != lhs.bytes[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Compares two byte strings for inequality.
+ /// </summary>
+ /// <param name="lhs">The first byte string to compare.</param>
+ /// <param name="rhs">The second byte string to compare.</param>
+ /// <returns><c>false</c> if the byte strings are equal; true otherwise.</returns>
+ public static bool operator !=(ByteString lhs, ByteString rhs)
+ {
+ return !(lhs == rhs);
+ }
+
+ /// <summary>
+ /// Compares this byte string with another object.
+ /// </summary>
+ /// <param name="obj">The object to compare this with.</param>
+ /// <returns><c>true</c> if <paramref name="obj"/> refers to an equal <see cref="ByteString"/>; <c>false</c> otherwise.</returns>
+ public override bool Equals(object obj)
+ {
+ return this == (obj as ByteString);
+ }
+
+ /// <summary>
+ /// Returns a hash code for this object. Two equal byte strings
+ /// will return the same hash code.
+ /// </summary>
+ /// <returns>A hash code for this object.</returns>
+ public override int GetHashCode()
+ {
+ int ret = 23;
+ foreach (byte b in bytes)
+ {
+ ret = (ret * 31) + b;
+ }
+ return ret;
+ }
+
+ /// <summary>
+ /// Compares this byte string with another.
+ /// </summary>
+ /// <param name="other">The <see cref="ByteString"/> to compare this with.</param>
+ /// <returns><c>true</c> if <paramref name="other"/> refers to an equal byte string; <c>false</c> otherwise.</returns>
+ public bool Equals(ByteString other)
+ {
+ return this == other;
+ }
+
+ /// <summary>
+ /// Used internally by CodedOutputStream to avoid creating a copy for the write
+ /// </summary>
+ internal void WriteRawBytesTo(CodedOutputStream outputStream)
+ {
+ outputStream.WriteRawBytes(bytes, 0, bytes.Length);
+ }
+
+ /// <summary>
+ /// Copies the entire byte array to the destination array provided at the offset specified.
+ /// </summary>
+ public void CopyTo(byte[] array, int position)
+ {
+ ByteArray.Copy(bytes, 0, array, position, bytes.Length);
+ }
+
+ /// <summary>
+ /// Writes the entire byte array to the provided stream
+ /// </summary>
+ public void WriteTo(Stream outputStream)
+ {
+ outputStream.Write(bytes, 0, bytes.Length);
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedInputStream.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedInputStream.cs
index 84f90a2551..0123a0f443 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedInputStream.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedInputStream.cs
@@ -1,1276 +1,1276 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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 Google.Protobuf.Collections;
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Reads and decodes protocol message fields.
- /// </summary>
- /// <remarks>
- /// <para>
- /// This class is generally used by generated code to read appropriate
- /// primitives from the stream. It effectively encapsulates the lowest
- /// levels of protocol buffer format.
- /// </para>
- /// <para>
- /// Repeated fields and map fields are not handled by this class; use <see cref="RepeatedField{T}"/>
- /// and <see cref="MapField{TKey, TValue}"/> to serialize such fields.
- /// </para>
- /// </remarks>
- public sealed class CodedInputStream : IDisposable
- {
- /// <summary>
- /// Whether to leave the underlying stream open when disposing of this stream.
- /// This is always true when there's no stream.
- /// </summary>
- private readonly bool leaveOpen;
-
- /// <summary>
- /// Buffer of data read from the stream or provided at construction time.
- /// </summary>
- private readonly byte[] buffer;
-
- /// <summary>
- /// The index of the buffer at which we need to refill from the stream (if there is one).
- /// </summary>
- private int bufferSize;
-
- private int bufferSizeAfterLimit = 0;
- /// <summary>
- /// The position within the current buffer (i.e. the next byte to read)
- /// </summary>
- private int bufferPos = 0;
-
- /// <summary>
- /// The stream to read further input from, or null if the byte array buffer was provided
- /// directly on construction, with no further data available.
- /// </summary>
- private readonly Stream input;
-
- /// <summary>
- /// The last tag we read. 0 indicates we've read to the end of the stream
- /// (or haven't read anything yet).
- /// </summary>
- private uint lastTag = 0;
-
- /// <summary>
- /// The next tag, used to store the value read by PeekTag.
- /// </summary>
- private uint nextTag = 0;
- private bool hasNextTag = false;
-
- internal const int DefaultRecursionLimit = 64;
- internal const int DefaultSizeLimit = 64 << 20; // 64MB
- internal const int BufferSize = 4096;
-
- /// <summary>
- /// The total number of bytes read before the current buffer. The
- /// total bytes read up to the current position can be computed as
- /// totalBytesRetired + bufferPos.
- /// </summary>
- private int totalBytesRetired = 0;
-
- /// <summary>
- /// The absolute position of the end of the current message.
- /// </summary>
- private int currentLimit = int.MaxValue;
-
- private int recursionDepth = 0;
-
- private readonly int recursionLimit;
- private readonly int sizeLimit;
-
- #region Construction
- // Note that the checks are performed such that we don't end up checking obviously-valid things
- // like non-null references for arrays we've just created.
-
- /// <summary>
- /// Creates a new CodedInputStream reading data from the given byte array.
- /// </summary>
- public CodedInputStream(byte[] buffer) : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), 0, buffer.Length, true)
- {
- }
-
- /// <summary>
- /// Creates a new <see cref="CodedInputStream"/> that reads from the given byte array slice.
- /// </summary>
- public CodedInputStream(byte[] buffer, int offset, int length)
- : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), offset, offset + length, true)
- {
- if (offset < 0 || offset > buffer.Length)
- {
- throw new ArgumentOutOfRangeException("offset", "Offset must be within the buffer");
- }
- if (length < 0 || offset + length > buffer.Length)
- {
- throw new ArgumentOutOfRangeException("length", "Length must be non-negative and within the buffer");
- }
- }
-
- /// <summary>
- /// Creates a new <see cref="CodedInputStream"/> reading data from the given stream, which will be disposed
- /// when the returned object is disposed.
- /// </summary>
- /// <param name="input">The stream to read from.</param>
- public CodedInputStream(Stream input) : this(input, false)
- {
- }
-
- /// <summary>
- /// Creates a new <see cref="CodedInputStream"/> reading data from the given stream.
- /// </summary>
- /// <param name="input">The stream to read from.</param>
- /// <param name="leaveOpen"><c>true</c> to leave <paramref name="input"/> open when the returned
- /// <c cref="CodedInputStream"/> is disposed; <c>false</c> to dispose of the given stream when the
- /// returned object is disposed.</param>
- public CodedInputStream(Stream input, bool leaveOpen)
- : this(ProtoPreconditions.CheckNotNull(input, "input"), new byte[BufferSize], 0, 0, leaveOpen)
- {
- }
-
- /// <summary>
- /// Creates a new CodedInputStream reading data from the given
- /// stream and buffer, using the default limits.
- /// </summary>
- internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, bool leaveOpen)
- {
- this.input = input;
- this.buffer = buffer;
- this.bufferPos = bufferPos;
- this.bufferSize = bufferSize;
- this.sizeLimit = DefaultSizeLimit;
- this.recursionLimit = DefaultRecursionLimit;
- this.leaveOpen = leaveOpen;
- }
-
- /// <summary>
- /// Creates a new CodedInputStream reading data from the given
- /// stream and buffer, using the specified limits.
- /// </summary>
- /// <remarks>
- /// This chains to the version with the default limits instead of vice versa to avoid
- /// having to check that the default values are valid every time.
- /// </remarks>
- internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, int sizeLimit, int recursionLimit, bool leaveOpen)
- : this(input, buffer, bufferPos, bufferSize, leaveOpen)
- {
- if (sizeLimit <= 0)
- {
- throw new ArgumentOutOfRangeException("sizeLimit", "Size limit must be positive");
- }
- if (recursionLimit <= 0)
- {
- throw new ArgumentOutOfRangeException("recursionLimit!", "Recursion limit must be positive");
- }
- this.sizeLimit = sizeLimit;
- this.recursionLimit = recursionLimit;
- }
- #endregion
-
- /// <summary>
- /// Creates a <see cref="CodedInputStream"/> with the specified size and recursion limits, reading
- /// from an input stream.
- /// </summary>
- /// <remarks>
- /// This method exists separately from the constructor to reduce the number of constructor overloads.
- /// It is likely to be used considerably less frequently than the constructors, as the default limits
- /// are suitable for most use cases.
- /// </remarks>
- /// <param name="input">The input stream to read from</param>
- /// <param name="sizeLimit">The total limit of data to read from the stream.</param>
- /// <param name="recursionLimit">The maximum recursion depth to allow while reading.</param>
- /// <returns>A <c>CodedInputStream</c> reading from <paramref name="input"/> with the specified size
- /// and recursion limits.</returns>
- public static CodedInputStream CreateWithLimits(Stream input, int sizeLimit, int recursionLimit)
- {
- // Note: we may want an overload accepting leaveOpen
- return new CodedInputStream(input, new byte[BufferSize], 0, 0, sizeLimit, recursionLimit, false);
- }
-
- /// <summary>
- /// Returns the current position in the input stream, or the position in the input buffer
- /// </summary>
- public long Position
- {
- get
- {
- if (input != null)
- {
- return input.Position - ((bufferSize + bufferSizeAfterLimit) - bufferPos);
- }
- return bufferPos;
- }
- }
-
- /// <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; } }
-
- /// <summary>
- /// Returns the size limit for this stream.
- /// </summary>
- /// <remarks>
- /// This limit is applied when reading from the underlying stream, as a sanity check. It is
- /// not applied when reading from a byte array data source without an underlying stream.
- /// The default value is 64MB.
- /// </remarks>
- /// <value>
- /// The size limit.
- /// </value>
- public int SizeLimit { get { return sizeLimit; } }
-
- /// <summary>
- /// Returns the recursion limit for this stream. This limit is applied whilst reading messages,
- /// to avoid maliciously-recursive data.
- /// </summary>
- /// <remarks>
- /// The default limit is 64.
- /// </remarks>
- /// <value>
- /// The recursion limit for this stream.
- /// </value>
- public int RecursionLimit { get { return recursionLimit; } }
-
- /// <summary>
- /// Disposes of this instance, potentially closing any underlying stream.
- /// </summary>
- /// <remarks>
- /// As there is no flushing to perform here, disposing of a <see cref="CodedInputStream"/> which
- /// was constructed with the <c>leaveOpen</c> option parameter set to <c>true</c> (or one which
- /// was constructed to read from a byte array) has no effect.
- /// </remarks>
- public void Dispose()
- {
- if (!leaveOpen)
- {
- input.Dispose();
- }
- }
-
- #region Validation
- /// <summary>
- /// Verifies that the last call to ReadTag() returned tag 0 - in other words,
- /// we've reached the end of the stream when we expected to.
- /// </summary>
- /// <exception cref="InvalidProtocolBufferException">The
- /// tag read was not the one specified</exception>
- internal void CheckReadEndOfStreamTag()
- {
- if (lastTag != 0)
- {
- throw InvalidProtocolBufferException.MoreDataAvailable();
- }
- }
- #endregion
-
- #region Reading of tags etc
-
- /// <summary>
- /// Peeks at the next field tag. This is like calling <see cref="ReadTag"/>, but the
- /// tag is not consumed. (So a subsequent call to <see cref="ReadTag"/> will return the
- /// same value.)
- /// </summary>
- public uint PeekTag()
- {
- if (hasNextTag)
- {
- return nextTag;
- }
-
- uint savedLast = lastTag;
- nextTag = ReadTag();
- hasNextTag = true;
- lastTag = savedLast; // Undo the side effect of ReadTag
- return nextTag;
- }
-
- /// <summary>
- /// Reads a field tag, returning the tag of 0 for "end of stream".
- /// </summary>
- /// <remarks>
- /// If this method returns 0, it doesn't necessarily mean the end of all
- /// the data in this CodedInputStream; it may be the end of the logical stream
- /// for an embedded message, for example.
- /// </remarks>
- /// <returns>The next field tag, or 0 for end of stream. (0 is never a valid tag.)</returns>
- public uint ReadTag()
- {
- if (hasNextTag)
- {
- lastTag = nextTag;
- hasNextTag = false;
- return lastTag;
- }
-
- // 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)
- {
- int tmp = buffer[bufferPos++];
- if (tmp < 128)
- {
- lastTag = (uint)tmp;
- }
- else
- {
- int result = tmp & 0x7f;
- if ((tmp = buffer[bufferPos++]) < 128)
- {
- result |= tmp << 7;
- lastTag = (uint) result;
- }
- else
- {
- // Nope, rewind and go the potentially slow route.
- bufferPos -= 2;
- lastTag = ReadRawVarint32();
- }
- }
- }
- else
- {
- if (IsAtEnd)
- {
- lastTag = 0;
- return 0; // This is the only case in which we return 0.
- }
-
- lastTag = ReadRawVarint32();
- }
- if (lastTag == 0)
- {
- // If we actually read zero, that's not a valid tag.
- throw InvalidProtocolBufferException.InvalidTag();
- }
- return lastTag;
- }
-
- /// <summary>
- /// Skips the data for the field with the tag we've just read.
- /// This should be called directly after <see cref="ReadTag"/>, when
- /// the caller wishes to skip an unknown field.
- /// </summary>
- /// <remarks>
- /// This method throws <see cref="InvalidProtocolBufferException"/> if the last-read tag was an end-group tag.
- /// If a caller wishes to skip a group, they should skip the whole group, by calling this method after reading the
- /// start-group tag. This behavior allows callers to call this method on any field they don't understand, correctly
- /// resulting in an error if an end-group tag has not been paired with an earlier start-group tag.
- /// </remarks>
- /// <exception cref="InvalidProtocolBufferException">The last tag was an end-group tag</exception>
- /// <exception cref="InvalidOperationException">The last read operation read to the end of the logical stream</exception>
- public void SkipLastField()
- {
- if (lastTag == 0)
- {
- throw new InvalidOperationException("SkipLastField cannot be called at the end of a stream");
- }
- switch (WireFormat.GetTagWireType(lastTag))
- {
- case WireFormat.WireType.StartGroup:
- SkipGroup(lastTag);
- break;
- case WireFormat.WireType.EndGroup:
- throw new InvalidProtocolBufferException(
- "SkipLastField called on an end-group tag, indicating that the corresponding start-group was missing");
- case WireFormat.WireType.Fixed32:
- ReadFixed32();
- break;
- case WireFormat.WireType.Fixed64:
- ReadFixed64();
- break;
- case WireFormat.WireType.LengthDelimited:
- var length = ReadLength();
- SkipRawBytes(length);
- break;
- case WireFormat.WireType.Varint:
- ReadRawVarint32();
- break;
- }
- }
-
- private void SkipGroup(uint startGroupTag)
- {
- // Note: Currently we expect this to be the way that groups are read. We could put the recursion
- // depth changes into the ReadTag method instead, potentially...
- recursionDepth++;
- if (recursionDepth >= recursionLimit)
- {
- throw InvalidProtocolBufferException.RecursionLimitExceeded();
- }
- uint tag;
- while (true)
- {
- tag = ReadTag();
- if (tag == 0)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- // Can't call SkipLastField for this case- that would throw.
- if (WireFormat.GetTagWireType(tag) == WireFormat.WireType.EndGroup)
- {
- break;
- }
- // This recursion will allow us to handle nested groups.
- SkipLastField();
- }
- int startField = WireFormat.GetTagFieldNumber(startGroupTag);
- int endField = WireFormat.GetTagFieldNumber(tag);
- if (startField != endField)
- {
- throw new InvalidProtocolBufferException(
- $"Mismatched end-group tag. Started with field {startField}; ended with field {endField}");
- }
- recursionDepth--;
- }
-
- /// <summary>
- /// Reads a double field from the stream.
- /// </summary>
- public double ReadDouble()
- {
- return BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64());
- }
-
- /// <summary>
- /// Reads a float field from the stream.
- /// </summary>
- public float ReadFloat()
- {
- if (BitConverter.IsLittleEndian && 4 <= bufferSize - bufferPos)
- {
- float ret = BitConverter.ToSingle(buffer, bufferPos);
- bufferPos += 4;
- return ret;
- }
- else
- {
- byte[] rawBytes = ReadRawBytes(4);
- if (!BitConverter.IsLittleEndian)
- {
- ByteArray.Reverse(rawBytes);
- }
- return BitConverter.ToSingle(rawBytes, 0);
- }
- }
-
- /// <summary>
- /// Reads a uint64 field from the stream.
- /// </summary>
- public ulong ReadUInt64()
- {
- return ReadRawVarint64();
- }
-
- /// <summary>
- /// Reads an int64 field from the stream.
- /// </summary>
- public long ReadInt64()
- {
- return (long) ReadRawVarint64();
- }
-
- /// <summary>
- /// Reads an int32 field from the stream.
- /// </summary>
- public int ReadInt32()
- {
- return (int) ReadRawVarint32();
- }
-
- /// <summary>
- /// Reads a fixed64 field from the stream.
- /// </summary>
- public ulong ReadFixed64()
- {
- return ReadRawLittleEndian64();
- }
-
- /// <summary>
- /// Reads a fixed32 field from the stream.
- /// </summary>
- public uint ReadFixed32()
- {
- return ReadRawLittleEndian32();
- }
-
- /// <summary>
- /// Reads a bool field from the stream.
- /// </summary>
- public bool ReadBool()
- {
- return ReadRawVarint32() != 0;
- }
-
- /// <summary>
- /// Reads a string field from the stream.
- /// </summary>
- public string ReadString()
- {
- int length = ReadLength();
- // No need to read any data for an empty string.
- if (length == 0)
- {
- return "";
- }
- 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, length);
- bufferPos += length;
- return result;
- }
- // Slow path: Build a byte array first then copy it.
- return CodedOutputStream.Utf8Encoding.GetString(ReadRawBytes(length), 0, length);
- }
-
- /// <summary>
- /// Reads an embedded message field value from the stream.
- /// </summary>
- public void ReadMessage(IMessage builder)
- {
- int length = ReadLength();
- if (recursionDepth >= recursionLimit)
- {
- throw InvalidProtocolBufferException.RecursionLimitExceeded();
- }
- int oldLimit = PushLimit(length);
- ++recursionDepth;
- builder.MergeFrom(this);
- CheckReadEndOfStreamTag();
- // Check that we've read exactly as much data as expected.
- if (!ReachedLimit)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- --recursionDepth;
- PopLimit(oldLimit);
- }
-
- /// <summary>
- /// Reads a bytes field value from the stream.
- /// </summary>
- public ByteString ReadBytes()
- {
- 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, length);
- bufferPos += length;
- return result;
- }
- else
- {
- // Slow path: Build a byte array and attach it to a new ByteString.
- return ByteString.AttachBytes(ReadRawBytes(length));
- }
- }
-
- /// <summary>
- /// Reads a uint32 field value from the stream.
- /// </summary>
- public uint ReadUInt32()
- {
- return ReadRawVarint32();
- }
-
- /// <summary>
- /// Reads an enum field value from the stream.
- /// </summary>
- public int ReadEnum()
- {
- // Currently just a pass-through, but it's nice to separate it logically from WriteInt32.
- return (int) ReadRawVarint32();
- }
-
- /// <summary>
- /// Reads an sfixed32 field value from the stream.
- /// </summary>
- public int ReadSFixed32()
- {
- return (int) ReadRawLittleEndian32();
- }
-
- /// <summary>
- /// Reads an sfixed64 field value from the stream.
- /// </summary>
- public long ReadSFixed64()
- {
- return (long) ReadRawLittleEndian64();
- }
-
- /// <summary>
- /// Reads an sint32 field value from the stream.
- /// </summary>
- public int ReadSInt32()
- {
- return DecodeZigZag32(ReadRawVarint32());
- }
-
- /// <summary>
- /// Reads an sint64 field value from the stream.
- /// </summary>
- public long ReadSInt64()
- {
- return DecodeZigZag64(ReadRawVarint64());
- }
-
- /// <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()
- {
- return (int) ReadRawVarint32();
- }
-
- /// <summary>
- /// Peeks at the next tag in the stream. If it matches <paramref name="tag"/>,
- /// the tag is consumed and the method returns <c>true</c>; otherwise, the
- /// stream is left in the original position and the method returns <c>false</c>.
- /// </summary>
- public bool MaybeConsumeTag(uint tag)
- {
- if (PeekTag() == tag)
- {
- hasNextTag = false;
- return true;
- }
- return false;
- }
-
- #endregion
-
- #region Underlying reading primitives
-
- /// <summary>
- /// Same code as ReadRawVarint32, but read each byte individually, checking for
- /// buffer overflow.
- /// </summary>
- private uint SlowReadRawVarint32()
- {
- int tmp = ReadRawByte();
- if (tmp < 128)
- {
- return (uint) tmp;
- }
- int result = tmp & 0x7f;
- if ((tmp = ReadRawByte()) < 128)
- {
- result |= tmp << 7;
- }
- else
- {
- result |= (tmp & 0x7f) << 7;
- if ((tmp = ReadRawByte()) < 128)
- {
- result |= tmp << 14;
- }
- else
- {
- result |= (tmp & 0x7f) << 14;
- if ((tmp = ReadRawByte()) < 128)
- {
- result |= tmp << 21;
- }
- else
- {
- result |= (tmp & 0x7f) << 21;
- result |= (tmp = ReadRawByte()) << 28;
- if (tmp >= 128)
- {
- // Discard upper 32 bits.
- for (int i = 0; i < 5; i++)
- {
- if (ReadRawByte() < 128)
- {
- return (uint) result;
- }
- }
- throw InvalidProtocolBufferException.MalformedVarint();
- }
- }
- }
- }
- return (uint) result;
- }
-
- /// <summary>
- /// 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>
- internal uint ReadRawVarint32()
- {
- if (bufferPos + 5 > bufferSize)
- {
- return SlowReadRawVarint32();
- }
-
- int tmp = buffer[bufferPos++];
- if (tmp < 128)
- {
- return (uint) tmp;
- }
- int result = tmp & 0x7f;
- if ((tmp = buffer[bufferPos++]) < 128)
- {
- result |= tmp << 7;
- }
- else
- {
- result |= (tmp & 0x7f) << 7;
- if ((tmp = buffer[bufferPos++]) < 128)
- {
- result |= tmp << 14;
- }
- else
- {
- result |= (tmp & 0x7f) << 14;
- if ((tmp = buffer[bufferPos++]) < 128)
- {
- result |= tmp << 21;
- }
- else
- {
- result |= (tmp & 0x7f) << 21;
- result |= (tmp = buffer[bufferPos++]) << 28;
- if (tmp >= 128)
- {
- // Discard upper 32 bits.
- // Note that this has to use ReadRawByte() as we only ensure we've
- // got at least 5 bytes at the start of the method. This lets us
- // use the fast path in more cases, and we rarely hit this section of code.
- for (int i = 0; i < 5; i++)
- {
- if (ReadRawByte() < 128)
- {
- return (uint) result;
- }
- }
- throw InvalidProtocolBufferException.MalformedVarint();
- }
- }
- }
- }
- return (uint) result;
- }
-
- /// <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)
- /// 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>
- internal static uint ReadRawVarint32(Stream input)
- {
- int result = 0;
- int offset = 0;
- for (; offset < 32; offset += 7)
- {
- int b = input.ReadByte();
- if (b == -1)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- result |= (b & 0x7f) << offset;
- if ((b & 0x80) == 0)
- {
- return (uint) result;
- }
- }
- // Keep reading up to 64 bits.
- for (; offset < 64; offset += 7)
- {
- int b = input.ReadByte();
- if (b == -1)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- if ((b & 0x80) == 0)
- {
- return (uint) result;
- }
- }
- throw InvalidProtocolBufferException.MalformedVarint();
- }
-
- /// <summary>
- /// Reads a raw varint from the stream.
- /// </summary>
- internal ulong ReadRawVarint64()
- {
- int shift = 0;
- ulong result = 0;
- while (shift < 64)
- {
- byte b = ReadRawByte();
- result |= (ulong) (b & 0x7F) << shift;
- if ((b & 0x80) == 0)
- {
- return result;
- }
- shift += 7;
- }
- throw InvalidProtocolBufferException.MalformedVarint();
- }
-
- /// <summary>
- /// Reads a 32-bit little-endian integer from the stream.
- /// </summary>
- internal uint ReadRawLittleEndian32()
- {
- uint b1 = ReadRawByte();
- uint b2 = ReadRawByte();
- uint b3 = ReadRawByte();
- uint b4 = ReadRawByte();
- return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
- }
-
- /// <summary>
- /// Reads a 64-bit little-endian integer from the stream.
- /// </summary>
- internal ulong ReadRawLittleEndian64()
- {
- ulong b1 = ReadRawByte();
- ulong b2 = ReadRawByte();
- ulong b3 = ReadRawByte();
- ulong b4 = ReadRawByte();
- ulong b5 = ReadRawByte();
- ulong b6 = ReadRawByte();
- ulong b7 = ReadRawByte();
- ulong b8 = ReadRawByte();
- return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)
- | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
- }
-
- /// <summary>
- /// Decode a 32-bit value with ZigZag encoding.
- /// </summary>
- /// <remarks>
- /// ZigZag encodes signed integers into values that can be efficiently
- /// encoded with varint. (Otherwise, negative values must be
- /// sign-extended to 64 bits to be varint encoded, thus always taking
- /// 10 bytes on the wire.)
- /// </remarks>
- internal static int DecodeZigZag32(uint n)
- {
- return (int)(n >> 1) ^ -(int)(n & 1);
- }
-
- /// <summary>
- /// Decode a 32-bit value with ZigZag encoding.
- /// </summary>
- /// <remarks>
- /// ZigZag encodes signed integers into values that can be efficiently
- /// encoded with varint. (Otherwise, negative values must be
- /// sign-extended to 64 bits to be varint encoded, thus always taking
- /// 10 bytes on the wire.)
- /// </remarks>
- internal static long DecodeZigZag64(ulong n)
- {
- return (long)(n >> 1) ^ -(long)(n & 1);
- }
- #endregion
-
- #region Internal reading and buffer management
-
- /// <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>
- internal int PushLimit(int byteLimit)
- {
- if (byteLimit < 0)
- {
- throw InvalidProtocolBufferException.NegativeSize();
- }
- byteLimit += totalBytesRetired + bufferPos;
- int oldLimit = currentLimit;
- if (byteLimit > oldLimit)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- currentLimit = byteLimit;
-
- RecomputeBufferSizeAfterLimit();
-
- return oldLimit;
- }
-
- private void RecomputeBufferSizeAfterLimit()
- {
- bufferSize += bufferSizeAfterLimit;
- int bufferEnd = totalBytesRetired + bufferSize;
- if (bufferEnd > currentLimit)
- {
- // Limit is in current buffer.
- bufferSizeAfterLimit = bufferEnd - currentLimit;
- bufferSize -= bufferSizeAfterLimit;
- }
- else
- {
- bufferSizeAfterLimit = 0;
- }
- }
-
- /// <summary>
- /// Discards the current limit, returning the previous limit.
- /// </summary>
- internal void PopLimit(int oldLimit)
- {
- currentLimit = oldLimit;
- RecomputeBufferSizeAfterLimit();
- }
-
- /// <summary>
- /// Returns whether or not all the data before the limit has been read.
- /// </summary>
- /// <returns></returns>
- internal bool ReachedLimit
- {
- get
- {
- if (currentLimit == int.MaxValue)
- {
- return false;
- }
- int currentAbsolutePosition = totalBytesRetired + bufferPos;
- return currentAbsolutePosition >= currentLimit;
- }
- }
-
- /// <summary>
- /// Returns true if the stream has reached the end of the input. This is the
- /// case if either the end of the underlying input source has been reached or
- /// the stream has reached a limit created using PushLimit.
- /// </summary>
- public bool IsAtEnd
- {
- get { return bufferPos == bufferSize && !RefillBuffer(false); }
- }
-
- /// <summary>
- /// Called when buffer is empty to read more bytes from the
- /// input. If <paramref name="mustSucceed"/> is true, RefillBuffer() gurantees that
- /// either there will be at least one byte in the buffer when it returns
- /// or it will throw an exception. If <paramref name="mustSucceed"/> is false,
- /// RefillBuffer() returns false if no more bytes were available.
- /// </summary>
- /// <param name="mustSucceed"></param>
- /// <returns></returns>
- private bool RefillBuffer(bool mustSucceed)
- {
- if (bufferPos < bufferSize)
- {
- throw new InvalidOperationException("RefillBuffer() called when buffer wasn't empty.");
- }
-
- if (totalBytesRetired + bufferSize == currentLimit)
- {
- // Oops, we hit a limit.
- if (mustSucceed)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- else
- {
- return false;
- }
- }
-
- totalBytesRetired += bufferSize;
-
- bufferPos = 0;
- bufferSize = (input == null) ? 0 : input.Read(buffer, 0, buffer.Length);
- if (bufferSize < 0)
- {
- throw new InvalidOperationException("Stream.Read returned a negative count");
- }
- if (bufferSize == 0)
- {
- if (mustSucceed)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- else
- {
- return false;
- }
- }
- else
- {
- RecomputeBufferSizeAfterLimit();
- int totalBytesRead =
- totalBytesRetired + bufferSize + bufferSizeAfterLimit;
- if (totalBytesRead > sizeLimit || totalBytesRead < 0)
- {
- throw InvalidProtocolBufferException.SizeLimitExceeded();
- }
- return true;
- }
- }
-
- /// <summary>
- /// Read one byte from the input.
- /// </summary>
- /// <exception cref="InvalidProtocolBufferException">
- /// the end of the stream or the current limit was reached
- /// </exception>
- internal byte ReadRawByte()
- {
- if (bufferPos == bufferSize)
- {
- RefillBuffer(true);
- }
- return buffer[bufferPos++];
- }
-
- /// <summary>
- /// 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>
- internal byte[] ReadRawBytes(int size)
- {
- if (size < 0)
- {
- throw InvalidProtocolBufferException.NegativeSize();
- }
-
- if (totalBytesRetired + bufferPos + size > currentLimit)
- {
- // Read to the end of the stream (up to the current limit) anyway.
- SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
- // Then fail.
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
-
- if (size <= bufferSize - bufferPos)
- {
- // We have all the bytes we need already.
- byte[] bytes = new byte[size];
- ByteArray.Copy(buffer, bufferPos, bytes, 0, size);
- bufferPos += size;
- return bytes;
- }
- else if (size < buffer.Length)
- {
- // Reading more bytes than are in the buffer, but not an excessive number
- // of bytes. We can safely allocate the resulting array ahead of time.
-
- // First copy what we have.
- byte[] bytes = new byte[size];
- int pos = bufferSize - bufferPos;
- ByteArray.Copy(buffer, bufferPos, bytes, 0, pos);
- bufferPos = bufferSize;
-
- // We want to use RefillBuffer() and then copy from the buffer into our
- // byte array rather than reading directly into our byte array because
- // the input may be unbuffered.
- RefillBuffer(true);
-
- while (size - pos > bufferSize)
- {
- Buffer.BlockCopy(buffer, 0, bytes, pos, bufferSize);
- pos += bufferSize;
- bufferPos = bufferSize;
- RefillBuffer(true);
- }
-
- ByteArray.Copy(buffer, 0, bytes, pos, size - pos);
- bufferPos = size - pos;
-
- return bytes;
- }
- else
- {
- // The size is very large. For security reasons, we can't allocate the
- // entire byte array yet. The size comes directly from the input, so a
- // maliciously-crafted message could provide a bogus very large size in
- // order to trick the app into allocating a lot of memory. We avoid this
- // by allocating and reading only a small chunk at a time, so that the
- // malicious message must actually *be* extremely large to cause
- // problems. Meanwhile, we limit the allowed size of a message elsewhere.
-
- // Remember the buffer markers since we'll have to copy the bytes out of
- // it later.
- int originalBufferPos = bufferPos;
- int originalBufferSize = bufferSize;
-
- // Mark the current buffer consumed.
- totalBytesRetired += bufferSize;
- bufferPos = 0;
- bufferSize = 0;
-
- // Read all the rest of the bytes we need.
- int sizeLeft = size - (originalBufferSize - originalBufferPos);
- List<byte[]> chunks = new List<byte[]>();
-
- while (sizeLeft > 0)
- {
- byte[] chunk = new byte[Math.Min(sizeLeft, buffer.Length)];
- int pos = 0;
- while (pos < chunk.Length)
- {
- int n = (input == null) ? -1 : input.Read(chunk, pos, chunk.Length - pos);
- if (n <= 0)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- totalBytesRetired += n;
- pos += n;
- }
- sizeLeft -= chunk.Length;
- chunks.Add(chunk);
- }
-
- // OK, got everything. Now concatenate it all into one buffer.
- byte[] bytes = new byte[size];
-
- // Start by copying the leftover bytes from this.buffer.
- int newPos = originalBufferSize - originalBufferPos;
- ByteArray.Copy(buffer, originalBufferPos, bytes, 0, newPos);
-
- // And now all the chunks.
- foreach (byte[] chunk in chunks)
- {
- Buffer.BlockCopy(chunk, 0, bytes, newPos, chunk.Length);
- newPos += chunk.Length;
- }
-
- // Done.
- return bytes;
- }
- }
-
- /// <summary>
- /// Reads and discards <paramref name="size"/> bytes.
- /// </summary>
- /// <exception cref="InvalidProtocolBufferException">the end of the stream
- /// or the current limit was reached</exception>
- private void SkipRawBytes(int size)
- {
- if (size < 0)
- {
- throw InvalidProtocolBufferException.NegativeSize();
- }
-
- if (totalBytesRetired + bufferPos + size > currentLimit)
- {
- // Read to the end of the stream anyway.
- SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
- // Then fail.
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
-
- if (size <= bufferSize - bufferPos)
- {
- // We have all the bytes we need already.
- bufferPos += size;
- }
- else
- {
- // Skipping more bytes than are in the buffer. First skip what we have.
- int pos = bufferSize - bufferPos;
-
- // ROK 5/7/2013 Issue #54: should retire all bytes in buffer (bufferSize)
- // totalBytesRetired += pos;
- totalBytesRetired += bufferSize;
-
- bufferPos = 0;
- bufferSize = 0;
-
- // Then skip directly from the InputStream for the rest.
- if (pos < size)
- {
- if (input == null)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- SkipImpl(size - pos);
- totalBytesRetired += size - pos;
- }
- }
- }
-
- /// <summary>
- /// Abstraction of skipping to cope with streams which can't really skip.
- /// </summary>
- private void SkipImpl(int amountToSkip)
- {
- if (input.CanSeek)
- {
- long previousPosition = input.Position;
- input.Position += amountToSkip;
- if (input.Position != previousPosition + amountToSkip)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- }
- else
- {
- byte[] skipBuffer = new byte[Math.Min(1024, amountToSkip)];
- while (amountToSkip > 0)
- {
- int bytesRead = input.Read(skipBuffer, 0, Math.Min(skipBuffer.Length, amountToSkip));
- if (bytesRead <= 0)
- {
- throw InvalidProtocolBufferException.TruncatedMessage();
- }
- amountToSkip -= bytesRead;
- }
- }
- }
-
- #endregion
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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 Google.Protobuf.Collections;
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Reads and decodes protocol message fields.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This class is generally used by generated code to read appropriate
+ /// primitives from the stream. It effectively encapsulates the lowest
+ /// levels of protocol buffer format.
+ /// </para>
+ /// <para>
+ /// Repeated fields and map fields are not handled by this class; use <see cref="RepeatedField{T}"/>
+ /// and <see cref="MapField{TKey, TValue}"/> to serialize such fields.
+ /// </para>
+ /// </remarks>
+ public sealed class CodedInputStream : IDisposable
+ {
+ /// <summary>
+ /// Whether to leave the underlying stream open when disposing of this stream.
+ /// This is always true when there's no stream.
+ /// </summary>
+ private readonly bool leaveOpen;
+
+ /// <summary>
+ /// Buffer of data read from the stream or provided at construction time.
+ /// </summary>
+ private readonly byte[] buffer;
+
+ /// <summary>
+ /// The index of the buffer at which we need to refill from the stream (if there is one).
+ /// </summary>
+ private int bufferSize;
+
+ private int bufferSizeAfterLimit = 0;
+ /// <summary>
+ /// The position within the current buffer (i.e. the next byte to read)
+ /// </summary>
+ private int bufferPos = 0;
+
+ /// <summary>
+ /// The stream to read further input from, or null if the byte array buffer was provided
+ /// directly on construction, with no further data available.
+ /// </summary>
+ private readonly Stream input;
+
+ /// <summary>
+ /// The last tag we read. 0 indicates we've read to the end of the stream
+ /// (or haven't read anything yet).
+ /// </summary>
+ private uint lastTag = 0;
+
+ /// <summary>
+ /// The next tag, used to store the value read by PeekTag.
+ /// </summary>
+ private uint nextTag = 0;
+ private bool hasNextTag = false;
+
+ internal const int DefaultRecursionLimit = 64;
+ internal const int DefaultSizeLimit = 64 << 20; // 64MB
+ internal const int BufferSize = 4096;
+
+ /// <summary>
+ /// The total number of bytes read before the current buffer. The
+ /// total bytes read up to the current position can be computed as
+ /// totalBytesRetired + bufferPos.
+ /// </summary>
+ private int totalBytesRetired = 0;
+
+ /// <summary>
+ /// The absolute position of the end of the current message.
+ /// </summary>
+ private int currentLimit = int.MaxValue;
+
+ private int recursionDepth = 0;
+
+ private readonly int recursionLimit;
+ private readonly int sizeLimit;
+
+ #region Construction
+ // Note that the checks are performed such that we don't end up checking obviously-valid things
+ // like non-null references for arrays we've just created.
+
+ /// <summary>
+ /// Creates a new CodedInputStream reading data from the given byte array.
+ /// </summary>
+ public CodedInputStream(byte[] buffer) : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), 0, buffer.Length, true)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="CodedInputStream"/> that reads from the given byte array slice.
+ /// </summary>
+ public CodedInputStream(byte[] buffer, int offset, int length)
+ : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), offset, offset + length, true)
+ {
+ if (offset < 0 || offset > buffer.Length)
+ {
+ throw new ArgumentOutOfRangeException("offset", "Offset must be within the buffer");
+ }
+ if (length < 0 || offset + length > buffer.Length)
+ {
+ throw new ArgumentOutOfRangeException("length", "Length must be non-negative and within the buffer");
+ }
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="CodedInputStream"/> reading data from the given stream, which will be disposed
+ /// when the returned object is disposed.
+ /// </summary>
+ /// <param name="input">The stream to read from.</param>
+ public CodedInputStream(Stream input) : this(input, false)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="CodedInputStream"/> reading data from the given stream.
+ /// </summary>
+ /// <param name="input">The stream to read from.</param>
+ /// <param name="leaveOpen"><c>true</c> to leave <paramref name="input"/> open when the returned
+ /// <c cref="CodedInputStream"/> is disposed; <c>false</c> to dispose of the given stream when the
+ /// returned object is disposed.</param>
+ public CodedInputStream(Stream input, bool leaveOpen)
+ : this(ProtoPreconditions.CheckNotNull(input, "input"), new byte[BufferSize], 0, 0, leaveOpen)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new CodedInputStream reading data from the given
+ /// stream and buffer, using the default limits.
+ /// </summary>
+ internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, bool leaveOpen)
+ {
+ this.input = input;
+ this.buffer = buffer;
+ this.bufferPos = bufferPos;
+ this.bufferSize = bufferSize;
+ this.sizeLimit = DefaultSizeLimit;
+ this.recursionLimit = DefaultRecursionLimit;
+ this.leaveOpen = leaveOpen;
+ }
+
+ /// <summary>
+ /// Creates a new CodedInputStream reading data from the given
+ /// stream and buffer, using the specified limits.
+ /// </summary>
+ /// <remarks>
+ /// This chains to the version with the default limits instead of vice versa to avoid
+ /// having to check that the default values are valid every time.
+ /// </remarks>
+ internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, int sizeLimit, int recursionLimit, bool leaveOpen)
+ : this(input, buffer, bufferPos, bufferSize, leaveOpen)
+ {
+ if (sizeLimit <= 0)
+ {
+ throw new ArgumentOutOfRangeException("sizeLimit", "Size limit must be positive");
+ }
+ if (recursionLimit <= 0)
+ {
+ throw new ArgumentOutOfRangeException("recursionLimit!", "Recursion limit must be positive");
+ }
+ this.sizeLimit = sizeLimit;
+ this.recursionLimit = recursionLimit;
+ }
+ #endregion
+
+ /// <summary>
+ /// Creates a <see cref="CodedInputStream"/> with the specified size and recursion limits, reading
+ /// from an input stream.
+ /// </summary>
+ /// <remarks>
+ /// This method exists separately from the constructor to reduce the number of constructor overloads.
+ /// It is likely to be used considerably less frequently than the constructors, as the default limits
+ /// are suitable for most use cases.
+ /// </remarks>
+ /// <param name="input">The input stream to read from</param>
+ /// <param name="sizeLimit">The total limit of data to read from the stream.</param>
+ /// <param name="recursionLimit">The maximum recursion depth to allow while reading.</param>
+ /// <returns>A <c>CodedInputStream</c> reading from <paramref name="input"/> with the specified size
+ /// and recursion limits.</returns>
+ public static CodedInputStream CreateWithLimits(Stream input, int sizeLimit, int recursionLimit)
+ {
+ // Note: we may want an overload accepting leaveOpen
+ return new CodedInputStream(input, new byte[BufferSize], 0, 0, sizeLimit, recursionLimit, false);
+ }
+
+ /// <summary>
+ /// Returns the current position in the input stream, or the position in the input buffer
+ /// </summary>
+ public long Position
+ {
+ get
+ {
+ if (input != null)
+ {
+ return input.Position - ((bufferSize + bufferSizeAfterLimit) - bufferPos);
+ }
+ return bufferPos;
+ }
+ }
+
+ /// <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; } }
+
+ /// <summary>
+ /// Returns the size limit for this stream.
+ /// </summary>
+ /// <remarks>
+ /// This limit is applied when reading from the underlying stream, as a sanity check. It is
+ /// not applied when reading from a byte array data source without an underlying stream.
+ /// The default value is 64MB.
+ /// </remarks>
+ /// <value>
+ /// The size limit.
+ /// </value>
+ public int SizeLimit { get { return sizeLimit; } }
+
+ /// <summary>
+ /// Returns the recursion limit for this stream. This limit is applied whilst reading messages,
+ /// to avoid maliciously-recursive data.
+ /// </summary>
+ /// <remarks>
+ /// The default limit is 64.
+ /// </remarks>
+ /// <value>
+ /// The recursion limit for this stream.
+ /// </value>
+ public int RecursionLimit { get { return recursionLimit; } }
+
+ /// <summary>
+ /// Disposes of this instance, potentially closing any underlying stream.
+ /// </summary>
+ /// <remarks>
+ /// As there is no flushing to perform here, disposing of a <see cref="CodedInputStream"/> which
+ /// was constructed with the <c>leaveOpen</c> option parameter set to <c>true</c> (or one which
+ /// was constructed to read from a byte array) has no effect.
+ /// </remarks>
+ public void Dispose()
+ {
+ if (!leaveOpen)
+ {
+ input.Dispose();
+ }
+ }
+
+ #region Validation
+ /// <summary>
+ /// Verifies that the last call to ReadTag() returned tag 0 - in other words,
+ /// we've reached the end of the stream when we expected to.
+ /// </summary>
+ /// <exception cref="InvalidProtocolBufferException">The
+ /// tag read was not the one specified</exception>
+ internal void CheckReadEndOfStreamTag()
+ {
+ if (lastTag != 0)
+ {
+ throw InvalidProtocolBufferException.MoreDataAvailable();
+ }
+ }
+ #endregion
+
+ #region Reading of tags etc
+
+ /// <summary>
+ /// Peeks at the next field tag. This is like calling <see cref="ReadTag"/>, but the
+ /// tag is not consumed. (So a subsequent call to <see cref="ReadTag"/> will return the
+ /// same value.)
+ /// </summary>
+ public uint PeekTag()
+ {
+ if (hasNextTag)
+ {
+ return nextTag;
+ }
+
+ uint savedLast = lastTag;
+ nextTag = ReadTag();
+ hasNextTag = true;
+ lastTag = savedLast; // Undo the side effect of ReadTag
+ return nextTag;
+ }
+
+ /// <summary>
+ /// Reads a field tag, returning the tag of 0 for "end of stream".
+ /// </summary>
+ /// <remarks>
+ /// If this method returns 0, it doesn't necessarily mean the end of all
+ /// the data in this CodedInputStream; it may be the end of the logical stream
+ /// for an embedded message, for example.
+ /// </remarks>
+ /// <returns>The next field tag, or 0 for end of stream. (0 is never a valid tag.)</returns>
+ public uint ReadTag()
+ {
+ if (hasNextTag)
+ {
+ lastTag = nextTag;
+ hasNextTag = false;
+ return lastTag;
+ }
+
+ // 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)
+ {
+ int tmp = buffer[bufferPos++];
+ if (tmp < 128)
+ {
+ lastTag = (uint)tmp;
+ }
+ else
+ {
+ int result = tmp & 0x7f;
+ if ((tmp = buffer[bufferPos++]) < 128)
+ {
+ result |= tmp << 7;
+ lastTag = (uint) result;
+ }
+ else
+ {
+ // Nope, rewind and go the potentially slow route.
+ bufferPos -= 2;
+ lastTag = ReadRawVarint32();
+ }
+ }
+ }
+ else
+ {
+ if (IsAtEnd)
+ {
+ lastTag = 0;
+ return 0; // This is the only case in which we return 0.
+ }
+
+ lastTag = ReadRawVarint32();
+ }
+ if (lastTag == 0)
+ {
+ // If we actually read zero, that's not a valid tag.
+ throw InvalidProtocolBufferException.InvalidTag();
+ }
+ return lastTag;
+ }
+
+ /// <summary>
+ /// Skips the data for the field with the tag we've just read.
+ /// This should be called directly after <see cref="ReadTag"/>, when
+ /// the caller wishes to skip an unknown field.
+ /// </summary>
+ /// <remarks>
+ /// This method throws <see cref="InvalidProtocolBufferException"/> if the last-read tag was an end-group tag.
+ /// If a caller wishes to skip a group, they should skip the whole group, by calling this method after reading the
+ /// start-group tag. This behavior allows callers to call this method on any field they don't understand, correctly
+ /// resulting in an error if an end-group tag has not been paired with an earlier start-group tag.
+ /// </remarks>
+ /// <exception cref="InvalidProtocolBufferException">The last tag was an end-group tag</exception>
+ /// <exception cref="InvalidOperationException">The last read operation read to the end of the logical stream</exception>
+ public void SkipLastField()
+ {
+ if (lastTag == 0)
+ {
+ throw new InvalidOperationException("SkipLastField cannot be called at the end of a stream");
+ }
+ switch (WireFormat.GetTagWireType(lastTag))
+ {
+ case WireFormat.WireType.StartGroup:
+ SkipGroup(lastTag);
+ break;
+ case WireFormat.WireType.EndGroup:
+ throw new InvalidProtocolBufferException(
+ "SkipLastField called on an end-group tag, indicating that the corresponding start-group was missing");
+ case WireFormat.WireType.Fixed32:
+ ReadFixed32();
+ break;
+ case WireFormat.WireType.Fixed64:
+ ReadFixed64();
+ break;
+ case WireFormat.WireType.LengthDelimited:
+ var length = ReadLength();
+ SkipRawBytes(length);
+ break;
+ case WireFormat.WireType.Varint:
+ ReadRawVarint32();
+ break;
+ }
+ }
+
+ private void SkipGroup(uint startGroupTag)
+ {
+ // Note: Currently we expect this to be the way that groups are read. We could put the recursion
+ // depth changes into the ReadTag method instead, potentially...
+ recursionDepth++;
+ if (recursionDepth >= recursionLimit)
+ {
+ throw InvalidProtocolBufferException.RecursionLimitExceeded();
+ }
+ uint tag;
+ while (true)
+ {
+ tag = ReadTag();
+ if (tag == 0)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ // Can't call SkipLastField for this case- that would throw.
+ if (WireFormat.GetTagWireType(tag) == WireFormat.WireType.EndGroup)
+ {
+ break;
+ }
+ // This recursion will allow us to handle nested groups.
+ SkipLastField();
+ }
+ int startField = WireFormat.GetTagFieldNumber(startGroupTag);
+ int endField = WireFormat.GetTagFieldNumber(tag);
+ if (startField != endField)
+ {
+ throw new InvalidProtocolBufferException(
+ $"Mismatched end-group tag. Started with field {startField}; ended with field {endField}");
+ }
+ recursionDepth--;
+ }
+
+ /// <summary>
+ /// Reads a double field from the stream.
+ /// </summary>
+ public double ReadDouble()
+ {
+ return BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64());
+ }
+
+ /// <summary>
+ /// Reads a float field from the stream.
+ /// </summary>
+ public float ReadFloat()
+ {
+ if (BitConverter.IsLittleEndian && 4 <= bufferSize - bufferPos)
+ {
+ float ret = BitConverter.ToSingle(buffer, bufferPos);
+ bufferPos += 4;
+ return ret;
+ }
+ else
+ {
+ byte[] rawBytes = ReadRawBytes(4);
+ if (!BitConverter.IsLittleEndian)
+ {
+ ByteArray.Reverse(rawBytes);
+ }
+ return BitConverter.ToSingle(rawBytes, 0);
+ }
+ }
+
+ /// <summary>
+ /// Reads a uint64 field from the stream.
+ /// </summary>
+ public ulong ReadUInt64()
+ {
+ return ReadRawVarint64();
+ }
+
+ /// <summary>
+ /// Reads an int64 field from the stream.
+ /// </summary>
+ public long ReadInt64()
+ {
+ return (long) ReadRawVarint64();
+ }
+
+ /// <summary>
+ /// Reads an int32 field from the stream.
+ /// </summary>
+ public int ReadInt32()
+ {
+ return (int) ReadRawVarint32();
+ }
+
+ /// <summary>
+ /// Reads a fixed64 field from the stream.
+ /// </summary>
+ public ulong ReadFixed64()
+ {
+ return ReadRawLittleEndian64();
+ }
+
+ /// <summary>
+ /// Reads a fixed32 field from the stream.
+ /// </summary>
+ public uint ReadFixed32()
+ {
+ return ReadRawLittleEndian32();
+ }
+
+ /// <summary>
+ /// Reads a bool field from the stream.
+ /// </summary>
+ public bool ReadBool()
+ {
+ return ReadRawVarint32() != 0;
+ }
+
+ /// <summary>
+ /// Reads a string field from the stream.
+ /// </summary>
+ public string ReadString()
+ {
+ int length = ReadLength();
+ // No need to read any data for an empty string.
+ if (length == 0)
+ {
+ return "";
+ }
+ 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, length);
+ bufferPos += length;
+ return result;
+ }
+ // Slow path: Build a byte array first then copy it.
+ return CodedOutputStream.Utf8Encoding.GetString(ReadRawBytes(length), 0, length);
+ }
+
+ /// <summary>
+ /// Reads an embedded message field value from the stream.
+ /// </summary>
+ public void ReadMessage(IMessage builder)
+ {
+ int length = ReadLength();
+ if (recursionDepth >= recursionLimit)
+ {
+ throw InvalidProtocolBufferException.RecursionLimitExceeded();
+ }
+ int oldLimit = PushLimit(length);
+ ++recursionDepth;
+ builder.MergeFrom(this);
+ CheckReadEndOfStreamTag();
+ // Check that we've read exactly as much data as expected.
+ if (!ReachedLimit)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ --recursionDepth;
+ PopLimit(oldLimit);
+ }
+
+ /// <summary>
+ /// Reads a bytes field value from the stream.
+ /// </summary>
+ public ByteString ReadBytes()
+ {
+ 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, length);
+ bufferPos += length;
+ return result;
+ }
+ else
+ {
+ // Slow path: Build a byte array and attach it to a new ByteString.
+ return ByteString.AttachBytes(ReadRawBytes(length));
+ }
+ }
+
+ /// <summary>
+ /// Reads a uint32 field value from the stream.
+ /// </summary>
+ public uint ReadUInt32()
+ {
+ return ReadRawVarint32();
+ }
+
+ /// <summary>
+ /// Reads an enum field value from the stream.
+ /// </summary>
+ public int ReadEnum()
+ {
+ // Currently just a pass-through, but it's nice to separate it logically from WriteInt32.
+ return (int) ReadRawVarint32();
+ }
+
+ /// <summary>
+ /// Reads an sfixed32 field value from the stream.
+ /// </summary>
+ public int ReadSFixed32()
+ {
+ return (int) ReadRawLittleEndian32();
+ }
+
+ /// <summary>
+ /// Reads an sfixed64 field value from the stream.
+ /// </summary>
+ public long ReadSFixed64()
+ {
+ return (long) ReadRawLittleEndian64();
+ }
+
+ /// <summary>
+ /// Reads an sint32 field value from the stream.
+ /// </summary>
+ public int ReadSInt32()
+ {
+ return DecodeZigZag32(ReadRawVarint32());
+ }
+
+ /// <summary>
+ /// Reads an sint64 field value from the stream.
+ /// </summary>
+ public long ReadSInt64()
+ {
+ return DecodeZigZag64(ReadRawVarint64());
+ }
+
+ /// <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()
+ {
+ return (int) ReadRawVarint32();
+ }
+
+ /// <summary>
+ /// Peeks at the next tag in the stream. If it matches <paramref name="tag"/>,
+ /// the tag is consumed and the method returns <c>true</c>; otherwise, the
+ /// stream is left in the original position and the method returns <c>false</c>.
+ /// </summary>
+ public bool MaybeConsumeTag(uint tag)
+ {
+ if (PeekTag() == tag)
+ {
+ hasNextTag = false;
+ return true;
+ }
+ return false;
+ }
+
+ #endregion
+
+ #region Underlying reading primitives
+
+ /// <summary>
+ /// Same code as ReadRawVarint32, but read each byte individually, checking for
+ /// buffer overflow.
+ /// </summary>
+ private uint SlowReadRawVarint32()
+ {
+ int tmp = ReadRawByte();
+ if (tmp < 128)
+ {
+ return (uint) tmp;
+ }
+ int result = tmp & 0x7f;
+ if ((tmp = ReadRawByte()) < 128)
+ {
+ result |= tmp << 7;
+ }
+ else
+ {
+ result |= (tmp & 0x7f) << 7;
+ if ((tmp = ReadRawByte()) < 128)
+ {
+ result |= tmp << 14;
+ }
+ else
+ {
+ result |= (tmp & 0x7f) << 14;
+ if ((tmp = ReadRawByte()) < 128)
+ {
+ result |= tmp << 21;
+ }
+ else
+ {
+ result |= (tmp & 0x7f) << 21;
+ result |= (tmp = ReadRawByte()) << 28;
+ if (tmp >= 128)
+ {
+ // Discard upper 32 bits.
+ for (int i = 0; i < 5; i++)
+ {
+ if (ReadRawByte() < 128)
+ {
+ return (uint) result;
+ }
+ }
+ throw InvalidProtocolBufferException.MalformedVarint();
+ }
+ }
+ }
+ }
+ return (uint) result;
+ }
+
+ /// <summary>
+ /// 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>
+ internal uint ReadRawVarint32()
+ {
+ if (bufferPos + 5 > bufferSize)
+ {
+ return SlowReadRawVarint32();
+ }
+
+ int tmp = buffer[bufferPos++];
+ if (tmp < 128)
+ {
+ return (uint) tmp;
+ }
+ int result = tmp & 0x7f;
+ if ((tmp = buffer[bufferPos++]) < 128)
+ {
+ result |= tmp << 7;
+ }
+ else
+ {
+ result |= (tmp & 0x7f) << 7;
+ if ((tmp = buffer[bufferPos++]) < 128)
+ {
+ result |= tmp << 14;
+ }
+ else
+ {
+ result |= (tmp & 0x7f) << 14;
+ if ((tmp = buffer[bufferPos++]) < 128)
+ {
+ result |= tmp << 21;
+ }
+ else
+ {
+ result |= (tmp & 0x7f) << 21;
+ result |= (tmp = buffer[bufferPos++]) << 28;
+ if (tmp >= 128)
+ {
+ // Discard upper 32 bits.
+ // Note that this has to use ReadRawByte() as we only ensure we've
+ // got at least 5 bytes at the start of the method. This lets us
+ // use the fast path in more cases, and we rarely hit this section of code.
+ for (int i = 0; i < 5; i++)
+ {
+ if (ReadRawByte() < 128)
+ {
+ return (uint) result;
+ }
+ }
+ throw InvalidProtocolBufferException.MalformedVarint();
+ }
+ }
+ }
+ }
+ return (uint) result;
+ }
+
+ /// <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)
+ /// 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>
+ internal static uint ReadRawVarint32(Stream input)
+ {
+ int result = 0;
+ int offset = 0;
+ for (; offset < 32; offset += 7)
+ {
+ int b = input.ReadByte();
+ if (b == -1)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ result |= (b & 0x7f) << offset;
+ if ((b & 0x80) == 0)
+ {
+ return (uint) result;
+ }
+ }
+ // Keep reading up to 64 bits.
+ for (; offset < 64; offset += 7)
+ {
+ int b = input.ReadByte();
+ if (b == -1)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ if ((b & 0x80) == 0)
+ {
+ return (uint) result;
+ }
+ }
+ throw InvalidProtocolBufferException.MalformedVarint();
+ }
+
+ /// <summary>
+ /// Reads a raw varint from the stream.
+ /// </summary>
+ internal ulong ReadRawVarint64()
+ {
+ int shift = 0;
+ ulong result = 0;
+ while (shift < 64)
+ {
+ byte b = ReadRawByte();
+ result |= (ulong) (b & 0x7F) << shift;
+ if ((b & 0x80) == 0)
+ {
+ return result;
+ }
+ shift += 7;
+ }
+ throw InvalidProtocolBufferException.MalformedVarint();
+ }
+
+ /// <summary>
+ /// Reads a 32-bit little-endian integer from the stream.
+ /// </summary>
+ internal uint ReadRawLittleEndian32()
+ {
+ uint b1 = ReadRawByte();
+ uint b2 = ReadRawByte();
+ uint b3 = ReadRawByte();
+ uint b4 = ReadRawByte();
+ return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
+ }
+
+ /// <summary>
+ /// Reads a 64-bit little-endian integer from the stream.
+ /// </summary>
+ internal ulong ReadRawLittleEndian64()
+ {
+ ulong b1 = ReadRawByte();
+ ulong b2 = ReadRawByte();
+ ulong b3 = ReadRawByte();
+ ulong b4 = ReadRawByte();
+ ulong b5 = ReadRawByte();
+ ulong b6 = ReadRawByte();
+ ulong b7 = ReadRawByte();
+ ulong b8 = ReadRawByte();
+ return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24)
+ | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
+ }
+
+ /// <summary>
+ /// Decode a 32-bit value with ZigZag encoding.
+ /// </summary>
+ /// <remarks>
+ /// ZigZag encodes signed integers into values that can be efficiently
+ /// encoded with varint. (Otherwise, negative values must be
+ /// sign-extended to 64 bits to be varint encoded, thus always taking
+ /// 10 bytes on the wire.)
+ /// </remarks>
+ internal static int DecodeZigZag32(uint n)
+ {
+ return (int)(n >> 1) ^ -(int)(n & 1);
+ }
+
+ /// <summary>
+ /// Decode a 32-bit value with ZigZag encoding.
+ /// </summary>
+ /// <remarks>
+ /// ZigZag encodes signed integers into values that can be efficiently
+ /// encoded with varint. (Otherwise, negative values must be
+ /// sign-extended to 64 bits to be varint encoded, thus always taking
+ /// 10 bytes on the wire.)
+ /// </remarks>
+ internal static long DecodeZigZag64(ulong n)
+ {
+ return (long)(n >> 1) ^ -(long)(n & 1);
+ }
+ #endregion
+
+ #region Internal reading and buffer management
+
+ /// <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>
+ internal int PushLimit(int byteLimit)
+ {
+ if (byteLimit < 0)
+ {
+ throw InvalidProtocolBufferException.NegativeSize();
+ }
+ byteLimit += totalBytesRetired + bufferPos;
+ int oldLimit = currentLimit;
+ if (byteLimit > oldLimit)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ currentLimit = byteLimit;
+
+ RecomputeBufferSizeAfterLimit();
+
+ return oldLimit;
+ }
+
+ private void RecomputeBufferSizeAfterLimit()
+ {
+ bufferSize += bufferSizeAfterLimit;
+ int bufferEnd = totalBytesRetired + bufferSize;
+ if (bufferEnd > currentLimit)
+ {
+ // Limit is in current buffer.
+ bufferSizeAfterLimit = bufferEnd - currentLimit;
+ bufferSize -= bufferSizeAfterLimit;
+ }
+ else
+ {
+ bufferSizeAfterLimit = 0;
+ }
+ }
+
+ /// <summary>
+ /// Discards the current limit, returning the previous limit.
+ /// </summary>
+ internal void PopLimit(int oldLimit)
+ {
+ currentLimit = oldLimit;
+ RecomputeBufferSizeAfterLimit();
+ }
+
+ /// <summary>
+ /// Returns whether or not all the data before the limit has been read.
+ /// </summary>
+ /// <returns></returns>
+ internal bool ReachedLimit
+ {
+ get
+ {
+ if (currentLimit == int.MaxValue)
+ {
+ return false;
+ }
+ int currentAbsolutePosition = totalBytesRetired + bufferPos;
+ return currentAbsolutePosition >= currentLimit;
+ }
+ }
+
+ /// <summary>
+ /// Returns true if the stream has reached the end of the input. This is the
+ /// case if either the end of the underlying input source has been reached or
+ /// the stream has reached a limit created using PushLimit.
+ /// </summary>
+ public bool IsAtEnd
+ {
+ get { return bufferPos == bufferSize && !RefillBuffer(false); }
+ }
+
+ /// <summary>
+ /// Called when buffer is empty to read more bytes from the
+ /// input. If <paramref name="mustSucceed"/> is true, RefillBuffer() gurantees that
+ /// either there will be at least one byte in the buffer when it returns
+ /// or it will throw an exception. If <paramref name="mustSucceed"/> is false,
+ /// RefillBuffer() returns false if no more bytes were available.
+ /// </summary>
+ /// <param name="mustSucceed"></param>
+ /// <returns></returns>
+ private bool RefillBuffer(bool mustSucceed)
+ {
+ if (bufferPos < bufferSize)
+ {
+ throw new InvalidOperationException("RefillBuffer() called when buffer wasn't empty.");
+ }
+
+ if (totalBytesRetired + bufferSize == currentLimit)
+ {
+ // Oops, we hit a limit.
+ if (mustSucceed)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ totalBytesRetired += bufferSize;
+
+ bufferPos = 0;
+ bufferSize = (input == null) ? 0 : input.Read(buffer, 0, buffer.Length);
+ if (bufferSize < 0)
+ {
+ throw new InvalidOperationException("Stream.Read returned a negative count");
+ }
+ if (bufferSize == 0)
+ {
+ if (mustSucceed)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ RecomputeBufferSizeAfterLimit();
+ int totalBytesRead =
+ totalBytesRetired + bufferSize + bufferSizeAfterLimit;
+ if (totalBytesRead > sizeLimit || totalBytesRead < 0)
+ {
+ throw InvalidProtocolBufferException.SizeLimitExceeded();
+ }
+ return true;
+ }
+ }
+
+ /// <summary>
+ /// Read one byte from the input.
+ /// </summary>
+ /// <exception cref="InvalidProtocolBufferException">
+ /// the end of the stream or the current limit was reached
+ /// </exception>
+ internal byte ReadRawByte()
+ {
+ if (bufferPos == bufferSize)
+ {
+ RefillBuffer(true);
+ }
+ return buffer[bufferPos++];
+ }
+
+ /// <summary>
+ /// 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>
+ internal byte[] ReadRawBytes(int size)
+ {
+ if (size < 0)
+ {
+ throw InvalidProtocolBufferException.NegativeSize();
+ }
+
+ if (totalBytesRetired + bufferPos + size > currentLimit)
+ {
+ // Read to the end of the stream (up to the current limit) anyway.
+ SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+ // Then fail.
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+
+ if (size <= bufferSize - bufferPos)
+ {
+ // We have all the bytes we need already.
+ byte[] bytes = new byte[size];
+ ByteArray.Copy(buffer, bufferPos, bytes, 0, size);
+ bufferPos += size;
+ return bytes;
+ }
+ else if (size < buffer.Length)
+ {
+ // Reading more bytes than are in the buffer, but not an excessive number
+ // of bytes. We can safely allocate the resulting array ahead of time.
+
+ // First copy what we have.
+ byte[] bytes = new byte[size];
+ int pos = bufferSize - bufferPos;
+ ByteArray.Copy(buffer, bufferPos, bytes, 0, pos);
+ bufferPos = bufferSize;
+
+ // We want to use RefillBuffer() and then copy from the buffer into our
+ // byte array rather than reading directly into our byte array because
+ // the input may be unbuffered.
+ RefillBuffer(true);
+
+ while (size - pos > bufferSize)
+ {
+ Buffer.BlockCopy(buffer, 0, bytes, pos, bufferSize);
+ pos += bufferSize;
+ bufferPos = bufferSize;
+ RefillBuffer(true);
+ }
+
+ ByteArray.Copy(buffer, 0, bytes, pos, size - pos);
+ bufferPos = size - pos;
+
+ return bytes;
+ }
+ else
+ {
+ // The size is very large. For security reasons, we can't allocate the
+ // entire byte array yet. The size comes directly from the input, so a
+ // maliciously-crafted message could provide a bogus very large size in
+ // order to trick the app into allocating a lot of memory. We avoid this
+ // by allocating and reading only a small chunk at a time, so that the
+ // malicious message must actually *be* extremely large to cause
+ // problems. Meanwhile, we limit the allowed size of a message elsewhere.
+
+ // Remember the buffer markers since we'll have to copy the bytes out of
+ // it later.
+ int originalBufferPos = bufferPos;
+ int originalBufferSize = bufferSize;
+
+ // Mark the current buffer consumed.
+ totalBytesRetired += bufferSize;
+ bufferPos = 0;
+ bufferSize = 0;
+
+ // Read all the rest of the bytes we need.
+ int sizeLeft = size - (originalBufferSize - originalBufferPos);
+ List<byte[]> chunks = new List<byte[]>();
+
+ while (sizeLeft > 0)
+ {
+ byte[] chunk = new byte[Math.Min(sizeLeft, buffer.Length)];
+ int pos = 0;
+ while (pos < chunk.Length)
+ {
+ int n = (input == null) ? -1 : input.Read(chunk, pos, chunk.Length - pos);
+ if (n <= 0)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ totalBytesRetired += n;
+ pos += n;
+ }
+ sizeLeft -= chunk.Length;
+ chunks.Add(chunk);
+ }
+
+ // OK, got everything. Now concatenate it all into one buffer.
+ byte[] bytes = new byte[size];
+
+ // Start by copying the leftover bytes from this.buffer.
+ int newPos = originalBufferSize - originalBufferPos;
+ ByteArray.Copy(buffer, originalBufferPos, bytes, 0, newPos);
+
+ // And now all the chunks.
+ foreach (byte[] chunk in chunks)
+ {
+ Buffer.BlockCopy(chunk, 0, bytes, newPos, chunk.Length);
+ newPos += chunk.Length;
+ }
+
+ // Done.
+ return bytes;
+ }
+ }
+
+ /// <summary>
+ /// Reads and discards <paramref name="size"/> bytes.
+ /// </summary>
+ /// <exception cref="InvalidProtocolBufferException">the end of the stream
+ /// or the current limit was reached</exception>
+ private void SkipRawBytes(int size)
+ {
+ if (size < 0)
+ {
+ throw InvalidProtocolBufferException.NegativeSize();
+ }
+
+ if (totalBytesRetired + bufferPos + size > currentLimit)
+ {
+ // Read to the end of the stream anyway.
+ SkipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+ // Then fail.
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+
+ if (size <= bufferSize - bufferPos)
+ {
+ // We have all the bytes we need already.
+ bufferPos += size;
+ }
+ else
+ {
+ // Skipping more bytes than are in the buffer. First skip what we have.
+ int pos = bufferSize - bufferPos;
+
+ // ROK 5/7/2013 Issue #54: should retire all bytes in buffer (bufferSize)
+ // totalBytesRetired += pos;
+ totalBytesRetired += bufferSize;
+
+ bufferPos = 0;
+ bufferSize = 0;
+
+ // Then skip directly from the InputStream for the rest.
+ if (pos < size)
+ {
+ if (input == null)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ SkipImpl(size - pos);
+ totalBytesRetired += size - pos;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Abstraction of skipping to cope with streams which can't really skip.
+ /// </summary>
+ private void SkipImpl(int amountToSkip)
+ {
+ if (input.CanSeek)
+ {
+ long previousPosition = input.Position;
+ input.Position += amountToSkip;
+ if (input.Position != previousPosition + amountToSkip)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ }
+ else
+ {
+ byte[] skipBuffer = new byte[Math.Min(1024, amountToSkip)];
+ while (amountToSkip > 0)
+ {
+ int bytesRead = input.Read(skipBuffer, 0, Math.Min(skipBuffer.Length, amountToSkip));
+ if (bytesRead <= 0)
+ {
+ throw InvalidProtocolBufferException.TruncatedMessage();
+ }
+ amountToSkip -= bytesRead;
+ }
+ }
+ }
+
+ #endregion
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs
index bf221c9c0a..e22937c13d 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs
@@ -1,304 +1,304 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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;
-
-namespace Google.Protobuf
-{
- // This part of CodedOutputStream provides all the static entry points that are used
- // by generated code and internally to compute the size of messages prior to being
- // written to an instance of CodedOutputStream.
- public sealed partial class CodedOutputStream
- {
- private const int LittleEndian64Size = 8;
- private const int LittleEndian32Size = 4;
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a
- /// double field, including the tag.
- /// </summary>
- public static int ComputeDoubleSize(double value)
- {
- return LittleEndian64Size;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a
- /// float field, including the tag.
- /// </summary>
- public static int ComputeFloatSize(float value)
- {
- return LittleEndian32Size;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a
- /// uint64 field, including the tag.
- /// </summary>
- public static int ComputeUInt64Size(ulong value)
- {
- return ComputeRawVarint64Size(value);
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode an
- /// int64 field, including the tag.
- /// </summary>
- public static int ComputeInt64Size(long value)
- {
- return ComputeRawVarint64Size((ulong) value);
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode an
- /// int32 field, including the tag.
- /// </summary>
- public static int ComputeInt32Size(int value)
- {
- if (value >= 0)
- {
- return ComputeRawVarint32Size((uint) value);
- }
- else
- {
- // Must sign-extend.
- return 10;
- }
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a
- /// fixed64 field, including the tag.
- /// </summary>
- public static int ComputeFixed64Size(ulong value)
- {
- return LittleEndian64Size;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a
- /// fixed32 field, including the tag.
- /// </summary>
- public static int ComputeFixed32Size(uint value)
- {
- return LittleEndian32Size;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a
- /// bool field, including the tag.
- /// </summary>
- public static int ComputeBoolSize(bool value)
- {
- return 1;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a
- /// string field, including the tag.
- /// </summary>
- public static int ComputeStringSize(String value)
- {
- int byteArraySize = Utf8Encoding.GetByteCount(value);
- return ComputeLengthSize(byteArraySize) + byteArraySize;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a
- /// group field, including the tag.
- /// </summary>
- public static int ComputeGroupSize(IMessage value)
- {
- return value.CalculateSize();
- }
-
- /// <summary>
- /// 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)
- {
- int size = value.CalculateSize();
- return ComputeLengthSize(size) + size;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a
- /// bytes field, including the tag.
- /// </summary>
- public static int ComputeBytesSize(ByteString value)
- {
- return ComputeLengthSize(value.Length) + value.Length;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a
- /// uint32 field, including the tag.
- /// </summary>
- public static int ComputeUInt32Size(uint value)
- {
- return ComputeRawVarint32Size(value);
- }
-
- /// <summary>
- /// 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>
- public static int ComputeEnumSize(int value)
- {
- // Currently just a pass-through, but it's nice to separate it logically.
- return ComputeInt32Size(value);
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode an
- /// sfixed32 field, including the tag.
- /// </summary>
- public static int ComputeSFixed32Size(int value)
- {
- return LittleEndian32Size;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode an
- /// sfixed64 field, including the tag.
- /// </summary>
- public static int ComputeSFixed64Size(long value)
- {
- return LittleEndian64Size;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode an
- /// sint32 field, including the tag.
- /// </summary>
- public static int ComputeSInt32Size(int value)
- {
- return ComputeRawVarint32Size(EncodeZigZag32(value));
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode an
- /// sint64 field, including the tag.
- /// </summary>
- public static int ComputeSInt64Size(long value)
- {
- return ComputeRawVarint64Size(EncodeZigZag64(value));
- }
-
- /// <summary>
- /// 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)
- {
- if ((value & (0xffffffff << 7)) == 0)
- {
- return 1;
- }
- if ((value & (0xffffffff << 14)) == 0)
- {
- return 2;
- }
- if ((value & (0xffffffff << 21)) == 0)
- {
- return 3;
- }
- if ((value & (0xffffffff << 28)) == 0)
- {
- return 4;
- }
- return 5;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a varint.
- /// </summary>
- public static int ComputeRawVarint64Size(ulong value)
- {
- if ((value & (0xffffffffffffffffL << 7)) == 0)
- {
- return 1;
- }
- if ((value & (0xffffffffffffffffL << 14)) == 0)
- {
- return 2;
- }
- if ((value & (0xffffffffffffffffL << 21)) == 0)
- {
- return 3;
- }
- if ((value & (0xffffffffffffffffL << 28)) == 0)
- {
- return 4;
- }
- if ((value & (0xffffffffffffffffL << 35)) == 0)
- {
- return 5;
- }
- if ((value & (0xffffffffffffffffL << 42)) == 0)
- {
- return 6;
- }
- if ((value & (0xffffffffffffffffL << 49)) == 0)
- {
- return 7;
- }
- if ((value & (0xffffffffffffffffL << 56)) == 0)
- {
- return 8;
- }
- if ((value & (0xffffffffffffffffL << 63)) == 0)
- {
- return 9;
- }
- return 10;
- }
-
- /// <summary>
- /// Computes the number of bytes that would be needed to encode a tag.
- /// </summary>
- public static int ComputeTagSize(int fieldNumber)
- {
- return ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, 0));
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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;
+
+namespace Google.Protobuf
+{
+ // This part of CodedOutputStream provides all the static entry points that are used
+ // by generated code and internally to compute the size of messages prior to being
+ // written to an instance of CodedOutputStream.
+ public sealed partial class CodedOutputStream
+ {
+ private const int LittleEndian64Size = 8;
+ private const int LittleEndian32Size = 4;
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a
+ /// double field, including the tag.
+ /// </summary>
+ public static int ComputeDoubleSize(double value)
+ {
+ return LittleEndian64Size;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a
+ /// float field, including the tag.
+ /// </summary>
+ public static int ComputeFloatSize(float value)
+ {
+ return LittleEndian32Size;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a
+ /// uint64 field, including the tag.
+ /// </summary>
+ public static int ComputeUInt64Size(ulong value)
+ {
+ return ComputeRawVarint64Size(value);
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode an
+ /// int64 field, including the tag.
+ /// </summary>
+ public static int ComputeInt64Size(long value)
+ {
+ return ComputeRawVarint64Size((ulong) value);
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode an
+ /// int32 field, including the tag.
+ /// </summary>
+ public static int ComputeInt32Size(int value)
+ {
+ if (value >= 0)
+ {
+ return ComputeRawVarint32Size((uint) value);
+ }
+ else
+ {
+ // Must sign-extend.
+ return 10;
+ }
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a
+ /// fixed64 field, including the tag.
+ /// </summary>
+ public static int ComputeFixed64Size(ulong value)
+ {
+ return LittleEndian64Size;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a
+ /// fixed32 field, including the tag.
+ /// </summary>
+ public static int ComputeFixed32Size(uint value)
+ {
+ return LittleEndian32Size;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a
+ /// bool field, including the tag.
+ /// </summary>
+ public static int ComputeBoolSize(bool value)
+ {
+ return 1;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a
+ /// string field, including the tag.
+ /// </summary>
+ public static int ComputeStringSize(String value)
+ {
+ int byteArraySize = Utf8Encoding.GetByteCount(value);
+ return ComputeLengthSize(byteArraySize) + byteArraySize;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a
+ /// group field, including the tag.
+ /// </summary>
+ public static int ComputeGroupSize(IMessage value)
+ {
+ return value.CalculateSize();
+ }
+
+ /// <summary>
+ /// 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)
+ {
+ int size = value.CalculateSize();
+ return ComputeLengthSize(size) + size;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a
+ /// bytes field, including the tag.
+ /// </summary>
+ public static int ComputeBytesSize(ByteString value)
+ {
+ return ComputeLengthSize(value.Length) + value.Length;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a
+ /// uint32 field, including the tag.
+ /// </summary>
+ public static int ComputeUInt32Size(uint value)
+ {
+ return ComputeRawVarint32Size(value);
+ }
+
+ /// <summary>
+ /// 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>
+ public static int ComputeEnumSize(int value)
+ {
+ // Currently just a pass-through, but it's nice to separate it logically.
+ return ComputeInt32Size(value);
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode an
+ /// sfixed32 field, including the tag.
+ /// </summary>
+ public static int ComputeSFixed32Size(int value)
+ {
+ return LittleEndian32Size;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode an
+ /// sfixed64 field, including the tag.
+ /// </summary>
+ public static int ComputeSFixed64Size(long value)
+ {
+ return LittleEndian64Size;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode an
+ /// sint32 field, including the tag.
+ /// </summary>
+ public static int ComputeSInt32Size(int value)
+ {
+ return ComputeRawVarint32Size(EncodeZigZag32(value));
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode an
+ /// sint64 field, including the tag.
+ /// </summary>
+ public static int ComputeSInt64Size(long value)
+ {
+ return ComputeRawVarint64Size(EncodeZigZag64(value));
+ }
+
+ /// <summary>
+ /// 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)
+ {
+ if ((value & (0xffffffff << 7)) == 0)
+ {
+ return 1;
+ }
+ if ((value & (0xffffffff << 14)) == 0)
+ {
+ return 2;
+ }
+ if ((value & (0xffffffff << 21)) == 0)
+ {
+ return 3;
+ }
+ if ((value & (0xffffffff << 28)) == 0)
+ {
+ return 4;
+ }
+ return 5;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a varint.
+ /// </summary>
+ public static int ComputeRawVarint64Size(ulong value)
+ {
+ if ((value & (0xffffffffffffffffL << 7)) == 0)
+ {
+ return 1;
+ }
+ if ((value & (0xffffffffffffffffL << 14)) == 0)
+ {
+ return 2;
+ }
+ if ((value & (0xffffffffffffffffL << 21)) == 0)
+ {
+ return 3;
+ }
+ if ((value & (0xffffffffffffffffL << 28)) == 0)
+ {
+ return 4;
+ }
+ if ((value & (0xffffffffffffffffL << 35)) == 0)
+ {
+ return 5;
+ }
+ if ((value & (0xffffffffffffffffL << 42)) == 0)
+ {
+ return 6;
+ }
+ if ((value & (0xffffffffffffffffL << 49)) == 0)
+ {
+ return 7;
+ }
+ if ((value & (0xffffffffffffffffL << 56)) == 0)
+ {
+ return 8;
+ }
+ if ((value & (0xffffffffffffffffL << 63)) == 0)
+ {
+ return 9;
+ }
+ return 10;
+ }
+
+ /// <summary>
+ /// Computes the number of bytes that would be needed to encode a tag.
+ /// </summary>
+ public static int ComputeTagSize(int fieldNumber)
+ {
+ return ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, 0));
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedOutputStream.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedOutputStream.cs
index 6211aac32c..827f0398cf 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedOutputStream.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/CodedOutputStream.cs
@@ -1,761 +1,761 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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 Google.Protobuf.Collections;
-using System;
-using System.IO;
-using System.Text;
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Encodes and writes protocol message fields.
- /// </summary>
- /// <remarks>
- /// <para>
- /// This class is generally used by generated code to write appropriate
- /// primitives to the stream. It effectively encapsulates the lowest
- /// levels of protocol buffer format. Unlike some other implementations,
- /// this does not include combined "write tag and value" methods. Generated
- /// code knows the exact byte representations of the tags they're going to write,
- /// so there's no need to re-encode them each time. Manually-written code calling
- /// this class should just call one of the <c>WriteTag</c> overloads before each value.
- /// </para>
- /// <para>
- /// Repeated fields and map fields are not handled by this class; use <c>RepeatedField&lt;T&gt;</c>
- /// and <c>MapField&lt;TKey, TValue&gt;</c> to serialize such fields.
- /// </para>
- /// </remarks>
- public sealed partial class CodedOutputStream : IDisposable
- {
- // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
- internal static readonly Encoding Utf8Encoding = Encoding.UTF8;
-
- /// <summary>
- /// The buffer size used by CreateInstance(Stream).
- /// </summary>
- public static readonly int DefaultBufferSize = 4096;
-
- private readonly bool leaveOpen;
- private readonly byte[] buffer;
- private readonly int limit;
- private int position;
- private readonly Stream output;
-
- #region Construction
- /// <summary>
- /// Creates a new CodedOutputStream that writes directly to the given
- /// byte array. If more bytes are written than fit in the array,
- /// OutOfSpaceException will be thrown.
- /// </summary>
- public CodedOutputStream(byte[] flatArray) : this(flatArray, 0, flatArray.Length)
- {
- }
-
- /// <summary>
- /// Creates a new CodedOutputStream that writes directly to the given
- /// byte array slice. If more bytes are written than fit in the array,
- /// OutOfSpaceException will be thrown.
- /// </summary>
- private CodedOutputStream(byte[] buffer, int offset, int length)
- {
- this.output = null;
- this.buffer = buffer;
- this.position = offset;
- this.limit = offset + length;
- leaveOpen = true; // Simple way of avoiding trying to dispose of a null reference
- }
-
- private CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen)
- {
- this.output = ProtoPreconditions.CheckNotNull(output, nameof(output));
- this.buffer = buffer;
- this.position = 0;
- this.limit = buffer.Length;
- this.leaveOpen = leaveOpen;
- }
-
- /// <summary>
- /// Creates a new <see cref="CodedOutputStream" /> which write to the given stream, and disposes of that
- /// stream when the returned <c>CodedOutputStream</c> is disposed.
- /// </summary>
- /// <param name="output">The stream to write to. It will be disposed when the returned <c>CodedOutputStream is disposed.</c></param>
- public CodedOutputStream(Stream output) : this(output, DefaultBufferSize, false)
- {
- }
-
- /// <summary>
- /// Creates a new CodedOutputStream which write to the given stream and uses
- /// the specified buffer size.
- /// </summary>
- /// <param name="output">The stream to write to. It will be disposed when the returned <c>CodedOutputStream is disposed.</c></param>
- /// <param name="bufferSize">The size of buffer to use internally.</param>
- public CodedOutputStream(Stream output, int bufferSize) : this(output, new byte[bufferSize], false)
- {
- }
-
- /// <summary>
- /// Creates a new CodedOutputStream which write to the given stream.
- /// </summary>
- /// <param name="output">The stream to write to.</param>
- /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is left open when the returned <c>CodedOutputStream</c> is disposed;
- /// if <c>false</c>, the provided stream is disposed as well.</param>
- public CodedOutputStream(Stream output, bool leaveOpen) : this(output, DefaultBufferSize, leaveOpen)
- {
- }
-
- /// <summary>
- /// Creates a new CodedOutputStream which write to the given stream and uses
- /// the specified buffer size.
- /// </summary>
- /// <param name="output">The stream to write to.</param>
- /// <param name="bufferSize">The size of buffer to use internally.</param>
- /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is left open when the returned <c>CodedOutputStream</c> is disposed;
- /// if <c>false</c>, the provided stream is disposed as well.</param>
- public CodedOutputStream(Stream output, int bufferSize, bool leaveOpen) : this(output, new byte[bufferSize], leaveOpen)
- {
- }
- #endregion
-
- /// <summary>
- /// Returns the current position in the stream, or the position in the output buffer
- /// </summary>
- public long Position
- {
- get
- {
- if (output != null)
- {
- return output.Position + position;
- }
- return position;
- }
- }
-
- #region Writing of values (not including tags)
-
- /// <summary>
- /// 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));
- }
-
- /// <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);
- if (!BitConverter.IsLittleEndian)
- {
- ByteArray.Reverse(rawBytes);
- }
-
- if (limit - position >= 4)
- {
- buffer[position++] = rawBytes[0];
- buffer[position++] = rawBytes[1];
- buffer[position++] = rawBytes[2];
- buffer[position++] = rawBytes[3];
- }
- else
- {
- WriteRawBytes(rawBytes, 0, 4);
- }
- }
-
- /// <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);
- }
-
- /// <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);
- }
-
- /// <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)
- {
- WriteRawVarint32((uint) value);
- }
- else
- {
- // Must sign-extend.
- WriteRawVarint64((ulong) value);
- }
- }
-
- /// <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);
- }
-
- /// <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);
- }
-
- /// <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);
- }
-
- /// <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);
- WriteLength(length);
- if (limit - position >= length)
- {
- if (length == value.Length) // Must be all ASCII...
- {
- for (int i = 0; i < length; i++)
- {
- buffer[position + i] = (byte)value[i];
- }
- }
- else
- {
- Utf8Encoding.GetBytes(value, 0, value.Length, buffer, position);
- }
- position += length;
- }
- else
- {
- byte[] bytes = Utf8Encoding.GetBytes(value);
- WriteRawBytes(bytes);
- }
- }
-
- /// <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)
- {
- WriteLength(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)
- {
- WriteLength(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);
- }
-
- /// <summary>
- /// Writes an sfixed32 value, without a tag, to the stream.
- /// </summary>
- /// <param name="value">The value to write.</param>
- public void WriteSFixed32(int value)
- {
- 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));
- }
-
- /// <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)
- {
- WriteRawVarint32((uint) length);
- }
-
- #endregion
-
- #region Raw tag writing
- /// <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));
- }
-
- /// <summary>
- /// Writes an already-encoded tag.
- /// </summary>
- /// <param name="tag">The encoded tag</param>
- public void WriteTag(uint tag)
- {
- WriteRawVarint32(tag);
- }
-
- /// <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);
- }
-
- /// <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);
- WriteRawByte(b2);
- }
-
- /// <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);
- WriteRawByte(b2);
- WriteRawByte(b3);
- }
-
- /// <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);
- WriteRawByte(b2);
- WriteRawByte(b3);
- WriteRawByte(b4);
- }
-
- /// <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);
- WriteRawByte(b2);
- WriteRawByte(b3);
- WriteRawByte(b4);
- WriteRawByte(b5);
- }
- #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>
- internal void WriteRawVarint32(uint value)
- {
- // Optimize for the common case of a single byte value
- if (value < 128 && position < limit)
- {
- buffer[position++] = (byte)value;
- return;
- }
-
- while (value > 127 && position < limit)
- {
- buffer[position++] = (byte) ((value & 0x7F) | 0x80);
- value >>= 7;
- }
- while (value > 127)
- {
- WriteRawByte((byte) ((value & 0x7F) | 0x80));
- value >>= 7;
- }
- if (position < limit)
- {
- buffer[position++] = (byte) value;
- }
- else
- {
- WriteRawByte((byte) value);
- }
- }
-
- internal void WriteRawVarint64(ulong value)
- {
- while (value > 127 && position < limit)
- {
- buffer[position++] = (byte) ((value & 0x7F) | 0x80);
- value >>= 7;
- }
- while (value > 127)
- {
- WriteRawByte((byte) ((value & 0x7F) | 0x80));
- value >>= 7;
- }
- if (position < limit)
- {
- buffer[position++] = (byte) value;
- }
- else
- {
- WriteRawByte((byte) value);
- }
- }
-
- internal void WriteRawLittleEndian32(uint value)
- {
- if (position + 4 > limit)
- {
- WriteRawByte((byte) value);
- WriteRawByte((byte) (value >> 8));
- WriteRawByte((byte) (value >> 16));
- WriteRawByte((byte) (value >> 24));
- }
- else
- {
- buffer[position++] = ((byte) value);
- buffer[position++] = ((byte) (value >> 8));
- buffer[position++] = ((byte) (value >> 16));
- buffer[position++] = ((byte) (value >> 24));
- }
- }
-
- internal void WriteRawLittleEndian64(ulong value)
- {
- if (position + 8 > limit)
- {
- WriteRawByte((byte) value);
- WriteRawByte((byte) (value >> 8));
- WriteRawByte((byte) (value >> 16));
- WriteRawByte((byte) (value >> 24));
- WriteRawByte((byte) (value >> 32));
- WriteRawByte((byte) (value >> 40));
- WriteRawByte((byte) (value >> 48));
- WriteRawByte((byte) (value >> 56));
- }
- else
- {
- buffer[position++] = ((byte) value);
- buffer[position++] = ((byte) (value >> 8));
- buffer[position++] = ((byte) (value >> 16));
- buffer[position++] = ((byte) (value >> 24));
- buffer[position++] = ((byte) (value >> 32));
- buffer[position++] = ((byte) (value >> 40));
- buffer[position++] = ((byte) (value >> 48));
- buffer[position++] = ((byte) (value >> 56));
- }
- }
-
- internal void WriteRawByte(byte value)
- {
- if (position == limit)
- {
- RefreshBuffer();
- }
-
- buffer[position++] = value;
- }
-
- internal void WriteRawByte(uint value)
- {
- WriteRawByte((byte) value);
- }
-
- /// <summary>
- /// Writes out an array of bytes.
- /// </summary>
- internal void WriteRawBytes(byte[] value)
- {
- WriteRawBytes(value, 0, value.Length);
- }
-
- /// <summary>
- /// Writes out part of an array of bytes.
- /// </summary>
- internal void WriteRawBytes(byte[] value, int offset, int length)
- {
- if (limit - position >= length)
- {
- ByteArray.Copy(value, offset, buffer, position, length);
- // We have room in the current buffer.
- position += length;
- }
- else
- {
- // Write extends past current buffer. Fill the rest of this buffer and
- // flush.
- int bytesWritten = limit - position;
- ByteArray.Copy(value, offset, buffer, position, bytesWritten);
- offset += bytesWritten;
- length -= bytesWritten;
- position = limit;
- RefreshBuffer();
-
- // Now deal with the rest.
- // Since we have an output stream, this is our buffer
- // and buffer offset == 0
- if (length <= limit)
- {
- // Fits in new buffer.
- ByteArray.Copy(value, offset, buffer, 0, length);
- position = length;
- }
- else
- {
- // Write is very big. Let's do it all at once.
- output.Write(value, offset, length);
- }
- }
- }
-
- #endregion
-
- /// <summary>
- /// Encode a 32-bit value with ZigZag encoding.
- /// </summary>
- /// <remarks>
- /// ZigZag encodes signed integers into values that can be efficiently
- /// encoded with varint. (Otherwise, negative values must be
- /// sign-extended to 64 bits to be varint encoded, thus always taking
- /// 10 bytes on the wire.)
- /// </remarks>
- internal static uint EncodeZigZag32(int n)
- {
- // Note: the right-shift must be arithmetic
- return (uint) ((n << 1) ^ (n >> 31));
- }
-
- /// <summary>
- /// Encode a 64-bit value with ZigZag encoding.
- /// </summary>
- /// <remarks>
- /// ZigZag encodes signed integers into values that can be efficiently
- /// encoded with varint. (Otherwise, negative values must be
- /// sign-extended to 64 bits to be varint encoded, thus always taking
- /// 10 bytes on the wire.)
- /// </remarks>
- internal static ulong EncodeZigZag64(long n)
- {
- return (ulong) ((n << 1) ^ (n >> 63));
- }
-
- private void RefreshBuffer()
- {
- if (output == null)
- {
- // We're writing to a single buffer.
- throw new OutOfSpaceException();
- }
-
- // Since we have an output stream, this is our buffer
- // and buffer offset == 0
- output.Write(buffer, 0, position);
- position = 0;
- }
-
- /// <summary>
- /// Indicates that a CodedOutputStream wrapping a flat byte array
- /// ran out of space.
- /// </summary>
- public sealed class OutOfSpaceException : IOException
- {
- internal OutOfSpaceException()
- : base("CodedOutputStream was writing to a flat byte array and ran out of space.")
- {
- }
- }
-
- /// <summary>
- /// Flushes any buffered data and optionally closes the underlying stream, if any.
- /// </summary>
- /// <remarks>
- /// <para>
- /// By default, any underlying stream is closed by this method. To configure this behaviour,
- /// use a constructor overload with a <c>leaveOpen</c> parameter. If this instance does not
- /// have an underlying stream, this method does nothing.
- /// </para>
- /// <para>
- /// For the sake of efficiency, calling this method does not prevent future write calls - but
- /// if a later write ends up writing to a stream which has been disposed, that is likely to
- /// fail. It is recommend that you not call any other methods after this.
- /// </para>
- /// </remarks>
- public void Dispose()
- {
- Flush();
- if (!leaveOpen)
- {
- output.Dispose();
- }
- }
-
- /// <summary>
- /// Flushes any buffered data to the underlying stream (if there is one).
- /// </summary>
- public void Flush()
- {
- if (output != null)
- {
- RefreshBuffer();
- }
- }
-
- /// <summary>
- /// Verifies that SpaceLeft returns zero. It's common to create a byte array
- /// that is exactly big enough to hold a message, then write to it with
- /// a CodedOutputStream. Calling CheckNoSpaceLeft after writing verifies that
- /// the message was actually as big as expected, which can help bugs.
- /// </summary>
- public void CheckNoSpaceLeft()
- {
- if (SpaceLeft != 0)
- {
- throw new InvalidOperationException("Did not write as much data as expected.");
- }
- }
-
- /// <summary>
- /// If writing to a flat array, returns the space left in the array. Otherwise,
- /// throws an InvalidOperationException.
- /// </summary>
- public int SpaceLeft
- {
- get
- {
- if (output == null)
- {
- return limit - position;
- }
- else
- {
- throw new InvalidOperationException(
- "SpaceLeft can only be called on CodedOutputStreams that are " +
- "writing to a flat array.");
- }
- }
- }
- }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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 Google.Protobuf.Collections;
+using System;
+using System.IO;
+using System.Text;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Encodes and writes protocol message fields.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This class is generally used by generated code to write appropriate
+ /// primitives to the stream. It effectively encapsulates the lowest
+ /// levels of protocol buffer format. Unlike some other implementations,
+ /// this does not include combined "write tag and value" methods. Generated
+ /// code knows the exact byte representations of the tags they're going to write,
+ /// so there's no need to re-encode them each time. Manually-written code calling
+ /// this class should just call one of the <c>WriteTag</c> overloads before each value.
+ /// </para>
+ /// <para>
+ /// Repeated fields and map fields are not handled by this class; use <c>RepeatedField&lt;T&gt;</c>
+ /// and <c>MapField&lt;TKey, TValue&gt;</c> to serialize such fields.
+ /// </para>
+ /// </remarks>
+ public sealed partial class CodedOutputStream : IDisposable
+ {
+ // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
+ internal static readonly Encoding Utf8Encoding = Encoding.UTF8;
+
+ /// <summary>
+ /// The buffer size used by CreateInstance(Stream).
+ /// </summary>
+ public static readonly int DefaultBufferSize = 4096;
+
+ private readonly bool leaveOpen;
+ private readonly byte[] buffer;
+ private readonly int limit;
+ private int position;
+ private readonly Stream output;
+
+ #region Construction
+ /// <summary>
+ /// Creates a new CodedOutputStream that writes directly to the given
+ /// byte array. If more bytes are written than fit in the array,
+ /// OutOfSpaceException will be thrown.
+ /// </summary>
+ public CodedOutputStream(byte[] flatArray) : this(flatArray, 0, flatArray.Length)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new CodedOutputStream that writes directly to the given
+ /// byte array slice. If more bytes are written than fit in the array,
+ /// OutOfSpaceException will be thrown.
+ /// </summary>
+ private CodedOutputStream(byte[] buffer, int offset, int length)
+ {
+ this.output = null;
+ this.buffer = buffer;
+ this.position = offset;
+ this.limit = offset + length;
+ leaveOpen = true; // Simple way of avoiding trying to dispose of a null reference
+ }
+
+ private CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen)
+ {
+ this.output = ProtoPreconditions.CheckNotNull(output, nameof(output));
+ this.buffer = buffer;
+ this.position = 0;
+ this.limit = buffer.Length;
+ this.leaveOpen = leaveOpen;
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="CodedOutputStream" /> which write to the given stream, and disposes of that
+ /// stream when the returned <c>CodedOutputStream</c> is disposed.
+ /// </summary>
+ /// <param name="output">The stream to write to. It will be disposed when the returned <c>CodedOutputStream is disposed.</c></param>
+ public CodedOutputStream(Stream output) : this(output, DefaultBufferSize, false)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new CodedOutputStream which write to the given stream and uses
+ /// the specified buffer size.
+ /// </summary>
+ /// <param name="output">The stream to write to. It will be disposed when the returned <c>CodedOutputStream is disposed.</c></param>
+ /// <param name="bufferSize">The size of buffer to use internally.</param>
+ public CodedOutputStream(Stream output, int bufferSize) : this(output, new byte[bufferSize], false)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new CodedOutputStream which write to the given stream.
+ /// </summary>
+ /// <param name="output">The stream to write to.</param>
+ /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is left open when the returned <c>CodedOutputStream</c> is disposed;
+ /// if <c>false</c>, the provided stream is disposed as well.</param>
+ public CodedOutputStream(Stream output, bool leaveOpen) : this(output, DefaultBufferSize, leaveOpen)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new CodedOutputStream which write to the given stream and uses
+ /// the specified buffer size.
+ /// </summary>
+ /// <param name="output">The stream to write to.</param>
+ /// <param name="bufferSize">The size of buffer to use internally.</param>
+ /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is left open when the returned <c>CodedOutputStream</c> is disposed;
+ /// if <c>false</c>, the provided stream is disposed as well.</param>
+ public CodedOutputStream(Stream output, int bufferSize, bool leaveOpen) : this(output, new byte[bufferSize], leaveOpen)
+ {
+ }
+ #endregion
+
+ /// <summary>
+ /// Returns the current position in the stream, or the position in the output buffer
+ /// </summary>
+ public long Position
+ {
+ get
+ {
+ if (output != null)
+ {
+ return output.Position + position;
+ }
+ return position;
+ }
+ }
+
+ #region Writing of values (not including tags)
+
+ /// <summary>
+ /// 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));
+ }
+
+ /// <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);
+ if (!BitConverter.IsLittleEndian)
+ {
+ ByteArray.Reverse(rawBytes);
+ }
+
+ if (limit - position >= 4)
+ {
+ buffer[position++] = rawBytes[0];
+ buffer[position++] = rawBytes[1];
+ buffer[position++] = rawBytes[2];
+ buffer[position++] = rawBytes[3];
+ }
+ else
+ {
+ WriteRawBytes(rawBytes, 0, 4);
+ }
+ }
+
+ /// <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);
+ }
+
+ /// <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);
+ }
+
+ /// <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)
+ {
+ WriteRawVarint32((uint) value);
+ }
+ else
+ {
+ // Must sign-extend.
+ WriteRawVarint64((ulong) value);
+ }
+ }
+
+ /// <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);
+ }
+
+ /// <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);
+ }
+
+ /// <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);
+ }
+
+ /// <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);
+ WriteLength(length);
+ if (limit - position >= length)
+ {
+ if (length == value.Length) // Must be all ASCII...
+ {
+ for (int i = 0; i < length; i++)
+ {
+ buffer[position + i] = (byte)value[i];
+ }
+ }
+ else
+ {
+ Utf8Encoding.GetBytes(value, 0, value.Length, buffer, position);
+ }
+ position += length;
+ }
+ else
+ {
+ byte[] bytes = Utf8Encoding.GetBytes(value);
+ WriteRawBytes(bytes);
+ }
+ }
+
+ /// <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)
+ {
+ WriteLength(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)
+ {
+ WriteLength(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);
+ }
+
+ /// <summary>
+ /// Writes an sfixed32 value, without a tag, to the stream.
+ /// </summary>
+ /// <param name="value">The value to write.</param>
+ public void WriteSFixed32(int value)
+ {
+ 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));
+ }
+
+ /// <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)
+ {
+ WriteRawVarint32((uint) length);
+ }
+
+ #endregion
+
+ #region Raw tag writing
+ /// <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));
+ }
+
+ /// <summary>
+ /// Writes an already-encoded tag.
+ /// </summary>
+ /// <param name="tag">The encoded tag</param>
+ public void WriteTag(uint tag)
+ {
+ WriteRawVarint32(tag);
+ }
+
+ /// <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);
+ }
+
+ /// <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);
+ WriteRawByte(b2);
+ }
+
+ /// <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);
+ WriteRawByte(b2);
+ WriteRawByte(b3);
+ }
+
+ /// <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);
+ WriteRawByte(b2);
+ WriteRawByte(b3);
+ WriteRawByte(b4);
+ }
+
+ /// <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);
+ WriteRawByte(b2);
+ WriteRawByte(b3);
+ WriteRawByte(b4);
+ WriteRawByte(b5);
+ }
+ #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>
+ internal void WriteRawVarint32(uint value)
+ {
+ // Optimize for the common case of a single byte value
+ if (value < 128 && position < limit)
+ {
+ buffer[position++] = (byte)value;
+ return;
+ }
+
+ while (value > 127 && position < limit)
+ {
+ buffer[position++] = (byte) ((value & 0x7F) | 0x80);
+ value >>= 7;
+ }
+ while (value > 127)
+ {
+ WriteRawByte((byte) ((value & 0x7F) | 0x80));
+ value >>= 7;
+ }
+ if (position < limit)
+ {
+ buffer[position++] = (byte) value;
+ }
+ else
+ {
+ WriteRawByte((byte) value);
+ }
+ }
+
+ internal void WriteRawVarint64(ulong value)
+ {
+ while (value > 127 && position < limit)
+ {
+ buffer[position++] = (byte) ((value & 0x7F) | 0x80);
+ value >>= 7;
+ }
+ while (value > 127)
+ {
+ WriteRawByte((byte) ((value & 0x7F) | 0x80));
+ value >>= 7;
+ }
+ if (position < limit)
+ {
+ buffer[position++] = (byte) value;
+ }
+ else
+ {
+ WriteRawByte((byte) value);
+ }
+ }
+
+ internal void WriteRawLittleEndian32(uint value)
+ {
+ if (position + 4 > limit)
+ {
+ WriteRawByte((byte) value);
+ WriteRawByte((byte) (value >> 8));
+ WriteRawByte((byte) (value >> 16));
+ WriteRawByte((byte) (value >> 24));
+ }
+ else
+ {
+ buffer[position++] = ((byte) value);
+ buffer[position++] = ((byte) (value >> 8));
+ buffer[position++] = ((byte) (value >> 16));
+ buffer[position++] = ((byte) (value >> 24));
+ }
+ }
+
+ internal void WriteRawLittleEndian64(ulong value)
+ {
+ if (position + 8 > limit)
+ {
+ WriteRawByte((byte) value);
+ WriteRawByte((byte) (value >> 8));
+ WriteRawByte((byte) (value >> 16));
+ WriteRawByte((byte) (value >> 24));
+ WriteRawByte((byte) (value >> 32));
+ WriteRawByte((byte) (value >> 40));
+ WriteRawByte((byte) (value >> 48));
+ WriteRawByte((byte) (value >> 56));
+ }
+ else
+ {
+ buffer[position++] = ((byte) value);
+ buffer[position++] = ((byte) (value >> 8));
+ buffer[position++] = ((byte) (value >> 16));
+ buffer[position++] = ((byte) (value >> 24));
+ buffer[position++] = ((byte) (value >> 32));
+ buffer[position++] = ((byte) (value >> 40));
+ buffer[position++] = ((byte) (value >> 48));
+ buffer[position++] = ((byte) (value >> 56));
+ }
+ }
+
+ internal void WriteRawByte(byte value)
+ {
+ if (position == limit)
+ {
+ RefreshBuffer();
+ }
+
+ buffer[position++] = value;
+ }
+
+ internal void WriteRawByte(uint value)
+ {
+ WriteRawByte((byte) value);
+ }
+
+ /// <summary>
+ /// Writes out an array of bytes.
+ /// </summary>
+ internal void WriteRawBytes(byte[] value)
+ {
+ WriteRawBytes(value, 0, value.Length);
+ }
+
+ /// <summary>
+ /// Writes out part of an array of bytes.
+ /// </summary>
+ internal void WriteRawBytes(byte[] value, int offset, int length)
+ {
+ if (limit - position >= length)
+ {
+ ByteArray.Copy(value, offset, buffer, position, length);
+ // We have room in the current buffer.
+ position += length;
+ }
+ else
+ {
+ // Write extends past current buffer. Fill the rest of this buffer and
+ // flush.
+ int bytesWritten = limit - position;
+ ByteArray.Copy(value, offset, buffer, position, bytesWritten);
+ offset += bytesWritten;
+ length -= bytesWritten;
+ position = limit;
+ RefreshBuffer();
+
+ // Now deal with the rest.
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ if (length <= limit)
+ {
+ // Fits in new buffer.
+ ByteArray.Copy(value, offset, buffer, 0, length);
+ position = length;
+ }
+ else
+ {
+ // Write is very big. Let's do it all at once.
+ output.Write(value, offset, length);
+ }
+ }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Encode a 32-bit value with ZigZag encoding.
+ /// </summary>
+ /// <remarks>
+ /// ZigZag encodes signed integers into values that can be efficiently
+ /// encoded with varint. (Otherwise, negative values must be
+ /// sign-extended to 64 bits to be varint encoded, thus always taking
+ /// 10 bytes on the wire.)
+ /// </remarks>
+ internal static uint EncodeZigZag32(int n)
+ {
+ // Note: the right-shift must be arithmetic
+ return (uint) ((n << 1) ^ (n >> 31));
+ }
+
+ /// <summary>
+ /// Encode a 64-bit value with ZigZag encoding.
+ /// </summary>
+ /// <remarks>
+ /// ZigZag encodes signed integers into values that can be efficiently
+ /// encoded with varint. (Otherwise, negative values must be
+ /// sign-extended to 64 bits to be varint encoded, thus always taking
+ /// 10 bytes on the wire.)
+ /// </remarks>
+ internal static ulong EncodeZigZag64(long n)
+ {
+ return (ulong) ((n << 1) ^ (n >> 63));
+ }
+
+ private void RefreshBuffer()
+ {
+ if (output == null)
+ {
+ // We're writing to a single buffer.
+ throw new OutOfSpaceException();
+ }
+
+ // Since we have an output stream, this is our buffer
+ // and buffer offset == 0
+ output.Write(buffer, 0, position);
+ position = 0;
+ }
+
+ /// <summary>
+ /// Indicates that a CodedOutputStream wrapping a flat byte array
+ /// ran out of space.
+ /// </summary>
+ public sealed class OutOfSpaceException : IOException
+ {
+ internal OutOfSpaceException()
+ : base("CodedOutputStream was writing to a flat byte array and ran out of space.")
+ {
+ }
+ }
+
+ /// <summary>
+ /// Flushes any buffered data and optionally closes the underlying stream, if any.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// By default, any underlying stream is closed by this method. To configure this behaviour,
+ /// use a constructor overload with a <c>leaveOpen</c> parameter. If this instance does not
+ /// have an underlying stream, this method does nothing.
+ /// </para>
+ /// <para>
+ /// For the sake of efficiency, calling this method does not prevent future write calls - but
+ /// if a later write ends up writing to a stream which has been disposed, that is likely to
+ /// fail. It is recommend that you not call any other methods after this.
+ /// </para>
+ /// </remarks>
+ public void Dispose()
+ {
+ Flush();
+ if (!leaveOpen)
+ {
+ output.Dispose();
+ }
+ }
+
+ /// <summary>
+ /// Flushes any buffered data to the underlying stream (if there is one).
+ /// </summary>
+ public void Flush()
+ {
+ if (output != null)
+ {
+ RefreshBuffer();
+ }
+ }
+
+ /// <summary>
+ /// Verifies that SpaceLeft returns zero. It's common to create a byte array
+ /// that is exactly big enough to hold a message, then write to it with
+ /// a CodedOutputStream. Calling CheckNoSpaceLeft after writing verifies that
+ /// the message was actually as big as expected, which can help bugs.
+ /// </summary>
+ public void CheckNoSpaceLeft()
+ {
+ if (SpaceLeft != 0)
+ {
+ throw new InvalidOperationException("Did not write as much data as expected.");
+ }
+ }
+
+ /// <summary>
+ /// If writing to a flat array, returns the space left in the array. Otherwise,
+ /// throws an InvalidOperationException.
+ /// </summary>
+ public int SpaceLeft
+ {
+ get
+ {
+ if (output == null)
+ {
+ return limit - position;
+ }
+ else
+ {
+ throw new InvalidOperationException(
+ "SpaceLeft can only be called on CodedOutputStreams that are " +
+ "writing to a flat array.");
+ }
+ }
+ }
+ }
+}
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs
index 84360667d8..28530a29a8 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Collections/ReadOnlyDictionary.cs
@@ -1,147 +1,147 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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;
-using System.Collections.Generic;
-
-namespace Google.Protobuf.Collections
-{
- /// <summary>
- /// Read-only wrapper around another dictionary.
- /// </summary>
- internal sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
- {
- private readonly IDictionary<TKey, TValue> wrapped;
-
- public ReadOnlyDictionary(IDictionary<TKey, TValue> wrapped)
- {
- this.wrapped = wrapped;
- }
-
- public void Add(TKey key, TValue value)
- {
- throw new InvalidOperationException();
- }
-
- public bool ContainsKey(TKey key)
- {
- return wrapped.ContainsKey(key);
- }
-
- public ICollection<TKey> Keys
- {
- get { return wrapped.Keys; }
- }
-
- public bool Remove(TKey key)
- {
- throw new InvalidOperationException();
- }
-
- public bool TryGetValue(TKey key, out TValue value)
- {
- return wrapped.TryGetValue(key, out value);
- }
-
- public ICollection<TValue> Values
- {
- get { return wrapped.Values; }
- }
-
- public TValue this[TKey key]
- {
- get { return wrapped[key]; }
- set { throw new InvalidOperationException(); }
- }
-
- public void Add(KeyValuePair<TKey, TValue> item)
- {
- throw new InvalidOperationException();
- }
-
- public void Clear()
- {
- throw new InvalidOperationException();
- }
-
- public bool Contains(KeyValuePair<TKey, TValue> item)
- {
- return wrapped.Contains(item);
- }
-
- public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
- {
- wrapped.CopyTo(array, arrayIndex);
- }
-
- public int Count
- {
- get { return wrapped.Count; }
- }
-
- public bool IsReadOnly
- {
- get { return true; }
- }
-
- public bool Remove(KeyValuePair<TKey, TValue> item)
- {
- throw new InvalidOperationException();
- }
-
- public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
- {
- return wrapped.GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return ((IEnumerable) wrapped).GetEnumerator();
- }
-
- public override bool Equals(object obj)
- {
- return wrapped.Equals(obj);
- }
-
- public override int GetHashCode()
- {
- return wrapped.GetHashCode();
- }
-
- public override string ToString()
- {
- return wrapped.ToString();
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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;
+using System.Collections.Generic;
+
+namespace Google.Protobuf.Collections
+{
+ /// <summary>
+ /// Read-only wrapper around another dictionary.
+ /// </summary>
+ internal sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
+ {
+ private readonly IDictionary<TKey, TValue> wrapped;
+
+ public ReadOnlyDictionary(IDictionary<TKey, TValue> wrapped)
+ {
+ this.wrapped = wrapped;
+ }
+
+ public void Add(TKey key, TValue value)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public bool ContainsKey(TKey key)
+ {
+ return wrapped.ContainsKey(key);
+ }
+
+ public ICollection<TKey> Keys
+ {
+ get { return wrapped.Keys; }
+ }
+
+ public bool Remove(TKey key)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
+ return wrapped.TryGetValue(key, out value);
+ }
+
+ public ICollection<TValue> Values
+ {
+ get { return wrapped.Values; }
+ }
+
+ public TValue this[TKey key]
+ {
+ get { return wrapped[key]; }
+ set { throw new InvalidOperationException(); }
+ }
+
+ public void Add(KeyValuePair<TKey, TValue> item)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public void Clear()
+ {
+ throw new InvalidOperationException();
+ }
+
+ public bool Contains(KeyValuePair<TKey, TValue> item)
+ {
+ return wrapped.Contains(item);
+ }
+
+ public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
+ {
+ wrapped.CopyTo(array, arrayIndex);
+ }
+
+ public int Count
+ {
+ get { return wrapped.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return true; }
+ }
+
+ public bool Remove(KeyValuePair<TKey, TValue> item)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+ {
+ return wrapped.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable) wrapped).GetEnumerator();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return wrapped.Equals(obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return wrapped.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return wrapped.ToString();
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/FrameworkPortability.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/FrameworkPortability.cs
index 9498dbe4cc..c8060f6ca8 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/FrameworkPortability.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/FrameworkPortability.cs
@@ -1,49 +1,49 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.Text.RegularExpressions;
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Class containing helpful workarounds for various platform compatibility
- /// </summary>
- internal static class FrameworkPortability
- {
- // The value of RegexOptions.Compiled is 8. We can test for the presence at
- // execution time using Enum.IsDefined, so a single build will do the right thing
- // on each platform. (RegexOptions.Compiled isn't supported by PCLs.)
- internal static readonly RegexOptions CompiledRegexWhereAvailable =
- Enum.IsDefined(typeof(RegexOptions), 8) ? (RegexOptions)8 : RegexOptions.None;
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.Text.RegularExpressions;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Class containing helpful workarounds for various platform compatibility
+ /// </summary>
+ internal static class FrameworkPortability
+ {
+ // The value of RegexOptions.Compiled is 8. We can test for the presence at
+ // execution time using Enum.IsDefined, so a single build will do the right thing
+ // on each platform. (RegexOptions.Compiled isn't supported by PCLs.)
+ internal static readonly RegexOptions CompiledRegexWhereAvailable =
+ Enum.IsDefined(typeof(RegexOptions), 8) ? (RegexOptions)8 : RegexOptions.None;
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/IMessage.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/IMessage.cs
index d089f94639..3e644c1773 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/IMessage.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/IMessage.cs
@@ -1,87 +1,87 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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 Google.Protobuf.Reflection;
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Interface for a Protocol Buffers message, supporting
- /// basic operations required for serialization.
- /// </summary>
- public interface IMessage
- {
- /// <summary>
- /// Merges the data from the specified coded input stream with the current message.
- /// </summary>
- /// <remarks>See the user guide for precise merge semantics.</remarks>
- /// <param name="input"></param>
- void MergeFrom(CodedInputStream input);
-
- /// <summary>
- /// Writes the data to the given coded output stream.
- /// </summary>
- /// <param name="output">Coded output stream to write the data to. Must not be null.</param>
- void WriteTo(CodedOutputStream output);
-
- /// <summary>
- /// Calculates the size of this message in Protocol Buffer wire format, in bytes.
- /// </summary>
- /// <returns>The number of bytes required to write this message
- /// to a coded output stream.</returns>
- int CalculateSize();
-
- /// <summary>
- /// Descriptor for this message. All instances are expected to return the same descriptor,
- /// and for generated types this will be an explicitly-implemented member, returning the
- /// same value as the static property declared on the type.
- /// </summary>
- MessageDescriptor Descriptor { get; }
- }
-
- /// <summary>
- /// Generic interface for a Protocol Buffers message,
- /// where the type parameter is expected to be the same type as
- /// the implementation class.
- /// </summary>
- /// <typeparam name="T">The message type.</typeparam>
- public interface IMessage<T> : IMessage, IEquatable<T>, IDeepCloneable<T> where T : IMessage<T>
- {
- /// <summary>
- /// Merges the given message into this one.
- /// </summary>
- /// <remarks>See the user guide for precise merge semantics.</remarks>
- /// <param name="message">The message to merge with this one. Must not be null.</param>
- void MergeFrom(T message);
- }
-}
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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 Google.Protobuf.Reflection;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Interface for a Protocol Buffers message, supporting
+ /// basic operations required for serialization.
+ /// </summary>
+ public interface IMessage
+ {
+ /// <summary>
+ /// Merges the data from the specified coded input stream with the current message.
+ /// </summary>
+ /// <remarks>See the user guide for precise merge semantics.</remarks>
+ /// <param name="input"></param>
+ void MergeFrom(CodedInputStream input);
+
+ /// <summary>
+ /// Writes the data to the given coded output stream.
+ /// </summary>
+ /// <param name="output">Coded output stream to write the data to. Must not be null.</param>
+ void WriteTo(CodedOutputStream output);
+
+ /// <summary>
+ /// Calculates the size of this message in Protocol Buffer wire format, in bytes.
+ /// </summary>
+ /// <returns>The number of bytes required to write this message
+ /// to a coded output stream.</returns>
+ int CalculateSize();
+
+ /// <summary>
+ /// Descriptor for this message. All instances are expected to return the same descriptor,
+ /// and for generated types this will be an explicitly-implemented member, returning the
+ /// same value as the static property declared on the type.
+ /// </summary>
+ MessageDescriptor Descriptor { get; }
+ }
+
+ /// <summary>
+ /// Generic interface for a Protocol Buffers message,
+ /// where the type parameter is expected to be the same type as
+ /// the implementation class.
+ /// </summary>
+ /// <typeparam name="T">The message type.</typeparam>
+ public interface IMessage<T> : IMessage, IEquatable<T>, IDeepCloneable<T> where T : IMessage<T>
+ {
+ /// <summary>
+ /// Merges the given message into this one.
+ /// </summary>
+ /// <remarks>See the user guide for precise merge semantics.</remarks>
+ /// <param name="message">The message to merge with this one. Must not be null.</param>
+ void MergeFrom(T message);
+ }
+}
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
index 0fbc530631..b3aee222db 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
@@ -1,129 +1,129 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.IO;
-
-namespace Google.Protobuf
-{
- /// <summary>
- /// Thrown when a protocol message being parsed is invalid in some way,
- /// e.g. it contains a malformed varint or a negative byte length.
- /// </summary>
- public sealed class InvalidProtocolBufferException : IOException
- {
- internal InvalidProtocolBufferException(string message)
- : base(message)
- {
- }
-
- internal InvalidProtocolBufferException(string message, Exception innerException)
- : base(message, innerException)
- {
- }
-
- internal static InvalidProtocolBufferException MoreDataAvailable()
- {
- return new InvalidProtocolBufferException(
- "Completed reading a message while more data was available in the stream.");
- }
-
- internal static InvalidProtocolBufferException TruncatedMessage()
- {
- return new InvalidProtocolBufferException(
- "While parsing a protocol message, the input ended unexpectedly " +
- "in the middle of a field. This could mean either that the " +
- "input has been truncated or that an embedded message " +
- "misreported its own length.");
- }
-
- internal static InvalidProtocolBufferException NegativeSize()
- {
- return new InvalidProtocolBufferException(
- "CodedInputStream encountered an embedded string or message " +
- "which claimed to have negative size.");
- }
-
- internal static InvalidProtocolBufferException MalformedVarint()
- {
- return new InvalidProtocolBufferException(
- "CodedInputStream encountered a malformed varint.");
- }
-
- /// <summary>
- /// Creates an exception for an error condition of an invalid tag being encountered.
- /// </summary>
- internal static InvalidProtocolBufferException InvalidTag()
- {
- return new InvalidProtocolBufferException(
- "Protocol message contained an invalid tag (zero).");
- }
-
- internal static InvalidProtocolBufferException InvalidBase64(Exception innerException)
- {
- return new InvalidProtocolBufferException("Invalid base64 data", innerException);
- }
-
- internal static InvalidProtocolBufferException InvalidEndTag()
- {
- return new InvalidProtocolBufferException(
- "Protocol message end-group tag did not match expected tag.");
- }
-
- internal static InvalidProtocolBufferException RecursionLimitExceeded()
- {
- return new InvalidProtocolBufferException(
- "Protocol message had too many levels of nesting. May be malicious. " +
- "Use CodedInputStream.SetRecursionLimit() to increase the depth limit.");
- }
-
- internal static InvalidProtocolBufferException JsonRecursionLimitExceeded()
- {
- return new InvalidProtocolBufferException(
- "Protocol message had too many levels of nesting. May be malicious. " +
- "Use JsonParser.Settings to increase the depth limit.");
- }
-
- internal static InvalidProtocolBufferException SizeLimitExceeded()
- {
- return new InvalidProtocolBufferException(
- "Protocol message was too large. May be malicious. " +
- "Use CodedInputStream.SetSizeLimit() to increase the size limit.");
- }
-
- internal static InvalidProtocolBufferException InvalidMessageStreamTag()
- {
- return new InvalidProtocolBufferException(
- "Stream of protocol messages had invalid tag. Expected tag is length-delimited field 1.");
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.IO;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Thrown when a protocol message being parsed is invalid in some way,
+ /// e.g. it contains a malformed varint or a negative byte length.
+ /// </summary>
+ public sealed class InvalidProtocolBufferException : IOException
+ {
+ internal InvalidProtocolBufferException(string message)
+ : base(message)
+ {
+ }
+
+ internal InvalidProtocolBufferException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ internal static InvalidProtocolBufferException MoreDataAvailable()
+ {
+ return new InvalidProtocolBufferException(
+ "Completed reading a message while more data was available in the stream.");
+ }
+
+ internal static InvalidProtocolBufferException TruncatedMessage()
+ {
+ return new InvalidProtocolBufferException(
+ "While parsing a protocol message, the input ended unexpectedly " +
+ "in the middle of a field. This could mean either that the " +
+ "input has been truncated or that an embedded message " +
+ "misreported its own length.");
+ }
+
+ internal static InvalidProtocolBufferException NegativeSize()
+ {
+ return new InvalidProtocolBufferException(
+ "CodedInputStream encountered an embedded string or message " +
+ "which claimed to have negative size.");
+ }
+
+ internal static InvalidProtocolBufferException MalformedVarint()
+ {
+ return new InvalidProtocolBufferException(
+ "CodedInputStream encountered a malformed varint.");
+ }
+
+ /// <summary>
+ /// Creates an exception for an error condition of an invalid tag being encountered.
+ /// </summary>
+ internal static InvalidProtocolBufferException InvalidTag()
+ {
+ return new InvalidProtocolBufferException(
+ "Protocol message contained an invalid tag (zero).");
+ }
+
+ internal static InvalidProtocolBufferException InvalidBase64(Exception innerException)
+ {
+ return new InvalidProtocolBufferException("Invalid base64 data", innerException);
+ }
+
+ internal static InvalidProtocolBufferException InvalidEndTag()
+ {
+ return new InvalidProtocolBufferException(
+ "Protocol message end-group tag did not match expected tag.");
+ }
+
+ internal static InvalidProtocolBufferException RecursionLimitExceeded()
+ {
+ return new InvalidProtocolBufferException(
+ "Protocol message had too many levels of nesting. May be malicious. " +
+ "Use CodedInputStream.SetRecursionLimit() to increase the depth limit.");
+ }
+
+ internal static InvalidProtocolBufferException JsonRecursionLimitExceeded()
+ {
+ return new InvalidProtocolBufferException(
+ "Protocol message had too many levels of nesting. May be malicious. " +
+ "Use JsonParser.Settings to increase the depth limit.");
+ }
+
+ internal static InvalidProtocolBufferException SizeLimitExceeded()
+ {
+ return new InvalidProtocolBufferException(
+ "Protocol message was too large. May be malicious. " +
+ "Use CodedInputStream.SetSizeLimit() to increase the size limit.");
+ }
+
+ internal static InvalidProtocolBufferException InvalidMessageStreamTag()
+ {
+ return new InvalidProtocolBufferException(
+ "Stream of protocol messages had invalid tag. Expected tag is length-delimited field 1.");
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs
index 9b179bd7cd..ae885f8c00 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs
@@ -1,49 +1,49 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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.Runtime.CompilerServices;
-using System.Security;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-
-#if !NCRUNCH
-[assembly: AllowPartiallyTrustedCallers]
-#endif
-
-[assembly: InternalsVisibleTo("Google.Protobuf.Test, PublicKey=" +
- "002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" +
- "7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" +
- "981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
- "b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
- "c5ae9cb6")]
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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.Runtime.CompilerServices;
+using System.Security;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+#if !NCRUNCH
+[assembly: AllowPartiallyTrustedCallers]
+#endif
+
+[assembly: InternalsVisibleTo("Google.Protobuf.Test, PublicKey=" +
+ "002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" +
+ "7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" +
+ "981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" +
+ "b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" +
+ "c5ae9cb6")]
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Reflection/PartialClasses.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Reflection/PartialClasses.cs
index 8c055d6d92..6c285410d4 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Reflection/PartialClasses.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/Reflection/PartialClasses.cs
@@ -1,59 +1,59 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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
-
-// This file just contains partial classes for any autogenerated classes that need additional support.
-namespace Google.Protobuf.Reflection
-{
- internal partial class FieldDescriptorProto
- {
- // We can't tell the difference between "explicitly set to 0" and "not set"
- // in proto3, but we need to tell the difference for OneofIndex. descriptor.proto
- // is really a proto2 file, but the runtime doesn't know about proto2 semantics...
- // We fake it by defaulting to -1.
- partial void OnConstruction()
- {
- OneofIndex = -1;
- }
- }
-
- internal partial class FieldOptions
- {
- // We can't tell the difference between "explicitly set to false" and "not set"
- // in proto3, but we need to tell the difference for FieldDescriptor.IsPacked.
- // This won't work if we ever need to support proto2, but at that point we'll be
- // able to remove this hack and use field presence instead.
- partial void OnConstruction()
- {
- Packed = true;
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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
+
+// This file just contains partial classes for any autogenerated classes that need additional support.
+namespace Google.Protobuf.Reflection
+{
+ internal partial class FieldDescriptorProto
+ {
+ // We can't tell the difference between "explicitly set to 0" and "not set"
+ // in proto3, but we need to tell the difference for OneofIndex. descriptor.proto
+ // is really a proto2 file, but the runtime doesn't know about proto2 semantics...
+ // We fake it by defaulting to -1.
+ partial void OnConstruction()
+ {
+ OneofIndex = -1;
+ }
+ }
+
+ internal partial class FieldOptions
+ {
+ // We can't tell the difference between "explicitly set to false" and "not set"
+ // in proto3, but we need to tell the difference for FieldDescriptor.IsPacked.
+ // This won't work if we ever need to support proto2, but at that point we'll be
+ // able to remove this hack and use field presence instead.
+ partial void OnConstruction()
+ {
+ Packed = true;
+ }
+ }
} \ No newline at end of file
diff --git a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/WireFormat.cs b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/WireFormat.cs
index faf1e715ef..e884da5205 100644
--- a/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/WireFormat.cs
+++ b/third_party/protobuf/3.4.0/csharp/src/Google.Protobuf/WireFormat.cs
@@ -1,104 +1,104 @@
-#region Copyright notice and license
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 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
-{
- /// <summary>
- /// This class is used internally by the Protocol Buffer Library and generated
- /// message implementations. It is public only for the sake of those generated
- /// messages. Others should not use this class directly.
- /// <para>
- /// This class contains constants and helper functions useful for dealing with
- /// the Protocol Buffer wire format.
- /// </para>
- /// </summary>
- public static class WireFormat
- {
- /// <summary>
- /// Wire types within protobuf encoding.
- /// </summary>
- public enum WireType : uint
- {
- /// <summary>
- /// Variable-length integer.
- /// </summary>
- Varint = 0,
- /// <summary>
- /// A fixed-length 64-bit value.
- /// </summary>
- Fixed64 = 1,
- /// <summary>
- /// A length-delimited value, i.e. a length followed by that many bytes of data.
- /// </summary>
- LengthDelimited = 2,
- /// <summary>
- /// A "start group" value - not supported by this implementation.
- /// </summary>
- StartGroup = 3,
- /// <summary>
- /// An "end group" value - not supported by this implementation.
- /// </summary>
- EndGroup = 4,
- /// <summary>
- /// A fixed-length 32-bit value.
- /// </summary>
- Fixed32 = 5
- }
-
- private const int TagTypeBits = 3;
- private const uint TagTypeMask = (1 << TagTypeBits) - 1;
-
- /// <summary>
- /// Given a tag value, determines the wire type (lower 3 bits).
- /// </summary>
- public static WireType GetTagWireType(uint tag)
- {
- return (WireType) (tag & TagTypeMask);
- }
-
- /// <summary>
- /// Given a tag value, determines the field number (the upper 29 bits).
- /// </summary>
- public static int GetTagFieldNumber(uint tag)
- {
- return (int) tag >> TagTypeBits;
- }
-
- /// <summary>
- /// Makes a tag value given a field number and wire type.
- /// </summary>
- public static uint MakeTag(int fieldNumber, WireType wireType)
- {
- return (uint) (fieldNumber << TagTypeBits) | (uint) wireType;
- }
- }
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 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
+{
+ /// <summary>
+ /// This class is used internally by the Protocol Buffer Library and generated
+ /// message implementations. It is public only for the sake of those generated
+ /// messages. Others should not use this class directly.
+ /// <para>
+ /// This class contains constants and helper functions useful for dealing with
+ /// the Protocol Buffer wire format.
+ /// </para>
+ /// </summary>
+ public static class WireFormat
+ {
+ /// <summary>
+ /// Wire types within protobuf encoding.
+ /// </summary>
+ public enum WireType : uint
+ {
+ /// <summary>
+ /// Variable-length integer.
+ /// </summary>
+ Varint = 0,
+ /// <summary>
+ /// A fixed-length 64-bit value.
+ /// </summary>
+ Fixed64 = 1,
+ /// <summary>
+ /// A length-delimited value, i.e. a length followed by that many bytes of data.
+ /// </summary>
+ LengthDelimited = 2,
+ /// <summary>
+ /// A "start group" value - not supported by this implementation.
+ /// </summary>
+ StartGroup = 3,
+ /// <summary>
+ /// An "end group" value - not supported by this implementation.
+ /// </summary>
+ EndGroup = 4,
+ /// <summary>
+ /// A fixed-length 32-bit value.
+ /// </summary>
+ Fixed32 = 5
+ }
+
+ private const int TagTypeBits = 3;
+ private const uint TagTypeMask = (1 << TagTypeBits) - 1;
+
+ /// <summary>
+ /// Given a tag value, determines the wire type (lower 3 bits).
+ /// </summary>
+ public static WireType GetTagWireType(uint tag)
+ {
+ return (WireType) (tag & TagTypeMask);
+ }
+
+ /// <summary>
+ /// Given a tag value, determines the field number (the upper 29 bits).
+ /// </summary>
+ public static int GetTagFieldNumber(uint tag)
+ {
+ return (int) tag >> TagTypeBits;
+ }
+
+ /// <summary>
+ /// Makes a tag value given a field number and wire type.
+ /// </summary>
+ public static uint MakeTag(int fieldNumber, WireType wireType)
+ {
+ return (uint) (fieldNumber << TagTypeBits) | (uint) wireType;
+ }
+ }
} \ No newline at end of file