From fe147994c83a4b50dd26c17036e3409d20f19322 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 28 May 2020 14:41:42 +0200 Subject: [PATCH] progress: stuff almost builds now --- .../src/Google.Protobuf/WriteBufferHelper.cs | 4 +- ...nternalState.cs => WriterInternalState.cs} | 2 +- ...dingPrimitives.cs => WritingPrimitives.cs} | 94 +++++++------------ .../WritingPrimitivesMessages.cs | 67 +++++++++++++ 4 files changed, 104 insertions(+), 63 deletions(-) rename csharp/src/Google.Protobuf/{EncoderInternalState.cs => WriterInternalState.cs} (98%) rename csharp/src/Google.Protobuf/{EncodingPrimitives.cs => WritingPrimitives.cs} (88%) create mode 100644 csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs diff --git a/csharp/src/Google.Protobuf/WriteBufferHelper.cs b/csharp/src/Google.Protobuf/WriteBufferHelper.cs index a13681b0e7..65da9612ca 100644 --- a/csharp/src/Google.Protobuf/WriteBufferHelper.cs +++ b/csharp/src/Google.Protobuf/WriteBufferHelper.cs @@ -72,7 +72,7 @@ namespace Google.Protobuf buffer = default; // TODO: initialize the initial buffer so that the first write is not via slowpath. } - public void RefreshBuffer(ref Span buffer, ref EncoderInternalState state) + public void RefreshBuffer(ref Span buffer, ref WriterInternalState state) { if (codedOutputStream?.InternalOutputStream != null) { @@ -94,7 +94,7 @@ namespace Google.Protobuf } } - public void Flush(ref Span buffer, ref EncoderInternalState state) + public void Flush(ref Span buffer, ref WriterInternalState state) { if (codedOutputStream?.InternalOutputStream != null) { diff --git a/csharp/src/Google.Protobuf/EncoderInternalState.cs b/csharp/src/Google.Protobuf/WriterInternalState.cs similarity index 98% rename from csharp/src/Google.Protobuf/EncoderInternalState.cs rename to csharp/src/Google.Protobuf/WriterInternalState.cs index 37dea8b889..521c891ffb 100644 --- a/csharp/src/Google.Protobuf/EncoderInternalState.cs +++ b/csharp/src/Google.Protobuf/WriterInternalState.cs @@ -45,7 +45,7 @@ namespace Google.Protobuf { // warning: this is a mutable struct, so it needs to be only passed as a ref! - internal struct EncoderInternalState + internal struct WriterInternalState { // NOTE: the Span representing the current buffer is kept separate so that this doesn't have to be a ref struct and so it can // be included in CodedOutputStream's internal state diff --git a/csharp/src/Google.Protobuf/EncodingPrimitives.cs b/csharp/src/Google.Protobuf/WritingPrimitives.cs similarity index 88% rename from csharp/src/Google.Protobuf/EncodingPrimitives.cs rename to csharp/src/Google.Protobuf/WritingPrimitives.cs index 254db64c77..ec4237aa4b 100644 --- a/csharp/src/Google.Protobuf/EncodingPrimitives.cs +++ b/csharp/src/Google.Protobuf/WritingPrimitives.cs @@ -31,15 +31,9 @@ #endregion using System; -using System.Buffers; -using System.Buffers.Binary; -using System.Collections.Generic; -using System.IO; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Security; using System.Text; -using Google.Protobuf.Collections; namespace Google.Protobuf { @@ -47,7 +41,7 @@ namespace Google.Protobuf /// Primitives for encoding protobuf wire format. /// [SecuritySafeCritical] - internal static class EncodingPrimitives + internal static class WritingPrimitives { // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.) internal static readonly Encoding Utf8Encoding = Encoding.UTF8; @@ -60,7 +54,7 @@ namespace Google.Protobuf /// Writes a double field value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteDouble(ref Span buffer, ref EncoderInternalState state, double value) + public static void WriteDouble(ref Span buffer, ref WriterInternalState state, double value) { WriteRawLittleEndian64(ref buffer, ref state, (ulong)BitConverter.DoubleToInt64Bits(value)); } @@ -69,7 +63,7 @@ namespace Google.Protobuf /// Writes a float field value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteFloat(ref Span buffer, ref EncoderInternalState state, float value) + public static void WriteFloat(ref Span buffer, ref WriterInternalState state, float value) { byte[] rawBytes = BitConverter.GetBytes(value); if (!BitConverter.IsLittleEndian) @@ -94,7 +88,7 @@ namespace Google.Protobuf /// Writes a uint64 field value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteUInt64(ref Span buffer, ref EncoderInternalState state, ulong value) + public static void WriteUInt64(ref Span buffer, ref WriterInternalState state, ulong value) { WriteRawVarint64(ref buffer, ref state, value); } @@ -103,7 +97,7 @@ namespace Google.Protobuf /// Writes an int64 field value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteInt64(ref Span buffer, ref EncoderInternalState state, long value) + public static void WriteInt64(ref Span buffer, ref WriterInternalState state, long value) { WriteRawVarint64(ref buffer, ref state, (ulong)value); } @@ -112,7 +106,7 @@ namespace Google.Protobuf /// Writes an int32 field value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteInt32(ref Span buffer, ref EncoderInternalState state, int value) + public static void WriteInt32(ref Span buffer, ref WriterInternalState state, int value) { if (value >= 0) { @@ -129,7 +123,7 @@ namespace Google.Protobuf /// Writes a fixed64 field value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteFixed64(ref Span buffer, ref EncoderInternalState state, ulong value) + public static void WriteFixed64(ref Span buffer, ref WriterInternalState state, ulong value) { WriteRawLittleEndian64(ref buffer, ref state, value); } @@ -138,7 +132,7 @@ namespace Google.Protobuf /// Writes a fixed32 field value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteFixed32(ref Span buffer, ref EncoderInternalState state, uint value) + public static void WriteFixed32(ref Span buffer, ref WriterInternalState state, uint value) { WriteRawLittleEndian32(ref buffer, ref state, value); } @@ -147,7 +141,7 @@ namespace Google.Protobuf /// Writes a bool field value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteBool(ref Span buffer, ref EncoderInternalState state, bool value) + public static void WriteBool(ref Span buffer, ref WriterInternalState state, bool value) { WriteRawByte(ref buffer, ref state, value ? (byte)1 : (byte)0); } @@ -157,7 +151,7 @@ namespace Google.Protobuf /// The data is length-prefixed. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteString(ref Span buffer, ref EncoderInternalState state, string value) + public static void WriteString(ref Span buffer, ref WriterInternalState state, string value) { // Optimise the case where we have enough space to write // the string directly to the buffer, which should be common. @@ -190,32 +184,12 @@ namespace Google.Protobuf } } - /// - /// Writes a message, without a tag, to the stream. - /// The data is length-prefixed. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteMessage(ref Span buffer, ref EncoderInternalState state, IMessage value) - { - WriteLength(ref buffer, ref state, value.CalculateSize()); - value.WriteTo(this); - } - - /// - /// Writes a group, without a tag, to the stream. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteGroup(ref Span buffer, ref EncoderInternalState state, IMessage value) - { - value.WriteTo(this); - } - /// /// Write a byte string, without a tag, to the stream. /// The data is length-prefixed. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteBytes(ref Span buffer, ref EncoderInternalState state, ByteString value) + public static void WriteBytes(ref Span buffer, ref WriterInternalState state, ByteString value) { WriteLength(ref buffer, ref state, value.Length); WriteRawBytes(ref buffer, ref state, value.Span); @@ -225,7 +199,7 @@ namespace Google.Protobuf /// Writes a uint32 value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteUInt32(ref Span buffer, ref EncoderInternalState state, uint value) + public static void WriteUInt32(ref Span buffer, ref WriterInternalState state, uint value) { WriteRawVarint32(ref buffer, ref state, value); } @@ -234,7 +208,7 @@ namespace Google.Protobuf /// Writes an enum value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteEnum(ref Span buffer, ref EncoderInternalState state, int value) + public static void WriteEnum(ref Span buffer, ref WriterInternalState state, int value) { WriteInt32(ref buffer, ref state, value); } @@ -243,7 +217,7 @@ namespace Google.Protobuf /// Writes an sfixed32 value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteSFixed32(ref Span buffer, ref EncoderInternalState state, int value) + public static void WriteSFixed32(ref Span buffer, ref WriterInternalState state, int value) { WriteRawLittleEndian32(ref buffer, ref state, (uint)value); } @@ -252,7 +226,7 @@ namespace Google.Protobuf /// Writes an sfixed64 value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteSFixed64(ref Span buffer, ref EncoderInternalState state, long value) + public static void WriteSFixed64(ref Span buffer, ref WriterInternalState state, long value) { WriteRawLittleEndian64(ref buffer, ref state, (ulong)value); } @@ -261,7 +235,7 @@ namespace Google.Protobuf /// Writes an sint32 value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteSInt32(ref Span buffer, ref EncoderInternalState state, int value) + public static void WriteSInt32(ref Span buffer, ref WriterInternalState state, int value) { WriteRawVarint32(ref buffer, ref state, EncodeZigZag32(value)); } @@ -270,7 +244,7 @@ namespace Google.Protobuf /// Writes an sint64 value, without a tag, to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteSInt64(ref Span buffer, ref EncoderInternalState state, long value) + public static void WriteSInt64(ref Span buffer, ref WriterInternalState state, long value) { WriteRawVarint64(ref buffer, ref state, EncodeZigZag64(value)); } @@ -283,7 +257,7 @@ namespace Google.Protobuf /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteLength(ref Span buffer, ref EncoderInternalState state, int length) + public static void WriteLength(ref Span buffer, ref WriterInternalState state, int length) { WriteRawVarint32(ref buffer, ref state, (uint)length); } @@ -297,7 +271,7 @@ namespace Google.Protobuf /// for each byte; otherwise, we resort to calling WriteRawByte each time. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawVarint32(ref Span buffer, ref EncoderInternalState state, uint value) + public static void WriteRawVarint32(ref Span buffer, ref WriterInternalState state, uint value) { // Optimize for the common case of a single byte value if (value < 128 && state.position < state.limit) @@ -327,7 +301,7 @@ namespace Google.Protobuf } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawVarint64(ref Span buffer, ref EncoderInternalState state, ulong value) + public static void WriteRawVarint64(ref Span buffer, ref WriterInternalState state, ulong value) { while (value > 127 && state.position < state.limit) { @@ -350,7 +324,7 @@ namespace Google.Protobuf } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawLittleEndian32(ref Span buffer, ref EncoderInternalState state, uint value) + public static void WriteRawLittleEndian32(ref Span buffer, ref WriterInternalState state, uint value) { if (state.position + 4 > state.limit) { @@ -369,7 +343,7 @@ namespace Google.Protobuf } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawLittleEndian64(ref Span buffer, ref EncoderInternalState state, ulong value) + public static void WriteRawLittleEndian64(ref Span buffer, ref WriterInternalState state, ulong value) { if (state.position + 8 > state.limit) { @@ -396,7 +370,7 @@ namespace Google.Protobuf } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawByte(ref Span buffer, ref EncoderInternalState state, byte value) + public static void WriteRawByte(ref Span buffer, ref WriterInternalState state, byte value) { if (state.position == state.limit) { @@ -407,7 +381,7 @@ namespace Google.Protobuf } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawByte(ref Span buffer, ref EncoderInternalState state, uint value) + public static void WriteRawByte(ref Span buffer, ref WriterInternalState state, uint value) { WriteRawByte(ref buffer, ref state, (byte)value); } @@ -416,7 +390,7 @@ namespace Google.Protobuf /// Writes out an array of bytes. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawBytes(ref Span buffer, ref EncoderInternalState state, byte[] value) + public static void WriteRawBytes(ref Span buffer, ref WriterInternalState state, byte[] value) { WriteRawBytes(ref buffer, ref state, new ReadOnlySpan(value)); } @@ -425,7 +399,7 @@ namespace Google.Protobuf /// Writes out part of an array of bytes. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawBytes(ref Span buffer, ref EncoderInternalState state, byte[] value, int offset, int length) + public static void WriteRawBytes(ref Span buffer, ref WriterInternalState state, byte[] value, int offset, int length) { WriteRawBytes(ref buffer, ref state, new ReadOnlySpan(value, offset, length)); } @@ -434,7 +408,7 @@ namespace Google.Protobuf /// Writes out part of an array of bytes. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawBytes(ref Span buffer, ref EncoderInternalState state, ReadOnlySpan value) + public static void WriteRawBytes(ref Span buffer, ref WriterInternalState state, ReadOnlySpan value) { if (state.limit - state.position >= value.Length) { @@ -469,7 +443,7 @@ namespace Google.Protobuf /// Encodes and writes a tag. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteTag(ref Span buffer, ref EncoderInternalState state, int fieldNumber, WireFormat.WireType type) + public static void WriteTag(ref Span buffer, ref WriterInternalState state, int fieldNumber, WireFormat.WireType type) { WriteRawVarint32(ref buffer, ref state, WireFormat.MakeTag(fieldNumber, type)); } @@ -478,7 +452,7 @@ namespace Google.Protobuf /// Writes an already-encoded tag. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteTag(ref Span buffer, ref EncoderInternalState state, uint tag) + public static void WriteTag(ref Span buffer, ref WriterInternalState state, uint tag) { WriteRawVarint32(ref buffer, ref state, tag); } @@ -487,7 +461,7 @@ namespace Google.Protobuf /// Writes the given single-byte tag directly to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawTag(ref Span buffer, ref EncoderInternalState state, byte b1) + public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1) { WriteRawByte(ref buffer, ref state, b1); } @@ -496,7 +470,7 @@ namespace Google.Protobuf /// Writes the given two-byte tag directly to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawTag(ref Span buffer, ref EncoderInternalState state, byte b1, byte b2) + public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); @@ -506,7 +480,7 @@ namespace Google.Protobuf /// Writes the given three-byte tag directly to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawTag(ref Span buffer, ref EncoderInternalState state, byte b1, byte b2, byte b3) + public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); @@ -517,7 +491,7 @@ namespace Google.Protobuf /// Writes the given four-byte tag directly to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawTag(ref Span buffer, ref EncoderInternalState state, byte b1, byte b2, byte b3, byte b4) + public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); @@ -529,7 +503,7 @@ namespace Google.Protobuf /// Writes the given five-byte tag directly to the stream. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteRawTag(ref Span buffer, ref EncoderInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5) + public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); diff --git a/csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs b/csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs new file mode 100644 index 0000000000..c75829c6f7 --- /dev/null +++ b/csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs @@ -0,0 +1,67 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion + +using System; +using System.Runtime.CompilerServices; +using System.Security; + +namespace Google.Protobuf +{ + /// + /// Writing messages / groups. + /// + [SecuritySafeCritical] + internal static class WritingPrimitivesMessages + { + /// + /// Writes a message, without a tag, to the stream. + /// The data is length-prefixed. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteMessage(ref Span buffer, ref WriterInternalState state, IMessage value) + { + WritingPrimitives.WriteLength(ref buffer, ref state, value.CalculateSize()); + // TODO: + //value.WriteTo(this); + } + + /// + /// Writes a group, without a tag, to the stream. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteGroup(ref Span buffer, ref WriterInternalState state, IMessage value) + { + // TODO: + //value.WriteTo(this); + } + } +} \ No newline at end of file