public void TryGetValueSafe() { var keys = new[] { "abcdefgh", "abcdefghabcd1", "abcdefghabcd2", "zeregzfw", "takohogergahu", "rezhgoerghouerhgouerhozughoreughozheorugheoghozuehrouehogreuhgoeuz", "mp1", "mp2", "mp3", "mp4", "mp5" }; var automata = new AutomataDictionary(); for (int i = 0; i < keys.Length; i++) { automata.Add(keys[i], i); } for (int i = 0; i < keys.Length; i++) { var enc = Encoding.UTF8.GetBytes(keys[i]); int v; automata.TryGetValueSafe(new ArraySegment <byte>(enc, 0, enc.Length), out v).IsTrue(); v.Is(i); } }
public PaginationItemFormatter(string itemFieldName) { dictionary = new Utf8Json.Internal.AutomataDictionary(); dictionary.Add(JsonWriter.GetEncodedPropertyNameWithoutQuotation(itemFieldName), 0); dictionary.Add(JsonWriter.GetEncodedPropertyNameWithoutQuotation(nameof(Pagination <T> .prev_page)), 1); dictionary.Add(JsonWriter.GetEncodedPropertyNameWithoutQuotation(nameof(Pagination <T> .next_page)), 2); dictionary.Add(JsonWriter.GetEncodedPropertyNameWithoutQuotation(nameof(Pagination <T> .total_count)), 3); dictionary.Add(JsonWriter.GetEncodedPropertyNameWithoutQuotation(nameof(Pagination <T> .page)), 4); dictionary.Add(JsonWriter.GetEncodedPropertyNameWithoutQuotation(nameof(Pagination <T> .per_page)), 5); dictionary.Add(JsonWriter.GetEncodedPropertyNameWithoutQuotation(nameof(Pagination <T> .max_per_page)), 6); }
public StringKeySerializerTargetFormatter_AutomataLookup() { this.keyMapping = new AutomataDictionary() { { "MyProperty1", 0 }, { "MyProperty2", 1 }, { "MyProperty3", 2 }, { "MyProperty4", 3 }, { "MyProperty5", 4 }, { "MyProperty6", 5 }, { "MyProperty7", 6 }, { "MyProperty8", 7 }, { "MyProperty9", 8 }, }; this.stringByteKeys = new byte[][] { Encoding.UTF8.GetBytes("MyProperty1"), Encoding.UTF8.GetBytes("MyProperty2"), Encoding.UTF8.GetBytes("MyProperty3"), Encoding.UTF8.GetBytes("MyProperty4"), Encoding.UTF8.GetBytes("MyProperty5"), Encoding.UTF8.GetBytes("MyProperty6"), Encoding.UTF8.GetBytes("MyProperty7"), Encoding.UTF8.GetBytes("MyProperty8"), Encoding.UTF8.GetBytes("MyProperty9"), }; }
static CollectionFormatterHelper() { GroupingName = new[] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Key"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Elements"), }; GroupingAutomata = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Key"), 0 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Elements"), 1 }, }; }
static StandardClassLibraryFormatterHelper() { keyValuePairName = new byte[][] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Key"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Value"), }; keyValuePairAutomata = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Key"), 0 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Value"), 1 }, }; }
public SimplePersonFormatter() { // escaped string byte cache with "{" and "," nameCaches = new byte[3][] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Age"), // {\"Age\": JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("FirstName"), // ",\"FirstName\": JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("LastName"), // ",\"LastName\": }; dictionary = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Age"), 0 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("FirstName"), 1 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("LastName"), 2 }, }; nameCaches2 = new byte[][] { JsonWriter.GetEncodedPropertyName("Age"), // JsonWriter.GetEncodedPropertyName("FirstName"), // JsonWriter.GetEncodedPropertyName("LastName"), // }; }
internal ReflectionObjectFormatter(ObjectSerializationInfo metaInfo) { this.metaInfo = metaInfo; // for write { var memberNameList = new List <byte[]>(metaInfo.Members.Length); var emmitableMemberList = new List <ObjectSerializationInfo.EmittableMember>(metaInfo.Members.Length); foreach (var item in metaInfo.Members) { if (item.IsWritable) { emmitableMemberList.Add(item); memberNameList.Add(Encoding.UTF8.GetBytes(item.Name)); } } this.writeMemberNames = memberNameList.ToArray(); this.writeMembers = emmitableMemberList.ToArray(); } // for read { var automata = new AutomataDictionary(); var emmitableMemberList = new List <ObjectSerializationInfo.EmittableMember>(metaInfo.Members.Length); int index = 0; foreach (var item in metaInfo.Members) { if (item.IsReadable) { emmitableMemberList.Add(item); automata.Add(item.Name, index++); } } this.readMembers = emmitableMemberList.ToArray(); this.mapMemberDictionary = automata; } }
static ValueTupleFormatterHelper() { nameCache1 = new byte[][] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Item1"), }; dictionary1 = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item1"), 0 }, }; nameCache2 = new byte[][] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Item1"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item2"), }; dictionary2 = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item1"), 0 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item2"), 1 }, }; nameCache3 = new byte[][] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Item1"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item2"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item3"), }; dictionary3 = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item1"), 0 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item2"), 1 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item3"), 2 }, }; nameCache4 = new byte[][] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Item1"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item2"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item3"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item4"), }; dictionary4 = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item1"), 0 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item2"), 1 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item3"), 2 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item4"), 3 }, }; nameCache5 = new byte[][] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Item1"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item2"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item3"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item4"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item5"), }; dictionary5 = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item1"), 0 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item2"), 1 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item3"), 2 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item4"), 3 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item5"), 4 }, }; nameCache6 = new byte[][] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Item1"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item2"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item3"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item4"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item5"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item6"), }; dictionary6 = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item1"), 0 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item2"), 1 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item3"), 2 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item4"), 3 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item5"), 4 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item6"), 5 }, }; nameCache7 = new byte[][] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Item1"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item2"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item3"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item4"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item5"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item6"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item7"), }; dictionary7 = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item1"), 0 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item2"), 1 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item3"), 2 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item4"), 3 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item5"), 4 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item6"), 5 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item7"), 6 }, }; nameCache8 = new byte[][] { JsonWriter.GetEncodedPropertyNameWithBeginObject("Item1"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item2"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item3"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item4"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item5"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item6"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Item7"), JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator("Rest"), }; dictionary8 = new AutomataDictionary { { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item1"), 0 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item2"), 1 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item3"), 2 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item4"), 3 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item5"), 4 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item6"), 5 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Item7"), 6 }, { JsonWriter.GetEncodedPropertyNameWithoutQuotation("Rest"), 7 }, }; }
static void EmitDeserializeUnionCase( ILGenerator il, Type type, UnionSerializationInfo info, LocalBuilder unionKey, FieldBuilder stringByteKeysField, ArgumentField reader, ArgumentField argOptions, LocalBuilder localResolver ) { // options.Security.DepthStep(ref reader); argOptions.EmitLoad(); il.EmitCall(getSecurityFromOptions); reader.EmitLdarg(); il.EmitCall(securityDepthStep); // var length = ReadMapHeader(ref byteSequence); LocalBuilder length = il.DeclareLocal(typeof(int)); // [loc:1] reader.EmitLdarg(); if (info.IsIntKey) { il.EmitCall(MessagePackReaderTypeInfo.ReadArrayHeader); } else { il.EmitCall(MessagePackReaderTypeInfo.ReadMapHeader); } il.EmitStloc(length); // make local fields Label?gotoDefault = null; DeserializeInfo[] infoList; if (info.IsIntKey) { var maxKey = info.Members.Select(x => x.IntKey).DefaultIfEmpty(-1).Max(); var len = maxKey + 1; var intKeyMap = info.Members.ToDictionary(x => x.IntKey); infoList = Enumerable.Range(0, len) .Select(x => { UnionSerializationInfo.EmittableMember member; if (intKeyMap.TryGetValue(x, out member)) { return(new DeserializeInfo { MemberInfo = member, LocalField = il.DeclareLocal(member.Type), SwitchLabel = il.DefineLabel() }); } else { // return null MemberInfo, should filter null if (gotoDefault == null) { gotoDefault = il.DefineLabel(); } return(new DeserializeInfo { MemberInfo = null, LocalField = null, SwitchLabel = gotoDefault.Value, }); } }) .ToArray(); } else { infoList = info.Members .Select(item => new DeserializeInfo { MemberInfo = item, LocalField = il.DeclareLocal(item.Type), SwitchLabel = il.DefineLabel() }) .ToArray(); } // Read Loop(for var i = 0; i< length; i++) if (info.IsStringKey) { var automata = new AutomataDictionary(); for (int i = 0; i < info.Members.Length; i++) { automata.Add(info.Members[i].StringKey, i); } LocalBuilder buffer = il.DeclareLocal(typeof(ReadOnlySpan <byte>)); LocalBuilder longKey = il.DeclareLocal(typeof(ulong)); // for (int i = 0; i < len; i++) il.EmitIncrementFor(length, forILocal => { Label readNext = il.DefineLabel(); Label loopEnd = il.DefineLabel(); reader.EmitLdarg(); il.EmitCall(ReadStringSpan); il.EmitStloc(buffer); // gen automata name lookup automata.EmitMatch( il, buffer, longKey, x => { var i = x.Value; if (infoList[i].MemberInfo != null) { EmitDeserializeValue(il, infoList[i], i, reader, argOptions, localResolver); il.Emit(OpCodes.Br, loopEnd); } else { il.Emit(OpCodes.Br, readNext); } }, () => { il.Emit(OpCodes.Br, readNext); }); il.MarkLabel(readNext); reader.EmitLdarg(); il.EmitCall(MessagePackReaderTypeInfo.Skip); il.MarkLabel(loopEnd); }); } else { LocalBuilder key = il.DeclareLocal(typeof(int)); Label switchDefault = il.DefineLabel(); il.EmitIncrementFor(length, forILocal => { Label loopEnd = il.DefineLabel(); il.EmitLdloc(forILocal); il.EmitStloc(key); // switch... local = Deserialize il.EmitLdloc(key); il.Emit(OpCodes.Switch, infoList.Select(x => x.SwitchLabel).ToArray()); il.MarkLabel(switchDefault); // default, only read. reader.ReadNextBlock(); reader.EmitLdarg(); il.EmitCall(MessagePackReaderTypeInfo.Skip); il.Emit(OpCodes.Br, loopEnd); if (gotoDefault != null) { il.MarkLabel(gotoDefault.Value); il.Emit(OpCodes.Br, switchDefault); } var i = 0; foreach (DeserializeInfo item in infoList) { if (item.MemberInfo != null) { il.MarkLabel(item.SwitchLabel); EmitDeserializeValue(il, item, i++, reader, argOptions, localResolver); il.Emit(OpCodes.Br, loopEnd); } } il.MarkLabel(loopEnd); }); } // create result union case LocalBuilder structLocal = EmitNewObject(il, type, info, infoList); // IMessagePackSerializationCallbackReceiver.OnAfterDeserialize() if (type.GetTypeInfo().ImplementedInterfaces.Any(x => x == typeof(IMessagePackSerializationCallbackReceiver))) { // call directly var runtimeMethods = type.GetRuntimeMethods().Where(x => x.Name == "OnAfterDeserialize").ToArray(); if (runtimeMethods.Length == 1) { if (info.IsClass) { il.Emit(OpCodes.Dup); } else { il.EmitLdloca(structLocal); } il.Emit(OpCodes.Call, runtimeMethods[0]); // don't use EmitCall helper(must use 'Call') } else { if (info.IsStruct) { il.EmitLdloc(structLocal); il.Emit(OpCodes.Box, type); } else { il.Emit(OpCodes.Dup); } il.EmitCall(onAfterDeserialize); } } // reader.Depth--; reader.EmitLdarg(); il.Emit(OpCodes.Dup); il.EmitCall(readerDepthGet); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Sub_Ovf); il.EmitCall(readerDepthSet); if (info.IsStruct) { il.Emit(OpCodes.Ldloc, structLocal); } }
internal static object Deserialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] readMembers, int[] constructorParameterIndexes, AutomataDictionary mapMemberDictionary, byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) { var startOffset = offset; object[] parameters = null; var headerType = MessagePackBinary.GetMessagePackType(bytes, offset); if (headerType == MessagePackType.Nil) { readSize = 1; return(null); } else if (headerType == MessagePackType.Array) { var arraySize = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); offset += readSize; // ReadValues parameters = new object[arraySize]; for (int i = 0; i < arraySize; i++) { var info = readMembers[i]; if (info != null) { parameters[i] = MessagePackSerializer.NonGeneric.Deserialize(info.Type, bytes, offset, formatterResolver, out readSize); offset += readSize; } else { offset += MessagePackBinary.ReadNextBlock(bytes, offset); } } } else if (headerType == MessagePackType.Map) { var mapSize = MessagePackBinary.ReadMapHeader(bytes, offset, out readSize); offset += readSize; // ReadValues parameters = new object[mapSize]; for (int i = 0; i < mapSize; i++) { var rawPropName = MessagePackBinary.ReadStringSegment(bytes, offset, out readSize); offset += readSize; int index; if (mapMemberDictionary.TryGetValue(rawPropName.Array, rawPropName.Offset, rawPropName.Count, out index)) { var info = readMembers[index]; parameters[index] = MessagePackSerializer.NonGeneric.Deserialize(info.Type, bytes, offset, formatterResolver, out readSize); offset += readSize; } else { offset += MessagePackBinary.ReadNextBlock(bytes, offset); } } } else { throw new InvalidOperationException("Invalid MessagePackType:" + MessagePackCode.ToFormatName(bytes[offset])); } // CreateObject object result = null; if (constructorParameterIndexes.Length == 0) { result = Activator.CreateInstance(metaInfo.Type); } else { var args = new object[constructorParameterIndexes.Length]; for (int i = 0; i < constructorParameterIndexes.Length; i++) { args[i] = parameters[constructorParameterIndexes[i]]; } result = Activator.CreateInstance(metaInfo.Type, args); } // SetMembers for (int i = 0; i < readMembers.Length; i++) { var info = readMembers[i]; if (info != null) { info.ReflectionStoreValue(result, parameters[i]); } } readSize = offset - startOffset; return(result); }
static void EmitDeserializeUnionCase(ILGenerator il, Type type, UnionSerializationInfo info, LocalBuilder unionKey, FieldBuilder stringByteKeysField) { // var startOffset = offset; var startOffsetLocal = il.DeclareLocal(typeof(int)); // [loc:0] il.EmitLdarg(2); il.EmitStloc(startOffsetLocal); // var length = ReadMapHeader var length = il.DeclareLocal(typeof(int)); il.EmitLdarg(1); il.EmitLdarg(2); il.EmitLdarg(4); if (info.IsIntKey) { il.EmitCall(MessagePackBinaryTypeInfo.ReadArrayHeader); } else { il.EmitCall(MessagePackBinaryTypeInfo.ReadMapHeader); } il.EmitStloc(length); EmitOffsetPlusReadSize(il); // make local fields Label?gotoDefault = null; DeserializeInfo[] infoList; if (info.IsIntKey) { var maxKey = info.Members.Select(x => x.IntKey).DefaultIfEmpty(-1).Max(); var len = maxKey + 1; var intKeyMap = info.Members.ToDictionary(x => x.IntKey); infoList = Enumerable.Range(0, len) .Select(x => { UnionSerializationInfo.EmittableMember member; if (intKeyMap.TryGetValue(x, out member)) { return(new DeserializeInfo { MemberInfo = member, LocalField = il.DeclareLocal(member.Type), SwitchLabel = il.DefineLabel() }); } else { // return null MemberInfo, should filter null if (gotoDefault == null) { gotoDefault = il.DefineLabel(); } return(new DeserializeInfo { MemberInfo = null, LocalField = null, SwitchLabel = gotoDefault.Value, }); } }) .ToArray(); } else { infoList = info.Members .Select(item => new DeserializeInfo { MemberInfo = item, LocalField = il.DeclareLocal(item.Type), SwitchLabel = il.DefineLabel() }) .ToArray(); } // Read Loop(for var i = 0; i< length; i++) if (info.IsStringKey) { var automata = new AutomataDictionary(); for (int i = 0; i < info.Members.Length; i++) { automata.Add(info.Members[i].StringKey, i); } var buffer = il.DeclareLocal(typeof(byte).MakeByRefType(), true); var keyArraySegment = il.DeclareLocal(typeof(ArraySegment <byte>)); var longKey = il.DeclareLocal(typeof(ulong)); var p = il.DeclareLocal(typeof(byte *)); var rest = il.DeclareLocal(typeof(int)); // fixed (byte* buffer = &bytes[0]) { il.EmitLdarg(1); il.EmitLdc_I4(0); il.Emit(OpCodes.Ldelema, typeof(byte)); il.EmitStloc(buffer); // for (int i = 0; i < len; i++) il.EmitIncrementFor(length, forILocal => { var readNext = il.DefineLabel(); var loopEnd = il.DefineLabel(); il.EmitLdarg(1); il.EmitLdarg(2); il.EmitLdarg(4); il.EmitCall(MessagePackBinaryTypeInfo.ReadStringSegment); il.EmitStloc(keyArraySegment); EmitOffsetPlusReadSize(il); // p = buffer + arraySegment.Offset il.EmitLdloc(buffer); il.Emit(OpCodes.Conv_I); il.EmitLdloca(keyArraySegment); il.EmitCall(typeof(ArraySegment <byte>).GetRuntimeProperty("Offset").GetGetMethod()); il.Emit(OpCodes.Add); il.EmitStloc(p); // rest = arraySegment.Count il.EmitLdloca(keyArraySegment); il.EmitCall(typeof(ArraySegment <byte>).GetRuntimeProperty("Count").GetGetMethod()); il.EmitStloc(rest); // if(rest == 0) goto End il.EmitLdloc(rest); il.Emit(OpCodes.Brfalse, readNext); // gen automata name lookup automata.EmitMatch(il, p, rest, longKey, x => { var i = x.Value; if (infoList[i].MemberInfo != null) { EmitDeserializeValue(il, infoList[i]); il.Emit(OpCodes.Br, loopEnd); } else { il.Emit(OpCodes.Br, readNext); } }, () => { il.Emit(OpCodes.Br, readNext); }); il.MarkLabel(readNext); il.EmitLdarg(4); il.EmitLdarg(1); il.EmitLdarg(2); il.EmitCall(MessagePackBinaryTypeInfo.ReadNextBlock); il.Emit(OpCodes.Stind_I4); il.MarkLabel(loopEnd); EmitOffsetPlusReadSize(il); }); // end fixed il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Conv_U); il.EmitStloc(buffer); } else { var key = il.DeclareLocal(typeof(int)); var switchDefault = il.DefineLabel(); il.EmitIncrementFor(length, forILocal => { var loopEnd = il.DefineLabel(); il.EmitLdloc(forILocal); il.EmitStloc(key); // switch... local = Deserialize il.EmitLdloc(key); il.Emit(OpCodes.Switch, infoList.Select(x => x.SwitchLabel).ToArray()); il.MarkLabel(switchDefault); // default, only read. readSize = MessagePackBinary.ReadNextBlock(bytes, offset); il.EmitLdarg(4); il.EmitLdarg(1); il.EmitLdarg(2); il.EmitCall(MessagePackBinaryTypeInfo.ReadNextBlock); il.Emit(OpCodes.Stind_I4); il.Emit(OpCodes.Br, loopEnd); if (gotoDefault != null) { il.MarkLabel(gotoDefault.Value); il.Emit(OpCodes.Br, switchDefault); } foreach (var item in infoList) { if (item.MemberInfo != null) { il.MarkLabel(item.SwitchLabel); EmitDeserializeValue(il, item); il.Emit(OpCodes.Br, loopEnd); } } // offset += readSize il.MarkLabel(loopEnd); EmitOffsetPlusReadSize(il); }); } // finish readSize: readSize = offset - startOffset; il.EmitLdarg(4); il.EmitLdarg(2); il.EmitLdloc(startOffsetLocal); il.Emit(OpCodes.Sub); il.Emit(OpCodes.Stind_I4); // create result union case var structLocal = EmitNewObject(il, type, info, infoList); // IMessagePackSerializationCallbackReceiver.OnAfterDeserialize() if (type.GetTypeInfo().ImplementedInterfaces.Any(x => x == typeof(IMessagePackSerializationCallbackReceiver))) { // call directly var runtimeMethods = type.GetRuntimeMethods().Where(x => x.Name == "OnAfterDeserialize").ToArray(); if (runtimeMethods.Length == 1) { if (info.IsClass) { il.Emit(OpCodes.Dup); } else { il.EmitLdloca(structLocal); } il.Emit(OpCodes.Call, runtimeMethods[0]); // don't use EmitCall helper(must use 'Call') } else { if (info.IsStruct) { il.EmitLdloc(structLocal); il.Emit(OpCodes.Box, type); } else { il.Emit(OpCodes.Dup); } il.EmitCall(onAfterDeserialize); } } if (info.IsStruct) { il.Emit(OpCodes.Ldloc, structLocal); } }