예제 #1
0
        /// <summary>
        /// Deserializes a property of a structure.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="instance">The instance to store the property to.</param>
        /// <param name="tagFieldInfo">The active element enumerator.</param>
        /// <param name="baseOffset">The offset of the start of the structure.</param>
        /// <exception cref="System.InvalidOperationException">Offset for property is outside of its structure</exception>
        public void DeserializeProperty(EndianReader reader, ISerializationContext context, object instance, TagFieldInfo tagFieldInfo, long baseOffset)
        {
            var attr = tagFieldInfo.Attribute;

            if (attr.Flags.HasFlag(Runtime) || !CacheVersionDetection.AttributeInCacheVersion(attr, Version))
            {
                return;
            }

            if (tagFieldInfo.FieldType.IsArray && attr.Flags.HasFlag(Relative))
            {
                var type  = instance.GetType();
                var field = type.GetField(
                    attr.Field,
                    BindingFlags.Instance | BindingFlags.Public);

                var attr2 = TagStructure.GetTagFieldAttribute(type, field);
                if (CacheVersionDetection.AttributeInCacheVersion(attr2, Version))
                {
                    attr.Length = (int)Convert.ChangeType(field.GetValue(instance), typeof(int));
                }
                else
                {
                    throw new InvalidOperationException(attr2.Field);
                }
            }

            if (attr.Flags.HasFlag(Padding))
            {
#if DEBUG
                var unused = reader.ReadBytes(attr.Length);

                foreach (var b in unused)
                {
                    if (b != 0)
                    {
                        Console.WriteLine($"WARNING: non-zero padding found in {tagFieldInfo.FieldInfo.DeclaringType.FullName}.{tagFieldInfo.FieldInfo.Name} = {b}");
                        break;
                    }
                }
#else
                reader.BaseStream.Position += attr.Length;
#endif
            }
            else
            {
                var value = DeserializeValue(reader, context, attr, tagFieldInfo.FieldType);
                tagFieldInfo.SetValue(instance, value);
            }
        }
예제 #2
0
        /// <summary>
        /// Builds the <see cref="Tags.TagFieldInfo"/> <see cref="List{T}"/> to be enumerated.
        /// </summary>
        private void Build()
        {
            uint offset = 0;

            // Build the field list. Scan through the type's inheritance
            // hierarchy and add any fields belonging to tag structures.
            foreach (var type in Info.Types.Reverse <Type>())
            {
                // Ensure that fields are in declaration order - GetFields does NOT guarantee
                foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).OrderBy(i => i.MetadataToken))
                {
                    var attr = TagStructure.GetTagFieldAttribute(type, field);

                    if (CacheVersionDetection.AttributeInCacheVersion(attr, Info.Version))
                    {
                        CreateTagFieldInfo(field, attr, Info.Version, ref offset);
                    }
                }
            }
        }