aboutsummaryrefslogtreecommitdiff
path: root/csharp
diff options
context:
space:
mode:
authorJon Skeet <skeet@pobox.com>2008-08-14 20:35:28 +0100
committerJon Skeet <skeet@pobox.com>2008-08-14 20:35:28 +0100
commitd6c9495797d202a19a93dee724c3c9fc0d6564c6 (patch)
tree287a54214295aee786c8be4f1295f2d52cd906d2 /csharp
parent19ed9c07821e39c5a33399b7cfc21ab1a4dc1f58 (diff)
downloadprotobuf-d6c9495797d202a19a93dee724c3c9fc0d6564c6.tar.gz
protobuf-d6c9495797d202a19a93dee724c3c9fc0d6564c6.tar.bz2
protobuf-d6c9495797d202a19a93dee724c3c9fc0d6564c6.zip
More tests, and a bug fix.
Diffstat (limited to 'csharp')
-rw-r--r--csharp/ProtocolBuffers.Test/WireFormatTest.cs192
-rw-r--r--csharp/ProtocolBuffers/DynamicMessage.cs2
-rw-r--r--csharp/ProtocolBuffers/ExtendableMessage.cs2
-rw-r--r--csharp/ProtocolBuffers/FieldSet.cs7
-rw-r--r--csharp/ProtocolBuffers/IBuilder.cs24
-rw-r--r--csharp/ProtocolBuffers/RpcUtil.cs2
6 files changed, 211 insertions, 18 deletions
diff --git a/csharp/ProtocolBuffers.Test/WireFormatTest.cs b/csharp/ProtocolBuffers.Test/WireFormatTest.cs
index 87c9dc6d..ecf87306 100644
--- a/csharp/ProtocolBuffers.Test/WireFormatTest.cs
+++ b/csharp/ProtocolBuffers.Test/WireFormatTest.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
+using Google.ProtocolBuffers.TestProtos;
using NUnit.Framework;
using Google.ProtocolBuffers.Descriptors;
@@ -16,5 +17,196 @@ namespace Google.ProtocolBuffers {
Assert.AreEqual(WireFormat.WireType.LengthDelimited, WireFormat.FieldTypeToWireFormatMap[FieldType.String]);
Assert.AreEqual(WireFormat.WireType.LengthDelimited, WireFormat.FieldTypeToWireFormatMap[FieldType.Message]);
}
+
+ [Test]
+ public void Serialization() {
+ TestAllTypes message = TestUtil.GetAllSet();
+
+ ByteString rawBytes = message.ToByteString();
+ Assert.AreEqual(rawBytes.Length, message.SerializedSize);
+
+ TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
+
+ TestUtil.AssertAllFieldsSet(message2);
+ }
+
+ [Test]
+ public void SerializeExtensions() {
+ // TestAllTypes and TestAllExtensions should have compatible wire formats,
+ // so if we serealize a TestAllExtensions then parse it as TestAllTypes
+ // it should work.
+
+ TestAllExtensions message = TestUtil.GetAllExtensionsSet();
+ ByteString rawBytes = message.ToByteString();
+ Assert.AreEqual(rawBytes.Length, message.SerializedSize);
+
+ TestAllTypes message2 = TestAllTypes.ParseFrom(rawBytes);
+
+ TestUtil.AssertAllFieldsSet(message2);
+ }
+
+ [Test]
+ public void ParseExtensions() {
+ // TestAllTypes and TestAllExtensions should have compatible wire formats,
+ // so if we serealize a TestAllTypes then parse it as TestAllExtensions
+ // it should work.
+
+ TestAllTypes message = TestUtil.GetAllSet();
+ ByteString rawBytes = message.ToByteString();
+
+ ExtensionRegistry registry = ExtensionRegistry.CreateInstance();
+ TestUtil.RegisterAllExtensions(registry);
+ registry = registry.AsReadOnly();
+
+ TestAllExtensions message2 =
+ TestAllExtensions.ParseFrom(rawBytes, registry);
+
+ TestUtil.AssertAllExtensionsSet(message2);
+ }
+
+ [Test]
+ public void ExtensionsSerializedSize() {
+ Assert.AreEqual(TestUtil.GetAllSet().SerializedSize, TestUtil.GetAllExtensionsSet().SerializedSize);
+ }
+
+ private void AssertFieldsInOrder(ByteString data) {
+ CodedInputStream input = data.CreateCodedInput();
+ uint previousTag = 0;
+
+ while (true) {
+ uint tag = input.ReadTag();
+ if (tag == 0) {
+ break;
+ }
+
+ Assert.IsTrue(tag > previousTag);
+ previousTag = tag;
+ input.SkipField(tag);
+ }
+ }
+
+ [Test]
+ public void InterleavedFieldsAndExtensions() {
+ // Tests that fields are written in order even when extension ranges
+ // are interleaved with field numbers.
+ ByteString data =
+ TestFieldOrderings.CreateBuilder()
+ .SetMyInt(1)
+ .SetMyString("foo")
+ .SetMyFloat(1.0F)
+ .SetExtension(UnitTestProtoFile.MyExtensionInt, 23)
+ .SetExtension(UnitTestProtoFile.MyExtensionString, "bar")
+ .Build().ToByteString();
+ AssertFieldsInOrder(data);
+
+ MessageDescriptor descriptor = TestFieldOrderings.Descriptor;
+ ByteString dynamic_data =
+ DynamicMessage.CreateBuilder(TestFieldOrderings.Descriptor)
+ .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_int"), 1L)
+ .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_string"), "foo")
+ .SetField(descriptor.FindDescriptor<FieldDescriptor>("my_float"), 1.0F)
+ .SetField(UnitTestProtoFile.MyExtensionInt.Descriptor, 23)
+ .SetField(UnitTestProtoFile.MyExtensionString.Descriptor, "bar")
+ .WeakBuild().ToByteString();
+ AssertFieldsInOrder(dynamic_data);
+ }
+
+ private const int UnknownTypeId = 1550055;
+ private static readonly int TypeId1 = TestMessageSetExtension1.Descriptor.Extensions[0].FieldNumber;
+ private static readonly int TypeId2 = TestMessageSetExtension2.Descriptor.Extensions[0].FieldNumber;
+
+ [Test]
+ public void SerializeMessageSet() {
+ // Set up a TestMessageSet with two known messages and an unknown one.
+ TestMessageSet messageSet =
+ TestMessageSet.CreateBuilder()
+ .SetExtension(
+ TestMessageSetExtension1.Types.MessageSetExtension,
+ TestMessageSetExtension1.CreateBuilder().SetI(123).Build())
+ .SetExtension(
+ TestMessageSetExtension2.Types.MessageSetExtension,
+ TestMessageSetExtension2.CreateBuilder().SetStr("foo").Build())
+ .SetUnknownFields(
+ UnknownFieldSet.CreateBuilder()
+ .AddField(UnknownTypeId,
+ UnknownField.CreateBuilder()
+ .AddLengthDelimited(ByteString.CopyFromUtf8("bar"))
+ .Build())
+ .Build())
+ .Build();
+
+ ByteString data = messageSet.ToByteString();
+
+ // Parse back using RawMessageSet and check the contents.
+ RawMessageSet raw = RawMessageSet.ParseFrom(data);
+
+ Assert.AreEqual(0, raw.UnknownFields.FieldDictionary.Count);
+
+ Assert.AreEqual(3, raw.ItemCount);
+ Assert.AreEqual(TypeId1, raw.ItemList[0].TypeId);
+ Assert.AreEqual(TypeId2, raw.ItemList[1].TypeId);
+ Assert.AreEqual(UnknownTypeId, raw.ItemList[2].TypeId);
+
+ TestMessageSetExtension1 message1 = TestMessageSetExtension1.ParseFrom(raw.GetItem(0).Message.ToByteArray());
+ Assert.AreEqual(123, message1.I);
+
+ TestMessageSetExtension2 message2 = TestMessageSetExtension2.ParseFrom(raw.GetItem(1).Message.ToByteArray());
+ Assert.AreEqual("foo", message2.Str);
+
+ Assert.AreEqual("bar", raw.GetItem(2).Message.ToStringUtf8());
+ }
+
+ [Test]
+ public void ParseMessageSet() {
+ ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
+ extensionRegistry.Add(TestMessageSetExtension1.Types.MessageSetExtension);
+ extensionRegistry.Add(TestMessageSetExtension2.Types.MessageSetExtension);
+
+ // Set up a RawMessageSet with two known messages and an unknown one.
+ RawMessageSet raw =
+ RawMessageSet.CreateBuilder()
+ .AddItem(
+ RawMessageSet.Types.Item.CreateBuilder()
+ .SetTypeId(TypeId1)
+ .SetMessage(
+ TestMessageSetExtension1.CreateBuilder()
+ .SetI(123)
+ .Build().ToByteString())
+ .Build())
+ .AddItem(
+ RawMessageSet.Types.Item.CreateBuilder()
+ .SetTypeId(TypeId2)
+ .SetMessage(
+ TestMessageSetExtension2.CreateBuilder()
+ .SetStr("foo")
+ .Build().ToByteString())
+ .Build())
+ .AddItem(
+ RawMessageSet.Types.Item.CreateBuilder()
+ .SetTypeId(UnknownTypeId)
+ .SetMessage(ByteString.CopyFromUtf8("bar"))
+ .Build())
+ .Build();
+
+ ByteString data = raw.ToByteString();
+
+ // Parse as a TestMessageSet and check the contents.
+ TestMessageSet messageSet =
+ TestMessageSet.ParseFrom(data, extensionRegistry);
+
+ Assert.AreEqual(123, messageSet.GetExtension(TestMessageSetExtension1.Types.MessageSetExtension).I);
+ Assert.AreEqual("foo", messageSet.GetExtension(TestMessageSetExtension2.Types.MessageSetExtension).Str);
+
+ // Check for unknown field with type LENGTH_DELIMITED,
+ // number UNKNOWN_TYPE_ID, and contents "bar".
+ UnknownFieldSet unknownFields = messageSet.UnknownFields;
+ Assert.AreEqual(1, unknownFields.FieldDictionary.Count);
+ Assert.IsTrue(unknownFields.HasField(UnknownTypeId));
+
+ UnknownField field = unknownFields[UnknownTypeId];
+ Assert.AreEqual(1, field.LengthDelimitedList.Count);
+ Assert.AreEqual("bar", field.LengthDelimitedList[0].ToStringUtf8());
+ }
+
}
}
diff --git a/csharp/ProtocolBuffers/DynamicMessage.cs b/csharp/ProtocolBuffers/DynamicMessage.cs
index f0f4cde1..224b8dee 100644
--- a/csharp/ProtocolBuffers/DynamicMessage.cs
+++ b/csharp/ProtocolBuffers/DynamicMessage.cs
@@ -233,7 +233,7 @@ namespace Google.ProtocolBuffers {
internal Builder(MessageDescriptor type) {
this.type = type;
- this.fields = FieldSet.CreateFieldSet();
+ this.fields = FieldSet.CreateInstance();
this.unknownFields = UnknownFieldSet.DefaultInstance;
}
diff --git a/csharp/ProtocolBuffers/ExtendableMessage.cs b/csharp/ProtocolBuffers/ExtendableMessage.cs
index 60d0d583..84a69b53 100644
--- a/csharp/ProtocolBuffers/ExtendableMessage.cs
+++ b/csharp/ProtocolBuffers/ExtendableMessage.cs
@@ -10,7 +10,7 @@ namespace Google.ProtocolBuffers {
where TBuilder : GeneratedBuilder<TMessage, TBuilder> {
protected ExtendableMessage() {}
- private readonly FieldSet extensions = FieldSet.CreateFieldSet();
+ private readonly FieldSet extensions = FieldSet.CreateInstance();
/// <summary>
/// Access for the builder.
diff --git a/csharp/ProtocolBuffers/FieldSet.cs b/csharp/ProtocolBuffers/FieldSet.cs
index 79394ca4..6e563e7b 100644
--- a/csharp/ProtocolBuffers/FieldSet.cs
+++ b/csharp/ProtocolBuffers/FieldSet.cs
@@ -30,8 +30,9 @@ namespace Google.ProtocolBuffers {
this.fields = fields;
}
- public static FieldSet CreateFieldSet() {
- return new FieldSet(new Dictionary<FieldDescriptor, object>());
+ public static FieldSet CreateInstance() {
+ // Use SortedList to keep fields in the canonical order
+ return new FieldSet(new SortedList<FieldDescriptor, object>());
}
/// <summary>
@@ -507,7 +508,7 @@ namespace Google.ProtocolBuffers {
}
/// <summary>
- /// See <see cref="IBuilder.MergeFrom(IMessage)" />
+ /// See <see cref="IBuilder{TMessage, TBuilder}.MergeFrom(IMessage)" />
/// </summary>
public void MergeFrom(IMessage other) {
MergeFields(other.AllFields);
diff --git a/csharp/ProtocolBuffers/IBuilder.cs b/csharp/ProtocolBuffers/IBuilder.cs
index 52263feb..44990792 100644
--- a/csharp/ProtocolBuffers/IBuilder.cs
+++ b/csharp/ProtocolBuffers/IBuilder.cs
@@ -36,6 +36,18 @@ namespace Google.ProtocolBuffers {
bool IsInitialized { get; }
/// <summary>
+ /// Only present in the nongeneric interface - useful for tests, but
+ /// not as much in real life.
+ /// </summary>
+ IBuilder SetField(FieldDescriptor field, object value);
+
+ /// <summary>
+ /// Only present in the nongeneric interface - useful for tests, but
+ /// not as much in real life.
+ /// </summary>
+ IBuilder SetRepeatedField(FieldDescriptor field, int index, object value);
+
+ /// <summary>
/// Behaves like the equivalent property in IMessage&lt;T&gt;.
/// The returned map may or may not reflect future changes to the builder.
/// Either way, the returned map is unmodifiable.
@@ -57,18 +69,6 @@ namespace Google.ProtocolBuffers {
MessageDescriptor DescriptorForType { get; }
/// <summary>
- /// Only present in the nongeneric interface - useful for tests, but
- /// not as much in real life.
- /// </summary>
- IBuilder SetField(FieldDescriptor field, object value);
-
- /// <summary>
- /// Only present in the nongeneric interface - useful for tests, but
- /// not as much in real life.
- /// </summary>
- IBuilder SetRepeatedField(FieldDescriptor field, int index, object value);
-
- /// <summary>
/// <see cref="IMessage{TMessage, TBuilder}.GetRepeatedFieldCount"/>
/// </summary>
/// <param name="field"></param>
diff --git a/csharp/ProtocolBuffers/RpcUtil.cs b/csharp/ProtocolBuffers/RpcUtil.cs
index ebd3f47f..92675c02 100644
--- a/csharp/ProtocolBuffers/RpcUtil.cs
+++ b/csharp/ProtocolBuffers/RpcUtil.cs
@@ -26,7 +26,7 @@ namespace Google.ProtocolBuffers {
where TBuilder : IBuilder<TMessage, TBuilder> {
return message => {
TMessage castMessage = message as TMessage;
- if (castMessage == null) {
+ if (castMessage == null) {
castMessage = defaultInstance.CreateBuilderForType().MergeFrom(message).Build();
}
action(castMessage);