Пример #1
0
            public static void WriteCellsParallel(
                IListGroupGetter <ICellBlockGetter> group,
                MasterReferenceReader masters,
                int targetIndex,
                Stream[] streamDepositArray)
            {
                if (group.Records.Count == 0)
                {
                    return;
                }
                Stream[] streams    = new Stream[group.Records.Count + 1];
                byte[]   groupBytes = new byte[GameConstants.Oblivion.GroupConstants.HeaderLength];
                BinaryPrimitives.WriteInt32LittleEndian(groupBytes.AsSpan(), RecordTypes.GRUP.TypeInt);
                var groupByteStream = new MemoryStream(groupBytes);

                using (var stream = new MutagenWriter(groupByteStream, GameConstants.Oblivion, dispose: false))
                {
                    stream.Position += 8;
                    ListGroupBinaryWriteTranslation.WriteEmbedded <ICellBlockGetter>(group, stream);
                }
                streams[0] = groupByteStream;
                Parallel.ForEach(group.Records, (cellBlock, state, counter) =>
                {
                    WriteBlocksParallel(
                        cellBlock,
                        masters,
                        (int)counter + 1,
                        streams);
                });
                PluginUtilityTranslation.CompileSetGroupLength(streams, groupBytes);
                streamDepositArray[targetIndex] = new CompositeReadStream(streams, resetPositions: true);
            }
Пример #2
0
            public static void WriteBlocksParallel(
                ICellBlockGetter block,
                MasterReferenceReader masters,
                int targetIndex,
                Stream[] streamDepositArray)
            {
                var subBlocks = block.SubBlocks;

                Stream[] streams    = new Stream[(subBlocks?.Count ?? 0) + 1];
                byte[]   groupBytes = new byte[GameConstants.Oblivion.GroupConstants.HeaderLength];
                BinaryPrimitives.WriteInt32LittleEndian(groupBytes.AsSpan(), RecordTypes.GRUP.TypeInt);
                var groupByteStream = new MemoryStream(groupBytes);

                using (var stream = new MutagenWriter(groupByteStream, GameConstants.Oblivion, dispose: false))
                {
                    stream.Position += 8;
                    CellBlockBinaryWriteTranslation.WriteEmbedded(block, stream);
                }
                streams[0] = groupByteStream;
                if (subBlocks != null)
                {
                    Parallel.ForEach(subBlocks, (cellSubBlock, state, counter) =>
                    {
                        WriteSubBlocksParallel(
                            cellSubBlock,
                            masters,
                            (int)counter + 1,
                            streams);
                    });
                }
                PluginUtilityTranslation.CompileSetGroupLength(streams, groupBytes);
                streamDepositArray[targetIndex] = new CompositeReadStream(streams, resetPositions: true);
            }
Пример #3
0
            public static void WriteSubBlocksParallel(
                IWorldspaceSubBlockGetter subBlock,
                MasterReferenceReader masters,
                int targetIndex,
                Stream[] streamDepositArray)
            {
                var items  = subBlock.Items;
                var bundle = new WritingBundle(GameConstants.Oblivion)
                {
                    MasterReferences = masters
                };

                Stream[] streams    = new Stream[(items?.Count ?? 0) + 1];
                byte[]   groupBytes = new byte[GameConstants.Oblivion.GroupConstants.HeaderLength];
                BinaryPrimitives.WriteInt32LittleEndian(groupBytes.AsSpan(), RecordTypes.GRUP.TypeInt);
                var groupByteStream = new MemoryStream(groupBytes);

                using (var stream = new MutagenWriter(groupByteStream, bundle, dispose: false))
                {
                    stream.Position += 8;
                    WorldspaceSubBlockBinaryWriteTranslation.WriteEmbedded(subBlock, stream);
                }
                streams[0] = groupByteStream;
                if (items != null)
                {
                    Parallel.ForEach(items, (cell, state, counter) =>
                    {
                        MemoryTributary trib = new MemoryTributary();
                        cell.WriteToBinary(new MutagenWriter(trib, bundle, dispose: false));
                        streams[(int)counter + 1] = trib;
                    });
                }
                PluginUtilityTranslation.CompileSetGroupLength(streams, groupBytes);
                streamDepositArray[targetIndex] = new CompositeReadStream(streams, resetPositions: true);
            }
Пример #4
0
        public void EmptyRead()
        {
            var compositeStream = new CompositeReadStream(EnumerableExt <Stream> .Empty);

            Assert.Equal(0, compositeStream.Remaining());
            Assert.Equal(0, compositeStream.Length);
            Assert.Equal(0, compositeStream.Position);
            Assert.Equal(0, compositeStream.Read(new byte[0], 0, 10));
        }
Пример #5
0
        public void TypicalOverread()
        {
            int toRead = 13;

            byte[] buf             = new byte[toRead];
            var    compositeStream = new CompositeReadStream(TypicalStreams());

            Assert.Equal(TotalLength, compositeStream.Remaining());
            Assert.Equal(TotalLength, compositeStream.Length);
            Assert.Equal(0, compositeStream.Position);
            Assert.Equal(toRead, compositeStream.Read(buf, 0, toRead));
            Assert.Equal(toRead, compositeStream.Position);
            Assert.Equal(TotalLength - toRead, compositeStream.Remaining());
            Assert.Equal(TotalLength, compositeStream.Length);
        }
Пример #6
0
        public void CopyIntoStream()
        {
            byte[] buf             = new byte[TotalLength];
            var    memStream       = new MemoryStream(buf);
            var    compositeStream = new CompositeReadStream(TypicalStreams());

            compositeStream.CopyTo(memStream);
            Assert.Equal(TotalLength, compositeStream.Position);
            Assert.Equal(0, compositeStream.Remaining());
            Assert.Equal(TotalLength, compositeStream.Length);
            Assert.Equal(TotalLength, memStream.Position);
            Assert.Equal(0, memStream.Remaining());
            Assert.Equal(TotalLength, memStream.Length);
            for (int i = 0; i < buf.Length; i++)
            {
                Assert.Equal(i, buf[i]);
            }
        }
Пример #7
0
            public static void WriteGroupParallel <T>(
                IGroupGetter <T> group,
                MasterReferenceReader masters,
                int targetIndex,
                GameConstants gameConstants,
                Stream[] streamDepositArray)
                where T : class, ISkyrimMajorRecordGetter, IBinaryItem
            {
                if (group.RecordCache.Count == 0)
                {
                    return;
                }
                var cuts = group.Cut(CutCount).ToArray();

                Stream[] subStreams = new Stream[cuts.Length + 1];
                byte[]   groupBytes = new byte[gameConstants.GroupConstants.HeaderLength];
                BinaryPrimitives.WriteInt32LittleEndian(groupBytes.AsSpan(), RecordTypes.GRUP.TypeInt);
                var groupByteStream = new MemoryStream(groupBytes);

                using (var stream = new MutagenWriter(groupByteStream, gameConstants, dispose: false))
                {
                    stream.Position += 8;
                    GroupBinaryWriteTranslation.WriteEmbedded <T>(group, stream);
                }
                subStreams[0] = groupByteStream;
                Parallel.ForEach(cuts, (cutItems, state, counter) =>
                {
                    MemoryTributary trib = new MemoryTributary();
                    var bundle           = new WritingBundle(gameConstants)
                    {
                        MasterReferences = masters
                    };
                    using (var stream = new MutagenWriter(trib, bundle, dispose: false))
                    {
                        foreach (var item in cutItems)
                        {
                            item.WriteToBinary(stream);
                        }
                    }
                    subStreams[(int)counter + 1] = trib;
                });
                UtilityTranslation.CompileSetGroupLength(subStreams, groupBytes);
                streamDepositArray[targetIndex] = new CompositeReadStream(subStreams, resetPositions: true);
            }
Пример #8
0
            public static void WriteWorldspacesParallel(
                IGroupGetter <IWorldspaceGetter> group,
                MasterReferenceReader masters,
                int targetIndex,
                Stream[] streamDepositArray)
            {
                var cache = group.RecordCache;

                if (cache == null || cache.Count == 0)
                {
                    return;
                }
                Stream[] streams = new Stream[cache.Count + 1];
                var      bundle  = new WritingBundle(GameConstants.Oblivion)
                {
                    MasterReferences = masters
                };

                byte[] groupBytes = new byte[GameConstants.Oblivion.GroupConstants.HeaderLength];
                BinaryPrimitives.WriteInt32LittleEndian(groupBytes.AsSpan(), RecordTypes.GRUP.TypeInt);
                var groupByteStream = new MemoryStream(groupBytes);

                using (var stream = new MutagenWriter(groupByteStream, GameConstants.Oblivion, dispose: false))
                {
                    stream.Position += 8;
                    GroupBinaryWriteTranslation.WriteEmbedded <IWorldspaceGetter>(group, stream);
                }
                streams[0] = groupByteStream;
                Parallel.ForEach(group, (worldspace, worldspaceState, worldspaceCounter) =>
                {
                    var worldTrib = new MemoryTributary();
                    using (var writer = new MutagenWriter(worldTrib, bundle, dispose: false))
                    {
                        using (HeaderExport.Header(
                                   writer: writer,
                                   record: RecordTypes.WRLD,
                                   type: ObjectType.Record))
                        {
                            WorldspaceBinaryWriteTranslation.WriteEmbedded(
                                item: worldspace,
                                writer: writer);
                            WorldspaceBinaryWriteTranslation.WriteRecordTypes(
                                item: worldspace,
                                writer: writer,
                                recordTypeConverter: null);
                        }
                    }
                    var road     = worldspace.Road;
                    var topCell  = worldspace.TopCell;
                    var subCells = worldspace.SubCells;
                    if (subCells?.Count == 0 &&
                        road == null &&
                        topCell == null)
                    {
                        streams[worldspaceCounter + 1] = worldTrib;
                        return;
                    }

                    Stream[] subStreams = new Stream[(subCells?.Count ?? 0) + 1];

                    var worldGroupTrib   = new MemoryTributary();
                    var worldGroupWriter = new MutagenWriter(worldGroupTrib, bundle, dispose: false);
                    worldGroupWriter.Write(RecordTypes.GRUP.TypeInt);
                    worldGroupWriter.Write(Zeros.Slice(0, GameConstants.Oblivion.GroupConstants.LengthLength));
                    FormKeyBinaryTranslation.Instance.Write(
                        worldGroupWriter,
                        worldspace.FormKey);
                    worldGroupWriter.Write((int)GroupTypeEnum.WorldChildren);
                    worldGroupWriter.Write(worldspace.SubCellsTimestamp);
                    road?.WriteToBinary(worldGroupWriter);
                    topCell?.WriteToBinary(worldGroupWriter);
                    subStreams[0] = worldGroupTrib;

                    if (subCells != null)
                    {
                        Parallel.ForEach(subCells, (block, blockState, blockCounter) =>
                        {
                            WriteBlocksParallel(
                                block,
                                masters,
                                (int)blockCounter + 1,
                                subStreams);
                        });
                    }

                    worldGroupWriter.Position = 4;
                    worldGroupWriter.Write((uint)(subStreams.NotNull().Select(s => s.Length).Sum()));
                    streams[worldspaceCounter + 1] = new CompositeReadStream(worldTrib.AsEnumerable().And(subStreams), resetPositions: true);
                });
                PluginUtilityTranslation.CompileSetGroupLength(streams, groupBytes);
                streamDepositArray[targetIndex] = new CompositeReadStream(streams, resetPositions: true);
            }