public void WriteContext_WritesWithFlushes()
        {
            TestAllTypes message = SampleMessages.CreateFullTestAllTypes();

            MemoryStream      expectedOutput = new MemoryStream();
            CodedOutputStream output         = new CodedOutputStream(expectedOutput);

            output.WriteMessage(message);
            output.Flush();
            byte[] expectedBytes1 = expectedOutput.ToArray();

            output.WriteMessage(message);
            output.Flush();
            byte[] expectedBytes2 = expectedOutput.ToArray();

            var bufferWriter = new TestArrayBufferWriter <byte>();

            WriteContext.Initialize(bufferWriter, out WriteContext ctx);
            ctx.WriteMessage(message);
            ctx.Flush();
            Assert.AreEqual(expectedBytes1, bufferWriter.WrittenSpan.ToArray());

            ctx.WriteMessage(message);
            ctx.Flush();
            Assert.AreEqual(expectedBytes2, bufferWriter.WrittenSpan.ToArray());
        }
        /// <summary>
        /// Parses the given bytes using WriteRawLittleEndian64() and checks
        /// that the result matches the given value.
        /// </summary>
        private static void AssertWriteLittleEndian64(byte[] data, ulong value)
        {
            {
                var rawOutput = new MemoryStream();
                var output    = new CodedOutputStream(rawOutput);
                output.WriteRawLittleEndian64(value);
                output.Flush();
                Assert.AreEqual(data, rawOutput.ToArray());

                var bufferWriter = new TestArrayBufferWriter <byte>();
                WriteContext.Initialize(bufferWriter, out WriteContext ctx);
                ctx.WriteFixed64(value);
                ctx.Flush();
                Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
            }

            // Try different block sizes.
            for (int blockSize = 1; blockSize <= 16; blockSize *= 2)
            {
                var rawOutput = new MemoryStream();
                var output    = new CodedOutputStream(rawOutput, blockSize);
                output.WriteRawLittleEndian64(value);
                output.Flush();
                Assert.AreEqual(data, rawOutput.ToArray());

                var bufferWriter = new TestArrayBufferWriter <byte> {
                    MaxGrowBy = blockSize
                };
                WriteContext.Initialize(bufferWriter, out WriteContext ctx);
                ctx.WriteFixed64(value);
                ctx.Flush();
                Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
            }
        }
Example #3
0
        public void LegacyGeneratedCodeThrowsWithIBufferWriter()
        {
            // if serialization started using IBufferWriter and we don't have a CodedOutputStream
            // instance at hand, we cannot fall back to the legacy WriteTo(CodedOutputStream)
            // method and serializatin will fail. As a consequence, one can only use serialization
            // to IBufferWriter if all the messages in the parsing tree have their generated
            // code up to date.
            var message = new ParseContextEnabledMessageB
            {
                A = new LegacyGeneratedCodeMessageA
                {
                    Bb = new ParseContextEnabledMessageB {
                        OptionalInt32 = 12345
                    }
                },
                OptionalInt32 = 6789
            };
            var exception = Assert.Throws <InvalidProtocolBufferException>(() =>
            {
                WriteContext.Initialize(new TestArrayBufferWriter <byte>(), out WriteContext writeCtx);
                ((IBufferMessage)message).InternalWriteTo(ref writeCtx);
            });

            Assert.AreEqual($"Message {typeof(LegacyGeneratedCodeMessageA).Name} doesn't provide the generated method that enables WriteContext-based serialization. You might need to regenerate the generated protobuf code.", exception.Message);
        }
Example #4
0
        public static void WriteTo(this IMessage message, IBufferWriter <byte> output)
        {
            ProtoPreconditions.CheckNotNull(message, nameof(message));
            ProtoPreconditions.CheckNotNull(output, nameof(output));

            WriteContext.Initialize(output, out WriteContext ctx);
            WritingPrimitivesMessages.WriteRawMessage(ref ctx, message);
            ctx.Flush();
        }
Example #5
0
 /// <summary>
 /// Serializes the set and writes it to <paramref name="output"/>.
 /// </summary>
 public void WriteTo(CodedOutputStream output)
 {
     WriteContext.Initialize(output, out WriteContext ctx);
     try
     {
         WriteTo(ref ctx);
     }
     finally
     {
         ctx.CopyStateTo(output);
     }
 }
            public void TestDefaultValue()
            {
                // WriteTagAndValue ignores default values
                var stream = new MemoryStream();
                CodedOutputStream codedOutput;

#if !NET35
                codedOutput = new CodedOutputStream(stream);
                codec.WriteTagAndValue(codedOutput, codec.DefaultValue);
                codedOutput.Flush();
                Assert.AreEqual(0, stream.Position);
                Assert.AreEqual(0, codec.CalculateSizeWithTag(codec.DefaultValue));
                if (typeof(T).GetTypeInfo().IsValueType)
                {
                    Assert.AreEqual(default(T), codec.DefaultValue);
                }
#endif

                // The plain ValueWriter/ValueReader delegates don't.
                if (codec.DefaultValue != null) // This part isn't appropriate for message types.
                {
                    codedOutput = new CodedOutputStream(stream);
                    WriteContext.Initialize(codedOutput, out WriteContext ctx);
                    try
                    {
                        // only write the value using the codec
                        codec.ValueWriter(ref ctx, codec.DefaultValue);
                    }
                    finally
                    {
                        ctx.CopyStateTo(codedOutput);
                    }

                    codedOutput.Flush();
                    Assert.AreNotEqual(0, stream.Position);
                    Assert.AreEqual(stream.Position, codec.ValueSizeCalculator(codec.DefaultValue));
                    stream.Position = 0;
                    var codedInput = new CodedInputStream(stream);
                    Assert.AreEqual(codec.DefaultValue, codec.Read(codedInput));
                }
            }
            public void TestRoundTripRaw()
            {
                var stream      = new MemoryStream();
                var codedOutput = new CodedOutputStream(stream);

                WriteContext.Initialize(codedOutput, out WriteContext ctx);
                try
                {
                    // only write the value using the codec
                    codec.ValueWriter(ref ctx, sampleValue);
                }
                finally
                {
                    ctx.CopyStateTo(codedOutput);
                }
                codedOutput.Flush();
                stream.Position = 0;
                var codedInput = new CodedInputStream(stream);

                Assert.AreEqual(sampleValue, codec.Read(codedInput));
                Assert.IsTrue(codedInput.IsAtEnd);
            }
        /// <summary>
        /// Writes the given value using WriteRawVarint32() and WriteRawVarint64() and
        /// checks that the result matches the given bytes
        /// </summary>
        private static void AssertWriteVarint(byte[] data, ulong value)
        {
            // Only do 32-bit write if the value fits in 32 bits.
            if ((value >> 32) == 0)
            {
                // CodedOutputStream
                MemoryStream      rawOutput = new MemoryStream();
                CodedOutputStream output    = new CodedOutputStream(rawOutput);
                output.WriteRawVarint32((uint)value);
                output.Flush();
                Assert.AreEqual(data, rawOutput.ToArray());

                // IBufferWriter
                var bufferWriter = new TestArrayBufferWriter <byte>();
                WriteContext.Initialize(bufferWriter, out WriteContext ctx);
                ctx.WriteUInt32((uint)value);
                ctx.Flush();
                Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());

                // Also try computing size.
                Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint)value));
            }

            {
                // CodedOutputStream
                MemoryStream      rawOutput = new MemoryStream();
                CodedOutputStream output    = new CodedOutputStream(rawOutput);
                output.WriteRawVarint64(value);
                output.Flush();
                Assert.AreEqual(data, rawOutput.ToArray());

                // IBufferWriter
                var bufferWriter = new TestArrayBufferWriter <byte>();
                WriteContext.Initialize(bufferWriter, out WriteContext ctx);
                ctx.WriteUInt64(value);
                ctx.Flush();
                Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());

                // Also try computing size.
                Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value));
            }

            // Try different buffer sizes.
            for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2)
            {
                // Only do 32-bit write if the value fits in 32 bits.
                if ((value >> 32) == 0)
                {
                    MemoryStream      rawOutput = new MemoryStream();
                    CodedOutputStream output    = new CodedOutputStream(rawOutput, bufferSize);
                    output.WriteRawVarint32((uint)value);
                    output.Flush();
                    Assert.AreEqual(data, rawOutput.ToArray());

                    var bufferWriter = new TestArrayBufferWriter <byte> {
                        MaxGrowBy = bufferSize
                    };
                    WriteContext.Initialize(bufferWriter, out WriteContext ctx);
                    ctx.WriteUInt32((uint)value);
                    ctx.Flush();
                    Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
                }

                {
                    MemoryStream      rawOutput = new MemoryStream();
                    CodedOutputStream output    = new CodedOutputStream(rawOutput, bufferSize);
                    output.WriteRawVarint64(value);
                    output.Flush();
                    Assert.AreEqual(data, rawOutput.ToArray());

                    var bufferWriter = new TestArrayBufferWriter <byte> {
                        MaxGrowBy = bufferSize
                    };
                    WriteContext.Initialize(bufferWriter, out WriteContext ctx);
                    ctx.WriteUInt64(value);
                    ctx.Flush();
                    Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray());
                }
            }
        }