예제 #1
0
        public static GroupListOverlay <T> Factory(
            IBinaryReadStream stream,
            ReadOnlyMemorySlice <byte> data,
            BinaryOverlayFactoryPackage package,
            ObjectType objectType,
            int offset)
        {
            List <int> locations = new List <int>();

            stream.Position -= package.MetaData.Constants.GroupConstants.HeaderLength;
            var groupMeta = stream.GetGroup(package);
            var finalPos  = stream.Position + groupMeta.TotalLength;

            stream.Position += package.MetaData.Constants.GroupConstants.HeaderLength;
            // Parse locations
            while (stream.Position < finalPos)
            {
                VariableHeader meta = package.MetaData.Constants.Constants(objectType).VariableMeta(stream.RemainingMemory);
                locations.Add(checked ((int)stream.Position - offset));
                stream.Position += checked ((int)meta.TotalLength);
            }

            return(new GroupListOverlay <T>(
                       locations,
                       data,
                       package));
        }
예제 #2
0
        public static void FillModTypes(
            IBinaryReadStream stream,
            ModTypeFillWrapper fill,
            BinaryOverlayFactoryPackage package)
        {
            int?      lastParsed      = null;
            ModHeader headerMeta      = stream.GetModHeader(package);
            var       minimumFinalPos = checked ((int)(stream.Position + headerMeta.TotalLength));

            fill(
                stream: stream,
                finalPos: minimumFinalPos,
                offset: 0,
                type: headerMeta.RecordType,
                lastParsed: lastParsed,
                recordTypeConverter: null);
            stream.Position = (int)headerMeta.TotalLength;
            while (!stream.Complete)
            {
                GroupHeader groupMeta = stream.GetGroup(package);
                if (!groupMeta.IsGroup)
                {
                    throw new ArgumentException("Did not see GRUP header as expected.");
                }
                if (groupMeta.ContentLength == 0)
                {
                    stream.Position += groupMeta.TotalLength;
                    continue;
                }
                minimumFinalPos = checked ((int)(stream.Position + groupMeta.TotalLength));
                var parsed = fill(
                    stream: stream,
                    finalPos: minimumFinalPos,
                    offset: 0,
                    type: groupMeta.ContainedRecordType,
                    lastParsed: lastParsed,
                    recordTypeConverter: null);
                if (!parsed.KeepParsing)
                {
                    break;
                }
                if (!parsed.KeepParsing)
                {
                    break;
                }
                if (minimumFinalPos > stream.Position)
                {
                    stream.Position = checked ((int)minimumFinalPos);
                }
                lastParsed = parsed.ParsedIndex;
            }
        }
예제 #3
0
파일: AGroup.cs 프로젝트: Deigue/Mutagen
            public static GroupMajorRecordCacheWrapper <T> Factory(
                IBinaryReadStream stream,
                ReadOnlyMemorySlice <byte> data,
                BinaryOverlayFactoryPackage package,
                int offset)
            {
                Dictionary <FormKey, int> locationDict = new Dictionary <FormKey, int>();

                stream.Position -= package.MetaData.Constants.GroupConstants.HeaderLength;
                var groupMeta = stream.GetGroup(package.MetaData);
                var finalPos  = stream.Position + groupMeta.TotalLength;

                stream.Position += package.MetaData.Constants.GroupConstants.HeaderLength;
                // Parse MajorRecord locations
                ObjectType?lastParsed = default;

                while (stream.Position < finalPos)
                {
                    VariableHeader varMeta = package.MetaData.Constants.NextRecordVariableMeta(stream.RemainingMemory);
                    if (varMeta.IsGroup)
                    {
                        if (lastParsed != ObjectType.Record)
                        {
                            throw new DataMisalignedException("Unexpected Group encountered which was not after a major record: " + GroupRecordTypeGetter <T> .GRUP_RECORD_TYPE);
                        }
                        stream.Position += checked ((int)varMeta.TotalLength);
                        lastParsed       = ObjectType.Group;
                    }
                    else
                    {
                        MajorRecordHeader majorMeta = package.MetaData.Constants.MajorRecord(stream.RemainingMemory);
                        if (majorMeta.RecordType != GroupRecordTypeGetter <T> .GRUP_RECORD_TYPE)
                        {
                            throw new DataMisalignedException("Unexpected type encountered when parsing MajorRecord locations: " + majorMeta.RecordType);
                        }
                        var formKey = FormKey.Factory(package.MetaData.MasterReferences !, majorMeta.FormID.Raw);
                        locationDict.Add(formKey, checked ((int)(stream.Position - offset)));
                        stream.Position += checked ((int)majorMeta.TotalLength);
                        lastParsed       = ObjectType.Record;
                    }
                }

                return(new GroupMajorRecordCacheWrapper <T>(
                           locationDict,
                           data,
                           package));
            }