public void MapWithOnlyValue()
        {
            // Hand-craft the stream to contain a single entry with just a value.
            var memoryStream = new MemoryStream();
            var output       = new CodedOutputStream(memoryStream);

            output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
            var nestedMessage = new ForeignMessage {
                C = 20
            };

            // Size of the entry (tag, size written by WriteMessage, data written by WriteMessage)
            output.WriteLength(2 + nestedMessage.CalculateSize());
            output.WriteTag(2, WireFormat.WireType.LengthDelimited);
            output.WriteMessage(nestedMessage);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
            {
                Assert.AreEqual(nestedMessage, parsed.MapInt32ForeignMessage[0]);
            });
        }
        public void MapIgnoresExtraFieldsWithinEntryMessages()
        {
            // Hand-craft the stream to contain a single entry with three fields
            var memoryStream = new MemoryStream();
            var output       = new CodedOutputStream(memoryStream);

            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);

            var key   = 10; // Field 1
            var value = 20; // Field 2
            var extra = 30; // Field 3

            // Each field can be represented in a single byte, with a single byte tag.
            // Total message size: 6 bytes.
            output.WriteLength(6);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value);
            output.WriteTag(3, WireFormat.WireType.Varint);
            output.WriteInt32(extra);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
            {
                Assert.AreEqual(value, parsed.MapInt32Int32[key]);
            });
        }
Example #3
0
        public void RoundTrip_ExtensionGroups()
        {
            var message = new TestAllExtensions();

            message.SetExtension(UnittestExtensions.OptionalGroupExtension, new OptionalGroup_extension {
                A = 10
            });
            message.GetOrInitializeExtension(UnittestExtensions.RepeatedGroupExtension).AddRange(new[]
            {
                new RepeatedGroup_extension {
                    A = 10
                },
                new RepeatedGroup_extension {
                    A = 20
                },
                new RepeatedGroup_extension {
                    A = 30
                }
            });

            MessageParsingHelpers.AssertRoundtrip(
                TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry()
            {
                UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension
            }),
                message);
        }
        public void RoundTrip_Groups()
        {
            var message = new TestAllTypes
            {
                OptionalGroup = new TestAllTypes.Types.OptionalGroup
                {
                    A = 10
                },
                RepeatedGroup =
                {
                    new TestAllTypes.Types.RepeatedGroup {
                        A = 10
                    },
                    new TestAllTypes.Types.RepeatedGroup {
                        A = 20
                    },
                    new TestAllTypes.Types.RepeatedGroup {
                        A = 30
                    }
                }
            };

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertRoundtrip(Proto2.TestAllTypes.Parser, message);
        }
        public void MapFieldOrderIsIrrelevant()
        {
            var memoryStream = new MemoryStream();
            var output       = new CodedOutputStream(memoryStream);

            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);

            var key   = 10;
            var value = 20;

            // Each field can be represented in a single byte, with a single byte tag.
            // Total message size: 4 bytes.
            output.WriteLength(4);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
            {
                Assert.AreEqual(value, parsed.MapInt32Int32[key]);
            });
        }
        public void DuplicateKeys_LastEntryWins()
        {
            var memoryStream = new MemoryStream();
            var output       = new CodedOutputStream(memoryStream);

            var key    = 10;
            var value1 = 20;
            var value2 = 30;

            // First entry
            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteLength(4);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value1);

            // Second entry - same key, different value
            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteLength(4);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value2);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
            {
                Assert.AreEqual(value2, parsed.MapInt32Int32[key]);
            });
        }
        public void RoundTrip_Maps()
        {
            var message = new TestMap
            {
                MapBoolBool =
                {
                    { false, true  },
                    { true,  false }
                },
                MapInt32Bytes =
                {
                    {  5, ByteString.CopyFrom(6, 7, 8) },
                    { 25, ByteString.CopyFrom(1, 2,3, 4, 5) },
                    { 10, ByteString.Empty }
                },
                MapInt32ForeignMessage =
                {
                    { 0, new ForeignMessage {
                          C = 10
                      } },
                    { 5, new ForeignMessage() },
                },
                MapInt32Enum =
                {
                    {    1, MapEnum.Bar },
                    { 2000, MapEnum.Foo }
                }
            };

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertRoundtrip(TestMap.Parser, message);
        }
        public void TruncatedMessageFieldThrows()
        {
            // 130, 3 is the message tag
            // 1 is the data length - but there's no data.
            var data = new byte[] { 130, 3, 1 };

            MessageParsingHelpers.AssertReadingMessageThrows <TestAllTypes, InvalidProtocolBufferException>(TestAllTypes.Parser, data);
        }
        public void MapNonContiguousEntries()
        {
            var memoryStream = new MemoryStream();
            var output       = new CodedOutputStream(memoryStream);

            // Message structure:
            // Entry for MapInt32Int32
            // Entry for MapStringString
            // Entry for MapInt32Int32

            // First entry
            var key1   = 10;
            var value1 = 20;

            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteLength(4);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key1);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value1);

            // Second entry
            var key2   = "a";
            var value2 = "b";

            output.WriteTag(TestMap.MapStringStringFieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteLength(6); // 3 bytes per entry: tag, size, character
            output.WriteTag(1, WireFormat.WireType.LengthDelimited);
            output.WriteString(key2);
            output.WriteTag(2, WireFormat.WireType.LengthDelimited);
            output.WriteString(value2);

            // Third entry
            var key3   = 15;
            var value3 = 25;

            output.WriteTag(TestMap.MapInt32Int32FieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteLength(4);
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key3);
            output.WriteTag(2, WireFormat.WireType.Varint);
            output.WriteInt32(value3);

            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
            {
                var expected = new TestMap
                {
                    MapInt32Int32   = { { key1, value1 }, { key3, value3 } },
                    MapStringString = { { key2, value2 } }
                };
                Assert.AreEqual(expected, parsed);
            });
        }
        public void RoundTrip_Empty()
        {
            var message = new TestAllTypes();

            // Without setting any values, there's nothing to write.
            byte[] bytes = message.ToByteArray();
            Assert.AreEqual(0, bytes.Length);

            MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message);
        }
        public void ExtraEndGroupThrows()
        {
            var stream = new MemoryStream();
            var output = new CodedOutputStream(stream);

            output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32);
            output.WriteFixed32(123);
            output.WriteTag(100, WireFormat.WireType.EndGroup);

            output.Flush();

            stream.Position = 0;
            MessageParsingHelpers.AssertReadingMessageThrows <TestAllTypes, InvalidProtocolBufferException>(TestAllTypes.Parser, stream.ToArray());
        }
        public void DiscardUnknownFields_AllTypes()
        {
            // Simple way of ensuring we can skip all kinds of fields.
            var data  = SampleMessages.CreateFullTestAllTypes().ToByteArray();
            var empty = Empty.Parser.ParseFrom(data);

            MessageParsingHelpers.AssertReadingMessage(
                Empty.Parser,
                data,
                parsed =>
            {
                // TODO(jieluo): Add test back when DiscardUnknownFields API is supported.
                // Assert.AreNotEqual(new Empty(), empty);
            });
        }
        public void OneofSerialization_NonDefaultValue()
        {
            var message = new TestAllTypes();

            message.OneofString = "this would take a bit of space";
            message.OneofUint32 = 10;
            var bytes = message.ToByteArray();

            Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string!

            MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message, parsedMessage =>
            {
                Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, parsedMessage.OneofFieldCase);
            });
        }
        public void OneofSerialization_DefaultValue()
        {
            var message = new TestAllTypes();

            message.OneofString = "this would take a bit of space";
            message.OneofUint32 = 0; // This is the default value for UInt32; normally wouldn't be serialized
            var bytes = message.ToByteArray();

            Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - it's still serialized

            MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message, parsedMessage =>
            {
                Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, parsedMessage.OneofFieldCase);
            });
        }
Example #15
0
        public void RoundTrip_NestedExtensionGroup()
        {
            var message = new TestGroupExtension();

            message.SetExtension(TestNestedExtension.Extensions.OptionalGroupExtension, new TestNestedExtension.Types.OptionalGroup_extension {
                A = 10
            });

            MessageParsingHelpers.AssertRoundtrip(
                TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry()
            {
                TestNestedExtension.Extensions.OptionalGroupExtension
            }),
                message);
        }
        public void RoundTrip_RepeatedValues()
        {
            var message = new TestAllTypes
            {
                RepeatedBool           = { true, false },
                RepeatedBytes          = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6) },
                RepeatedDouble         = { -12.25, 23.5 },
                RepeatedFixed32        = { uint.MaxValue, 23 },
                RepeatedFixed64        = { ulong.MaxValue, 1234567890123 },
                RepeatedFloat          = { 100f, 12.25f },
                RepeatedForeignEnum    = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
                RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage {
                                               C = 10
                                           } },
                RepeatedImportEnum    = { ImportEnum.ImportBaz, ImportEnum.Unspecified },
                RepeatedImportMessage = { new ImportMessage {
                                              D = 20
                                          }, new ImportMessage{
                                              D = 25
                                          } },
                RepeatedInt32         = { 100, 200 },
                RepeatedInt64         = { 3210987654321, long.MaxValue },
                RepeatedNestedEnum    = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
                RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage {
                                              Bb = 35
                                          }, new TestAllTypes.Types.NestedMessage{
                                              Bb = 10
                                          } },
                RepeatedPublicImportMessage = { new PublicImportMessage {
                                                    E = 54
                                                }, new PublicImportMessage{
                                                    E = -1
                                                } },
                RepeatedSfixed32 = { -123, 123 },
                RepeatedSfixed64 = { -12345678901234, 12345678901234 },
                RepeatedSint32   = { -456, 100 },
                RepeatedSint64   = { -12345678901235, 123 },
                RepeatedString   = { "foo", "bar" },
                RepeatedUint32   = { uint.MaxValue, uint.MinValue },
                RepeatedUint64   = { ulong.MaxValue, uint.MinValue }
            };

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message);
        }
        public void TestDiscardUnknownFields(IMessage message)
        {
            var goldenEmptyMessage = new TestEmptyMessage();

            byte[] data     = message.ToByteArray();
            int    fullSize = message.CalculateSize();

            void AssertEmpty(IMessage msg)
            {
                Assert.AreEqual(0, msg.CalculateSize());
                Assert.AreEqual(goldenEmptyMessage, msg);
            }

            void AssertFull(IMessage msg) => Assert.AreEqual(fullSize, msg.CalculateSize());

            // Test the behavior of the parsers with and without discarding, both generic and non-generic.
            MessageParser <TestEmptyMessage> retainingParser1 = TestEmptyMessage.Parser;
            MessageParser retainingParser2 = retainingParser1;
            MessageParser <TestEmptyMessage> discardingParser1 = retainingParser1.WithDiscardUnknownFields(true);
            MessageParser discardingParser2 = retainingParser2.WithDiscardUnknownFields(true);

            // Test parse from byte[]
            MessageParsingHelpers.AssertReadingMessage(retainingParser1, data, m => AssertFull(m));
            MessageParsingHelpers.AssertReadingMessage(retainingParser2, data, m => AssertFull(m));
            MessageParsingHelpers.AssertReadingMessage(discardingParser1, data, m => AssertEmpty(m));
            MessageParsingHelpers.AssertReadingMessage(discardingParser2, data, m => AssertEmpty(m));

            // Test parse from byte[] with offset
            AssertFull(retainingParser1.ParseFrom(data, 0, data.Length));
            AssertFull(retainingParser2.ParseFrom(data, 0, data.Length));
            AssertEmpty(discardingParser1.ParseFrom(data, 0, data.Length));
            AssertEmpty(discardingParser2.ParseFrom(data, 0, data.Length));

            // Test parse from CodedInputStream
            AssertFull(retainingParser1.ParseFrom(new CodedInputStream(data)));
            AssertFull(retainingParser2.ParseFrom(new CodedInputStream(data)));
            AssertEmpty(discardingParser1.ParseFrom(new CodedInputStream(data)));
            AssertEmpty(discardingParser2.ParseFrom(new CodedInputStream(data)));

            // Test parse from Stream
            AssertFull(retainingParser1.ParseFrom(new MemoryStream(data)));
            AssertFull(retainingParser2.ParseFrom(new MemoryStream(data)));
            AssertEmpty(discardingParser1.ParseFrom(new MemoryStream(data)));
            AssertEmpty(discardingParser2.ParseFrom(new MemoryStream(data)));
        }
Example #18
0
        public void TestMergeCodedInput()
        {
            var message = new TestAllExtensions();

            message.SetExtension(OptionalBoolExtension, true);
            var serialized = message.ToByteArray();

            MessageParsingHelpers.AssertReadingMessage(
                TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry()
            {
                OptionalBoolExtension
            }),
                serialized,
                other =>
            {
                Assert.AreEqual(message, other);
                Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
            });
        }
        public void MapWithEmptyEntry()
        {
            var message = new TestMap
            {
                MapInt32Bytes = { { 0, ByteString.Empty } }
            };

            byte[] bytes = message.ToByteArray();
            Assert.AreEqual(2, bytes.Length); // Tag for field entry (1 byte), length of entry (0; 1 byte)

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                bytes,
                parsed =>
            {
                Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
                Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
            });
        }
        public void RoundTrip_SingleValues()
        {
            var message = new TestAllTypes
            {
                SingleBool           = true,
                SingleBytes          = ByteString.CopyFrom(1, 2, 3, 4),
                SingleDouble         = 23.5,
                SingleFixed32        = 23,
                SingleFixed64        = 1234567890123,
                SingleFloat          = 12.25f,
                SingleForeignEnum    = ForeignEnum.ForeignBar,
                SingleForeignMessage = new ForeignMessage {
                    C = 10
                },
                SingleImportEnum    = ImportEnum.ImportBaz,
                SingleImportMessage = new ImportMessage {
                    D = 20
                },
                SingleInt32         = 100,
                SingleInt64         = 3210987654321,
                SingleNestedEnum    = TestAllTypes.Types.NestedEnum.Foo,
                SingleNestedMessage = new TestAllTypes.Types.NestedMessage {
                    Bb = 35
                },
                SinglePublicImportMessage = new PublicImportMessage {
                    E = 54
                },
                SingleSfixed32 = -123,
                SingleSfixed64 = -12345678901234,
                SingleSint32   = -456,
                SingleSint64   = -12345678901235,
                SingleString   = "test",
                SingleUint32   = uint.MaxValue,
                SingleUint64   = ulong.MaxValue
            };

            MessageParsingHelpers.AssertWritingMessage(message);

            MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message);
        }
        public void DiscardUnknownFields_RealDataStillRead()
        {
            var message           = SampleMessages.CreateFullTestAllTypes();
            var stream            = new MemoryStream();
            var output            = new CodedOutputStream(stream);
            var unusedFieldNumber = 23456;

            Assert.IsFalse(TestAllTypes.Descriptor.Fields.InDeclarationOrder().Select(x => x.FieldNumber).Contains(unusedFieldNumber));
            output.WriteTag(unusedFieldNumber, WireFormat.WireType.LengthDelimited);
            output.WriteString("ignore me");
            message.WriteTo(output);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestAllTypes.Parser,
                stream.ToArray(),
                parsed =>
            {
                // TODO(jieluo): Add test back when DiscardUnknownFields API is supported.
                // Assert.AreEqual(message, parsed);
            });
        }
        public void MapWithOnlyKey_MessageValue()
        {
            // Hand-craft the stream to contain a single entry with just a key.
            var memoryStream = new MemoryStream();
            var output       = new CodedOutputStream(memoryStream);

            output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
            int key = 10;

            output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
            output.WriteTag(1, WireFormat.WireType.Varint);
            output.WriteInt32(key);
            output.Flush();

            MessageParsingHelpers.AssertReadingMessage(
                TestMap.Parser,
                memoryStream.ToArray(),
                parsed =>
            {
                Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]);
            });
        }
Example #23
0
 public void RequiredFieldsNoThrow()
 {
     Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser, new byte[0], m => { }));
     Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser as MessageParser, new byte[0], m => { }));
 }