Use a switch instead of a map for WireFormat.

pull/288/head
Jon Skeet 17 years ago
parent 0980982095
commit 6d0cbe7200
  1. 14
      csharp/ProtocolBuffers.Test/WireFormatTest.cs
  2. 2
      csharp/ProtocolBuffers/UnknownFieldSet.cs
  3. 49
      csharp/ProtocolBuffers/WireFormat.cs

@ -13,6 +13,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using System.Reflection;
using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.TestProtos; using Google.ProtocolBuffers.TestProtos;
using NUnit.Framework; using NUnit.Framework;
@ -21,13 +22,16 @@ namespace Google.ProtocolBuffers {
[TestFixture] [TestFixture]
public class WireFormatTest { public class WireFormatTest {
/// <summary>
/// Keeps the attributes on FieldType and the switch statement in WireFormat in sync.
/// </summary>
[Test] [Test]
public void FieldTypeToWireTypeMapping() { public void FieldTypeToWireTypeMapping() {
foreach (FieldInfo field in typeof(FieldType).GetFields(BindingFlags.Static | BindingFlags.Public)) {
// Just test a few values FieldType fieldType = (FieldType)field.GetValue(null);
Assert.AreEqual(WireFormat.WireType.Fixed64, WireFormat.FieldTypeToWireFormatMap[FieldType.SFixed64]); FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0];
Assert.AreEqual(WireFormat.WireType.LengthDelimited, WireFormat.FieldTypeToWireFormatMap[FieldType.String]); Assert.AreEqual(mapping.WireType, WireFormat.GetWireType(fieldType));
Assert.AreEqual(WireFormat.WireType.LengthDelimited, WireFormat.FieldTypeToWireFormatMap[FieldType.Message]); }
} }
[Test] [Test]

@ -480,7 +480,7 @@ namespace Google.ProtocolBuffers {
} }
// Unknown field or wrong wire type. Skip. // 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); return MergeFieldFrom(tag, input);
} }

@ -13,6 +13,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
using System;
using System.Reflection; using System.Reflection;
using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.Descriptors;
using System.Collections.Generic; using System.Collections.Generic;
@ -77,19 +78,45 @@ namespace Google.ProtocolBuffers {
} }
/// <summary> /// <summary>
/// Immutable mapping from field type to wire type. Built using the attributes on /// Converts a field type to its wire type. Done with a switch for the sake
/// FieldType values. /// of speed - this is significantly faster than a dictionary lookup.
/// </summary> /// </summary>
public static readonly IDictionary<FieldType, WireType> FieldTypeToWireFormatMap = MapFieldTypes(); public static WireType GetWireType(FieldType fieldType) {
switch (fieldType) {
private static IDictionary<FieldType, WireType> MapFieldTypes() { case FieldType.Double:
var map = new Dictionary<FieldType, WireType>(); return WireType.Fixed64;
foreach (FieldInfo field in typeof(FieldType).GetFields(BindingFlags.Static | BindingFlags.Public)) { case FieldType.Float:
FieldType fieldType = (FieldType) field.GetValue(null); return WireType.Fixed32;
FieldMappingAttribute mapping = (FieldMappingAttribute)field.GetCustomAttributes(typeof(FieldMappingAttribute), false)[0]; case FieldType.Int64:
map[fieldType] = mapping.WireType; 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);
} }
} }
} }

Loading…
Cancel
Save