CodedOutputStreamTest.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. using NUnit.Framework;
  2. using System.IO;
  3. namespace Google.ProtocolBuffers {
  4. [TestFixture]
  5. public class CodedOutputStreamTest {
  6. /// <summary>
  7. /// Helper to construct a byte array from a bunch of bytes. The inputs are
  8. /// actually ints so that I can use hex notation and not get stupid errors
  9. /// about precision.
  10. /// </summary>
  11. private static byte[] Bytes(params int[] bytesAsInts) {
  12. byte[] bytes = new byte[bytesAsInts.Length];
  13. for (int i = 0; i < bytesAsInts.Length; i++) {
  14. bytes[i] = (byte) bytesAsInts[i];
  15. }
  16. return bytes;
  17. }
  18. /// <summary>
  19. /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
  20. /// checks that the result matches the given bytes
  21. /// </summary>
  22. private static void AssertWriteVarint(byte[] data, ulong value) {
  23. // Only do 32-bit write if the value fits in 32 bits.
  24. if ((value >> 32) == 0) {
  25. MemoryStream rawOutput = new MemoryStream();
  26. CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
  27. output.WriteRawVarint32((uint) value);
  28. output.Flush();
  29. Assert.AreEqual(data, rawOutput.ToArray());
  30. // Also try computing size.
  31. Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value));
  32. }
  33. {
  34. MemoryStream rawOutput = new MemoryStream();
  35. CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
  36. output.WriteRawVarint64(value);
  37. output.Flush();
  38. Assert.AreEqual(data, rawOutput.ToArray());
  39. // Also try computing size.
  40. Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
  41. }
  42. // Try different buffer sizes.
  43. for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) {
  44. // Only do 32-bit write if the value fits in 32 bits.
  45. if ((value >> 32) == 0) {
  46. MemoryStream rawOutput = new MemoryStream();
  47. CodedOutputStream output =
  48. CodedOutputStream.CreateInstance(rawOutput, bufferSize);
  49. output.WriteRawVarint32((uint) value);
  50. output.Flush();
  51. Assert.AreEqual(data, rawOutput.ToArray());
  52. }
  53. {
  54. MemoryStream rawOutput = new MemoryStream();
  55. CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput, bufferSize);
  56. output.WriteRawVarint64(value);
  57. output.Flush();
  58. Assert.AreEqual(data, rawOutput.ToArray());
  59. }
  60. }
  61. }
  62. /// <summary>
  63. /// Tests WriteRawVarint32() and WriteRawVarint64()
  64. /// </summary>
  65. [Test]
  66. public void WriteVarint() {
  67. AssertWriteVarint(Bytes(0x00), 0);
  68. AssertWriteVarint(Bytes(0x01), 1);
  69. AssertWriteVarint(Bytes(0x7f), 127);
  70. // 14882
  71. AssertWriteVarint(Bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
  72. // 2961488830
  73. AssertWriteVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
  74. (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
  75. (0x0bL << 28));
  76. // 64-bit
  77. // 7256456126
  78. AssertWriteVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
  79. (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
  80. (0x1bL << 28));
  81. // 41256202580718336
  82. AssertWriteVarint(
  83. Bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
  84. (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
  85. (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
  86. // 11964378330978735131
  87. AssertWriteVarint(
  88. Bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
  89. unchecked((ulong)
  90. ((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
  91. (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
  92. (0x05L << 49) | (0x26L << 56) | (0x01L << 63))));
  93. }
  94. /// <summary>
  95. /// Parses the given bytes using WriteRawLittleEndian32() and checks
  96. /// that the result matches the given value.
  97. /// </summary>
  98. private static void AssertWriteLittleEndian32(byte[] data, int value) {
  99. MemoryStream rawOutput = new MemoryStream();
  100. CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
  101. output.WriteRawLittleEndian32(value);
  102. output.Flush();
  103. Assert.AreEqual(data, rawOutput.ToArray());
  104. // Try different buffer sizes.
  105. for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) {
  106. rawOutput = new MemoryStream();
  107. output = CodedOutputStream.CreateInstance(rawOutput, bufferSize);
  108. output.WriteRawLittleEndian32(value);
  109. output.Flush();
  110. Assert.AreEqual(data, rawOutput.ToArray());
  111. }
  112. }
  113. /// <summary>
  114. /// Parses the given bytes using WriteRawLittleEndian64() and checks
  115. /// that the result matches the given value.
  116. /// </summary>
  117. private static void AssertWriteLittleEndian64(byte[] data, long value) {
  118. MemoryStream rawOutput = new MemoryStream();
  119. CodedOutputStream output = CodedOutputStream.CreateInstance(rawOutput);
  120. output.WriteRawLittleEndian64(value);
  121. output.Flush();
  122. Assert.AreEqual(data, rawOutput.ToArray());
  123. // Try different block sizes.
  124. for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
  125. rawOutput = new MemoryStream();
  126. output = CodedOutputStream.CreateInstance(rawOutput, blockSize);
  127. output.WriteRawLittleEndian64(value);
  128. output.Flush();
  129. Assert.AreEqual(data, rawOutput.ToArray());
  130. }
  131. }
  132. /// <summary>
  133. /// Tests writeRawLittleEndian32() and writeRawLittleEndian64().
  134. /// </summary>
  135. [Test]
  136. public void WriteLittleEndian() {
  137. AssertWriteLittleEndian32(Bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
  138. AssertWriteLittleEndian32(Bytes(0xf0, 0xde, 0xbc, 0x9a), unchecked((int)0x9abcdef0));
  139. AssertWriteLittleEndian64(
  140. Bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
  141. 0x123456789abcdef0L);
  142. AssertWriteLittleEndian64(
  143. Bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a),
  144. unchecked((long)0x9abcdef012345678L));
  145. }
  146. /* TODO(jonskeet): Put this back when we've got the rest working!
  147. [Test]
  148. public void testWriteWholeMessage() throws Exception {
  149. TestAllTypes message = TestUtil.getAllSet();
  150. byte[] rawBytes = message.toByteArray();
  151. assertEqualBytes(TestUtil.getGoldenMessage().toByteArray(), rawBytes);
  152. // Try different block sizes.
  153. for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
  154. MemoryStream rawOutput = new MemoryStream();
  155. CodedOutputStream output =
  156. CodedOutputStream.newInstance(rawOutput, blockSize);
  157. message.writeTo(output);
  158. output.flush();
  159. assertEqualBytes(rawBytes, rawOutput.toByteArray());
  160. }
  161. } */
  162. [Test]
  163. public void EncodeZigZag32() {
  164. Assert.AreEqual(0, CodedOutputStream.EncodeZigZag32( 0));
  165. Assert.AreEqual(1, CodedOutputStream.EncodeZigZag32(-1));
  166. Assert.AreEqual(2, CodedOutputStream.EncodeZigZag32( 1));
  167. Assert.AreEqual(3, CodedOutputStream.EncodeZigZag32(-2));
  168. Assert.AreEqual(0x7FFFFFFE, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
  169. Assert.AreEqual(0x7FFFFFFF, CodedOutputStream.EncodeZigZag32(unchecked((int)0xC0000000)));
  170. Assert.AreEqual(0xFFFFFFFE, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
  171. Assert.AreEqual(0xFFFFFFFF, CodedOutputStream.EncodeZigZag32(unchecked((int)0x80000000)));
  172. }
  173. [Test]
  174. public void EncodeZigZag64() {
  175. Assert.AreEqual(0, CodedOutputStream.EncodeZigZag64( 0));
  176. Assert.AreEqual(1, CodedOutputStream.EncodeZigZag64(-1));
  177. Assert.AreEqual(2, CodedOutputStream.EncodeZigZag64( 1));
  178. Assert.AreEqual(3, CodedOutputStream.EncodeZigZag64(-2));
  179. Assert.AreEqual(0x000000007FFFFFFEL,
  180. CodedOutputStream.EncodeZigZag64(unchecked((long)0x000000003FFFFFFFUL)));
  181. Assert.AreEqual(0x000000007FFFFFFFL,
  182. CodedOutputStream.EncodeZigZag64(unchecked((long)0xFFFFFFFFC0000000UL)));
  183. Assert.AreEqual(0x00000000FFFFFFFEL,
  184. CodedOutputStream.EncodeZigZag64(unchecked((long)0x000000007FFFFFFFUL)));
  185. Assert.AreEqual(0x00000000FFFFFFFFL,
  186. CodedOutputStream.EncodeZigZag64(unchecked((long)0xFFFFFFFF80000000UL)));
  187. Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
  188. CodedOutputStream.EncodeZigZag64(unchecked((long)0x7FFFFFFFFFFFFFFFUL)));
  189. Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
  190. CodedOutputStream.EncodeZigZag64(unchecked((long)0x8000000000000000UL)));
  191. }
  192. [Test]
  193. public void RoundTripZigZag32() {
  194. // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
  195. // were chosen semi-randomly via keyboard bashing.
  196. Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
  197. Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
  198. Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
  199. Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
  200. Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
  201. }
  202. [Test]
  203. public void RoundTripZigZag64() {
  204. Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
  205. Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
  206. Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
  207. Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
  208. Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
  209. Assert.AreEqual(856912304801416L, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
  210. Assert.AreEqual(-75123905439571256L, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
  211. }
  212. }
  213. }