예제 #1
0
        public PartitionReader(PartitionFile partition, params Type[] enumTypes)
        {
            if (partition == null)
            {
                throw new ArgumentNullException("partition");
            }

            this._Partition      = partition;
            this._EnumTypes      = this.DiscoverEnumTypes(enumTypes);
            this._DataLock       = new object();
            this._Data           = this._Partition.DataBytes == null ? null : new MemoryStream(this._Partition.DataBytes, false);
            this._FlattenedTypes = this.FlattenTypes().ToArray();
            this._Instances      = this.CreateInstances().ToArray();
        }
        public PartitionFlattenedType(PartitionFile partition, int typeIndex)
        {
            if (partition == null)
            {
                throw new ArgumentNullException("partition");
            }

            if (typeIndex < 0 || typeIndex >= partition.TypeDefinitionEntries.Count)
            {
                throw new ArgumentOutOfRangeException("typeIndex");
            }

            this._Index  = typeIndex;
            this._Name   = partition.TypeDefinitionEntries[typeIndex].Name;
            this._Fields = FlattenFields(partition, typeIndex).ToArray();
        }
        private static IEnumerable <Partition.FieldDefinitionEntry> FlattenFields(PartitionFile partition,
                                                                                  int typeIndex)
        {
            const uint baseTypeNameHash = 0x0002B581; // hash of "$"

            var fields = new LinkedList <Partition.FieldDefinitionEntry>();

            var typeDefinition = partition.TypeDefinitionEntries[typeIndex];

            for (int i = typeDefinition.FieldStartIndex, o = 0; o < typeDefinition.FieldCount; i++, o++)
            {
                fields.AddLast(partition.FieldDefinitionEntries[i]);
            }

            var current = fields.First;

            while (current != null)
            {
                var parentField = current.Value;
                if (parentField.NameHash != baseTypeNameHash ||
                    parentField.Flags.DataType != Partition.DataType.Void ||
                    parentField.Flags.DataKind != Partition.DataKind.None ||
                    parentField.Flags.DataFlags != Partition.DataFlags.None)
                {
                    current = current.Next;
                    continue;
                }

                typeDefinition = partition.TypeDefinitionEntries[parentField.TypeIndex];
                for (int i = typeDefinition.FieldStartIndex, o = 0; o < typeDefinition.FieldCount; i++, o++)
                {
                    fields.AddBefore(current, partition.FieldDefinitionEntries[i]);
                }
                fields.Remove(current);
                current = fields.First;
            }

            foreach (var field in fields)
            {
                yield return(field);
            }
        }