예제 #1
0
        private static object ReadValueType(Type valueType, ExtendedBinaryReader br, bool noAlign = false)
        {
            if (!noAlign)
            {
                br.AlignStream();
            }

            if (valueType == typeof(string))
            {
                return(br.ReadAlignedString());
            }
            else if (valueType == typeof(Int32))
            {
                return(br.ReadInt32());
            }
            else if (valueType == typeof(UInt32))
            {
                return(br.ReadUInt32());
            }
            else if (valueType == typeof(Int64))
            {
                return(br.ReadInt64());
            }
            else if (valueType == typeof(UInt64))
            {
                return(br.ReadUInt64());
            }
            else if (valueType == typeof(Int16))
            {
                return(br.ReadInt16());
            }
            else if (valueType == typeof(UInt16))
            {
                return(br.ReadUInt16());
            }
            else if (valueType == typeof(Byte))
            {
                return(br.ReadByte());
            }
            else if (valueType == typeof(SByte))
            {
                return(br.ReadSByte());
            }
            else if (valueType == typeof(Boolean))
            {
                return(br.ReadBoolean());
            }
            else if (valueType == typeof(Double))
            {
                return(br.ReadDouble());
            }
            else if (valueType == typeof(Single))
            {
                return(br.ReadSingle());
            }
            else
            {
                throw new ArgumentException($"{valueType} is not a value type");
            }
        }
예제 #2
0
        private Array ReadArray(Type elementType, ExtendedBinaryReader br)
        {
            int size = br.ReadInt32();

            if (size > 0x40000)
            {
                throw new IOException("Size exceeds limit : " + size);
            }

            var valueArray = Array.CreateInstance(elementType, size);

            if (elementType == typeof(string))
            {
                for (int i = 0; i < size; i++)
                {
                    valueArray.SetValue(br.ReadAlignedString(), i);
                }
            }
            else
            {
                for (int i = 0; i < size; i++)
                {
                    valueArray.SetValue(Deserialize(elementType, br), i);
                }
            }

            return(valueArray);
        }
예제 #3
0
        public object Deserialize(Type classType, ExtendedBinaryReader br, object obj = null)
        {
            if (!Attribute.IsDefined(classType, typeof(UnitySerializableAttribute)))
            {
                throw new UnitySerializationException("Not deserializable type : " + classType.FullName);
            }

            if (obj == null)
            {
                obj = Activator.CreateInstance(classType);
            }

            // Deserialize base type first because Type.GetFields() returns base fields last
            if (Attribute.IsDefined(classType.BaseType, typeof(UnitySerializableAttribute)))
            {
                Deserialize(classType.BaseType, br, obj);
            }

            var fieldArray = classType.GetFields();

            foreach (var field in fieldArray)
            {
                if (!field.DeclaringType.Equals(classType))
                {
                    continue;
                }

                if (field.IsLiteral || field.IsInitOnly)
                {
                    continue;
                }

                Type fieldType = field.FieldType;

                if (Attribute.IsDefined(field, typeof(UnityMinVersionAttribute)))
                {
                    var minAttrib = Attribute.GetCustomAttribute(field, typeof(UnityMinVersionAttribute)) as UnityMinVersionAttribute;
                    if (minAttrib.version > version)
                    {
                        field.SetValue(obj, GetDefault(fieldType));
                        continue;
                    }
                }

                if (Attribute.IsDefined(field, typeof(UnityMaxVersionAttribute)))
                {
                    var maxAttrib = Attribute.GetCustomAttribute(field, typeof(UnityMaxVersionAttribute)) as UnityMaxVersionAttribute;
                    if (maxAttrib.version < version)
                    {
                        field.SetValue(obj, GetDefault(fieldType));
                        continue;
                    }
                }

                object value      = null;
                bool   doNotAlign = Attribute.IsDefined(field, typeof(UnityDoNotAlignAttribute));
                if (!doNotAlign)
                {
                    br.AlignStream();
                }

                if (fieldType.IsEnum)
                {
                    var enumType = Enum.GetUnderlyingType(fieldType);
                    value = ReadValueType(enumType, br);
                }
                else if (fieldType.IsValueType)
                {
                    value = ReadValueType(fieldType, br);
                }
                else if (fieldType.IsArray && fieldType.GetElementType().IsValueType) // Value type array
                {
                    value = ReadValueArray(fieldType.GetElementType(), br);
                }
                else if (fieldType == typeof(string))
                {
                    value = br.ReadAlignedString();
                }
                else if (fieldType.IsClass || Attribute.IsDefined(fieldType, typeof(UnitySerializableAttribute)))
                {
                    if (fieldType.IsArray)
                    {
                        var elementType = fieldType.GetElementType();

                        value = ReadArray(elementType, br);
                    }
                    else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(List <>))
                    {
                        var elementType = fieldType.GetGenericArguments()[0];

                        object array;
                        if (elementType.IsValueType)
                        {
                            array = ReadValueArray(elementType, br);
                        }
                        else
                        {
                            array = ReadArray(elementType, br);
                        }

                        value = Activator.CreateInstance(fieldType, (IEnumerable)array);
                    }
                    else
                    {
                        value = Deserialize(fieldType, br);
                    }
                }
                else
                {
                    throw new IOException("Failed to deserialize, unknown type : " + fieldType.ToString());
                }

                field.SetValue(obj, value);
            }

            return(obj);
        }