예제 #1
0
        public static void Sort(
            Func <IMutagenReadStream> streamCreator,
            Stream outputStream,
            GameRelease release)
        {
            using var inputStream   = streamCreator();
            using var locatorStream = streamCreator();
            using var writer        = new MutagenWriter(outputStream, release, dispose: false);
            while (!inputStream.Complete)
            {
                long noRecordLength;
                foreach (var grupLoc in RecordLocator.IterateBaseGroupLocations(locatorStream))
                {
                    noRecordLength = grupLoc.Value - inputStream.Position;
                    inputStream.WriteTo(writer.BaseStream, (int)noRecordLength);

                    // If complete overall, return
                    if (inputStream.Complete)
                    {
                        return;
                    }

                    var groupMeta = inputStream.GetGroup();

                    var storage = new Dictionary <FormKey, List <ReadOnlyMemorySlice <byte> > >();
                    using (var grupFrame = new MutagenFrame(inputStream).SpawnWithLength(groupMeta.TotalLength))
                    {
                        inputStream.WriteTo(writer.BaseStream, inputStream.MetaData.Constants.GroupConstants.HeaderLength);
                        locatorStream.Position = grupLoc.Value;
                        foreach (var rec in RecordLocator.ParseTopLevelGRUP(locatorStream))
                        {
                            MajorRecordHeader majorMeta = inputStream.GetMajorRecord();
                            storage.GetOrAdd(rec.FormKey).Add(inputStream.ReadMemory(checked ((int)majorMeta.TotalLength), readSafe: true));
                            if (grupFrame.Complete)
                            {
                                continue;
                            }
                            if (inputStream.TryGetGroup(out var subGroupMeta))
                            {
                                storage.GetOrAdd(rec.FormKey).Add(inputStream.ReadMemory(checked ((int)subGroupMeta.TotalLength), readSafe: true));
                            }
                        }
                    }

                    // Sorts via Record ID (as opposed to just the first 6 bytes)
                    foreach (var item in storage.OrderBy((i) => i.Key.ID))
                    {
                        foreach (var bytes in item.Value)
                        {
                            writer.Write(bytes);
                        }
                    }
                }

                inputStream.WriteTo(writer.BaseStream, (int)inputStream.Remaining);
            }
        }
예제 #2
0
 public object BaseGRUPIterator()
 {
     stream.Position = 0;
     return(RecordLocator.IterateBaseGroupLocations(stream));
 }
예제 #3
0
        public static void Sort(
            Func <Stream> streamCreator,
            Stream outputStream,
            GameMode gameMode)
        {
            var meta = new ParsingBundle(GameConstants.Get(gameMode));

            using var inputStream   = new MutagenBinaryReadStream(streamCreator(), meta);
            using var locatorStream = new MutagenBinaryReadStream(streamCreator(), meta);
            using var writer        = new MutagenWriter(outputStream, gameMode, dispose: false);
            while (!inputStream.Complete)
            {
                long noRecordLength;
                foreach (var grupLoc in RecordLocator.IterateBaseGroupLocations(locatorStream))
                {
                    noRecordLength = grupLoc.Value - inputStream.Position;
                    inputStream.WriteTo(writer.BaseStream, (int)noRecordLength);

                    // If complete overall, return
                    if (inputStream.Complete)
                    {
                        return;
                    }

                    var groupMeta = inputStream.GetGroup();
                    if (!groupMeta.IsGroup)
                    {
                        throw new ArgumentException();
                    }

                    var storage = new Dictionary <FormID, List <ReadOnlyMemorySlice <byte> > >();
                    using (var grupFrame = new MutagenFrame(inputStream).SpawnWithLength(groupMeta.TotalLength))
                    {
                        inputStream.WriteTo(writer.BaseStream, meta.Constants.GroupConstants.HeaderLength);
                        locatorStream.Position = grupLoc.Value;
                        foreach (var rec in RecordLocator.ParseTopLevelGRUP(locatorStream))
                        {
                            MajorRecordHeader majorMeta = inputStream.GetMajorRecord();
                            storage.TryCreateValue(rec.FormID).Add(inputStream.ReadMemory(checked ((int)majorMeta.TotalLength), readSafe: true));
                            if (grupFrame.Complete)
                            {
                                continue;
                            }
                            GroupHeader subGroupMeta = inputStream.GetGroup();
                            if (subGroupMeta.IsGroup)
                            {
                                storage.TryCreateValue(rec.FormID).Add(inputStream.ReadMemory(checked ((int)subGroupMeta.TotalLength), readSafe: true));
                            }
                        }
                    }

                    foreach (var item in storage.OrderBy((i) => i.Key.ID))
                    {
                        foreach (var bytes in item.Value)
                        {
                            writer.Write(bytes);
                        }
                    }
                }

                inputStream.WriteTo(writer.BaseStream, (int)inputStream.Remaining);
            }
        }