diff --git a/Compression.BSA.Test/BSATests.cs b/Compression.BSA.Test/BSATests.cs index 92d1aa63..ecf14c9d 100644 --- a/Compression.BSA.Test/BSATests.cs +++ b/Compression.BSA.Test/BSATests.cs @@ -119,7 +119,7 @@ namespace Compression.BSA.Test TestContext.WriteLine($"Building {bsa}"); - await using (var w = ViaJson(a.State).MakeBuilder(size)) + await using (var w = await ViaJson(a.State).MakeBuilder(size)) { var streams = await a.Files.PMap(Queue, async file => { diff --git a/Compression.BSA/BA2Builder.cs b/Compression.BSA/BA2Builder.cs index 217e3ce0..2e366a80 100644 --- a/Compression.BSA/BA2Builder.cs +++ b/Compression.BSA/BA2Builder.cs @@ -29,10 +29,10 @@ namespace Compression.BSA private List _entries = new List(); private DiskSlabAllocator _slab; - public BA2Builder(BA2StateObject state, long size) + public static async Task Create(BA2StateObject state, long size) { - _state = state; - _slab = new DiskSlabAllocator(size); + var self = new BA2Builder {_state = state, _slab = await DiskSlabAllocator.Create(size)}; + return self; } public async ValueTask DisposeAsync() diff --git a/Compression.BSA/BA2Reader.cs b/Compression.BSA/BA2Reader.cs index 1fcf390b..32e5639e 100644 --- a/Compression.BSA/BA2Reader.cs +++ b/Compression.BSA/BA2Reader.cs @@ -144,9 +144,9 @@ namespace Compression.BSA public EntryType Type { get; set; } public string HeaderMagic { get; set; } public uint Version { get; set; } - public override IBSABuilder MakeBuilder(long size) + public override async Task MakeBuilder(long size) { - return new BA2Builder(this, size); + return await BA2Builder.Create(this, size); } } diff --git a/Compression.BSA/BSABuilder.cs b/Compression.BSA/BSABuilder.cs index dbc5dc56..cf56468d 100644 --- a/Compression.BSA/BSABuilder.cs +++ b/Compression.BSA/BSABuilder.cs @@ -26,18 +26,24 @@ namespace Compression.BSA internal uint _version; internal DiskSlabAllocator _slab; - public BSABuilder(long size) + public static async Task Create(long size) { - _fileId = Encoding.ASCII.GetBytes("BSA\0"); - _offset = 0x24; - _slab = new DiskSlabAllocator(size); + var self = new BSABuilder + { + _fileId = Encoding.ASCII.GetBytes("BSA\0"), + _offset = 0x24, + _slab = await DiskSlabAllocator.Create(size) + }; + return self; } - public BSABuilder(BSAStateObject bsaStateObject, long size) : this(size) + public static async Task Create(BSAStateObject bsaStateObject, long size) { - _version = bsaStateObject.Version; - _fileFlags = bsaStateObject.FileFlags; - _archiveFlags = bsaStateObject.ArchiveFlags; + var self = await Create(size); + self._version = bsaStateObject.Version; + self._fileFlags = bsaStateObject.FileFlags; + self._archiveFlags = bsaStateObject.ArchiveFlags; + return self; } public IEnumerable Files => _files; diff --git a/Compression.BSA/BSAReader.cs b/Compression.BSA/BSAReader.cs index 6858c4a8..452c43b4 100644 --- a/Compression.BSA/BSAReader.cs +++ b/Compression.BSA/BSAReader.cs @@ -179,9 +179,9 @@ namespace Compression.BSA } - public override IBSABuilder MakeBuilder(long size) + public override async Task MakeBuilder(long size) { - return new BSABuilder(this, size); + return await BSABuilder.Create(this, size); } public string Magic { get; set; } diff --git a/Compression.BSA/IBSAReader.cs b/Compression.BSA/IBSAReader.cs index 46f6ca4b..316a8a11 100644 --- a/Compression.BSA/IBSAReader.cs +++ b/Compression.BSA/IBSAReader.cs @@ -26,7 +26,7 @@ namespace Compression.BSA public class ArchiveStateObject { - public virtual IBSABuilder MakeBuilder(long size) + public virtual async Task MakeBuilder(long size) { throw new NotImplementedException(); } diff --git a/Compression.BSA/TES3Reader.cs b/Compression.BSA/TES3Reader.cs index 45ffecdc..b57d38cf 100644 --- a/Compression.BSA/TES3Reader.cs +++ b/Compression.BSA/TES3Reader.cs @@ -100,7 +100,7 @@ namespace Compression.BSA public uint HashOffset { get; set; } public uint VersionNumber { get; set; } - public override IBSABuilder MakeBuilder(long size) + public override async Task MakeBuilder(long size) { return new TES3Builder(this); } diff --git a/Wabbajack.Common/Util/DiskSlabAllocator.cs b/Wabbajack.Common/Util/DiskSlabAllocator.cs index 20ce2aa4..2f0c133d 100644 --- a/Wabbajack.Common/Util/DiskSlabAllocator.cs +++ b/Wabbajack.Common/Util/DiskSlabAllocator.cs @@ -12,19 +12,31 @@ namespace Wabbajack.Common /// public class DiskSlabAllocator : IAsyncDisposable { - private readonly TempFile _file; - private readonly MemoryMappedFile _mmap; + private TempFile? _file; + private MemoryMappedFile? _mmap; private long _head = 0; - private readonly FileStream _fileStream; + private FileStream? _fileStream; private List _allocated = new List(); private long _size; - public DiskSlabAllocator(long size) + private DiskSlabAllocator() { - _file = new TempFile(); - _fileStream = _file.File.Open(FileMode.Create, FileAccess.ReadWrite); - _size = Math.Max(size, 1024); - _mmap = MemoryMappedFile.CreateFromFile(_fileStream, null, size, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false); + + } + + public static async Task Create(long size) + { + var file = new TempFile(); + var fileStream = await file.Path.Create(); + var self = new DiskSlabAllocator + { + _file = file, + _size = Math.Max(size, 1024), + _fileStream = fileStream, + _mmap = MemoryMappedFile.CreateFromFile(fileStream, null, size, MemoryMappedFileAccess.ReadWrite, + HandleInheritability.None, false) + }; + return self; } public Stream Allocate(long size) @@ -39,7 +51,7 @@ namespace Wabbajack.Common var startAt = _head; _head += size; - var stream = _mmap.CreateViewStream(startAt, size, MemoryMappedFileAccess.ReadWrite); + var stream = _mmap!.CreateViewStream(startAt, size, MemoryMappedFileAccess.ReadWrite); _allocated.Add(stream); return stream; } @@ -49,9 +61,9 @@ namespace Wabbajack.Common { foreach (var allocated in _allocated) await allocated.DisposeAsync(); - _mmap.Dispose(); - await _fileStream.DisposeAsync(); - await _file.DisposeAsync(); + _mmap!.Dispose(); + await _fileStream!.DisposeAsync(); + await _file!.DisposeAsync(); } } } diff --git a/Wabbajack.Lib/MO2Installer.cs b/Wabbajack.Lib/MO2Installer.cs index b01a450f..b40be3b8 100644 --- a/Wabbajack.Lib/MO2Installer.cs +++ b/Wabbajack.Lib/MO2Installer.cs @@ -266,7 +266,7 @@ namespace Wabbajack.Lib var bsaSize = bsa.FileStates.Select(state => sourceDir.Combine(state.Path).Size).Sum(); - await using var a = bsa.State.MakeBuilder(bsaSize); + await using var a = await bsa.State.MakeBuilder(bsaSize); var streams = await bsa.FileStates.PMap(Queue, async state => { Status($"Adding {state.Path} to BSA"); diff --git a/Wabbajack.Test/SanityTests.cs b/Wabbajack.Test/SanityTests.cs index 90a7be4a..365c8641 100644 --- a/Wabbajack.Test/SanityTests.cs +++ b/Wabbajack.Test/SanityTests.cs @@ -302,7 +302,7 @@ namespace Wabbajack.Test Magic = "BSA\0", Version = 0x69, ArchiveFlags = 0x107, FileFlags = 0x0, }; - await using (var bsa = bsaState.MakeBuilder(1024 * 1024)) + await using (var bsa = await bsaState.MakeBuilder(1024 * 1024)) { await bsa.AddFile(new BSAFileStateObject { @@ -344,7 +344,7 @@ namespace Wabbajack.Test var tempFileData = utils.RandomData(1024); - await using (var bsa = bsaState.MakeBuilder(1024 * 1024)) + await using (var bsa = await bsaState.MakeBuilder(1024 * 1024)) { await bsa.AddFile(new BSAFileStateObject { @@ -382,7 +382,7 @@ namespace Wabbajack.Test Magic = "BSA\0", Version = 0x69, ArchiveFlags = 0x107, FileFlags = 0x0, }; - await using (var bsa = bsaState.MakeBuilder(1024 * 1024)) + await using (var bsa = await bsaState.MakeBuilder(1024 * 1024)) { await bsa.AddFile(new BSAFileStateObject { @@ -418,7 +418,7 @@ namespace Wabbajack.Test // Create the download await using var tempFile = new TempFile(); - await using (var bsa = bsaState.MakeBuilder(1024 * 1024)) + await using (var bsa = await bsaState.MakeBuilder(1024 * 1024)) { await bsa.AddFile(new BSAFileStateObject { @@ -431,7 +431,7 @@ namespace Wabbajack.Test // Create the result - await using (var bsa = bsaState.MakeBuilder(1024 * 1024)) + await using (var bsa = await bsaState.MakeBuilder(1024 * 1024)) { await bsa.AddFile(new BSAFileStateObject {