Commit 96ddf01a authored by Jon Skeet's avatar Jon Skeet

Coded*Stream streamlining.

Remove ICodedInputStream and ICodedOutputStream, and rewrite CodedInputStream and CodedOutputStream to be specific to the binary format. If we want to support text-based formats, that can be a whole different serialization mechanism.
parent 39aaf21d
......@@ -336,13 +336,11 @@ namespace Google.Protobuf
CodedInputStream input = CodedInputStream.CreateInstance(ms);
uint testtag;
string ignore;
Assert.IsTrue(input.ReadTag(out testtag, out ignore));
Assert.IsTrue(input.ReadTag(out testtag));
Assert.AreEqual(tag, testtag);
ByteString bytes = null;
// TODO(jonskeet): Should this be ArgumentNullException instead?
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes(ref bytes));
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
}
private static TestRecursiveMessage MakeRecursiveMessage(int depth)
......@@ -435,13 +433,10 @@ namespace Google.Protobuf
CodedInputStream input = CodedInputStream.CreateInstance(ms);
uint testtag;
string ignored;
Assert.IsTrue(input.ReadTag(out testtag, out ignored));
Assert.AreEqual(tag, testtag);
string text = null;
input.ReadString(ref text);
uint actualTag;
Assert.IsTrue(input.ReadTag(out actualTag));
Assert.AreEqual(tag, actualTag);
string text = input.ReadString();
Assert.AreEqual('\ufffd', text[0]);
}
......@@ -473,11 +468,8 @@ namespace Google.Protobuf
{
byte[] bytes = new byte[10] { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };
CodedInputStream input = CodedInputStream.CreateInstance(bytes);
int val = 0;
Assert.IsTrue(input.ReadEnum(ref val));
Assert.AreEqual((int)TestNegEnum.Value, input.ReadEnum());
Assert.IsTrue(input.IsAtEnd);
Assert.AreEqual((int) TestNegEnum.Value, val);
}
[Test]
......@@ -487,17 +479,16 @@ namespace Google.Protobuf
int msgSize = 1 + 1 + arraySize;
byte[] bytes = new byte[msgSize];
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
output.WritePackedInt32Array(8, "", new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });
output.WritePackedInt32Array(8, new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = CodedInputStream.CreateInstance(bytes);
uint tag;
string name;
Assert.IsTrue(input.ReadTag(out tag, out name));
Assert.IsTrue(input.ReadTag(out tag));
List<TestNegEnum> values = new List<TestNegEnum>();
input.ReadEnumArray(tag, name, values);
input.ReadEnumArray(tag, values);
Assert.AreEqual(6, values.Count);
Assert.AreEqual(TestNegEnum.None, values[0]);
......@@ -512,17 +503,16 @@ namespace Google.Protobuf
int msgSize = arraySize;
byte[] bytes = new byte[msgSize];
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
output.WriteInt32Array(8, "", new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });
output.WriteInt32Array(8, new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = CodedInputStream.CreateInstance(bytes);
uint tag;
string name;
Assert.IsTrue(input.ReadTag(out tag, out name));
Assert.IsTrue(input.ReadTag(out tag));
List<TestNegEnum> values = new List<TestNegEnum>();
input.ReadEnumArray(tag, name, values);
input.ReadEnumArray(tag, values);
Assert.AreEqual(6, values.Count);
Assert.AreEqual(TestNegEnum.None, values[0]);
......@@ -537,26 +527,21 @@ namespace Google.Protobuf
using (var ms = new MemoryStream())
{
CodedOutputStream output = CodedOutputStream.CreateInstance(ms);
output.WriteField(FieldType.Bytes, 1, "bytes", ByteString.CopyFrom(new byte[100]));
output.WriteField(FieldType.Bytes, 2, "bytes", ByteString.CopyFrom(new byte[100]));
output.WriteBytes(1, ByteString.CopyFrom(new byte[100]));
output.WriteBytes(2, ByteString.CopyFrom(new byte[100]));
output.Flush();
ms.Position = 0;
CodedInputStream input = CodedInputStream.CreateInstance(ms, new byte[ms.Length / 2]);
uint tag;
string ignore;
ByteString value;
Assert.IsTrue(input.ReadTag(out tag, out ignore));
Assert.IsTrue(input.ReadTag(out tag));
Assert.AreEqual(1, WireFormat.GetTagFieldNumber(tag));
value = ByteString.Empty;
Assert.IsTrue(input.ReadBytes(ref value) && value.Length == 100);
Assert.AreEqual(100, input.ReadBytes().Length);
Assert.IsTrue(input.ReadTag(out tag, out ignore));
Assert.IsTrue(input.ReadTag(out tag));
Assert.AreEqual(2, WireFormat.GetTagFieldNumber(tag));
value = ByteString.Empty;
Assert.IsTrue(input.ReadBytes(ref value) && value.Length == 100);
Assert.AreEqual(100, input.ReadBytes().Length);
}
}
}
......
......@@ -316,7 +316,7 @@ namespace Google.Protobuf
byte[] bytes = new byte[11];
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
output.WriteEnum(8, "", (int) TestNegEnum.Value);
output.WriteEnum(8, (int) TestNegEnum.Value);
Assert.AreEqual(0, output.SpaceLeft);
//fyi, 0x40 == 0x08 << 3 + 0, field num + wire format shift
......@@ -330,18 +330,17 @@ namespace Google.Protobuf
int msgSize = 1 + 1 + arraySize;
byte[] bytes = new byte[msgSize];
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
output.WritePackedEnumArray(8, "", new RepeatedField<TestNegEnum> {
output.WritePackedEnumArray(8, new RepeatedField<TestNegEnum> {
0, (TestNegEnum) (-1), TestNegEnum.Value, (TestNegEnum) (-3), (TestNegEnum) (-4), (TestNegEnum) (-5) });
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = CodedInputStream.CreateInstance(bytes);
uint tag;
string name;
Assert.IsTrue(input.ReadTag(out tag, out name));
Assert.IsTrue(input.ReadTag(out tag));
List<int> values = new List<int>();
input.ReadInt32Array(tag, name, values);
input.ReadInt32Array(tag, values);
Assert.AreEqual(6, values.Count);
for (int i = 0; i > -6; i--)
......@@ -355,17 +354,16 @@ namespace Google.Protobuf
int msgSize = arraySize;
byte[] bytes = new byte[msgSize];
CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
output.WriteEnumArray(8, "", new RepeatedField<TestNegEnum> {
output.WriteEnumArray(8, new RepeatedField<TestNegEnum> {
0, (TestNegEnum) (-1), TestNegEnum.Value, (TestNegEnum) (-3), (TestNegEnum) (-4), (TestNegEnum) (-5) });
Assert.AreEqual(0, output.SpaceLeft);
CodedInputStream input = CodedInputStream.CreateInstance(bytes);
uint tag;
string name;
Assert.IsTrue(input.ReadTag(out tag, out name));
Assert.IsTrue(input.ReadTag(out tag));
List<int> values = new List<int>();
input.ReadInt32Array(tag, name, values);
input.ReadInt32Array(tag, values);
Assert.AreEqual(6, values.Count);
for (int i = 0; i > -6; i--)
......@@ -425,16 +423,14 @@ namespace Google.Protobuf
{
CodedInputStream cin = CodedInputStream.CreateInstance(new MemoryStream(bytes), new byte[50]);
uint tag;
int intValue = 0;
string ignore;
Assert.AreEqual(0, cin.Position);
// Field 1:
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 1);
Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 1);
Assert.AreEqual(1, cin.Position);
Assert.IsTrue(cin.ReadInt32(ref intValue) && intValue == 500);
Assert.AreEqual(500, cin.ReadInt32());
Assert.AreEqual(3, cin.Position);
//Field 2:
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 2);
Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 2);
Assert.AreEqual(4, cin.Position);
uint childlen = cin.ReadRawVarint32();
Assert.AreEqual(120u, childlen);
......@@ -444,30 +440,31 @@ namespace Google.Protobuf
// Now we are reading child message
{
// Field 11: numeric value: 500
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 11);
Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 11);
Assert.AreEqual(6, cin.Position);
Assert.IsTrue(cin.ReadInt32(ref intValue) && intValue == 500);
Assert.AreEqual(500, cin.ReadInt32());
Assert.AreEqual(8, cin.Position);
//Field 12: length delimited 120 bytes
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 12);
Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 12);
Assert.AreEqual(9, cin.Position);
ByteString bstr = null;
Assert.IsTrue(cin.ReadBytes(ref bstr) && bstr.Length == 110 && bstr.ToByteArray()[109] == 109);
ByteString bstr = cin.ReadBytes();
Assert.AreEqual(110, bstr.Length);
Assert.AreEqual((byte) 109, bstr[109]);
Assert.AreEqual(120, cin.Position);
// Field 13: fixed numeric value: 501
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 13);
Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 13);
// ROK - Previously broken here, this returned 126 failing to account for bufferSizeAfterLimit
Assert.AreEqual(121, cin.Position);
Assert.IsTrue(cin.ReadSFixed32(ref intValue) && intValue == 501);
Assert.AreEqual(501, cin.ReadSFixed32());
Assert.AreEqual(125, cin.Position);
Assert.IsTrue(cin.IsAtEnd);
}
cin.PopLimit(oldlimit);
Assert.AreEqual(125, cin.Position);
// Field 3: fixed numeric value: 501
Assert.IsTrue(cin.ReadTag(out tag, out ignore) && tag >> 3 == 3);
Assert.IsTrue(cin.ReadTag(out tag) && tag >> 3 == 3);
Assert.AreEqual(126, cin.Position);
Assert.IsTrue(cin.ReadSFixed32(ref intValue) && intValue == 501);
Assert.AreEqual(501, cin.ReadSFixed32());
Assert.AreEqual(130, cin.Position);
Assert.IsTrue(cin.IsAtEnd);
}
......
......@@ -107,10 +107,9 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
public void WriteTo(pb::ICodedOutputStream output) {
string[] fieldNames = _fieldNames;
public void WriteTo(pb::CodedOutputStream output) {
if (D != 0) {
output.WriteInt32(1, fieldNames[0], D);
output.WriteInt32(1, D);
}
}
......@@ -130,16 +129,9 @@ namespace Google.Protobuf.TestProtos {
}
}
public void MergeFrom(pb::ICodedInputStream input) {
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
string fieldName;
while (input.ReadTag(out tag, out fieldName)) {
if (tag == 0 && fieldName != null) {
int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
if (fieldOrdinal >= 0) {
tag = _fieldTags[fieldOrdinal];
}
}
while (input.ReadTag(out tag)) {
switch(tag) {
case 0:
throw pb::InvalidProtocolBufferException.InvalidTag();
......@@ -149,7 +141,7 @@ namespace Google.Protobuf.TestProtos {
}
break;
case 8: {
input.ReadInt32(ref d_);
d_ = input.ReadInt32();
break;
}
}
......
......@@ -92,10 +92,9 @@ namespace Google.Protobuf.TestProtos {
return hash;
}
public void WriteTo(pb::ICodedOutputStream output) {
string[] fieldNames = _fieldNames;
public void WriteTo(pb::CodedOutputStream output) {
if (E != 0) {
output.WriteInt32(1, fieldNames[0], E);
output.WriteInt32(1, E);
}
}
......@@ -115,16 +114,9 @@ namespace Google.Protobuf.TestProtos {
}
}
public void MergeFrom(pb::ICodedInputStream input) {
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
string fieldName;
while (input.ReadTag(out tag, out fieldName)) {
if (tag == 0 && fieldName != null) {
int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
if (fieldOrdinal >= 0) {
tag = _fieldTags[fieldOrdinal];
}
}
while (input.ReadTag(out tag)) {
switch(tag) {
case 0:
throw pb::InvalidProtocolBufferException.InvalidTag();
......@@ -134,7 +126,7 @@ namespace Google.Protobuf.TestProtos {
}
break;
case 8: {
input.ReadInt32(ref e_);
e_ = input.ReadInt32();
break;
}
}
......
......@@ -153,13 +153,12 @@ namespace UnitTest.Issues.TestProtos {
return hash;
}
public void WriteTo(pb::ICodedOutputStream output) {
string[] fieldNames = _fieldNames;
public void WriteTo(pb::CodedOutputStream output) {
if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
output.WriteEnum(1, fieldNames[1], (int) Value);
output.WriteEnum(1, (int) Value);
}
output.WriteEnumArray(2, fieldNames[2], values_);
output.WritePackedEnumArray(3, fieldNames[0], packedValues_);
output.WriteEnumArray(2, values_);
output.WritePackedEnumArray(3, packedValues_);
}
public int CalculateSize() {
......@@ -201,16 +200,9 @@ namespace UnitTest.Issues.TestProtos {
packedValues_.Add(other.packedValues_);
}
public void MergeFrom(pb::ICodedInputStream input) {
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
string fieldName;
while (input.ReadTag(out tag, out fieldName)) {
if (tag == 0 && fieldName != null) {
int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
if (fieldOrdinal >= 0) {
tag = _fieldTags[fieldOrdinal];
}
}
while (input.ReadTag(out tag)) {
switch(tag) {
case 0:
throw pb::InvalidProtocolBufferException.InvalidTag();
......@@ -220,18 +212,17 @@ namespace UnitTest.Issues.TestProtos {
}
break;
case 8: {
int tmp = 0;
input.ReadEnum(ref tmp);
value_ = (global::UnitTest.Issues.TestProtos.NegativeEnum) tmp;break;
value_ = (global::UnitTest.Issues.TestProtos.NegativeEnum) input.ReadEnum();
break;
}
case 18:
case 16: {
input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(tag, fieldName, values_);
input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(tag, values_);
break;
}
case 26:
case 24: {
input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(tag, fieldName, packedValues_);
input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(tag, packedValues_);
break;
}
}
......@@ -278,8 +269,7 @@ namespace UnitTest.Issues.TestProtos {
return hash;
}
public void WriteTo(pb::ICodedOutputStream output) {
string[] fieldNames = _fieldNames;
public void WriteTo(pb::CodedOutputStream output) {
}
public int CalculateSize() {
......@@ -292,16 +282,9 @@ namespace UnitTest.Issues.TestProtos {
}
}
public void MergeFrom(pb::ICodedInputStream input) {
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
string fieldName;
while (input.ReadTag(out tag, out fieldName)) {
if (tag == 0 && fieldName != null) {
int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
if (fieldOrdinal >= 0) {
tag = _fieldTags[fieldOrdinal];
}
}
while (input.ReadTag(out tag)) {
switch(tag) {
case 0:
throw pb::InvalidProtocolBufferException.InvalidTag();
......@@ -412,20 +395,19 @@ namespace UnitTest.Issues.TestProtos {
return hash;
}
public void WriteTo(pb::ICodedOutputStream output) {
string[] fieldNames = _fieldNames;
public void WriteTo(pb::CodedOutputStream output) {
if (PrimitiveValue != 0) {
output.WriteInt32(1, fieldNames[5], PrimitiveValue);
output.WriteInt32(1, PrimitiveValue);
}
output.WritePackedInt32Array(2, fieldNames[4], primitiveArray_);
output.WritePackedInt32Array(2, primitiveArray_);
if (messageValue_ != null) {
output.WriteMessage(3, fieldNames[3], MessageValue);
output.WriteMessage(3, MessageValue);
}
output.WriteMessageArray(4, fieldNames[2], messageArray_);
output.WriteMessageArray(4, messageArray_);
if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
output.WriteEnum(5, fieldNames[1], (int) EnumValue);
output.WriteEnum(5, (int) EnumValue);
}
output.WritePackedEnumArray(6, fieldNames[0], enumArray_);
output.WritePackedEnumArray(6, enumArray_);
}
public int CalculateSize() {
......@@ -486,16 +468,9 @@ namespace UnitTest.Issues.TestProtos {
enumArray_.Add(other.enumArray_);
}
public void MergeFrom(pb::ICodedInputStream input) {
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
string fieldName;
while (input.ReadTag(out tag, out fieldName)) {
if (tag == 0 && fieldName != null) {
int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
if (fieldOrdinal >= 0) {
tag = _fieldTags[fieldOrdinal];
}
}
while (input.ReadTag(out tag)) {
switch(tag) {
case 0:
throw pb::InvalidProtocolBufferException.InvalidTag();
......@@ -505,12 +480,12 @@ namespace UnitTest.Issues.TestProtos {
}
break;
case 8: {
input.ReadInt32(ref primitiveValue_);
primitiveValue_ = input.ReadInt32();
break;
}
case 18:
case 16: {
input.ReadInt32Array(tag, fieldName, primitiveArray_);
input.ReadInt32Array(tag, primitiveArray_);
break;
}
case 26: {
......@@ -521,17 +496,16 @@ namespace UnitTest.Issues.TestProtos {
break;
}
case 34: {
input.ReadMessageArray(tag, fieldName, messageArray_, global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser);
input.ReadMessageArray(tag, messageArray_, global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser);
break;
}
case 40: {
int tmp = 0;
input.ReadEnum(ref tmp);
enumValue_ = (global::UnitTest.Issues.TestProtos.DeprecatedEnum) tmp;break;
enumValue_ = (global::UnitTest.Issues.TestProtos.DeprecatedEnum) input.ReadEnum();
break;
}
case 50:
case 48: {
input.ReadEnumArray<global::UnitTest.Issues.TestProtos.DeprecatedEnum>(tag, fieldName, enumArray_);
input.ReadEnumArray<global::UnitTest.Issues.TestProtos.DeprecatedEnum>(tag, enumArray_);
break;
}
}
......@@ -588,10 +562,9 @@ namespace UnitTest.Issues.TestProtos {
return hash;
}
public void WriteTo(pb::ICodedOutputStream output) {
string[] fieldNames = _fieldNames;
public void WriteTo(pb::CodedOutputStream output) {
if (Item != 0) {
output.WriteInt32(1, fieldNames[0], Item);
output.WriteInt32(1, Item);
}
}
......@@ -611,16 +584,9 @@ namespace UnitTest.Issues.TestProtos {
}
}
public void MergeFrom(pb::ICodedInputStream input) {
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
string fieldName;
while (input.ReadTag(out tag, out fieldName)) {
if (tag == 0 && fieldName != null) {
int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);
if (fieldOrdinal >= 0) {
tag = _fieldTags[fieldOrdinal];
}
}
while (input.ReadTag(out tag)) {
switch(tag) {
case 0:
throw pb::InvalidProtocolBufferException.InvalidTag();
......@@ -630,7 +596,7 @@ namespace UnitTest.Issues.TestProtos {
}
break;
case 8: {
input.ReadInt32(ref item_);
item_ = input.ReadInt32();
break;
}
}
......
......@@ -413,41 +413,12 @@ namespace Google.Protobuf
return ComputeRawVarint64Size(EncodeZigZag64(value));
}
/*
* Compute the number of bytes that would be needed to encode a
* MessageSet extension to the stream. For historical reasons,
* the wire format differs from normal fields.
*/
/// <summary>
/// Compute the number of bytes that would be needed to encode a
/// MessageSet extension to the stream. For historical reasons,
/// the wire format differs from normal fields.
/// </summary>
public static int ComputeMessageSetExtensionSize(int fieldNumber, IMessage value)
{
return ComputeTagSize(WireFormat.MessageSetField.Item)*2 +
ComputeUInt32Size(WireFormat.MessageSetField.TypeID, (uint) fieldNumber) +
ComputeMessageSize(WireFormat.MessageSetField.Message, value);
}
/// <summary>
/// Compute the number of bytes that would be needed to encode an
/// unparsed MessageSet extension field to the stream. For
/// historical reasons, the wire format differs from normal fields.
/// </summary>
public static int ComputeRawMessageSetExtensionSize(int fieldNumber, ByteString value)
{
return ComputeTagSize(WireFormat.MessageSetField.Item)*2 +
ComputeUInt32Size(WireFormat.MessageSetField.TypeID, (uint) fieldNumber) +
ComputeBytesSize(WireFormat.MessageSetField.Message, value);
}
/// <summary>
/// Compute the number of bytes that would be needed to encode a varint.
/// </summary>
public static int ComputeRawVarint32Size(uint value)
{
// TODO(jonskeet): Look at optimizing this to just hard-coded comparisons.
if ((value & (0xffffffff << 7)) == 0)
{
return 1;
......@@ -472,6 +443,7 @@ namespace Google.Protobuf
/// </summary>
public static int ComputeRawVarint64Size(ulong value)
{
// TODO(jonskeet): Look at optimizing this to just hard-coded comparisons.
if ((value & (0xffffffffffffffffL << 7)) == 0)
{
return 1;
......@@ -511,106 +483,6 @@ namespace Google.Protobuf
return 10;
}
/// <summary>
/// Compute the number of bytes that would be needed to encode a
/// field of arbitrary type, including the tag, to the stream.
/// </summary>
// TODO(jonskeet): Why do we need this?
public static int ComputeFieldSize(FieldType fieldType, int fieldNumber, Object value)
{
switch (fieldType)
{
case FieldType.Double:
return ComputeDoubleSize(fieldNumber, (double) value);
case FieldType.Float:
return ComputeFloatSize(fieldNumber, (float) value);
case FieldType.Int64:
return ComputeInt64Size(fieldNumber, (long) value);
case FieldType.UInt64:
return ComputeUInt64Size(fieldNumber, (ulong) value);
case FieldType.Int32:
return ComputeInt32Size(fieldNumber, (int) value);
case FieldType.Fixed64:
return ComputeFixed64Size(fieldNumber, (ulong) value);
case FieldType.Fixed32:
return ComputeFixed32Size(fieldNumber, (uint) value);
case FieldType.Bool:
return ComputeBoolSize(fieldNumber, (bool) value);
case FieldType.String:
return ComputeStringSize(fieldNumber, (string) value);
case FieldType.Group:
return ComputeGroupSize(fieldNumber, (IMessage) value);
case FieldType.Message:
return ComputeMessageSize(fieldNumber, (IMessage) value);
case FieldType.Bytes:
return ComputeBytesSize(fieldNumber, (ByteString) value);
case FieldType.UInt32:
return ComputeUInt32Size(fieldNumber, (uint) value);
case FieldType.SFixed32:
return ComputeSFixed32Size(fieldNumber, (int) value);
case FieldType.SFixed64:
return ComputeSFixed64Size(fieldNumber, (long) value);
case FieldType.SInt32:
return ComputeSInt32Size(fieldNumber, (int) value);
case FieldType.SInt64:
return ComputeSInt64Size(fieldNumber, (long) value);
case FieldType.Enum:
return ComputeEnumSize(fieldNumber, (int) value);
default:
throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
}
}
/// <summary>
/// Compute the number of bytes that would be needed to encode a
/// field of arbitrary type, excluding the tag, to the stream.
/// </summary>
// TODO(jonskeet): Why do we need this?
public static int ComputeFieldSizeNoTag(FieldType fieldType, Object value)
{
switch (fieldType)
{
case FieldType.Double:
return ComputeDoubleSizeNoTag((double) value);
case FieldType.Float:
return ComputeFloatSizeNoTag((float) value);
case FieldType.Int64:
return ComputeInt64SizeNoTag((long) value);
case FieldType.UInt64:
return ComputeUInt64SizeNoTag((ulong) value);
case FieldType.Int32:
return ComputeInt32SizeNoTag((int) value);
case FieldType.Fixed64:
return ComputeFixed64SizeNoTag((ulong) value);
case FieldType.Fixed32:
return ComputeFixed32SizeNoTag((uint) value);
case FieldType.Bool:
return ComputeBoolSizeNoTag((bool) value);
case FieldType.String:
return ComputeStringSizeNoTag((string) value);
case FieldType.Group:
return ComputeGroupSizeNoTag((IMessage) value);
case FieldType.Message:
return ComputeMessageSizeNoTag((IMessage) value);
case FieldType.Bytes:
return ComputeBytesSizeNoTag((ByteString) value);
case FieldType.UInt32:
return ComputeUInt32SizeNoTag((uint) value);
case FieldType.SFixed32:
return ComputeSFixed32SizeNoTag((int) value);
case FieldType.SFixed64:
return ComputeSFixed64SizeNoTag((long) value);
case FieldType.SInt32:
return ComputeSInt32SizeNoTag((int) value);
case FieldType.SInt64:
return ComputeSInt64SizeNoTag((long) value);
case FieldType.Enum:
return ComputeEnumSizeNoTag((int) value);
default:
throw new ArgumentOutOfRangeException("Invalid field type " + fieldType);
}
}
/// <summary>
/// Compute the number of bytes that would be needed to encode a tag.
/// </summary>
......
......@@ -49,7 +49,7 @@ namespace Google.Protobuf
codedOutput.Flush();
}
public static void WriteTo(this IMessage message, ICodedOutputStream output)
public static void WriteTo(this IMessage message, CodedOutputStream output)
{
message.WriteTo(output);
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -51,8 +51,8 @@ namespace Google.Protobuf
public interface IMessage
{
void MergeFrom(ICodedInputStream input);
void WriteTo(ICodedOutputStream output);
void MergeFrom(CodedInputStream input);
void WriteTo(CodedOutputStream output);
int CalculateSize();
}
......
......@@ -47,7 +47,7 @@ namespace Google.Protobuf
return message;
}
public T ParseFrom(ICodedInputStream input)
public T ParseFrom(CodedInputStream input)
{
T message = factory();
message.MergeFrom(input);
......
......@@ -93,8 +93,6 @@
<Compile Include="FieldAccess\FieldAccessorTable.cs" />
<Compile Include="FieldAccess\OneofAccessor.cs" />
<Compile Include="FrameworkPortability.cs" />
<Compile Include="ICodedInputStream.cs" />
<Compile Include="ICodedOutputStream.cs" />
<Compile Include="IMessage.cs" />
<Compile Include="InvalidProtocolBufferException.cs" />
<Compile Include="LimitedInputStream.cs" />
......
......@@ -54,17 +54,14 @@ EnumFieldGenerator::~EnumFieldGenerator() {
}
void EnumFieldGenerator::GenerateParsingCode(io::Printer* printer) {
// TODO(jonskeet): Get rid of the temporary variable when we sanitize CodedInputStream not to use ref.
printer->Print(variables_,
"int tmp = 0;\n"
"input.ReadEnum(ref tmp);\n"
"$name$_ = ($type_name$) tmp;");
"$name$_ = ($type_name$) input.ReadEnum();\n");
}
void EnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
printer->Print(variables_,
"if ($has_property_check$) {\n"
" output.WriteEnum($number$, fieldNames[$field_ordinal$], (int) $property_name$);\n"
" output.WriteEnum($number$, (int) $property_name$);\n"
"}\n");
}
......@@ -88,18 +85,15 @@ void EnumOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
// TODO(jonskeet): What about if we read the default value?
printer->Print(
variables_,
"int enumValue = 0;\n"
"if(input.ReadEnum(ref enumValue)) {\n"
" $oneof_name$_ = enumValue;\n"
" $oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
"}\n");
"$oneof_name$_ = input.ReadEnum();\n"
"$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n");
}
void EnumOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
printer->Print(
variables_,
"if ($has_property_check$) {\n"
" output.WriteEnum($number$, fieldNames[$field_ordinal$], (int) $property_name$);\n"
" output.WriteEnum($number$, (int) $property_name$);\n"
"}\n");
}
......
......@@ -350,9 +350,8 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) {
printer->Print(
"public void WriteTo(pb::ICodedOutputStream output) {\n");
"public void WriteTo(pb::CodedOutputStream output) {\n");
printer->Indent();
printer->Print("string[] fieldNames = _fieldNames;\n");
// Serialize all the fields
for (int i = 0; i < fields_by_number().size(); i++) {
......@@ -423,21 +422,13 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
}
printer->Outdent();
printer->Print("}\n\n");
printer->Print("public void MergeFrom(pb::ICodedInputStream input) {\n");
printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n");
printer->Indent();
printer->Print(
"uint tag;\n"
"string fieldName;\n"
"while (input.ReadTag(out tag, out fieldName)) {\n");
"while (input.ReadTag(out tag)) {\n"
" switch(tag) {\n");
printer->Indent();
printer->Print(
"if (tag == 0 && fieldName != null) {\n"
" int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.StringComparer.Ordinal);\n"
" if (fieldOrdinal >= 0) {\n"
" tag = _fieldTags[fieldOrdinal];\n"
" }\n"
"}\n"
"switch(tag) {\n");
printer->Indent();
printer->Print(
"case 0:\n" // 0 signals EOF / limit reached
......
......@@ -87,6 +87,7 @@ void MessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
"if ($has_not_property_check$) {\n"
" $name$_ = new $type_name$();\n"
"}\n"
// TODO(jonskeet): Do we really need merging behaviour like this?
"input.ReadMessage($name$_);\n"); // No need to support TYPE_GROUP...
}
......@@ -95,7 +96,7 @@ void MessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
printer->Print(
variables_,
"if ($has_property_check$) {\n"
" output.WriteMessage($number$, fieldNames[$field_ordinal$], $property_name$);\n"
" output.WriteMessage($number$, $property_name$);\n"
"}\n");
}
......
......@@ -73,7 +73,6 @@ void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
printer->Print(
variables_,
" set { $name$_ = value; }\n");
} else {
printer->Print(
variables_,
......@@ -93,14 +92,14 @@ void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) {
void PrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) {
printer->Print(
variables_,
"input.Read$capitalized_type_name$(ref $name$_);\n");
"$name$_ = input.Read$capitalized_type_name$();\n");
}
void PrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
printer->Print(
variables_,
"if ($has_property_check$) {\n"
" output.Write$capitalized_type_name$($number$, fieldNames[$field_ordinal$], $property_name$);\n"
" output.Write$capitalized_type_name$($number$, $property_name$);\n"
"}\n");
}
......@@ -169,13 +168,10 @@ void PrimitiveOneofFieldGenerator::WriteToString(io::Printer* printer) {
void PrimitiveOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
// TODO(jonskeet): What if the value we read is the default value for the type?
printer->Print(
variables_,
"$type_name$ value = $default_value$;\n"
"if (input.Read$capitalized_type_name$(ref value)) {\n"
" $oneof_name$_ = value;\n"
" $oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
"}\n");
printer->Print(
variables_,
"$oneof_name$_ = input.Read$capitalized_type_name$()\n;"
"$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n");
}
} // namespace csharp
......
......@@ -76,7 +76,7 @@ void RepeatedEnumFieldGenerator::GenerateMergingCode(io::Printer* printer) {
void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer) {
printer->Print(
variables_,
"input.ReadEnumArray<$type_name$>(tag, fieldName, $name$_);\n");
"input.ReadEnumArray<$type_name$>(tag, $name$_);\n");
}
void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
......@@ -84,7 +84,7 @@ void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer)
// The Write* call should make that cheap though - no need to generate it every time.
printer->Print(
variables_,
"output.Write$packed$EnumArray($number$, fieldNames[$field_ordinal$], $name$_);\n");
"output.Write$packed$EnumArray($number$, $name$_);\n");
}
void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
......
......@@ -75,7 +75,7 @@ void RepeatedMessageFieldGenerator::GenerateMergingCode(io::Printer* printer) {
void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
printer->Print(
variables_,
"input.ReadMessageArray(tag, fieldName, $name$_, $type_name$.Parser);\n");
"input.ReadMessageArray(tag, $name$_, $type_name$.Parser);\n");
}
void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
......@@ -83,7 +83,7 @@ void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* print
// The Write* call should make that cheap though - no need to generate it every time.
printer->Print(
variables_,
"output.WriteMessageArray($number$, fieldNames[$field_ordinal$], $name$_);\n");
"output.WriteMessageArray($number$, $name$_);\n");
}
void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
......
......@@ -74,7 +74,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer)
void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) {
printer->Print(variables_,
"input.Read$capitalized_type_name$Array(tag, fieldName, $name$_);\n");
"input.Read$capitalized_type_name$Array(tag, $name$_);\n");
}
void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(
......@@ -83,10 +83,10 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(
// The Write* call should make that cheap though - no need to generate it every time.
if (descriptor_->is_packed()) {
printer->Print(variables_,
"output.WritePacked$capitalized_type_name$Array($number$, fieldNames[$field_ordinal$], $name$_);\n");
"output.WritePacked$capitalized_type_name$Array($number$, $name$_);\n");
} else {
printer->Print(variables_,
"output.Write$capitalized_type_name$Array($number$, fieldNames[$field_ordinal$], $name$_);\n");
"output.Write$capitalized_type_name$Array($number$, $name$_);\n");
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment