diff --git a/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
index b9ff51521f..d64ef625d4 100644
--- a/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
+++ b/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
@@ -211,35 +211,35 @@ namespace Google.Protobuf
[Test]
public void EncodeZigZag32()
{
- Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag32(0));
- Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag32(-1));
- Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag32(1));
- Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag32(-2));
- Assert.AreEqual(0x7FFFFFFEu, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF));
- Assert.AreEqual(0x7FFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000)));
- Assert.AreEqual(0xFFFFFFFEu, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF));
- Assert.AreEqual(0xFFFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000)));
+ Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag32(0));
+ Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag32(-1));
+ Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag32(1));
+ Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag32(-2));
+ Assert.AreEqual(0x7FFFFFFEu, WritingPrimitives.EncodeZigZag32(0x3FFFFFFF));
+ Assert.AreEqual(0x7FFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0xC0000000)));
+ Assert.AreEqual(0xFFFFFFFEu, WritingPrimitives.EncodeZigZag32(0x7FFFFFFF));
+ Assert.AreEqual(0xFFFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0x80000000)));
}
[Test]
public void EncodeZigZag64()
{
- Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag64(0));
- Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag64(-1));
- Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag64(1));
- Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag64(-2));
+ Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag64(0));
+ Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag64(-1));
+ Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag64(1));
+ Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag64(-2));
Assert.AreEqual(0x000000007FFFFFFEuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
+ WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL)));
Assert.AreEqual(0x000000007FFFFFFFuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
+ WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL)));
Assert.AreEqual(0x00000000FFFFFFFEuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
+ WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL)));
Assert.AreEqual(0x00000000FFFFFFFFuL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
+ WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFEL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
+ WritingPrimitives.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL)));
Assert.AreEqual(0xFFFFFFFFFFFFFFFFL,
- CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
+ WritingPrimitives.EncodeZigZag64(unchecked((long) 0x8000000000000000UL)));
}
[Test]
@@ -247,26 +247,26 @@ namespace Google.Protobuf
{
// Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1)
// were chosen semi-randomly via keyboard bashing.
- Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0)));
- Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1)));
- Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1)));
- Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927)));
- Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612)));
+ Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(0)));
+ Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(1)));
+ Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-1)));
+ Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(14927)));
+ Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-3612)));
}
[Test]
public void RoundTripZigZag64()
{
- Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0)));
- Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1)));
- Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1)));
- Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927)));
- Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612)));
+ Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(0)));
+ Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(1)));
+ Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-1)));
+ Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(14927)));
+ Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-3612)));
Assert.AreEqual(856912304801416L,
- ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L)));
+ ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(856912304801416L)));
Assert.AreEqual(-75123905439571256L,
- ParsingPrimitives.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
+ ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-75123905439571256L)));
}
[Test]
diff --git a/csharp/src/Google.Protobuf/CodedOutputStream.cs b/csharp/src/Google.Protobuf/CodedOutputStream.cs
index ccf7520525..002fae3d0e 100644
--- a/csharp/src/Google.Protobuf/CodedOutputStream.cs
+++ b/csharp/src/Google.Protobuf/CodedOutputStream.cs
@@ -263,9 +263,19 @@ namespace Google.Protobuf
/// The value to write
public void WriteMessage(IMessage value)
{
- // TOOD: implement....
- WriteLength(value.CalculateSize());
- value.WriteTo(this);
+ // TODO(jtattermusch): if the message doesn't implement IBufferMessage (and thus does not provide the InternalWriteTo method),
+ // what we're doing here works fine, but could be more efficient.
+ // For now, this inefficiency is fine, considering this is only a backward-compatibility scenario (and regenerating the code fixes it).
+ var span = new Span(buffer);
+ WriteContext.Initialize(ref span, ref state, out WriteContext ctx);
+ try
+ {
+ WritingPrimitivesMessages.WriteMessage(ref ctx, value);
+ }
+ finally
+ {
+ ctx.CopyStateTo(this);
+ }
}
///
@@ -274,8 +284,16 @@ namespace Google.Protobuf
/// The value to write
public void WriteGroup(IMessage value)
{
- // TODO: implement...
- value.WriteTo(this);
+ var span = new Span(buffer);
+ WriteContext.Initialize(ref span, ref state, out WriteContext ctx);
+ try
+ {
+ WritingPrimitivesMessages.WriteGroup(ref ctx, value);
+ }
+ finally
+ {
+ ctx.CopyStateTo(this);
+ }
}
///
@@ -448,123 +466,49 @@ namespace Google.Protobuf
}
#endregion
- //#region Underlying writing primitives
- /////
- ///// 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.
- /////
- //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);
- // }
- //}
+ #region Underlying writing primitives
+
+ ///
+ /// 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.
+ ///
+ internal void WriteRawVarint32(uint value)
+ {
+ var span = new Span(buffer);
+ WritingPrimitives.WriteRawVarint32(ref span, ref state, 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 WriteRawVarint64(ulong value)
+ {
+ var span = new Span(buffer);
+ WritingPrimitives.WriteRawVarint64(ref span, ref state, value);
+ }
- //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 WriteRawLittleEndian32(uint value)
+ {
+ var span = new Span(buffer);
+ WritingPrimitives.WriteRawLittleEndian32(ref span, ref state, value);
+ }
- //internal void WriteRawByte(byte value)
- //{
- // if (position == limit)
- // {
- // RefreshBuffer();
- // }
+ internal void WriteRawLittleEndian64(ulong value)
+ {
+ var span = new Span(buffer);
+ WritingPrimitives.WriteRawLittleEndian64(ref span, ref state, value);
+ }
- // buffer[position++] = value;
- //}
+ internal void WriteRawByte(byte value)
+ {
+ var span = new Span(buffer);
+ WritingPrimitives.WriteRawByte(ref span, ref state, value);
+ }
- //internal void WriteRawByte(uint value)
- //{
- // WriteRawByte((byte) value);
- //}
+ internal void WriteRawByte(uint value)
+ {
+ var span = new Span(buffer);
+ WritingPrimitives.WriteRawByte(ref span, ref state, value);
+ }
- // TODO: get rid of this internal method
///
/// Writes out an array of bytes.
///
@@ -573,7 +517,6 @@ namespace Google.Protobuf
WriteRawBytes(value, 0, value.Length);
}
- // TODO: get rid of this internal method
///
/// Writes out part of an array of bytes.
///
@@ -583,7 +526,7 @@ namespace Google.Protobuf
WritingPrimitives.WriteRawBytes(ref span, ref state, value, offset, length);
}
- //#endregion
+ #endregion
/////
///// Encode a 32-bit value with ZigZag encoding.