Example #1
0
        private static void CreateDeserializeMethod(TypeDefinition wrapper, ModuleDefinition module, IReadOnlyList <IExposedProperty> properties)
        {
            MethodDefinition m = wrapper.AddMethod <object>("Deserialize",
                                                            MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual);

            ParameterDefinition paraId      = m.AddParameter <int>("id");
            ParameterDefinition paraReader  = m.AddParameter(module.GetTypeReference(typeof(MessagePackReader).MakeByRefType()), "reader");
            ParameterDefinition paraOptions = m.AddParameter <MessagePackSerializerOptions>("options");

            ILProcessor il = m.BeginEdit();

            il.EmitIfElse(properties, (property, index, next, body, fill) =>
            {
                // if (id == <id>)
                fill.Add(ILHelper.Ldarg(il, paraId));
                if (property.Id == 0)
                {
                    fill.Add(Instruction.Create(OpCodes.Brtrue, next));
                }
                else
                {
                    fill.Add(ILHelper.Int(property.Id));
                    fill.Add(Instruction.Create(OpCodes.Bne_Un, next));
                }
            }, (property, index, next, fill) =>
            {
                // return reader.Read()
                // return options.Resolver.GetFormatterWithVerify<Type>().Deserialize(ref reader, options)

                fill.AddRange(FormatterHelper.GetReadValue(property.FieldTypeComponentAware, module, il, paraReader, paraOptions));
                if (property.IsValueType)
                {
                    fill.Add(Instruction.Create(OpCodes.Box, property.FieldTypeComponentAware));
                }

                fill.Add(Instruction.Create(OpCodes.Ret));
            }, fill =>
            {
                // return null
                fill.Add(Instruction.Create(OpCodes.Ldnull));
                fill.Add(Instruction.Create(OpCodes.Ret));
            });

            m.EndEdit();
        }