|  | @@ -67,8 +67,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          private readonly bool leaveOpen;
 | 
	
		
			
				|  |  |          private readonly byte[] buffer;
 | 
	
		
			
				|  |  | -        private readonly int limit;
 | 
	
		
			
				|  |  | -        private int position;
 | 
	
		
			
				|  |  | +        private WriterInternalState state;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          private readonly Stream output;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          #region Construction
 | 
	
	
		
			
				|  | @@ -90,8 +90,9 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              this.output = null;
 | 
	
		
			
				|  |  |              this.buffer = ProtoPreconditions.CheckNotNull(buffer, nameof(buffer));
 | 
	
		
			
				|  |  | -            this.position = offset;
 | 
	
		
			
				|  |  | -            this.limit = offset + length;
 | 
	
		
			
				|  |  | +            this.state.position = offset;
 | 
	
		
			
				|  |  | +            this.state.limit = offset + length;
 | 
	
		
			
				|  |  | +            WriteBufferHelper.Initialize(this, out this.state.writeBufferHelper);
 | 
	
		
			
				|  |  |              leaveOpen = true; // Simple way of avoiding trying to dispose of a null reference
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -99,8 +100,9 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              this.output = ProtoPreconditions.CheckNotNull(output, nameof(output));
 | 
	
		
			
				|  |  |              this.buffer = buffer;
 | 
	
		
			
				|  |  | -            this.position = 0;
 | 
	
		
			
				|  |  | -            this.limit = buffer.Length;
 | 
	
		
			
				|  |  | +            this.state.position = 0;
 | 
	
		
			
				|  |  | +            this.state.limit = buffer.Length;
 | 
	
		
			
				|  |  | +            WriteBufferHelper.Initialize(this, out this.state.writeBufferHelper);
 | 
	
		
			
				|  |  |              this.leaveOpen = leaveOpen;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -155,9 +157,9 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  if (output != null)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  | -                    return output.Position + position;
 | 
	
		
			
				|  |  | +                    return output.Position + state.position;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                return position;
 | 
	
		
			
				|  |  | +                return state.position;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -169,7 +171,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteDouble(double value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawLittleEndian64((ulong)BitConverter.DoubleToInt64Bits(value));
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteDouble(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -178,23 +181,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteFloat(float value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            byte[] rawBytes = BitConverter.GetBytes(value);
 | 
	
		
			
				|  |  | -            if (!BitConverter.IsLittleEndian)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                ByteArray.Reverse(rawBytes);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            if (limit - position >= 4)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                buffer[position++] = rawBytes[0];
 | 
	
		
			
				|  |  | -                buffer[position++] = rawBytes[1];
 | 
	
		
			
				|  |  | -                buffer[position++] = rawBytes[2];
 | 
	
		
			
				|  |  | -                buffer[position++] = rawBytes[3];
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                WriteRawBytes(rawBytes, 0, 4);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteFloat(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -203,7 +191,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteUInt64(ulong value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawVarint64(value);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteUInt64(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -212,7 +201,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteInt64(long value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawVarint64((ulong) value);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteInt64(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -221,15 +211,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteInt32(int value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            if (value >= 0)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                WriteRawVarint32((uint) value);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                // Must sign-extend.
 | 
	
		
			
				|  |  | -                WriteRawVarint64((ulong) value);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteInt32(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -238,7 +221,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteFixed64(ulong value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawLittleEndian64(value);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteFixed64(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -247,7 +231,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteFixed32(uint value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawLittleEndian32(value);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteFixed32(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -256,7 +241,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteBool(bool value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawByte(value ? (byte) 1 : (byte) 0);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteBool(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -266,30 +252,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteString(string value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            // Optimise the case where we have enough space to write
 | 
	
		
			
				|  |  | -            // the string directly to the buffer, which should be common.
 | 
	
		
			
				|  |  | -            int length = Utf8Encoding.GetByteCount(value);
 | 
	
		
			
				|  |  | -            WriteLength(length);
 | 
	
		
			
				|  |  | -            if (limit - position >= length)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                if (length == value.Length) // Must be all ASCII...
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    for (int i = 0; i < length; i++)
 | 
	
		
			
				|  |  | -                    {
 | 
	
		
			
				|  |  | -                        buffer[position + i] = (byte)value[i];
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                else
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    Utf8Encoding.GetBytes(value, 0, value.Length, buffer, position);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                position += length;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                byte[] bytes = Utf8Encoding.GetBytes(value);
 | 
	
		
			
				|  |  | -                WriteRawBytes(bytes);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteString(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -299,6 +263,7 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteMessage(IMessage value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | +            // TOOD: implement....
 | 
	
		
			
				|  |  |              WriteLength(value.CalculateSize());
 | 
	
		
			
				|  |  |              value.WriteTo(this);
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -309,6 +274,7 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteGroup(IMessage value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | +            // TODO: implement...
 | 
	
		
			
				|  |  |              value.WriteTo(this);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -319,8 +285,9 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteBytes(ByteString value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteLength(value.Length);
 | 
	
		
			
				|  |  | -            value.WriteRawBytesTo(this);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteLength(ref span, ref state, value.Length);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteBytes(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -329,7 +296,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteUInt32(uint value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawVarint32(value);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteUInt32(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -338,7 +306,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteEnum(int value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteInt32(value);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteEnum(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -347,7 +316,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write.</param>
 | 
	
		
			
				|  |  |          public void WriteSFixed32(int value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawLittleEndian32((uint) value);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteSFixed32(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -356,7 +326,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteSFixed64(long value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawLittleEndian64((ulong) value);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteSFixed64(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -365,7 +336,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteSInt32(int value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawVarint32(EncodeZigZag32(value));
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteSInt32(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -374,7 +346,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="value">The value to write</param>
 | 
	
		
			
				|  |  |          public void WriteSInt64(long value)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawVarint64(EncodeZigZag64(value));
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteSInt64(ref span, ref state, value);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -386,7 +359,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="length">Length value, in bytes.</param>
 | 
	
		
			
				|  |  |          public void WriteLength(int length)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawVarint32((uint) length);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteLength(ref span, ref state, length);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          #endregion
 | 
	
	
		
			
				|  | @@ -399,7 +373,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="type">The wire format type of the tag to write</param>
 | 
	
		
			
				|  |  |          public void WriteTag(int fieldNumber, WireFormat.WireType type)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type));
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteTag(ref span, ref state, fieldNumber, type);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -408,7 +383,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="tag">The encoded tag</param>
 | 
	
		
			
				|  |  |          public void WriteTag(uint tag)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawVarint32(tag);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteTag(ref span, ref state, tag);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -417,7 +393,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="b1">The encoded tag</param>
 | 
	
		
			
				|  |  |          public void WriteRawTag(byte b1)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawByte(b1);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteRawTag(ref span, ref state, b1);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -427,8 +404,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="b2">The second byte of the encoded tag</param>
 | 
	
		
			
				|  |  |          public void WriteRawTag(byte b1, byte b2)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawByte(b1);
 | 
	
		
			
				|  |  | -            WriteRawByte(b2);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -439,9 +416,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="b3">The third byte of the encoded tag</param>
 | 
	
		
			
				|  |  |          public void WriteRawTag(byte b1, byte b2, byte b3)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawByte(b1);
 | 
	
		
			
				|  |  | -            WriteRawByte(b2);
 | 
	
		
			
				|  |  | -            WriteRawByte(b3);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -453,10 +429,8 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="b4">The fourth byte of the encoded tag</param>
 | 
	
		
			
				|  |  |          public void WriteRawTag(byte b1, byte b2, byte b3, byte b4)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawByte(b1);
 | 
	
		
			
				|  |  | -            WriteRawByte(b2);
 | 
	
		
			
				|  |  | -            WriteRawByte(b3);
 | 
	
		
			
				|  |  | -            WriteRawByte(b4);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -469,130 +443,128 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// <param name="b5">The fifth byte of the encoded tag</param>
 | 
	
		
			
				|  |  |          public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            WriteRawByte(b1);
 | 
	
		
			
				|  |  | -            WriteRawByte(b2);
 | 
	
		
			
				|  |  | -            WriteRawByte(b3);
 | 
	
		
			
				|  |  | -            WriteRawByte(b4);
 | 
	
		
			
				|  |  | -            WriteRawByte(b5);
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4, b5);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          #endregion
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        #region Underlying writing primitives
 | 
	
		
			
				|  |  | -        /// <summary>
 | 
	
		
			
				|  |  | -        /// Writes a 32 bit value as a varint. The fast route is taken when
 | 
	
		
			
				|  |  | -        /// there's enough buffer space left to whizz through without checking
 | 
	
		
			
				|  |  | -        /// for each byte; otherwise, we resort to calling WriteRawByte each time.
 | 
	
		
			
				|  |  | -        /// </summary>
 | 
	
		
			
				|  |  | -        internal void WriteRawVarint32(uint value)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            // Optimize for the common case of a single byte value
 | 
	
		
			
				|  |  | -            if (value < 128 && position < limit)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                buffer[position++] = (byte)value;
 | 
	
		
			
				|  |  | -                return;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            while (value > 127 && position < limit)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                buffer[position++] = (byte) ((value & 0x7F) | 0x80);
 | 
	
		
			
				|  |  | -                value >>= 7;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            while (value > 127)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) ((value & 0x7F) | 0x80));
 | 
	
		
			
				|  |  | -                value >>= 7;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            if (position < limit)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                buffer[position++] = (byte) value;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) value);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        internal void WriteRawVarint64(ulong value)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            while (value > 127 && position < limit)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                buffer[position++] = (byte) ((value & 0x7F) | 0x80);
 | 
	
		
			
				|  |  | -                value >>= 7;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            while (value > 127)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) ((value & 0x7F) | 0x80));
 | 
	
		
			
				|  |  | -                value >>= 7;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            if (position < limit)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                buffer[position++] = (byte) value;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) value);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        internal void WriteRawLittleEndian32(uint value)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            if (position + 4 > limit)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) value);
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) (value >> 8));
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) (value >> 16));
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) (value >> 24));
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) value);
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) (value >> 8));
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) (value >> 16));
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) (value >> 24));
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        internal void WriteRawLittleEndian64(ulong value)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            if (position + 8 > limit)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) value);
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) (value >> 8));
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) (value >> 16));
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) (value >> 24));
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) (value >> 32));
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) (value >> 40));
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) (value >> 48));
 | 
	
		
			
				|  |  | -                WriteRawByte((byte) (value >> 56));
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) value);
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) (value >> 8));
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) (value >> 16));
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) (value >> 24));
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) (value >> 32));
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) (value >> 40));
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) (value >> 48));
 | 
	
		
			
				|  |  | -                buffer[position++] = ((byte) (value >> 56));
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        internal void WriteRawByte(byte value)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            if (position == limit)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                RefreshBuffer();
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            buffer[position++] = value;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        internal void WriteRawByte(uint value)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            WriteRawByte((byte) value);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +        //#region Underlying writing primitives
 | 
	
		
			
				|  |  | +        ///// <summary>
 | 
	
		
			
				|  |  | +        ///// Writes a 32 bit value as a varint. The fast route is taken when
 | 
	
		
			
				|  |  | +        ///// there's enough buffer space left to whizz through without checking
 | 
	
		
			
				|  |  | +        ///// for each byte; otherwise, we resort to calling WriteRawByte each time.
 | 
	
		
			
				|  |  | +        ///// </summary>
 | 
	
		
			
				|  |  | +        //internal void WriteRawVarint32(uint value)
 | 
	
		
			
				|  |  | +        //{
 | 
	
		
			
				|  |  | +        //    // Optimize for the common case of a single byte value
 | 
	
		
			
				|  |  | +        //    if (value < 128 && position < limit)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        buffer[position++] = (byte)value;
 | 
	
		
			
				|  |  | +        //        return;
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //    while (value > 127 && position < limit)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        buffer[position++] = (byte) ((value & 0x7F) | 0x80);
 | 
	
		
			
				|  |  | +        //        value >>= 7;
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //    while (value > 127)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) ((value & 0x7F) | 0x80));
 | 
	
		
			
				|  |  | +        //        value >>= 7;
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //    if (position < limit)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        buffer[position++] = (byte) value;
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //    else
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) value);
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //internal void WriteRawVarint64(ulong value)
 | 
	
		
			
				|  |  | +        //{
 | 
	
		
			
				|  |  | +        //    while (value > 127 && position < limit)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        buffer[position++] = (byte) ((value & 0x7F) | 0x80);
 | 
	
		
			
				|  |  | +        //        value >>= 7;
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //    while (value > 127)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) ((value & 0x7F) | 0x80));
 | 
	
		
			
				|  |  | +        //        value >>= 7;
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //    if (position < limit)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        buffer[position++] = (byte) value;
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //    else
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) value);
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //internal void WriteRawLittleEndian32(uint value)
 | 
	
		
			
				|  |  | +        //{
 | 
	
		
			
				|  |  | +        //    if (position + 4 > limit)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) value);
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) (value >> 8));
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) (value >> 16));
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) (value >> 24));
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //    else
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) value);
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) (value >> 8));
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) (value >> 16));
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) (value >> 24));
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //internal void WriteRawLittleEndian64(ulong value)
 | 
	
		
			
				|  |  | +        //{
 | 
	
		
			
				|  |  | +        //    if (position + 8 > limit)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) value);
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) (value >> 8));
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) (value >> 16));
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) (value >> 24));
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) (value >> 32));
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) (value >> 40));
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) (value >> 48));
 | 
	
		
			
				|  |  | +        //        WriteRawByte((byte) (value >> 56));
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //    else
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) value);
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) (value >> 8));
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) (value >> 16));
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) (value >> 24));
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) (value >> 32));
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) (value >> 40));
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) (value >> 48));
 | 
	
		
			
				|  |  | +        //        buffer[position++] = ((byte) (value >> 56));
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +        //}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //internal void WriteRawByte(byte value)
 | 
	
		
			
				|  |  | +        //{
 | 
	
		
			
				|  |  | +        //    if (position == limit)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        RefreshBuffer();
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //    buffer[position++] = value;
 | 
	
		
			
				|  |  | +        //}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //internal void WriteRawByte(uint value)
 | 
	
		
			
				|  |  | +        //{
 | 
	
		
			
				|  |  | +        //    WriteRawByte((byte) value);
 | 
	
		
			
				|  |  | +        //}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // TODO: get rid of this internal method
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  |          /// Writes out an array of bytes.
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
	
		
			
				|  | @@ -601,89 +573,60 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |              WriteRawBytes(value, 0, value.Length);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        // TODO: get rid of this internal method
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  |          /// Writes out part of an array of bytes.
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  |          internal void WriteRawBytes(byte[] value, int offset, int length)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            if (limit - position >= length)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                ByteArray.Copy(value, offset, buffer, position, length);
 | 
	
		
			
				|  |  | -                // We have room in the current buffer.
 | 
	
		
			
				|  |  | -                position += length;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            else
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                // Write extends past current buffer.  Fill the rest of this buffer and
 | 
	
		
			
				|  |  | -                // flush.
 | 
	
		
			
				|  |  | -                int bytesWritten = limit - position;
 | 
	
		
			
				|  |  | -                ByteArray.Copy(value, offset, buffer, position, bytesWritten);
 | 
	
		
			
				|  |  | -                offset += bytesWritten;
 | 
	
		
			
				|  |  | -                length -= bytesWritten;
 | 
	
		
			
				|  |  | -                position = limit;
 | 
	
		
			
				|  |  | -                RefreshBuffer();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                // Now deal with the rest.
 | 
	
		
			
				|  |  | -                // Since we have an output stream, this is our buffer
 | 
	
		
			
				|  |  | -                // and buffer offset == 0
 | 
	
		
			
				|  |  | -                if (length <= limit)
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    // Fits in new buffer.
 | 
	
		
			
				|  |  | -                    ByteArray.Copy(value, offset, buffer, 0, length);
 | 
	
		
			
				|  |  | -                    position = length;
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                else
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    // Write is very big.  Let's do it all at once.
 | 
	
		
			
				|  |  | -                    output.Write(value, offset, length);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        #endregion
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        /// <summary>
 | 
	
		
			
				|  |  | -        /// Encode a 32-bit value with ZigZag encoding.
 | 
	
		
			
				|  |  | -        /// </summary>
 | 
	
		
			
				|  |  | -        /// <remarks>
 | 
	
		
			
				|  |  | -        /// ZigZag encodes signed integers into values that can be efficiently
 | 
	
		
			
				|  |  | -        /// encoded with varint.  (Otherwise, negative values must be 
 | 
	
		
			
				|  |  | -        /// sign-extended to 64 bits to be varint encoded, thus always taking
 | 
	
		
			
				|  |  | -        /// 10 bytes on the wire.)
 | 
	
		
			
				|  |  | -        /// </remarks>
 | 
	
		
			
				|  |  | -        internal static uint EncodeZigZag32(int n)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            // Note:  the right-shift must be arithmetic
 | 
	
		
			
				|  |  | -            return (uint) ((n << 1) ^ (n >> 31));
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        /// <summary>
 | 
	
		
			
				|  |  | -        /// Encode a 64-bit value with ZigZag encoding.
 | 
	
		
			
				|  |  | -        /// </summary>
 | 
	
		
			
				|  |  | -        /// <remarks>
 | 
	
		
			
				|  |  | -        /// ZigZag encodes signed integers into values that can be efficiently
 | 
	
		
			
				|  |  | -        /// encoded with varint.  (Otherwise, negative values must be 
 | 
	
		
			
				|  |  | -        /// sign-extended to 64 bits to be varint encoded, thus always taking
 | 
	
		
			
				|  |  | -        /// 10 bytes on the wire.)
 | 
	
		
			
				|  |  | -        /// </remarks>
 | 
	
		
			
				|  |  | -        internal static ulong EncodeZigZag64(long n)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            return (ulong) ((n << 1) ^ (n >> 63));
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        private void RefreshBuffer()
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            if (output == null)
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                // We're writing to a single buffer.
 | 
	
		
			
				|  |  | -                throw new OutOfSpaceException();
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            // Since we have an output stream, this is our buffer
 | 
	
		
			
				|  |  | -            // and buffer offset == 0
 | 
	
		
			
				|  |  | -            output.Write(buffer, 0, position);
 | 
	
		
			
				|  |  | -            position = 0;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            WritingPrimitives.WriteRawBytes(ref span, ref state, value, offset, length);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //#endregion
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        ///// <summary>
 | 
	
		
			
				|  |  | +        ///// Encode a 32-bit value with ZigZag encoding.
 | 
	
		
			
				|  |  | +        ///// </summary>
 | 
	
		
			
				|  |  | +        ///// <remarks>
 | 
	
		
			
				|  |  | +        ///// ZigZag encodes signed integers into values that can be efficiently
 | 
	
		
			
				|  |  | +        ///// encoded with varint.  (Otherwise, negative values must be 
 | 
	
		
			
				|  |  | +        ///// sign-extended to 64 bits to be varint encoded, thus always taking
 | 
	
		
			
				|  |  | +        ///// 10 bytes on the wire.)
 | 
	
		
			
				|  |  | +        ///// </remarks>
 | 
	
		
			
				|  |  | +        //internal static uint EncodeZigZag32(int n)
 | 
	
		
			
				|  |  | +        //{
 | 
	
		
			
				|  |  | +        //    // Note:  the right-shift must be arithmetic
 | 
	
		
			
				|  |  | +        //    return (uint) ((n << 1) ^ (n >> 31));
 | 
	
		
			
				|  |  | +        //}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        ///// <summary>
 | 
	
		
			
				|  |  | +        ///// Encode a 64-bit value with ZigZag encoding.
 | 
	
		
			
				|  |  | +        ///// </summary>
 | 
	
		
			
				|  |  | +        ///// <remarks>
 | 
	
		
			
				|  |  | +        ///// ZigZag encodes signed integers into values that can be efficiently
 | 
	
		
			
				|  |  | +        ///// encoded with varint.  (Otherwise, negative values must be 
 | 
	
		
			
				|  |  | +        ///// sign-extended to 64 bits to be varint encoded, thus always taking
 | 
	
		
			
				|  |  | +        ///// 10 bytes on the wire.)
 | 
	
		
			
				|  |  | +        ///// </remarks>
 | 
	
		
			
				|  |  | +        //internal static ulong EncodeZigZag64(long n)
 | 
	
		
			
				|  |  | +        //{
 | 
	
		
			
				|  |  | +        //    return (ulong) ((n << 1) ^ (n >> 63));
 | 
	
		
			
				|  |  | +        //}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //private void RefreshBuffer()
 | 
	
		
			
				|  |  | +        //{
 | 
	
		
			
				|  |  | +        //    if (output == null)
 | 
	
		
			
				|  |  | +        //    {
 | 
	
		
			
				|  |  | +        //        // We're writing to a single buffer.
 | 
	
		
			
				|  |  | +        //        throw new OutOfSpaceException();
 | 
	
		
			
				|  |  | +        //    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //    // Since we have an output stream, this is our buffer
 | 
	
		
			
				|  |  | +        //    // and buffer offset == 0
 | 
	
		
			
				|  |  | +        //    output.Write(buffer, 0, position);
 | 
	
		
			
				|  |  | +        //    position = 0;
 | 
	
		
			
				|  |  | +        //}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
		
			
				|  |  |          /// Indicates that a CodedOutputStream wrapping a flat byte array
 | 
	
	
		
			
				|  | @@ -726,10 +669,13 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          /// </summary>
 | 
	
		
			
				|  |  |          public void Flush()
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            if (output != null)
 | 
	
		
			
				|  |  | +            var span = new Span<byte>(buffer);
 | 
	
		
			
				|  |  | +            state.writeBufferHelper.Flush(ref span, ref state);
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            /*if (output != null)
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  RefreshBuffer();
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +            }*/
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          /// <summary>
 | 
	
	
		
			
				|  | @@ -756,7 +702,7 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  |                  if (output == null)
 | 
	
		
			
				|  |  |                  {
 | 
	
		
			
				|  |  | -                    return limit - position;
 | 
	
		
			
				|  |  | +                    return state.limit - state.position;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  else
 | 
	
		
			
				|  |  |                  {
 | 
	
	
		
			
				|  | @@ -770,5 +716,7 @@ namespace Google.Protobuf
 | 
	
		
			
				|  |  |          internal byte[] InternalBuffer => buffer;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          internal Stream InternalOutputStream => output;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        internal ref WriterInternalState InternalState => ref state;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |