Exemple #1
0
        /// <summary>
        /// 获取成员转换函数信息
        /// </summary>
        /// <param name="type">成员类型</param>
        /// <param name="isCustom"></param>
        /// <returns>成员转换函数信息</returns>
        internal static MethodInfo GetMemberMethodInfo(Type type, ref bool isCustom)
        {
            MethodInfo methodInfo = JsonDeSerializer.GetDeSerializeMethod(type);

            if (methodInfo != null)
            {
                return(methodInfo);
            }
            if (type.IsArray)
            {
                return(GenericType.Get(type.GetElementType()).JsonDeSerializeArrayMethod.Method);
            }
            if (type.IsEnum)
            {
                if (type.IsDefined(typeof(FlagsAttribute), false))
                {
                    return((EnumGenericType.Get(type).JsonDeSerializeEnumFlagsDelegate).Method);
                }
                return((EnumGenericType.Get(type).JsonDeSerializeEnumDelegate).Method);
            }
            if (type.IsGenericType)
            {
                Type genericType = type.GetGenericTypeDefinition();
                if (genericType == typeof(Dictionary <,>))
                {
                    return(GenericType2.Get(type.GetGenericArguments()).JsonDeSerializeDictionaryMethod.Method);
                }
                if (genericType == typeof(Nullable <>))
                {
                    return(GetNullable(type).Method);
                }
                if (genericType == typeof(KeyValuePair <,>))
                {
                    return(GenericType2.Get(type.GetGenericArguments()).JsonDeSerializeKeyValuePairMethod.Method);
                }
            }
            if ((methodInfo = GetCustom(type)) != null)
            {
                isCustom = type.IsValueType;
                return(methodInfo);
            }
            if ((methodInfo = GetIEnumerableConstructor(type)) != null)
            {
                return(methodInfo);
            }
            if (type.IsValueType)
            {
                return(StructGenericType.Get(type).JsonDeSerializeStructMethod);
            }
            return(GenericType.Get(type).JsonDeSerializeTypeMethod);
        }
        static TypeDeSerializer()
        {
            Type       type       = typeof(T);
            MethodInfo methodInfo = JsonDeSerializer.GetDeSerializeMethod(type);

            if (methodInfo != null)
            {
                DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>), methodInfo);
                return;
            }
            if (type.IsArray)
            {
                if (type.GetArrayRank() == 1)
                {
                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)GenericType.Get(type.GetElementType()).JsonDeSerializeArrayMethod;
                }
                else
                {
                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)GenericType.Get(type).JsonDeSerializeNotSupportDelegate;
                }
                return;
            }
            if (type.IsEnum)
            {
                if (type.IsDefined(typeof(FlagsAttribute), false))
                {
                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)EnumGenericType.Get(type).JsonDeSerializeEnumFlagsDelegate;
                }
                else
                {
                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)EnumGenericType.Get(type).JsonDeSerializeEnumDelegate;
                }
                return;
            }
            if (type.isSerializeNotSupport())
            {
                DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)GenericType.Get(type).JsonDeSerializeNotSupportDelegate;
                return;
            }
            if (type.IsGenericType)
            {
                Type genericType = type.GetGenericTypeDefinition();
                if (genericType == typeof(Dictionary <,>))
                {
                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)GenericType2.Get(type.GetGenericArguments()).JsonDeSerializeDictionaryMethod;
                    return;
                }
                if (genericType == typeof(Nullable <>))
                {
                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)DeSerializeMethodCache.GetNullable(type);
                    return;
                }
                if (genericType == typeof(KeyValuePair <,>))
                {
                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)GenericType2.Get(type.GetGenericArguments()).JsonDeSerializeKeyValuePairMethod;
                    isValueType         = true;
                    return;
                }
            }
            if ((methodInfo = DeSerializeMethodCache.GetCustom(type)) != null)
            {
                if (type.IsValueType)
                {
#if NOJIT
                    DefaultDeSerializer = new CustomDeSerializer(methodInfo).DeSerialize;
#else
                    DynamicMethod dynamicMethod = new DynamicMethod("CustomJsonDeSerializer", null, new Type[] { typeof(JsonDeSerializer), type.MakeByRefType() }, type, true);
                    ILGenerator   generator     = dynamicMethod.GetILGenerator();
                    generator.Emit(OpCodes.Ldarg_1);
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.call(methodInfo);
                    generator.Emit(OpCodes.Ret);
                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)dynamicMethod.CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>));
#endif
                }
                else
                {
                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>), methodInfo);
                }
            }
            else
            {
                Type attributeType;
                attribute = type.customAttribute <JsonDeSerializeAttribute>(out attributeType) ?? JsonDeSerializer.AllMemberAttribute;
                if ((methodInfo = DeSerializeMethodCache.GetIEnumerableConstructor(type)) != null)
                {
                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>), methodInfo);
                }
                else
                {
                    if (type.IsValueType)
                    {
                        isValueType = true;
                    }
                    else if (attribute != JsonDeSerializer.AllMemberAttribute && attributeType != type)
                    {
                        for (Type baseType = type.BaseType; baseType != typeof(object); baseType = baseType.BaseType)
                        {
                            JsonDeSerializeAttribute baseAttribute = baseType.customAttribute <JsonDeSerializeAttribute>();
                            if (baseAttribute != null)
                            {
                                if (baseAttribute.IsBaseType)
                                {
                                    methodInfo          = DeSerializeMethodCache.BaseDeSerializeMethod.MakeGenericMethod(baseType, type);
                                    DefaultDeSerializer = (JsonDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>), methodInfo);
                                    return;
                                }
                                break;
                            }
                        }
                    }
                    FieldIndex             defaultMember = null;
                    LeftArray <FieldIndex> fields        = DeSerializeMethodCache.GetFields(MemberIndexGroup <T> .GetFields(attribute.MemberFilters), attribute, ref defaultMember);
                    LeftArray <KeyValue <PropertyIndex, MethodInfo> > properties = DeSerializeMethodCache.GetProperties(MemberIndexGroup <T> .GetProperties(attribute.MemberFilters), attribute);
                    bool isBox = false;
                    if (type.IsValueType && fields.Length + properties.Length == 1)
                    {
                        BoxSerializeAttribute boxSerialize = AutoCSer.Metadata.TypeAttribute.GetAttribute <BoxSerializeAttribute>(type);
                        if (boxSerialize != null && boxSerialize.IsJson)
                        {
                            isBox         = true;
                            defaultMember = null;
                        }
                    }
                    TryDeSerializeFilter[] deSerializers = new TryDeSerializeFilter[fields.Length + properties.Length + (defaultMember == null ? 0 : 1)];
                    //memberMap.type memberMapType = memberMap<valueType>.TypeInfo;
                    string[] names = isBox ? null : new string[deSerializers.Length];
#if !NOJIT
                    DeSerializeDynamicMethod dynamicMethod = isBox ? default(DeSerializeDynamicMethod) : new DeSerializeDynamicMethod(type, false), memberMapDynamicMethod = isBox ? default(DeSerializeDynamicMethod) : new DeSerializeDynamicMethod(type, true);
#endif
                    int index = 0, nameLength = 0, maxNameLength = 0;
                    foreach (FieldIndex member in fields)
                    {
                        TryDeSerializeFilter tryDeSerialize = deSerializers[index] = new TryDeSerializeFilter
                        {
#if NOJIT
                            TryDeSerialize = new FieldDeSerializer(member.Member).DeSerializer(),
#else
                            TryDeSerialize = (JsonDeSerializer.DeSerializeDelegate <T>)DeSerializeMethodCache.CreateDynamicMethod(type, member.Member).CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>)),
#endif
                            MemberMapIndex = member.MemberIndex,
                            //MemberFilters = member.Member.IsPublic ? Metadata.MemberFilters.PublicInstanceField : Metadata.MemberFilters.NonPublicInstanceField
                        };
                        if (!isBox)
                        {
#if !NOJIT
                            dynamicMethod.Push(member);
                            memberMapDynamicMethod.Push(member);
#endif
                            string name = member.AnonymousName;
                            if (name.Length > maxNameLength)
                            {
                                maxNameLength = name.Length;
                            }
                            nameLength += (names[index++] = name).Length;
                            if (member == defaultMember)
                            {
                                deSerializers[deSerializers.Length - 1] = tryDeSerialize;
                                names[deSerializers.Length - 1]         = string.Empty;
                            }
                        }
                    }
                    foreach (KeyValue <PropertyIndex, MethodInfo> member in properties)
                    {
                        deSerializers[index] = new TryDeSerializeFilter
                        {
#if NOJIT
                            TryDeSerialize = new PropertyDeSerializer(member.Key.Member).DeSerializer(),
#else
                            TryDeSerialize = (JsonDeSerializer.DeSerializeDelegate <T>)DeSerializeMethodCache.CreateDynamicMethod(type, member.Key.Member, member.Value).CreateDelegate(typeof(JsonDeSerializer.DeSerializeDelegate <T>)),
#endif
                            MemberMapIndex = member.Key.MemberIndex,
                            //MemberFilters = member.Value.IsPublic ? Metadata.MemberFilters.PublicInstanceProperty : Metadata.MemberFilters.NonPublicInstanceProperty
                        };
                        if (!isBox)
                        {
#if !NOJIT
                            dynamicMethod.Push(member.Key, member.Value);
                            memberMapDynamicMethod.Push(member.Key, member.Value);
#endif
                            if (member.Key.Member.Name.Length > maxNameLength)
                            {
                                maxNameLength = member.Key.Member.Name.Length;
                            }
                            nameLength += (names[index++] = member.Key.Member.Name).Length;
                        }
                    }
                    if (isBox)
                    {
                        unboxDeSerializer   = deSerializers[0].TryDeSerialize;
                        DefaultDeSerializer = unbox;
                    }
                    else
                    {
#if !NOJIT
                        deSerializeMember    = (DeSerializeMember)dynamicMethod.Create <DeSerializeMember>();
                        deSerializeMemberMap = (DeSerializeMemberMap)memberMapDynamicMethod.Create <DeSerializeMemberMap>();
#endif
                        if (type.Name[0] == '<')
                        {
                            isAnonymousType = true;
                        }
                        if (maxNameLength > (short.MaxValue >> 1) - 4 || nameLength == 0)
                        {
                            memberNames = Unmanaged.NullByte8;
                        }
                        else
                        {
                            memberNames = Unmanaged.GetStaticPointer((nameLength + (names.Length - (defaultMember == null ? 0 : 1)) * 5 + 1) << 1, false);
                            byte *write = memberNames.Byte;
                            foreach (string name in names)
                            {
                                if (name.Length != 0)
                                {
                                    if (write == memberNames.Byte)
                                    {
                                        *(short *)write = (short)((name.Length + 3) * sizeof(char));
                                        *(char *)(write + sizeof(short)) = '"';
                                        write += sizeof(short) + sizeof(char);
                                    }
                                    else
                                    {
                                        *(short *)write = (short)((name.Length + 4) * sizeof(char));
                                        *(int *)(write + sizeof(short)) = ',' + ('"' << 16);
                                        write += sizeof(short) + sizeof(int);
                                    }
                                    fixed(char *nameFixed = name) AutoCSer.Extensions.StringExtension.SimpleCopyNotNull(nameFixed, (char *)write, name.Length);

                                    *(int *)(write += name.Length << 1) = '"' + (':' << 16);
                                    write += sizeof(int);
                                }
                            }
                            *(short *)write = 0;
                        }
                        memberSearcher      = new StateSearcher(StateSearcher.GetMemberSearcher(type, names));
                        memberDeSerializers = deSerializers;

                        Type refType = type.MakeByRefType();
                        foreach (AutoCSer.Metadata.AttributeMethod attributeMethod in AutoCSer.Metadata.AttributeMethod.GetStatic(type))
                        {
                            if ((methodInfo = attributeMethod.Method).ReturnType == typeof(void))
                            {
                                ParameterInfo[] parameters = methodInfo.GetParameters();
                                if (parameters.Length == 3 && parameters[0].ParameterType == typeof(JsonDeSerializer) && parameters[1].ParameterType == refType && parameters[2].ParameterType == Emit.Pub.PointerSizeRefType)
                                {
                                    if (attributeMethod.GetAttribute <JsonDeSerializeUnknownNameAttriubte>() != null)
                                    {
                                        onUnknownName = (UnknownDeSerialize)Delegate.CreateDelegate(typeof(UnknownDeSerialize), methodInfo);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }