public EnumSerializer(Type enumType, EnumSerializer.EnumPair[] map) { if (enumType == null) { throw new ArgumentNullException("enumType"); } this.enumType = enumType; this.map = map; if (map != null) { for (int i = 1; i < map.Length; i++) { for (int j = 0; j < i; j++) { if (map[i].WireValue == map[j].WireValue && !object.Equals(map[i].RawValue, map[j].RawValue)) { throw new ProtoException("Multiple enums with wire-value " + map[i].WireValue.ToString()); } if (object.Equals(map[i].RawValue, map[j].RawValue) && map[i].WireValue != map[j].WireValue) { throw new ProtoException("Multiple enums with deserialized-value " + map[i].RawValue); } } } } }
void ProtoBuf.Serializers.IProtoSerializer.EmitWrite(CompilerContext ctx, Local valueFrom) { ProtoTypeCode typeCode = this.GetTypeCode(); if (this.map == null) { ctx.LoadValue(valueFrom); ctx.ConvertToInt32(typeCode, false); ctx.EmitBasicWrite("WriteInt32", null); return; } using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom)) { CodeLabel codeLabel = ctx.DefineLabel(); for (int i = 0; i < (int)this.map.Length; i++) { CodeLabel codeLabel1 = ctx.DefineLabel(); CodeLabel codeLabel2 = ctx.DefineLabel(); ctx.LoadValue(localWithValue); EnumSerializer.WriteEnumValue(ctx, typeCode, this.map[i].RawValue); ctx.BranchIfEqual(codeLabel2, true); ctx.Branch(codeLabel1, true); ctx.MarkLabel(codeLabel2); ctx.LoadValue(this.map[i].WireValue); ctx.EmitBasicWrite("WriteInt32", null); ctx.Branch(codeLabel, false); ctx.MarkLabel(codeLabel1); } ctx.LoadReaderWriter(); ctx.LoadValue(localWithValue); ctx.CastToObject(this.ExpectedType); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("ThrowEnumException")); ctx.MarkLabel(codeLabel); } }
private static void WriteEnumValue(CompilerContext ctx, ProtoTypeCode typeCode, CodeLabel handler, CodeLabel @continue, object value, Local local) { ctx.MarkLabel(handler); EnumSerializer.WriteEnumValue(ctx, typeCode, value); ctx.StoreValue(local); ctx.Branch(@continue, false); }
void ProtoBuf.Serializers.IProtoSerializer.EmitRead(CompilerContext ctx, Local valueFrom) { ProtoTypeCode typeCode = this.GetTypeCode(); if (this.map == null) { ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int))); ctx.ConvertFromInt32(typeCode, false); return; } int[] wireValue = new int[(int)this.map.Length]; object[] rawValue = new object[(int)this.map.Length]; for (int i = 0; i < (int)this.map.Length; i++) { wireValue[i] = this.map[i].WireValue; rawValue[i] = this.map[i].RawValue; } using (Local local = new Local(ctx, this.ExpectedType)) { using (Local local1 = new Local(ctx, ctx.MapType(typeof(int)))) { ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int))); ctx.StoreValue(local1); CodeLabel codeLabel = ctx.DefineLabel(); BasicList.NodeEnumerator enumerator = BasicList.GetContiguousGroups(wireValue, rawValue).GetEnumerator(); while (enumerator.MoveNext()) { BasicList.Group current = (BasicList.Group)enumerator.Current; CodeLabel codeLabel1 = ctx.DefineLabel(); int count = current.Items.Count; if (count != 1) { ctx.LoadValue(local1); ctx.LoadValue(current.First); ctx.Subtract(); CodeLabel[] codeLabelArray = new CodeLabel[count]; for (int j = 0; j < count; j++) { codeLabelArray[j] = ctx.DefineLabel(); } ctx.Switch(codeLabelArray); ctx.Branch(codeLabel1, false); for (int k = 0; k < count; k++) { EnumSerializer.WriteEnumValue(ctx, typeCode, codeLabelArray[k], codeLabel, current.Items[k], local); } } else { ctx.LoadValue(local1); ctx.LoadValue(current.First); CodeLabel codeLabel2 = ctx.DefineLabel(); ctx.BranchIfEqual(codeLabel2, true); ctx.Branch(codeLabel1, false); EnumSerializer.WriteEnumValue(ctx, typeCode, codeLabel2, codeLabel, current.Items[0], local); } ctx.MarkLabel(codeLabel1); } ctx.LoadReaderWriter(); ctx.LoadValue(this.ExpectedType); ctx.LoadValue(local1); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("ThrowEnumException")); ctx.MarkLabel(codeLabel); ctx.LoadValue(local); } } }