From 6d0cbe7200e5e20526e346b6db15525ee328850f Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Thu, 14 Aug 2008 20:38:08 +0100 Subject: [PATCH] Use a switch instead of a map for WireFormat. --- csharp/ProtocolBuffers.Test/WireFormatTest.cs | 14 ++++-- csharp/ProtocolBuffers/UnknownFieldSet.cs | 2 +- csharp/ProtocolBuffers/WireFormat.cs | 49 ++++++++++++++----- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/csharp/ProtocolBuffers.Test/WireFormatTest.cs b/csharp/ProtocolBuffers.Test/WireFormatTest.cs index 6e4e506fe6..c5fc3e412d 100644 --- a/csharp/ProtocolBuffers.Test/WireFormatTest.cs +++ b/csharp/ProtocolBuffers.Test/WireFormatTest.cs @@ -13,6 +13,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +using System.Reflection; using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.TestProtos; using NUnit.Framework; @@ -21,13 +22,16 @@ namespace Google.ProtocolBuffers { [TestFixture] public class WireFormatTest { + /// + /// Keeps the attributes on FieldType and the switch statement in WireFormat in sync. + /// [Test] public void FieldTypeToWireTypeMapping() { - - // Just test a few values - Assert.AreEqual(WireFormat.WireType.Fixed64, WireFormat.FieldTypeToWireFormatMap[FieldType.SFixed64]); - Assert.AreEqual(WireFormat.WireType.LengthDelimited, WireFormat.FieldTypeToWireFormatMap[FieldType.String]); - Assert.AreEqual(WireFormat.WireType.LengthDelimited, WireFormat.FieldTypeToWireFormatMap[FieldType.Message]); + foreach (FieldInfo field in typeof(FieldType).GetFields(BindingFlags.Static | BindingFlags.Public)) { + FieldType fieldType = (FieldType)field.GetValue(null); + FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0]; + Assert.AreEqual(mapping.WireType, WireFormat.GetWireType(fieldType)); + } } [Test] diff --git a/csharp/ProtocolBuffers/UnknownFieldSet.cs b/csharp/ProtocolBuffers/UnknownFieldSet.cs index 468970e5da..4e3e4e9598 100644 --- a/csharp/ProtocolBuffers/UnknownFieldSet.cs +++ b/csharp/ProtocolBuffers/UnknownFieldSet.cs @@ -480,7 +480,7 @@ namespace Google.ProtocolBuffers { } // Unknown field or wrong wire type. Skip. - if (field == null || wireType != WireFormat.FieldTypeToWireFormatMap[field.FieldType]) { + if (field == null || wireType != WireFormat.GetWireType(field.FieldType)) { return MergeFieldFrom(tag, input); } diff --git a/csharp/ProtocolBuffers/WireFormat.cs b/csharp/ProtocolBuffers/WireFormat.cs index 6def39e414..0ea9332256 100644 --- a/csharp/ProtocolBuffers/WireFormat.cs +++ b/csharp/ProtocolBuffers/WireFormat.cs @@ -13,6 +13,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +using System; using System.Reflection; using Google.ProtocolBuffers.Descriptors; using System.Collections.Generic; @@ -77,19 +78,45 @@ namespace Google.ProtocolBuffers { } /// - /// Immutable mapping from field type to wire type. Built using the attributes on - /// FieldType values. + /// Converts a field type to its wire type. Done with a switch for the sake + /// of speed - this is significantly faster than a dictionary lookup. /// - public static readonly IDictionary FieldTypeToWireFormatMap = MapFieldTypes(); - - private static IDictionary MapFieldTypes() { - var map = new Dictionary(); - foreach (FieldInfo field in typeof(FieldType).GetFields(BindingFlags.Static | BindingFlags.Public)) { - FieldType fieldType = (FieldType) field.GetValue(null); - FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0]; - map[fieldType] = mapping.WireType; + public static WireType GetWireType(FieldType fieldType) { + switch (fieldType) { + case FieldType.Double: + return WireType.Fixed64; + case FieldType.Float: + return WireType.Fixed32; + case FieldType.Int64: + case FieldType.UInt64: + case FieldType.Int32: + return WireType.Varint; + case FieldType.Fixed64: + return WireType.Fixed64; + case FieldType.Fixed32: + return WireType.Fixed32; + case FieldType.Bool: + return WireType.Varint; + case FieldType.String: + return WireType.LengthDelimited; + case FieldType.Group: + return WireType.StartGroup; + case FieldType.Message: + case FieldType.Bytes: + return WireType.LengthDelimited; + case FieldType.UInt32: + return WireType.Varint; + case FieldType.SFixed32: + return WireType.Fixed32; + case FieldType.SFixed64: + return WireType.Fixed64; + case FieldType.SInt32: + case FieldType.SInt64: + case FieldType.Enum: + return WireType.Varint; + default: + throw new ArgumentOutOfRangeException("No such field type"); } - return Dictionaries.AsReadOnly(map); } } }