Example #1
0
        /// <summary>
        /// 二进制数据反序列化
        /// </summary>
        /// <param name="globalVersion"></param>
        /// <param name="fields"></param>
        /// <param name="memberCountVerify"></param>
        internal TypeDeSerializer(uint globalVersion, ref Fields <FieldSize> fields, int memberCountVerify)
        {
            Type type = typeof(T);

            this.globalVersion     = globalVersion;
            this.memberCountVerify = memberCountVerify;
            fixedFillSize          = -fields.FixedSize & 3;
#if NOJIT
            fixedMemberDeSerializer = new FieldDeSerializer(ref fields.FixedFields).DeSerialize;
            if (isMemberMap)
            {
                fixedMemberMapDeSerializer = new MemberMapDeSerializer(ref fields.FixedFields).DeSerialize;
            }
            if (fields.FieldArray.Length != 0)
            {
                memberDeSerializer = new FieldDeSerializer(ref fields.FieldArray).DeSerialize;
                if (isMemberMap)
                {
                    memberMapDeSerializer = new MemberMapDeSerializer(ref fields.FieldArray).DeSerialize;
                }
            }
#else
            DeSerializeMemberDynamicMethod    fixedDynamicMethod          = new DeSerializeMemberDynamicMethod(type);
            DeSerializeMemberMapDynamicMethod fixedMemberMapDynamicMethod = isMemberMap ? new DeSerializeMemberMapDynamicMethod(type) : default(DeSerializeMemberMapDynamicMethod);
            foreach (FieldSize member in fields.FixedFields)
            {
                fixedDynamicMethod.Push(member);
                if (isMemberMap)
                {
                    fixedMemberMapDynamicMethod.Push(member);
                }
            }
            fixedMemberDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)fixedDynamicMethod.Create <BinaryDeSerializer.DeSerializeDelegate <T> >();
            if (isMemberMap)
            {
                fixedMemberMapDeSerializer = (memberMapDeSerialize)fixedMemberMapDynamicMethod.Create <memberMapDeSerialize>();
            }

            if (fields.FieldArray.Length != 0)
            {
                DeSerializeMemberDynamicMethod    dynamicMethod          = new DeSerializeMemberDynamicMethod(type);
                DeSerializeMemberMapDynamicMethod memberMapDynamicMethod = isMemberMap ? new DeSerializeMemberMapDynamicMethod(type) : default(DeSerializeMemberMapDynamicMethod);
                foreach (FieldSize member in fields.FieldArray)
                {
                    dynamicMethod.Push(member);
                    if (isMemberMap)
                    {
                        memberMapDynamicMethod.Push(member);
                    }
                }
                memberDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)dynamicMethod.Create <BinaryDeSerializer.DeSerializeDelegate <T> >();
                if (isMemberMap)
                {
                    memberMapDeSerializer = (memberMapDeSerialize)memberMapDynamicMethod.Create <memberMapDeSerialize>();
                }
            }
#endif
            if (fields.JsonFields.Length != 0)
            {
                jsonMemberMap    = new MemberMap <T>();
                jsonMemberIndexs = new int[fields.JsonFields.Length];
                int index = 0;
                foreach (FieldIndex field in fields.JsonFields)
                {
                    jsonMemberMap.SetMember(jsonMemberIndexs[index++] = field.MemberIndex);
                }
            }
        }
Example #2
0
        static TypeDeSerializer()
        {
            Type       type = typeof(T), attributeType;
            MethodInfo methodInfo = BinaryDeSerializer.GetDeSerializeMethod(type);

            attribute = type.customAttribute <BinarySerializeAttribute>(out attributeType) ?? BinarySerializer.DefaultAttribute;
            if (methodInfo != null)
            {
                DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(BinaryDeSerializer.DeSerializeDelegate <T>), methodInfo);
                IsReferenceMember   = false;
                isValueType         = true;
                return;
            }
            if (type.IsArray)
            {
                isValueType = true;
                if (type.GetArrayRank() == 1)
                {
                    Type elementType = type.GetElementType();
                    if (!elementType.IsPointer && !typeof(Delegate).IsAssignableFrom(elementType))
                    {
                        Delegate arrayDelegate;
                        if (elementType.IsValueType)
                        {
                            if (elementType.IsEnum)
                            {
                                arrayDelegate     = EnumGenericType.Get(elementType).BinaryDeSerializeEnumArrayDelegate;
                                IsReferenceMember = false;
                            }
                            else if (elementType.IsGenericType && elementType.GetGenericTypeDefinition() == typeof(Nullable <>))
                            {
                                arrayDelegate     = StructGenericType.Get(elementType = elementType.GetGenericArguments()[0]).BinaryDeSerializeNullableArrayMethod;
                                IsReferenceMember = SerializeMethodCache.IsReferenceMember(elementType);
                            }
                            else
                            {
                                arrayDelegate     = GenericType.Get(elementType).BinaryDeSerializeStructArrayMethod;
                                IsReferenceMember = SerializeMethodCache.IsReferenceMember(elementType);
                            }
                        }
                        else
                        {
                            arrayDelegate     = ClassGenericType.Get(elementType).BinaryDeSerializeArrayMethod;
                            IsReferenceMember = SerializeMethodCache.IsReferenceMember(elementType);
                        }
                        DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)arrayDelegate;
                        return;
                    }
                }
                DefaultDeSerializer = fromNull;
                IsReferenceMember   = false;
                return;
            }
            if (type.IsEnum)
            {
                DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)EnumGenericType.Get(type).BinaryDeSerializeEnumDelegate;
                IsReferenceMember   = false;
                isValueType         = true;
                return;
            }
            if (type.IsPointer || typeof(Delegate).IsAssignableFrom(type))
            {
                DefaultDeSerializer = fromNull;
                IsReferenceMember   = false;
                isValueType         = true;
                return;
            }
            if (type.IsGenericType)
            {
                Type   genericType    = type.GetGenericTypeDefinition();
                Type[] parameterTypes = type.GetGenericArguments();
                if (genericType == typeof(LeftArray <>))
                {
                    DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)GenericType.Get(type.GetGenericArguments()[0]).BinaryDeSerializeLeftArrayMethod;
                    IsReferenceMember   = SerializeMethodCache.IsReferenceMember(parameterTypes[0]);
                    isValueType         = true;
                    return;
                }
#if !Serialize
                if (genericType == typeof(SubArray <>))
                {
                    DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)GenericType.Get(type.GetGenericArguments()[0]).BinaryDeSerializeSubArrayMethod;
                    IsReferenceMember   = SerializeMethodCache.IsReferenceMember(parameterTypes[0]);
                    isValueType         = true;
                    return;
                }
#endif
                if (genericType == typeof(Dictionary <,>))
                {
                    DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)GenericType2.Get(type.GetGenericArguments()).BinaryDeSerializeDictionaryMethod;
                    IsReferenceMember   = SerializeMethodCache.IsReferenceMember(parameterTypes[0]) || SerializeMethodCache.IsReferenceMember(parameterTypes[1]);
                    isValueType         = true;
                    return;
                }
                if (genericType == typeof(Nullable <>))
                {
                    DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)StructGenericType.Get(type.GetGenericArguments()[0]).BinaryDeSerializeNullableMethod;
                    IsReferenceMember   = SerializeMethodCache.IsReferenceMember(parameterTypes[0]);
                    isValueType         = true;
                    return;
                }
                if (genericType == typeof(KeyValuePair <,>))
                {
                    DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)GenericType2.Get(type.GetGenericArguments()).BinaryDeSerializeKeyValuePairMethod;
                    IsReferenceMember   = SerializeMethodCache.IsReferenceMember(parameterTypes[0]) || SerializeMethodCache.IsReferenceMember(parameterTypes[1]);
                    isValueType         = true;
                    return;
                }
                if (genericType == typeof(SortedDictionary <,>))
                {
                    DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)GenericType2.Get(type.GetGenericArguments()).BinaryDeSerializeSortedDictionaryMethod;
                    IsReferenceMember   = SerializeMethodCache.IsReferenceMember(parameterTypes[0]) || SerializeMethodCache.IsReferenceMember(parameterTypes[1]);
                    isValueType         = true;
                    return;
                }
                if (genericType == typeof(SortedList <,>))
                {
                    DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)GenericType2.Get(type.GetGenericArguments()).BinaryDeSerializeSortedListMethod;
                    IsReferenceMember   = SerializeMethodCache.IsReferenceMember(parameterTypes[0]) || SerializeMethodCache.IsReferenceMember(parameterTypes[1]);
                    isValueType         = true;
                    return;
                }
            }
            if ((methodInfo = SerializeMethodCache.GetCustom(type, false)) != null)
            {
                if (type.IsValueType)
                {
#if NOJIT
                    DefaultDeSerializer = new CustomDeSerializer(methodInfo).DeSerialize;
#else
                    DynamicMethod dynamicMethod = new DynamicMethod("CustomDeSerializer", null, new Type[] { typeof(BinaryDeSerializer), 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 = (BinaryDeSerializer.DeSerializeDelegate <T>)dynamicMethod.CreateDelegate(typeof(BinaryDeSerializer.DeSerializeDelegate <T>));
#endif
                }
                else
                {
                    DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(BinaryDeSerializer.DeSerializeDelegate <T>), methodInfo);
                }
                IsReferenceMember = attribute.IsReferenceMember;
                isValueType       = true;
                return;
            }
            if (type.isSerializeNotSupport())
            {
                DefaultDeSerializer = noConstructor;
                isValueType         = IsReferenceMember = true;
                return;
            }
            IsReferenceMember = attribute.IsReferenceMember;
            Delegate collectionDelegate = null;
            foreach (Type interfaceType in type.GetInterfaces())
            {
                if (interfaceType.IsGenericType)
                {
                    Type genericType = interfaceType.GetGenericTypeDefinition();
                    if (genericType == typeof(ICollection <>))
                    {
                        Type[] parameters   = interfaceType.GetGenericArguments();
                        Type   argumentType = parameters[0];
                        parameters[0] = argumentType.MakeArrayType();
                        ConstructorInfo constructorInfo = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, parameters, null);
                        if (constructorInfo != null)
                        {
                            if (type.IsValueType)
                            {
                                collectionDelegate = CollectionGenericType2.Get(type, argumentType).BinaryDeSerializeStructCollectionMethod;
                            }
                            else
                            {
                                collectionDelegate = CollectionGenericType2.Get(type, argumentType).BinaryDeSerializeClassCollectionMethod;
                            }
                            break;
                        }
                        parameters[0]   = typeof(IList <>).MakeGenericType(argumentType);
                        constructorInfo = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, parameters, null);
                        if (constructorInfo != null)
                        {
                            if (type.IsValueType)
                            {
                                collectionDelegate = CollectionGenericType2.Get(type, argumentType).BinaryDeSerializeStructCollectionMethod;
                            }
                            else
                            {
                                collectionDelegate = CollectionGenericType2.Get(type, argumentType).BinaryDeSerializeClassCollectionMethod;
                            }
                            break;
                        }
                        parameters[0]   = typeof(ICollection <>).MakeGenericType(argumentType);
                        constructorInfo = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, parameters, null);
                        if (constructorInfo != null)
                        {
                            if (type.IsValueType)
                            {
                                collectionDelegate = CollectionGenericType2.Get(type, argumentType).BinaryDeSerializeStructCollectionMethod;
                            }
                            else
                            {
                                collectionDelegate = CollectionGenericType2.Get(type, argumentType).BinaryDeSerializeClassCollectionMethod;
                            }
                            break;
                        }
                        parameters[0]   = typeof(IEnumerable <>).MakeGenericType(argumentType);
                        constructorInfo = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, parameters, null);
                        if (constructorInfo != null)
                        {
                            if (type.IsValueType)
                            {
                                collectionDelegate = CollectionGenericType2.Get(type, argumentType).BinaryDeSerializeStructCollectionMethod;
                            }
                            else
                            {
                                collectionDelegate = CollectionGenericType2.Get(type, argumentType).BinaryDeSerializeClassCollectionMethod;
                            }
                            break;
                        }
                    }
                    else if (genericType == typeof(IDictionary <,>))
                    {
                        ConstructorInfo constructorInfo = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { interfaceType }, null);
                        if (constructorInfo != null)
                        {
                            Type[] parameters = interfaceType.GetGenericArguments();
                            if (type.IsValueType)
                            {
                                collectionDelegate = DictionaryGenericType3.Get(type, parameters[0], parameters[1]).BinaryDeSerializeStructDictionaryMethod;
                            }
                            else
                            {
                                collectionDelegate = DictionaryGenericType3.Get(type, parameters[0], parameters[1]).BinaryDeSerializeClassDictionaryMethod;
                            }
                            break;
                        }
                    }
                }
            }
            if (collectionDelegate != null)
            {
                DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)collectionDelegate;
                return;
            }
            if (type.IsValueType)
            {
                isValueType = true;
            }
            else if (attribute != BinarySerializer.DefaultAttribute && attributeType != type)
            {
                for (Type baseType = type.BaseType; baseType != typeof(object); baseType = baseType.BaseType)
                {
                    BinarySerializeAttribute baseAttribute = baseType.customAttribute <BinarySerializeAttribute>();
                    if (baseAttribute != null)
                    {
                        if (baseAttribute.IsBaseType)
                        {
                            methodInfo          = DeSerializeMethodCache.BaseSerializeMethod.MakeGenericMethod(baseType, type);
                            DefaultDeSerializer = (BinaryDeSerializer.DeSerializeDelegate <T>)Delegate.CreateDelegate(typeof(BinaryDeSerializer.DeSerializeDelegate <T>), methodInfo);
                            return;
                        }
                        break;
                    }
                }
            }

            LeftArray <DeSerializeVersionField> attributeFields = new LeftArray <DeSerializeVersionField>(0);
            if ((attribute.MemberFilters & MemberFilters.PublicInstanceField) != 0)
            {
                appendField(ref attributeFields, MemberIndexGroup <T> .Group.PublicFields);
            }
            else
            {
                foreach (FieldIndex field in MemberIndexGroup <T> .Group.PublicFields)
                {
                    attributeFields.Add(new DeSerializeVersionField {
                        Field = field
                    });
                }
            }
            if ((attribute.MemberFilters & MemberFilters.NonPublicInstanceField) != 0)
            {
                appendField(ref attributeFields, MemberIndexGroup <T> .Group.NonPublicFields);
            }
            if (attribute.IsAnonymousFields)
            {
                appendField(ref attributeFields, MemberIndexGroup <T> .Group.AnonymousFields);
            }
            foreach (FieldIndex field in new MemberIndexGroup(type, true).NonPublicFields)
            {
                Type fieldType = field.Member.FieldType;
                if (!fieldType.IsPointer && (!fieldType.IsArray || fieldType.GetArrayRank() == 1) && !field.IsIgnore && !typeof(Delegate).IsAssignableFrom(fieldType))
                {
                    BinarySerializeMemberAttribute memberAttribute = field.GetAttribute <BinarySerializeMemberAttribute>(true);
                    if (memberAttribute != null && memberAttribute.IsSetup && memberAttribute.RemoveGlobalVersion != memberAttribute.GlobalVersion)
                    {
                        attributeFields.Add(new DeSerializeVersionField {
                            Field = field, Attribute = memberAttribute
                        });
                        if (memberAttribute.IsRemove)
                        {
                            attributeFields.Add(new DeSerializeVersionField {
                                Field = field, Attribute = memberAttribute, IsRemove = true
                            });
                        }
                    }
                }
            }

            isMemberMap = attribute.GetIsMemberMap;
            isJson      = attribute.GetIsJson;
            uint globalVersion = 0, removeMemberCount = 0;
            int  noSerializeMemberCount = 0;
            LeftArray <DeSerializeVersionFields <T> > deSerializeVersionFields = new LeftArray <DeSerializeVersionFields <T> >(0);
            LeftArray <DeSerializeVersionField>       attributeVersionFields   = new LeftArray <DeSerializeVersionField>(attributeFields.Length);
            foreach (DeSerializeVersionField field in attributeFields.Sort(DeSerializeVersionField.GlobalVersionSort))
            {
                if (field.GlobalVersion != globalVersion)
                {
                    deSerializeVersionFields.Add(new DeSerializeVersionFields <T>(globalVersion, attributeVersionFields.GetArray(), removeMemberCount, noSerializeMemberCount));
                    globalVersion = field.GlobalVersion;
                }
                if (field.IsRemove)
                {
                    attributeVersionFields.RemoveToEnd(value => object.ReferenceEquals(value.Field, field.Field));
                    if (field.Attribute.IsRemove)
                    {
                        --removeMemberCount;
                    }
                }
                else
                {
                    attributeVersionFields.Add(field);
                    if (field.Attribute != null)
                    {
                        if (field.Attribute.IsRemove)
                        {
                            ++removeMemberCount;
                        }
                    }
                    else
                    {
                        ++noSerializeMemberCount;
                    }
                }
            }
            fieldDeSerializer = new DeSerializeVersionFields <T>(globalVersion, attributeVersionFields.GetArray(), removeMemberCount, noSerializeMemberCount).CreateOnly(attribute);
            if (deSerializeVersionFields.Length != 0)
            {
                int count = deSerializeVersionFields.Length;
                DeSerializeVersionFields <T>[] deSerializeVersionFieldsArray = new DeSerializeVersionFields <T> [count];
                foreach (DeSerializeVersionFields <T> value in deSerializeVersionFields)
                {
                    deSerializeVersionFieldsArray[--count]          = value;
                    deSerializeVersionFieldsArray[count].CreateLock = new object();
                }
                fieldDeSerializers = deSerializeVersionFieldsArray;
            }
        }