• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 // Protocol Buffers - Google's data interchange format
3 // Copyright 2008 Google Inc.  All rights reserved.
4 // https://developers.google.com/protocol-buffers/
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
8 // met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following disclaimer
14 // in the documentation and/or other materials provided with the
15 // distribution.
16 //     * Neither the name of Google Inc. nor the names of its
17 // contributors may be used to endorse or promote products derived from
18 // this software without specific prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #endregion
32 
33 using System;
34 using System.Text;
35 using NUnit.Framework;
36 using System.IO;
37 #if !NET35
38 using System.Threading.Tasks;
39 #endif
40 
41 namespace Google.Protobuf
42 {
43     public class ByteStringTest
44     {
45         [Test]
Equality()46         public void Equality()
47         {
48             ByteString b1 = ByteString.CopyFrom(1, 2, 3);
49             ByteString b2 = ByteString.CopyFrom(1, 2, 3);
50             ByteString b3 = ByteString.CopyFrom(1, 2, 4);
51             ByteString b4 = ByteString.CopyFrom(1, 2, 3, 4);
52             EqualityTester.AssertEquality(b1, b1);
53             EqualityTester.AssertEquality(b1, b2);
54             EqualityTester.AssertInequality(b1, b3);
55             EqualityTester.AssertInequality(b1, b4);
56             EqualityTester.AssertInequality(b1, null);
57 #pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1)
58             Assert.IsTrue(b1 == b1);
59             Assert.IsTrue(b1 == b2);
60             Assert.IsFalse(b1 == b3);
61             Assert.IsFalse(b1 == b4);
62             Assert.IsFalse(b1 == null);
63             Assert.IsTrue((ByteString) null == null);
64             Assert.IsFalse(b1 != b1);
65             Assert.IsFalse(b1 != b2);
66 #pragma warning disable 1718
67             Assert.IsTrue(b1 != b3);
68             Assert.IsTrue(b1 != b4);
69             Assert.IsTrue(b1 != null);
70             Assert.IsFalse((ByteString) null != null);
71         }
72 
73         [Test]
EmptyByteStringHasZeroSize()74         public void EmptyByteStringHasZeroSize()
75         {
76             Assert.AreEqual(0, ByteString.Empty.Length);
77         }
78 
79         [Test]
CopyFromStringWithExplicitEncoding()80         public void CopyFromStringWithExplicitEncoding()
81         {
82             ByteString bs = ByteString.CopyFrom("AB", Encoding.Unicode);
83             Assert.AreEqual(4, bs.Length);
84             Assert.AreEqual(65, bs[0]);
85             Assert.AreEqual(0, bs[1]);
86             Assert.AreEqual(66, bs[2]);
87             Assert.AreEqual(0, bs[3]);
88         }
89 
90         [Test]
IsEmptyWhenEmpty()91         public void IsEmptyWhenEmpty()
92         {
93             Assert.IsTrue(ByteString.CopyFromUtf8("").IsEmpty);
94         }
95 
96         [Test]
IsEmptyWhenNotEmpty()97         public void IsEmptyWhenNotEmpty()
98         {
99             Assert.IsFalse(ByteString.CopyFromUtf8("X").IsEmpty);
100         }
101 
102         [Test]
CopyFromByteArrayCopiesContents()103         public void CopyFromByteArrayCopiesContents()
104         {
105             byte[] data = new byte[1];
106             data[0] = 10;
107             ByteString bs = ByteString.CopyFrom(data);
108             Assert.AreEqual(10, bs[0]);
109             data[0] = 5;
110             Assert.AreEqual(10, bs[0]);
111         }
112 
113         [Test]
CopyFromReadOnlySpanCopiesContents()114         public void CopyFromReadOnlySpanCopiesContents()
115         {
116             byte[] data = new byte[1];
117             data[0] = 10;
118             ReadOnlySpan<byte> byteSpan = data;
119             var bs = ByteString.CopyFrom(byteSpan);
120             Assert.AreEqual(10, bs[0]);
121             data[0] = 5;
122             Assert.AreEqual(10, bs[0]);
123         }
124 
125         [Test]
ToByteArrayCopiesContents()126         public void ToByteArrayCopiesContents()
127         {
128             ByteString bs = ByteString.CopyFromUtf8("Hello");
129             byte[] data = bs.ToByteArray();
130             Assert.AreEqual((byte)'H', data[0]);
131             Assert.AreEqual((byte)'H', bs[0]);
132             data[0] = 0;
133             Assert.AreEqual(0, data[0]);
134             Assert.AreEqual((byte)'H', bs[0]);
135         }
136 
137         [Test]
CopyFromUtf8UsesUtf8()138         public void CopyFromUtf8UsesUtf8()
139         {
140             ByteString bs = ByteString.CopyFromUtf8("\u20ac");
141             Assert.AreEqual(3, bs.Length);
142             Assert.AreEqual(0xe2, bs[0]);
143             Assert.AreEqual(0x82, bs[1]);
144             Assert.AreEqual(0xac, bs[2]);
145         }
146 
147         [Test]
CopyFromPortion()148         public void CopyFromPortion()
149         {
150             byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
151             ByteString bs = ByteString.CopyFrom(data, 2, 3);
152             Assert.AreEqual(3, bs.Length);
153             Assert.AreEqual(2, bs[0]);
154             Assert.AreEqual(3, bs[1]);
155         }
156 
157         [Test]
ToStringUtf8()158         public void ToStringUtf8()
159         {
160             ByteString bs = ByteString.CopyFromUtf8("\u20ac");
161             Assert.AreEqual("\u20ac", bs.ToStringUtf8());
162         }
163 
164         [Test]
ToStringWithExplicitEncoding()165         public void ToStringWithExplicitEncoding()
166         {
167             ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
168             Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
169         }
170 
171         [Test]
FromBase64_WithText()172         public void FromBase64_WithText()
173         {
174             byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
175             string base64 = Convert.ToBase64String(data);
176             ByteString bs = ByteString.FromBase64(base64);
177             Assert.AreEqual(data, bs.ToByteArray());
178         }
179 
180         [Test]
FromBase64_Empty()181         public void FromBase64_Empty()
182         {
183             // Optimization which also fixes issue 61.
184             Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
185         }
186 
187         [Test]
FromStream_Seekable()188         public void FromStream_Seekable()
189         {
190             var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
191             // Consume the first byte, just to test that it's "from current position"
192             stream.ReadByte();
193             var actual = ByteString.FromStream(stream);
194             ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
195             Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
196         }
197 
198         [Test]
FromStream_NotSeekable()199         public void FromStream_NotSeekable()
200         {
201             var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
202             // Consume the first byte, just to test that it's "from current position"
203             stream.ReadByte();
204             // Wrap the original stream in LimitedInputStream, which has CanSeek=false
205             var limitedStream = new LimitedInputStream(stream, 3);
206             var actual = ByteString.FromStream(limitedStream);
207             ByteString expected = ByteString.CopyFrom(2, 3, 4);
208             Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
209         }
210 
211 #if !NET35
212         [Test]
FromStreamAsync_Seekable()213         public async Task FromStreamAsync_Seekable()
214         {
215             var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
216             // Consume the first byte, just to test that it's "from current position"
217             stream.ReadByte();
218             var actual = await ByteString.FromStreamAsync(stream);
219             ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
220             Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
221         }
222 
223         [Test]
FromStreamAsync_NotSeekable()224         public async Task FromStreamAsync_NotSeekable()
225         {
226             var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
227             // Consume the first byte, just to test that it's "from current position"
228             stream.ReadByte();
229             // Wrap the original stream in LimitedInputStream, which has CanSeek=false
230             var limitedStream = new LimitedInputStream(stream, 3);
231             var actual = await ByteString.FromStreamAsync(limitedStream);
232             ByteString expected = ByteString.CopyFrom(2, 3, 4);
233             Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
234         }
235 #endif
236 
237         [Test]
GetHashCode_Regression()238         public void GetHashCode_Regression()
239         {
240             // We used to have an awful hash algorithm where only the last four
241             // bytes were relevant. This is a regression test for
242             // https://github.com/protocolbuffers/protobuf/issues/2511
243 
244             ByteString b1 = ByteString.CopyFrom(100, 1, 2, 3, 4);
245             ByteString b2 = ByteString.CopyFrom(200, 1, 2, 3, 4);
246             Assert.AreNotEqual(b1.GetHashCode(), b2.GetHashCode());
247         }
248 
249         [Test]
GetContentsAsReadOnlySpan()250         public void GetContentsAsReadOnlySpan()
251         {
252             var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5);
253             var copied = byteString.Span.ToArray();
254             CollectionAssert.AreEqual(byteString, copied);
255         }
256 
257         [Test]
GetContentsAsReadOnlyMemory()258         public void GetContentsAsReadOnlyMemory()
259         {
260             var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5);
261             var copied = byteString.Memory.ToArray();
262             CollectionAssert.AreEqual(byteString, copied);
263         }
264     }
265 }