parent
40db3dabf0
commit
a29e0e3f44
210 changed files with 17729 additions and 15756 deletions
@ -0,0 +1,17 @@ |
||||
# Remove the line below if you want to inherit .editorconfig settings from higher directories |
||||
root = true |
||||
|
||||
# C# files |
||||
[*.cs] |
||||
|
||||
#### Core EditorConfig Options #### |
||||
|
||||
# Indentation and spacing |
||||
indent_size = 4 |
||||
indent_style = space |
||||
tab_width = 4 |
||||
|
||||
# New line preferences |
||||
end_of_line = lf |
||||
insert_final_newline = false |
||||
trim_trailing_whitespace = true |
@ -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("")); |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -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, WritingPrimitives.EncodeZigZag32(0)); |
||||
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag32(-1)); |
||||
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag32(1)); |
||||
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag32(-2)); |
||||
Assert.AreEqual(0x7FFFFFFEu, WritingPrimitives.EncodeZigZag32(0x3FFFFFFF)); |
||||
Assert.AreEqual(0x7FFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0xC0000000))); |
||||
Assert.AreEqual(0xFFFFFFFEu, WritingPrimitives.EncodeZigZag32(0x7FFFFFFF)); |
||||
Assert.AreEqual(0xFFFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0x80000000))); |
||||
} |
||||
|
||||
[Test] |
||||
public void EncodeZigZag64() |
||||
{ |
||||
Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag64(0)); |
||||
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag64(-1)); |
||||
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag64(1)); |
||||
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag64(-2)); |
||||
Assert.AreEqual(0x000000007FFFFFFEuL, |
||||
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL))); |
||||
Assert.AreEqual(0x000000007FFFFFFFuL, |
||||
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL))); |
||||
Assert.AreEqual(0x00000000FFFFFFFEuL, |
||||
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL))); |
||||
Assert.AreEqual(0x00000000FFFFFFFFuL, |
||||
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL))); |
||||
Assert.AreEqual(0xFFFFFFFFFFFFFFFEL, |
||||
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL))); |
||||
Assert.AreEqual(0xFFFFFFFFFFFFFFFFL, |
||||
WritingPrimitives.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, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(0))); |
||||
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(1))); |
||||
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-1))); |
||||
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(14927))); |
||||
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-3612))); |
||||
} |
||||
|
||||
[Test] |
||||
public void RoundTripZigZag64() |
||||
{ |
||||
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(0))); |
||||
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(1))); |
||||
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-1))); |
||||
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(14927))); |
||||
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-3612))); |
||||
|
||||
Assert.AreEqual(856912304801416L, |
||||
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(856912304801416L))); |
||||
Assert.AreEqual(-75123905439571256L, |
||||
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.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.WriteRawBytes(new byte[] {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.WriteRawBytes(new byte[] {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, WritingPrimitives.EncodeZigZag32(0)); |
||||
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag32(-1)); |
||||
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag32(1)); |
||||
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag32(-2)); |
||||
Assert.AreEqual(0x7FFFFFFEu, WritingPrimitives.EncodeZigZag32(0x3FFFFFFF)); |
||||
Assert.AreEqual(0x7FFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0xC0000000))); |
||||
Assert.AreEqual(0xFFFFFFFEu, WritingPrimitives.EncodeZigZag32(0x7FFFFFFF)); |
||||
Assert.AreEqual(0xFFFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0x80000000))); |
||||
} |
||||
|
||||
[Test] |
||||
public void EncodeZigZag64() |
||||
{ |
||||
Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag64(0)); |
||||
Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag64(-1)); |
||||
Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag64(1)); |
||||
Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag64(-2)); |
||||
Assert.AreEqual(0x000000007FFFFFFEuL, |
||||
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL))); |
||||
Assert.AreEqual(0x000000007FFFFFFFuL, |
||||
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL))); |
||||
Assert.AreEqual(0x00000000FFFFFFFEuL, |
||||
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL))); |
||||
Assert.AreEqual(0x00000000FFFFFFFFuL, |
||||
WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL))); |
||||
Assert.AreEqual(0xFFFFFFFFFFFFFFFEL, |
||||
WritingPrimitives.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL))); |
||||
Assert.AreEqual(0xFFFFFFFFFFFFFFFFL, |
||||
WritingPrimitives.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, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(0))); |
||||
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(1))); |
||||
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-1))); |
||||
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(14927))); |
||||
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-3612))); |
||||
} |
||||
|
||||
[Test] |
||||
public void RoundTripZigZag64() |
||||
{ |
||||
Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(0))); |
||||
Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(1))); |
||||
Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-1))); |
||||
Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(14927))); |
||||
Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-3612))); |
||||
|
||||
Assert.AreEqual(856912304801416L, |
||||
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(856912304801416L))); |
||||
Assert.AreEqual(-75123905439571256L, |
||||
ParsingPrimitives.DecodeZigZag64(WritingPrimitives.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.WriteRawBytes(new byte[] {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.WriteRawBytes(new byte[] {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 |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -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; |
||||
} |
||||
} |
||||
} |
@ -1,439 +1,439 @@ |
||||
#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; |
||||
using System.Collections.Generic; |
||||
using System.Collections; |
||||
using System.Linq; |
||||
using System.Buffers; |
||||
using System.Runtime.InteropServices; |
||||
using System.Threading; |
||||
using System.Runtime.CompilerServices; |
||||
#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); |
||||
EqualityTester.AssertEquality(ByteString.Empty, ByteString.Empty); |
||||
#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); |
||||
Assert.IsTrue(ByteString.Empty == ByteString.Empty); |
||||
#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 CopyFromReadOnlySpanCopiesContents() |
||||
{ |
||||
byte[] data = new byte[1]; |
||||
data[0] = 10; |
||||
ReadOnlySpan<byte> byteSpan = data; |
||||
var bs = ByteString.CopyFrom(byteSpan); |
||||
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 CopyTo() |
||||
{ |
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; |
||||
ByteString bs = ByteString.CopyFrom(data); |
||||
|
||||
byte[] dest = new byte[data.Length]; |
||||
bs.CopyTo(dest, 0); |
||||
|
||||
CollectionAssert.AreEqual(data, dest); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetEnumerator() |
||||
{ |
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; |
||||
ByteString bs = ByteString.CopyFrom(data); |
||||
|
||||
IEnumerator<byte> genericEnumerator = bs.GetEnumerator(); |
||||
Assert.IsTrue(genericEnumerator.MoveNext()); |
||||
Assert.AreEqual(0, genericEnumerator.Current); |
||||
|
||||
IEnumerator enumerator = ((IEnumerable)bs).GetEnumerator(); |
||||
Assert.IsTrue(enumerator.MoveNext()); |
||||
Assert.AreEqual(0, enumerator.Current); |
||||
|
||||
// Call via LINQ |
||||
CollectionAssert.AreEqual(bs.Span.ToArray(), bs.ToArray()); |
||||
} |
||||
|
||||
[Test] |
||||
public void UnsafeWrap() |
||||
{ |
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; |
||||
ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3)); |
||||
ReadOnlySpan<byte> s = bs.Span; |
||||
|
||||
Assert.AreEqual(3, s.Length); |
||||
Assert.AreEqual(2, s[0]); |
||||
Assert.AreEqual(3, s[1]); |
||||
Assert.AreEqual(4, s[2]); |
||||
|
||||
// Check that the value is not a copy |
||||
data[2] = byte.MaxValue; |
||||
Assert.AreEqual(byte.MaxValue, s[0]); |
||||
} |
||||
|
||||
[Test] |
||||
public void CreateCodedInput_FromArraySegment() |
||||
{ |
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; |
||||
ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3)); |
||||
CodedInputStream codedInputStream = bs.CreateCodedInput(); |
||||
|
||||
byte[] bytes = codedInputStream.ReadRawBytes(3); |
||||
|
||||
Assert.AreEqual(3, bytes.Length); |
||||
Assert.AreEqual(2, bytes[0]); |
||||
Assert.AreEqual(3, bytes[1]); |
||||
Assert.AreEqual(4, bytes[2]); |
||||
Assert.IsTrue(codedInputStream.IsAtEnd); |
||||
} |
||||
|
||||
[Test] |
||||
public void WriteToStream() |
||||
{ |
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; |
||||
ByteString bs = ByteString.CopyFrom(data); |
||||
|
||||
MemoryStream ms = new MemoryStream(); |
||||
bs.WriteTo(ms); |
||||
|
||||
CollectionAssert.AreEqual(data, ms.ToArray()); |
||||
} |
||||
|
||||
[Test] |
||||
public void WriteToStream_Stackalloc() |
||||
{ |
||||
byte[] data = Encoding.UTF8.GetBytes("Hello world"); |
||||
Span<byte> s = stackalloc byte[data.Length]; |
||||
data.CopyTo(s); |
||||
|
||||
MemoryStream ms = new MemoryStream(); |
||||
|
||||
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s)) |
||||
{ |
||||
ByteString bs = ByteString.AttachBytes(manager.Memory); |
||||
|
||||
bs.WriteTo(ms); |
||||
} |
||||
|
||||
CollectionAssert.AreEqual(data, ms.ToArray()); |
||||
} |
||||
|
||||
[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 ToString_Stackalloc() |
||||
{ |
||||
byte[] data = Encoding.UTF8.GetBytes("Hello world"); |
||||
Span<byte> s = stackalloc byte[data.Length]; |
||||
data.CopyTo(s); |
||||
|
||||
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s)) |
||||
{ |
||||
ByteString bs = ByteString.AttachBytes(manager.Memory); |
||||
|
||||
Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8)); |
||||
} |
||||
} |
||||
|
||||
[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 ToBase64_Array() |
||||
{ |
||||
ByteString bs = ByteString.CopyFrom(Encoding.UTF8.GetBytes("Hello world")); |
||||
|
||||
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64()); |
||||
} |
||||
|
||||
[Test] |
||||
public void ToBase64_Stackalloc() |
||||
{ |
||||
byte[] data = Encoding.UTF8.GetBytes("Hello world"); |
||||
Span<byte> s = stackalloc byte[data.Length]; |
||||
data.CopyTo(s); |
||||
|
||||
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s)) |
||||
{ |
||||
ByteString bs = ByteString.AttachBytes(manager.Memory); |
||||
|
||||
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64()); |
||||
} |
||||
} |
||||
|
||||
[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/protocolbuffers/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()); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetContentsAsReadOnlySpan() |
||||
{ |
||||
var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5); |
||||
var copied = byteString.Span.ToArray(); |
||||
CollectionAssert.AreEqual(byteString, copied); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetContentsAsReadOnlyMemory() |
||||
{ |
||||
var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5); |
||||
var copied = byteString.Memory.ToArray(); |
||||
CollectionAssert.AreEqual(byteString, copied); |
||||
} |
||||
|
||||
// Create Memory<byte> from non-array source. |
||||
// Use by ByteString tests that have optimized path for array backed Memory<byte>. |
||||
private sealed unsafe class UnmanagedMemoryManager<T> : MemoryManager<T> where T : unmanaged |
||||
{ |
||||
private readonly T* _pointer; |
||||
private readonly int _length; |
||||
|
||||
public UnmanagedMemoryManager(Span<T> span) |
||||
{ |
||||
fixed (T* ptr = &MemoryMarshal.GetReference(span)) |
||||
{ |
||||
_pointer = ptr; |
||||
_length = span.Length; |
||||
} |
||||
} |
||||
|
||||
public override Span<T> GetSpan() => new Span<T>(_pointer, _length); |
||||
|
||||
public override MemoryHandle Pin(int elementIndex = 0) |
||||
{ |
||||
if (elementIndex < 0 || elementIndex >= _length) |
||||
{ |
||||
throw new ArgumentOutOfRangeException(nameof(elementIndex)); |
||||
} |
||||
|
||||
return new MemoryHandle(_pointer + elementIndex); |
||||
} |
||||
|
||||
public override void Unpin() { } |
||||
|
||||
protected override void Dispose(bool disposing) { } |
||||
} |
||||
} |
||||
#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; |
||||
using System.Collections.Generic; |
||||
using System.Collections; |
||||
using System.Linq; |
||||
using System.Buffers; |
||||
using System.Runtime.InteropServices; |
||||
using System.Threading; |
||||
using System.Runtime.CompilerServices; |
||||
#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); |
||||
EqualityTester.AssertEquality(ByteString.Empty, ByteString.Empty); |
||||
#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); |
||||
Assert.IsTrue(ByteString.Empty == ByteString.Empty); |
||||
#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 CopyFromReadOnlySpanCopiesContents() |
||||
{ |
||||
byte[] data = new byte[1]; |
||||
data[0] = 10; |
||||
ReadOnlySpan<byte> byteSpan = data; |
||||
var bs = ByteString.CopyFrom(byteSpan); |
||||
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 CopyTo() |
||||
{ |
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; |
||||
ByteString bs = ByteString.CopyFrom(data); |
||||
|
||||
byte[] dest = new byte[data.Length]; |
||||
bs.CopyTo(dest, 0); |
||||
|
||||
CollectionAssert.AreEqual(data, dest); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetEnumerator() |
||||
{ |
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; |
||||
ByteString bs = ByteString.CopyFrom(data); |
||||
|
||||
IEnumerator<byte> genericEnumerator = bs.GetEnumerator(); |
||||
Assert.IsTrue(genericEnumerator.MoveNext()); |
||||
Assert.AreEqual(0, genericEnumerator.Current); |
||||
|
||||
IEnumerator enumerator = ((IEnumerable)bs).GetEnumerator(); |
||||
Assert.IsTrue(enumerator.MoveNext()); |
||||
Assert.AreEqual(0, enumerator.Current); |
||||
|
||||
// Call via LINQ |
||||
CollectionAssert.AreEqual(bs.Span.ToArray(), bs.ToArray()); |
||||
} |
||||
|
||||
[Test] |
||||
public void UnsafeWrap() |
||||
{ |
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; |
||||
ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3)); |
||||
ReadOnlySpan<byte> s = bs.Span; |
||||
|
||||
Assert.AreEqual(3, s.Length); |
||||
Assert.AreEqual(2, s[0]); |
||||
Assert.AreEqual(3, s[1]); |
||||
Assert.AreEqual(4, s[2]); |
||||
|
||||
// Check that the value is not a copy |
||||
data[2] = byte.MaxValue; |
||||
Assert.AreEqual(byte.MaxValue, s[0]); |
||||
} |
||||
|
||||
[Test] |
||||
public void CreateCodedInput_FromArraySegment() |
||||
{ |
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; |
||||
ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3)); |
||||
CodedInputStream codedInputStream = bs.CreateCodedInput(); |
||||
|
||||
byte[] bytes = codedInputStream.ReadRawBytes(3); |
||||
|
||||
Assert.AreEqual(3, bytes.Length); |
||||
Assert.AreEqual(2, bytes[0]); |
||||
Assert.AreEqual(3, bytes[1]); |
||||
Assert.AreEqual(4, bytes[2]); |
||||
Assert.IsTrue(codedInputStream.IsAtEnd); |
||||
} |
||||
|
||||
[Test] |
||||
public void WriteToStream() |
||||
{ |
||||
byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; |
||||
ByteString bs = ByteString.CopyFrom(data); |
||||
|
||||
MemoryStream ms = new MemoryStream(); |
||||
bs.WriteTo(ms); |
||||
|
||||
CollectionAssert.AreEqual(data, ms.ToArray()); |
||||
} |
||||
|
||||
[Test] |
||||
public void WriteToStream_Stackalloc() |
||||
{ |
||||
byte[] data = Encoding.UTF8.GetBytes("Hello world"); |
||||
Span<byte> s = stackalloc byte[data.Length]; |
||||
data.CopyTo(s); |
||||
|
||||
MemoryStream ms = new MemoryStream(); |
||||
|
||||
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s)) |
||||
{ |
||||
ByteString bs = ByteString.AttachBytes(manager.Memory); |
||||
|
||||
bs.WriteTo(ms); |
||||
} |
||||
|
||||
CollectionAssert.AreEqual(data, ms.ToArray()); |
||||
} |
||||
|
||||
[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 ToString_Stackalloc() |
||||
{ |
||||
byte[] data = Encoding.UTF8.GetBytes("Hello world"); |
||||
Span<byte> s = stackalloc byte[data.Length]; |
||||
data.CopyTo(s); |
||||
|
||||
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s)) |
||||
{ |
||||
ByteString bs = ByteString.AttachBytes(manager.Memory); |
||||
|
||||
Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8)); |
||||
} |
||||
} |
||||
|
||||
[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 ToBase64_Array() |
||||
{ |
||||
ByteString bs = ByteString.CopyFrom(Encoding.UTF8.GetBytes("Hello world")); |
||||
|
||||
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64()); |
||||
} |
||||
|
||||
[Test] |
||||
public void ToBase64_Stackalloc() |
||||
{ |
||||
byte[] data = Encoding.UTF8.GetBytes("Hello world"); |
||||
Span<byte> s = stackalloc byte[data.Length]; |
||||
data.CopyTo(s); |
||||
|
||||
using (UnmanagedMemoryManager<byte> manager = new UnmanagedMemoryManager<byte>(s)) |
||||
{ |
||||
ByteString bs = ByteString.AttachBytes(manager.Memory); |
||||
|
||||
Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64()); |
||||
} |
||||
} |
||||
|
||||
[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/protocolbuffers/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()); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetContentsAsReadOnlySpan() |
||||
{ |
||||
var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5); |
||||
var copied = byteString.Span.ToArray(); |
||||
CollectionAssert.AreEqual(byteString, copied); |
||||
} |
||||
|
||||
[Test] |
||||
public void GetContentsAsReadOnlyMemory() |
||||
{ |
||||
var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5); |
||||
var copied = byteString.Memory.ToArray(); |
||||
CollectionAssert.AreEqual(byteString, copied); |
||||
} |
||||
|
||||
// Create Memory<byte> from non-array source. |
||||
// Use by ByteString tests that have optimized path for array backed Memory<byte>. |
||||
private sealed unsafe class UnmanagedMemoryManager<T> : MemoryManager<T> where T : unmanaged |
||||
{ |
||||
private readonly T* _pointer; |
||||
private readonly int _length; |
||||
|
||||
public UnmanagedMemoryManager(Span<T> span) |
||||
{ |
||||
fixed (T* ptr = &MemoryMarshal.GetReference(span)) |
||||
{ |
||||
_pointer = ptr; |
||||
_length = span.Length; |
||||
} |
||||
} |
||||
|
||||
public override Span<T> GetSpan() => new Span<T>(_pointer, _length); |
||||
|
||||
public override MemoryHandle Pin(int elementIndex = 0) |
||||
{ |
||||
if (elementIndex < 0 || elementIndex >= _length) |
||||
{ |
||||
throw new ArgumentOutOfRangeException(nameof(elementIndex)); |
||||
} |
||||
|
||||
return new MemoryHandle(_pointer + elementIndex); |
||||
} |
||||
|
||||
public override void Unpin() { } |
||||
|
||||
protected override void Dispose(bool disposing) { } |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,434 +1,434 @@ |
||||
#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.Runtime.InteropServices; |
||||
using System.Security; |
||||
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> |
||||
[SecuritySafeCritical] |
||||
public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString> |
||||
{ |
||||
private static readonly ByteString empty = new ByteString(new byte[0]); |
||||
|
||||
private readonly ReadOnlyMemory<byte> bytes; |
||||
|
||||
/// <summary> |
||||
/// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance. |
||||
/// </summary> |
||||
internal static ByteString AttachBytes(ReadOnlyMemory<byte> bytes) |
||||
{ |
||||
return new ByteString(bytes); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance. |
||||
/// This method encapsulates converting array to memory. Reduces need for SecuritySafeCritical |
||||
/// in .NET Framework. |
||||
/// </summary> |
||||
internal static ByteString AttachBytes(byte[] bytes) |
||||
{ |
||||
return AttachBytes(bytes.AsMemory()); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs a new ByteString from the given memory. The memory is |
||||
/// *not* copied, and must not be modified after this constructor is called. |
||||
/// </summary> |
||||
private ByteString(ReadOnlyMemory<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> |
||||
/// Provides read-only access to the data of this <see cref="ByteString"/>. |
||||
/// No data is copied so this is the most efficient way of accessing. |
||||
/// </summary> |
||||
public ReadOnlySpan<byte> Span |
||||
{ |
||||
get { return bytes.Span; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Provides read-only access to the data of this <see cref="ByteString"/>. |
||||
/// No data is copied so this is the most efficient way of accessing. |
||||
/// </summary> |
||||
public ReadOnlyMemory<byte> Memory |
||||
{ |
||||
get { return bytes; } |
||||
} |
||||
|
||||
/// <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 bytes.ToArray(); |
||||
} |
||||
|
||||
/// <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() |
||||
{ |
||||
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment)) |
||||
{ |
||||
// Fast path. ByteString was created with an array, so pass the underlying array. |
||||
return Convert.ToBase64String(segment.Array, segment.Offset, segment.Count); |
||||
} |
||||
else |
||||
{ |
||||
// Slow path. BytesString is not an array. Convert memory and pass result to ToBase64String. |
||||
return Convert.ToBase64String(bytes.ToArray()); |
||||
} |
||||
} |
||||
|
||||
/// <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_1 || NETSTANDARD2_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 static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) |
||||
{ |
||||
ProtoPreconditions.CheckNotNull(stream, nameof(stream)); |
||||
return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken); |
||||
} |
||||
#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> |
||||
/// Constructs a <see cref="ByteString" /> from a read only span. The contents |
||||
/// are copied, so further modifications to the span will not |
||||
/// be reflected in the returned <see cref="ByteString" />. |
||||
/// </summary> |
||||
public static ByteString CopyFrom(ReadOnlySpan<byte> bytes) |
||||
{ |
||||
return new ByteString(bytes.ToArray()); |
||||
} |
||||
|
||||
/// <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> |
||||
/// Returns the byte at the given index. |
||||
/// </summary> |
||||
public byte this[int index] |
||||
{ |
||||
get { return bytes.Span[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) |
||||
{ |
||||
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment)) |
||||
{ |
||||
// Fast path. ByteString was created with an array. |
||||
return encoding.GetString(segment.Array, segment.Offset, segment.Count); |
||||
} |
||||
else |
||||
{ |
||||
// Slow path. BytesString is not an array. Convert memory and pass result to GetString. |
||||
// TODO: Consider using GetString overload that takes a pointer. |
||||
byte[] array = bytes.ToArray(); |
||||
return encoding.GetString(array, 0, array.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> |
||||
[SecuritySafeCritical] |
||||
public IEnumerator<byte> GetEnumerator() |
||||
{ |
||||
return MemoryMarshal.ToEnumerable(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 |
||||
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment) && segment.Count == bytes.Length) |
||||
{ |
||||
// Fast path. ByteString was created with a complete array. |
||||
return new CodedInputStream(segment.Array, segment.Offset, segment.Count); |
||||
} |
||||
else |
||||
{ |
||||
// Slow path. BytesString is not an array, or is a slice of an array. |
||||
// Convert memory and pass result to WriteRawBytes. |
||||
return new CodedInputStream(bytes.ToArray()); |
||||
} |
||||
} |
||||
|
||||
/// <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; |
||||
} |
||||
|
||||
return lhs.bytes.Span.SequenceEqual(rhs.bytes.Span); |
||||
} |
||||
|
||||
/// <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> |
||||
[SecuritySafeCritical] |
||||
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> |
||||
[SecuritySafeCritical] |
||||
public override int GetHashCode() |
||||
{ |
||||
ReadOnlySpan<byte> b = bytes.Span; |
||||
|
||||
int ret = 23; |
||||
for (int i = 0; i < b.Length; i++) |
||||
{ |
||||
ret = (ret * 31) + b[i]; |
||||
} |
||||
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> |
||||
/// Copies the entire byte array to the destination array provided at the offset specified. |
||||
/// </summary> |
||||
public void CopyTo(byte[] array, int position) |
||||
{ |
||||
bytes.CopyTo(array.AsMemory(position)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Writes the entire byte array to the provided stream |
||||
/// </summary> |
||||
public void WriteTo(Stream outputStream) |
||||
{ |
||||
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment)) |
||||
{ |
||||
// Fast path. ByteString was created with an array, so pass the underlying array. |
||||
outputStream.Write(segment.Array, segment.Offset, segment.Count); |
||||
} |
||||
else |
||||
{ |
||||
// Slow path. BytesString is not an array. Convert memory and pass result to WriteRawBytes. |
||||
var array = bytes.ToArray(); |
||||
outputStream.Write(array, 0, array.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.Runtime.InteropServices; |
||||
using System.Security; |
||||
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> |
||||
[SecuritySafeCritical] |
||||
public sealed class ByteString : IEnumerable<byte>, IEquatable<ByteString> |
||||
{ |
||||
private static readonly ByteString empty = new ByteString(new byte[0]); |
||||
|
||||
private readonly ReadOnlyMemory<byte> bytes; |
||||
|
||||
/// <summary> |
||||
/// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance. |
||||
/// </summary> |
||||
internal static ByteString AttachBytes(ReadOnlyMemory<byte> bytes) |
||||
{ |
||||
return new ByteString(bytes); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance. |
||||
/// This method encapsulates converting array to memory. Reduces need for SecuritySafeCritical |
||||
/// in .NET Framework. |
||||
/// </summary> |
||||
internal static ByteString AttachBytes(byte[] bytes) |
||||
{ |
||||
return AttachBytes(bytes.AsMemory()); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs a new ByteString from the given memory. The memory is |
||||
/// *not* copied, and must not be modified after this constructor is called. |
||||
/// </summary> |
||||
private ByteString(ReadOnlyMemory<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> |
||||
/// Provides read-only access to the data of this <see cref="ByteString"/>. |
||||
/// No data is copied so this is the most efficient way of accessing. |
||||
/// </summary> |
||||
public ReadOnlySpan<byte> Span |
||||
{ |
||||
get { return bytes.Span; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Provides read-only access to the data of this <see cref="ByteString"/>. |
||||
/// No data is copied so this is the most efficient way of accessing. |
||||
/// </summary> |
||||
public ReadOnlyMemory<byte> Memory |
||||
{ |
||||
get { return bytes; } |
||||
} |
||||
|
||||
/// <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 bytes.ToArray(); |
||||
} |
||||
|
||||
/// <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() |
||||
{ |
||||
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment)) |
||||
{ |
||||
// Fast path. ByteString was created with an array, so pass the underlying array. |
||||
return Convert.ToBase64String(segment.Array, segment.Offset, segment.Count); |
||||
} |
||||
else |
||||
{ |
||||
// Slow path. BytesString is not an array. Convert memory and pass result to ToBase64String. |
||||
return Convert.ToBase64String(bytes.ToArray()); |
||||
} |
||||
} |
||||
|
||||
/// <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_1 || NETSTANDARD2_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 static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) |
||||
{ |
||||
ProtoPreconditions.CheckNotNull(stream, nameof(stream)); |
||||
return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken); |
||||
} |
||||
#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> |
||||
/// Constructs a <see cref="ByteString" /> from a read only span. The contents |
||||
/// are copied, so further modifications to the span will not |
||||
/// be reflected in the returned <see cref="ByteString" />. |
||||
/// </summary> |
||||
public static ByteString CopyFrom(ReadOnlySpan<byte> bytes) |
||||
{ |
||||
return new ByteString(bytes.ToArray()); |
||||
} |
||||
|
||||
/// <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> |
||||
/// Returns the byte at the given index. |
||||
/// </summary> |
||||
public byte this[int index] |
||||
{ |
||||
get { return bytes.Span[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) |
||||
{ |
||||
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment)) |
||||
{ |
||||
// Fast path. ByteString was created with an array. |
||||
return encoding.GetString(segment.Array, segment.Offset, segment.Count); |
||||
} |
||||
else |
||||
{ |
||||
// Slow path. BytesString is not an array. Convert memory and pass result to GetString. |
||||
// TODO: Consider using GetString overload that takes a pointer. |
||||
byte[] array = bytes.ToArray(); |
||||
return encoding.GetString(array, 0, array.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> |
||||
[SecuritySafeCritical] |
||||
public IEnumerator<byte> GetEnumerator() |
||||
{ |
||||
return MemoryMarshal.ToEnumerable(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 |
||||
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment) && segment.Count == bytes.Length) |
||||
{ |
||||
// Fast path. ByteString was created with a complete array. |
||||
return new CodedInputStream(segment.Array, segment.Offset, segment.Count); |
||||
} |
||||
else |
||||
{ |
||||
// Slow path. BytesString is not an array, or is a slice of an array. |
||||
// Convert memory and pass result to WriteRawBytes. |
||||
return new CodedInputStream(bytes.ToArray()); |
||||
} |
||||
} |
||||
|
||||
/// <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; |
||||
} |
||||
|
||||
return lhs.bytes.Span.SequenceEqual(rhs.bytes.Span); |
||||
} |
||||
|
||||
/// <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> |
||||
[SecuritySafeCritical] |
||||
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> |
||||
[SecuritySafeCritical] |
||||
public override int GetHashCode() |
||||
{ |
||||
ReadOnlySpan<byte> b = bytes.Span; |
||||
|
||||
int ret = 23; |
||||
for (int i = 0; i < b.Length; i++) |
||||
{ |
||||
ret = (ret * 31) + b[i]; |
||||
} |
||||
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> |
||||
/// Copies the entire byte array to the destination array provided at the offset specified. |
||||
/// </summary> |
||||
public void CopyTo(byte[] array, int position) |
||||
{ |
||||
bytes.CopyTo(array.AsMemory(position)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Writes the entire byte array to the provided stream |
||||
/// </summary> |
||||
public void WriteTo(Stream outputStream) |
||||
{ |
||||
if (MemoryMarshal.TryGetArray(bytes, out ArraySegment<byte> segment)) |
||||
{ |
||||
// Fast path. ByteString was created with an array, so pass the underlying array. |
||||
outputStream.Write(segment.Array, segment.Offset, segment.Count); |
||||
} |
||||
else |
||||
{ |
||||
// Slow path. BytesString is not an array. Convert memory and pass result to WriteRawBytes. |
||||
var array = bytes.ToArray(); |
||||
outputStream.Write(array, 0, array.Length); |
||||
} |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,308 +1,308 @@ |
||||
#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; |
||||
|
||||
internal const int DoubleSize = LittleEndian64Size; |
||||
internal const int FloatSize = LittleEndian32Size; |
||||
internal const int BoolSize = 1; |
||||
|
||||
/// <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 DoubleSize; |
||||
} |
||||
|
||||
/// <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 FloatSize; |
||||
} |
||||
|
||||
/// <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 BoolSize; |
||||
} |
||||
|
||||
/// <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 = WritingPrimitives.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(WritingPrimitives.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(WritingPrimitives.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; |
||||
|
||||
internal const int DoubleSize = LittleEndian64Size; |
||||
internal const int FloatSize = LittleEndian32Size; |
||||
internal const int BoolSize = 1; |
||||
|
||||
/// <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 DoubleSize; |
||||
} |
||||
|
||||
/// <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 FloatSize; |
||||
} |
||||
|
||||
/// <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 BoolSize; |
||||
} |
||||
|
||||
/// <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 = WritingPrimitives.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(WritingPrimitives.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(WritingPrimitives.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)); |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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(); |
||||
} |
||||
} |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -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); |
||||
} |
||||
} |
||||
|
@ -1,140 +1,140 @@ |
||||
#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 InvalidWireType() |
||||
{ |
||||
return new InvalidProtocolBufferException( |
||||
"Protocol message contained a tag with an invalid wire type."); |
||||
} |
||||
|
||||
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."); |
||||
} |
||||
|
||||
internal static InvalidProtocolBufferException MissingFields() |
||||
{ |
||||
return new InvalidProtocolBufferException("Message was missing required fields"); |
||||
} |
||||
} |
||||
#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 InvalidWireType() |
||||
{ |
||||
return new InvalidProtocolBufferException( |
||||
"Protocol message contained a tag with an invalid wire type."); |
||||
} |
||||
|
||||
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."); |
||||
} |
||||
|
||||
internal static InvalidProtocolBufferException MissingFields() |
||||
{ |
||||
return new InvalidProtocolBufferException("Message was missing required fields"); |
||||
} |
||||
} |
||||
} |
@ -1,56 +1,56 @@ |
||||
#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")] |
||||
|
||||
[assembly: InternalsVisibleTo("Google.Protobuf.Benchmarks, 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")] |
||||
|
||||
[assembly: InternalsVisibleTo("Google.Protobuf.Benchmarks, PublicKey=" + |
||||
"002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" + |
||||
"7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" + |
||||
"981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" + |
||||
"b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" + |
||||
"c5ae9cb6")] |
||||
|
@ -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 |
||||
/// </summary> |
||||
StartGroup = 3, |
||||
/// <summary> |
||||
/// An "end group" value |
||||
/// </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 |
||||
/// </summary> |
||||
StartGroup = 3, |
||||
/// <summary> |
||||
/// An "end group" value |
||||
/// </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; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,92 @@ |
||||
# Log capturing for the Kokoro runtime environment. |
||||
# |
||||
# This script should be `source`d from Kokoro build scripts to configure log |
||||
# capturing when running under Kokoro. |
||||
# |
||||
# When not running under Kokoro, no logs will be collected. If you want to run |
||||
# locally and collect logs anyway, set the KOKORO_ARTIFACTS_DIR environment |
||||
# variable to a directory where the logs should go. |
||||
# |
||||
# The job `.cfg` file needs the following stanzas to declare the captured logs |
||||
# as outputs (yes, these are globs, not regexes): |
||||
# |
||||
# action: { |
||||
# define_artifacts: { |
||||
# regex: "**/*sponge_log.log" |
||||
# regex: "**/*sponge_log.xml" |
||||
# } |
||||
# } |
||||
# |
||||
# Use the provided functions below as build/test fixtures, e.g.: |
||||
# |
||||
# source kokoro/capture_logs.sh |
||||
# caplog build/step1 <build command> |
||||
# caplog tests/step2 <test command> |
||||
# |
||||
# If log capturing is enabled, this script will set some variables that can be |
||||
# used if necessary: |
||||
# |
||||
# CAPLOG_DIR is used for logs |
||||
# CAPLOG_CMAKE_ARGS contains extra cmake args to enable test XML output |
||||
# CAPLOG_CTEST_ARGS contains extra ctest args to capture combined test logs |
||||
# |
||||
# For example: |
||||
# |
||||
# if [[ -v CAPLOG_DIR_BUILD ]]; then |
||||
# cp extra_diagnostics.log "${CAPLOG_DIR_BUILD}/diagnostics.log" |
||||
# fi |
||||
# |
||||
# # Use ${...:-} form under `set -u`: |
||||
# caplog build/01_configure cmake -G Ninja ${CAPLOG_CMAKE_ARGS:-} |
||||
# caplog build/02_build cmake --build |
||||
# caplog test/03_test ctest ${CAPLOG_CTEST_ARGS:-} |
||||
|
||||
if [[ -z ${KOKORO_ARTIFACTS_DIR:-} ]]; then |
||||
function caplog() { shift; "$@"; } |
||||
else |
||||
|
||||
CAPLOG_DIR="$(mktemp -d)" |
||||
CAPLOG_CMAKE_ARGS="-Dprotobuf_TEST_XML_OUTDIR=${CAPLOG_DIR}/tests/" |
||||
CAPLOG_CTEST_ARGS="--verbose" |
||||
|
||||
# Captures the stdout/stderr of a command to a named log file. |
||||
# Usage: caplog NAME COMMAND [ARGS...] |
||||
function caplog() { |
||||
_name="${CAPLOG_DIR}/${1%.log}.log"; shift |
||||
mkdir -p "${_name%/*}" |
||||
date |
||||
time ( "$@" 2>&1 | tee "${_name}" ) |
||||
if [[ $? != 0 ]] ; then |
||||
cat "${_name}" |
||||
return 1 |
||||
fi |
||||
} |
||||
|
||||
# Trap handler: renames logs on script exit so they will be found by Kokoro. |
||||
function _caplog_onexit() { |
||||
_rc=$? |
||||
set +x |
||||
echo "Collecting logs [${BASH_SOURCE}]" |
||||
|
||||
find "${CAPLOG_DIR}" -type f -name '*.log' \ |
||||
| while read _textlog; do |
||||
# Ensure an XML file exists for each .log file. |
||||
touch ${_textlog%.log}.xml |
||||
done |
||||
|
||||
find "${CAPLOG_DIR}" -type f \( -name '*.xml' -or -name '*.log' \) \ |
||||
| while read _src; do |
||||
# Move to artifacts dir, preserving the path relative to CAPLOG_DIR. |
||||
# The filename changes from foo/bar.log to foo/bar/sponge_log.log. |
||||
_logfile=${_src/${CAPLOG_DIR}\//} |
||||
_stem=${KOKORO_ARTIFACTS_DIR}/${_logfile%.*} |
||||
_ext=${_logfile##*.} |
||||
mkdir -p ${_stem} |
||||
mv -v "${_src}" "${_stem}/sponge_log.${_ext}" |
||||
done |
||||
rm -rv "${CAPLOG_DIR}" |
||||
exit ${_rc} |
||||
} |
||||
trap _caplog_onexit EXIT |
||||
|
||||
fi |
@ -0,0 +1,4 @@ |
||||
# macOS-next |
||||
|
||||
This builder is temporary for developing and testing builds using the "next" |
||||
macOS version without affecting the ordinary builds. |
@ -0,0 +1,55 @@ |
||||
#!/bin/bash -eux |
||||
# |
||||
# Build file to set up and run tests |
||||
|
||||
set -o pipefail |
||||
|
||||
if [[ -h /tmpfs ]] && [[ ${PWD} == /tmpfs/src ]]; then |
||||
# Workaround for internal Kokoro bug: b/227401944 |
||||
cd /Volumes/BuildData/tmpfs/src |
||||
fi |
||||
|
||||
# These vars can be changed when running manually, e.g.: |
||||
# |
||||
# % BUILD_CONFIG=RelWithDebInfo path/to/build.sh |
||||
|
||||
# By default, build using Debug config. |
||||
: ${BUILD_CONFIG:=Debug} |
||||
|
||||
# By default, find the sources based on this script path. |
||||
: ${SOURCE_DIR:=$(cd $(dirname $0)/../../..; pwd)} |
||||
|
||||
# By default, put outputs under <git root>/cmake/build. |
||||
: ${BUILD_DIR:=${SOURCE_DIR}/cmake/build} |
||||
|
||||
source ${SOURCE_DIR}/kokoro/caplog.sh |
||||
|
||||
# |
||||
# Update submodules |
||||
# |
||||
git -C "${SOURCE_DIR}" submodule update --init --recursive |
||||
|
||||
# |
||||
# Configure and build in a separate directory |
||||
# |
||||
mkdir -p "${BUILD_DIR}" |
||||
|
||||
caplog 01_configure \ |
||||
cmake -S "${SOURCE_DIR}" -B "${BUILD_DIR}" ${CAPLOG_CMAKE_ARGS:-} |
||||
|
||||
if [[ -n ${CAPLOG_DIR:-} ]]; then |
||||
mkdir -p "${CAPLOG_DIR}/CMakeFiles" |
||||
cp "${BUILD_DIR}"/CMakeFiles/CMake*.log "${CAPLOG_DIR}/CMakeFiles" |
||||
fi |
||||
|
||||
caplog 02_build \ |
||||
cmake --build "${BUILD_DIR}" --config "${BUILD_CONFIG}" |
||||
|
||||
# |
||||
# Run tests |
||||
# |
||||
( |
||||
cd "${BUILD_DIR}" |
||||
caplog 03_combined_testlog \ |
||||
ctest -C "${BUILD_CONFIG}" -j4 ${CAPLOG_CTEST_ARGS:-} |
||||
) |
@ -0,0 +1,13 @@ |
||||
# Config file for running tests in Kokoro |
||||
|
||||
# Location of the build script in repository |
||||
build_file: "protobuf/kokoro/macos-next/cpp/build.sh" |
||||
timeout_mins: 1440 |
||||
|
||||
# Upload logs |
||||
action: { |
||||
define_artifacts: { |
||||
regex: "**/*sponge_log.log" |
||||
regex: "**/*sponge_log.xml" |
||||
} |
||||
} |
@ -0,0 +1,13 @@ |
||||
# Config file for running tests in Kokoro |
||||
|
||||
# Location of the build script in repository |
||||
build_file: "protobuf/kokoro/macos-next/cpp/build.sh" |
||||
timeout_mins: 1440 |
||||
|
||||
# Upload logs |
||||
action: { |
||||
define_artifacts: { |
||||
regex: "**/*sponge_log.log" |
||||
regex: "**/*sponge_log.xml" |
||||
} |
||||
} |
@ -1 +1 @@ |
||||
PROTOBUF_VERSION = '3.20.0-rc-1' |
||||
PROTOBUF_VERSION = '3.20.0' |
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue