blob: d6a4e6728b22233f6089a1c4d84f2f83b56846a6 [file] [log] [blame]
Jon Skeet68036862008-10-22 13:30:34 +01001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.
3// http://code.google.com/p/protobuf/
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16using System.IO;
17using Google.ProtocolBuffers.TestProtos;
18using NUnit.Framework;
19
20namespace Google.ProtocolBuffers {
21 [TestFixture]
22 public class CodedOutputStreamTest {
23
24 /// <summary>
25 /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
26 /// checks that the result matches the given bytes
27 /// </summary>
28 private static void AssertWriteVarint(byte[] data, ulong value) {
29 // Only do 32-bit write if the value fits in 32 bits.
30 if ((value >> 32) == 0) {
31 MemoryStream rawOutput = new MemoryStream();
32 CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
33 output.WriteRawVarint32((uint) value);
34 output.Flush();
35 Assert.AreEqual(data, rawOutput.ToArray());
36 // Also try computing size.
37 Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
38 }
39
40 {
41 MemoryStream rawOutput = new MemoryStream();
42 CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
43 output.WriteRawVarint64(value);
44 output.Flush();
45 Assert.AreEqual(data, rawOutput.ToArray());
46
47 // Also try computing size.
48 Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
49 }
50
51 // Try different buffer sizes.
52 for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) {
53 // Only do 32-bit write if the value fits in 32 bits.
54 if ((value >> 32) == 0) {
55 MemoryStream rawOutput = new MemoryStream();
56 CodedOutputStream output =
57 CodedOutputStream.CreateInstance(rawOutput, bufferSize);
58 output.WriteRawVarint32((uint) value);
59 output.Flush();
60 Assert.AreEqual(data, rawOutput.ToArray());
61 }
62
63 {
64 MemoryStream rawOutput = new MemoryStream();
65 CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput, bufferSize);
66 output.WriteRawVarint64(value);
67 output.Flush();
68 Assert.AreEqual(data, rawOutput.ToArray());
69 }
70 }
71 }
72
73 /// <summary>
74 /// Tests WriteRawVarint32() and WriteRawVarint64()
75 /// </summary>
76 [Test]
77 public void WriteVarint() {
78 AssertWriteVarint(new byte[] {0x00}, 0);
79 AssertWriteVarint(new byte[] {0x01}, 1);
80 AssertWriteVarint(new byte[] {0x7f}, 127);
81 // 14882
82 AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
83 // 2961488830
84 AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
85 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
86 (0x0bL << 28));
87
88 // 64-bit
89 // 7256456126
90 AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
91 (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
92 (0x1bL << 28));
93 // 41256202580718336
94 AssertWriteVarint(
95 new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
96 (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
97 (0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
98 // 11964378330978735131
99 AssertWriteVarint(
100 new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
101 unchecked((ulong)
102 ((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
103 (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
104 (0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
105 }
106
107 /// <summary>
108 /// Parses the given bytes using WriteRawLittleEndian32() and checks
109 /// that the result matches the given value.
110 /// </summary>
111 private static void AssertWriteLittleEndian32(byte[] data, uint value) {
112 MemoryStream rawOutput = new MemoryStream();
113 CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
114 output.WriteRawLittleEndian32(value);
115 output.Flush();
116 Assert.AreEqual(data, rawOutput.ToArray());
117
118 // Try different buffer sizes.
119 for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) {
120 rawOutput = new MemoryStream();
121 output = CodedOutputStream.CreateInstance(rawOutput, bufferSize);
122 output.WriteRawLittleEndian32(value);
123 output.Flush();
124 Assert.AreEqual(data, rawOutput.ToArray());
125 }
126 }
127
128 /// <summary>
129 /// Parses the given bytes using WriteRawLittleEndian64() and checks
130 /// that the result matches the given value.
131 /// </summary>
132 private static void AssertWriteLittleEndian64(byte[] data, ulong value) {
133 MemoryStream rawOutput = new MemoryStream();
134 CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
135 output.WriteRawLittleEndian64(value);
136 output.Flush();
137 Assert.AreEqual(data, rawOutput.ToArray());
138
139 // Try different block sizes.
140 for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
141 rawOutput = new MemoryStream();
142 output = CodedOutputStream.CreateInstance(rawOutput, blockSize);
143 output.WriteRawLittleEndian64(value);
144 output.Flush();
145 Assert.AreEqual(data, rawOutput.ToArray());
146 }
147 }
148
149 /// <summary>
150 /// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
151 /// </summary>
152 [Test]
153 public void WriteLittleEndian() {
154 AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
155 AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
156
157 AssertWriteLittleEndian64(
158 new byte[]{0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
159 0x123456789abcdef0L);
160 AssertWriteLittleEndian64(
161 new byte[]{0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
162 0x9abcdef012345678UL);
163 }
164
165 [Test]
166 public void WriteWholeMessage() {
167 TestAllTypes message = TestUtil.GetAllSet();
168
169 byte[] rawBytes = message.ToByteArray();
170 TestUtil.AssertEqualBytes(TestUtil.GoldenMessage.ToByteArray(), rawBytes);
171
172 // Try different block sizes.
173 for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
174 MemoryStream rawOutput = new MemoryStream();
175 CodedOutputStream output =
176 CodedOutputStream.CreateInstance(rawOutput, blockSize);
177 message.WriteTo(output);
178 output.Flush();
179 TestUtil.AssertEqualBytes(rawBytes, rawOutput.ToArray());
180 }
181 }
182
183
184 [Test]
185 public void EncodeZigZag32() {
186 Assert.AreEqual(0, CodedOutputStream.EncodeZigZag32( 0));
187 Assert.AreEqual(1, CodedOutputStream.EncodeZigZag32(-1));
188 Assert.AreEqual(2, CodedOutputStream.EncodeZigZag32( 1));
189 Assert.AreEqual(3, CodedOutputStream.EncodeZigZag32(-2));
190 Assert.AreEqual(0x7FFFFFFE, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
191 Assert.AreEqual(0x7FFFFFFF, CodedOutputStream.EncodeZigZag32(unchecked((int)0xC0000000)));
192 Assert.AreEqual(0xFFFFFFFE, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
193 Assert.AreEqual(0xFFFFFFFF, CodedOutputStream.EncodeZigZag32(unchecked((int)0x80000000)));
194 }
195
196 [Test]
197 public void EncodeZigZag64() {
198 Assert.AreEqual(0, CodedOutputStream.EncodeZigZag64( 0));
199 Assert.AreEqual(1, CodedOutputStream.EncodeZigZag64(-1));
200 Assert.AreEqual(2, CodedOutputStream.EncodeZigZag64( 1));
201 Assert.AreEqual(3, CodedOutputStream.EncodeZigZag64(-2));
202 Assert.AreEqual(0x000000007FFFFFFEL,
203 CodedOutputStream.EncodeZigZag64(unchecked((long)0x000000003FFFFFFFUL)));
204 Assert.AreEqual(0x000000007FFFFFFFL,
205 CodedOutputStream.EncodeZigZag64(unchecked((long)0xFFFFFFFFC0000000UL)));
206 Assert.AreEqual(0x00000000FFFFFFFEL,
207 CodedOutputStream.EncodeZigZag64(unchecked((long)0x000000007FFFFFFFUL)));
208 Assert.AreEqual(0x00000000FFFFFFFFL,
209 CodedOutputStream.EncodeZigZag64(unchecked((long)0xFFFFFFFF80000000UL)));
210 Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
211 CodedOutputStream.EncodeZigZag64(unchecked((long)0x7FFFFFFFFFFFFFFFUL)));
212 Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
213 CodedOutputStream.EncodeZigZag64(unchecked((long)0x8000000000000000UL)));
214 }
215
216 [Test]
217 public void RoundTripZigZag32() {
218 // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
219 // were chosen semi-randomly via keyboard bashing.
220 Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
221 Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
222 Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
223 Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
224 Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
225 }
226
227 [Test]
228 public void RoundTripZigZag64() {
229 Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
230 Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
231 Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
232 Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
233 Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
234
235 Assert.AreEqual(856912304801416L, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
236 Assert.AreEqual(-75123905439571256L, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
237 }
238 }
239}