• 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]
ToByteArrayCopiesContents()114         public void ToByteArrayCopiesContents()
115         {
116             ByteString bs = ByteString.CopyFromUtf8("Hello");
117             byte[] data = bs.ToByteArray();
118             Assert.AreEqual((byte)'H', data[0]);
119             Assert.AreEqual((byte)'H', bs[0]);
120             data[0] = 0;
121             Assert.AreEqual(0, data[0]);
122             Assert.AreEqual((byte)'H', bs[0]);
123         }
124 
125         [Test]
CopyFromUtf8UsesUtf8()126         public void CopyFromUtf8UsesUtf8()
127         {
128             ByteString bs = ByteString.CopyFromUtf8("\u20ac");
129             Assert.AreEqual(3, bs.Length);
130             Assert.AreEqual(0xe2, bs[0]);
131             Assert.AreEqual(0x82, bs[1]);
132             Assert.AreEqual(0xac, bs[2]);
133         }
134 
135         [Test]
CopyFromPortion()136         public void CopyFromPortion()
137         {
138             byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
139             ByteString bs = ByteString.CopyFrom(data, 2, 3);
140             Assert.AreEqual(3, bs.Length);
141             Assert.AreEqual(2, bs[0]);
142             Assert.AreEqual(3, bs[1]);
143         }
144 
145         [Test]
ToStringUtf8()146         public void ToStringUtf8()
147         {
148             ByteString bs = ByteString.CopyFromUtf8("\u20ac");
149             Assert.AreEqual("\u20ac", bs.ToStringUtf8());
150         }
151 
152         [Test]
ToStringWithExplicitEncoding()153         public void ToStringWithExplicitEncoding()
154         {
155             ByteString bs = ByteString.CopyFrom("\u20ac", Encoding.Unicode);
156             Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode));
157         }
158 
159         [Test]
FromBase64_WithText()160         public void FromBase64_WithText()
161         {
162             byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6};
163             string base64 = Convert.ToBase64String(data);
164             ByteString bs = ByteString.FromBase64(base64);
165             Assert.AreEqual(data, bs.ToByteArray());
166         }
167 
168         [Test]
FromBase64_Empty()169         public void FromBase64_Empty()
170         {
171             // Optimization which also fixes issue 61.
172             Assert.AreSame(ByteString.Empty, ByteString.FromBase64(""));
173         }
174 
175         [Test]
FromStream_Seekable()176         public void FromStream_Seekable()
177         {
178             var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
179             // Consume the first byte, just to test that it's "from current position"
180             stream.ReadByte();
181             var actual = ByteString.FromStream(stream);
182             ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
183             Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
184         }
185 
186         [Test]
FromStream_NotSeekable()187         public void FromStream_NotSeekable()
188         {
189             var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
190             // Consume the first byte, just to test that it's "from current position"
191             stream.ReadByte();
192             // Wrap the original stream in LimitedInputStream, which has CanSeek=false
193             var limitedStream = new LimitedInputStream(stream, 3);
194             var actual = ByteString.FromStream(limitedStream);
195             ByteString expected = ByteString.CopyFrom(2, 3, 4);
196             Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
197         }
198 
199 #if !NET35
200         [Test]
FromStreamAsync_Seekable()201         public async Task FromStreamAsync_Seekable()
202         {
203             var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
204             // Consume the first byte, just to test that it's "from current position"
205             stream.ReadByte();
206             var actual = await ByteString.FromStreamAsync(stream);
207             ByteString expected = ByteString.CopyFrom(2, 3, 4, 5);
208             Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
209         }
210 
211         [Test]
FromStreamAsync_NotSeekable()212         public async Task FromStreamAsync_NotSeekable()
213         {
214             var stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5 });
215             // Consume the first byte, just to test that it's "from current position"
216             stream.ReadByte();
217             // Wrap the original stream in LimitedInputStream, which has CanSeek=false
218             var limitedStream = new LimitedInputStream(stream, 3);
219             var actual = await ByteString.FromStreamAsync(limitedStream);
220             ByteString expected = ByteString.CopyFrom(2, 3, 4);
221             Assert.AreEqual(expected, actual, $"{expected.ToBase64()} != {actual.ToBase64()}");
222         }
223 #endif
224 
225         [Test]
GetHashCode_Regression()226         public void GetHashCode_Regression()
227         {
228             // We used to have an awful hash algorithm where only the last four
229             // bytes were relevant. This is a regression test for
230             // https://github.com/protocolbuffers/protobuf/issues/2511
231 
232             ByteString b1 = ByteString.CopyFrom(100, 1, 2, 3, 4);
233             ByteString b2 = ByteString.CopyFrom(200, 1, 2, 3, 4);
234             Assert.AreNotEqual(b1.GetHashCode(), b2.GetHashCode());
235         }
236     }
237 }