wabbajack/Wabbajack.Compression.BSA/TES3Archive/Reader.cs

88 lines
2.5 KiB
C#
Raw Normal View History

2021-09-27 12:42:46 +00:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Wabbajack.Compression.BSA.Interfaces;
using Wabbajack.DTOs.BSA.ArchiveStates;
using Wabbajack.DTOs.Streams;
using Wabbajack.Paths;
2021-10-23 16:51:17 +00:00
namespace Wabbajack.Compression.BSA.TES3Archive;
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
public class Reader : IReader
{
public static string TES3_MAGIC = Encoding.ASCII.GetString(new byte[] {0, 1, 0, 0});
internal long _dataOffset;
private uint _fileCount;
private TES3FileEntry[] _files;
private uint _hashTableOffset;
public IStreamFactory _streamFactory;
private uint _versionNumber;
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
public IEnumerable<IFile> Files => _files;
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
public IArchive State =>
new TES3State
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
FileCount = _fileCount,
DataOffset = _dataOffset,
HashOffset = _hashTableOffset,
VersionNumber = _versionNumber
};
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
public static async ValueTask<Reader> Load(IStreamFactory factory)
{
await using var fs = await factory.GetStream();
using var br = new BinaryReader(fs);
var rdr = new Reader
{
_streamFactory = factory,
_versionNumber = br.ReadUInt32(),
_hashTableOffset = br.ReadUInt32(),
_fileCount = br.ReadUInt32()
};
2021-09-27 12:42:46 +00:00
2021-10-23 16:51:17 +00:00
rdr._files = new TES3FileEntry[rdr._fileCount];
for (var i = 0; i < rdr._fileCount; i++)
{
var file = new TES3FileEntry
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
Index = i,
Archive = rdr,
Size = br.ReadUInt32(),
Offset = br.ReadUInt32()
};
rdr._files[i] = file;
2021-09-27 12:42:46 +00:00
}
2021-10-23 16:51:17 +00:00
for (var i = 0; i < rdr._fileCount; i++) rdr._files[i].NameOffset = br.ReadUInt32();
var origPos = br.BaseStream.Position;
for (var i = 0; i < rdr._fileCount; i++)
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
br.BaseStream.Position = origPos + rdr._files[i].NameOffset;
rdr._files[i].Path = br.ReadStringTerm(VersionType.TES3).ToRelativePath();
2021-09-27 12:42:46 +00:00
}
2021-10-23 16:51:17 +00:00
br.BaseStream.Position = rdr._hashTableOffset + 12;
for (var i = 0; i < rdr._fileCount; i++)
2021-09-27 12:42:46 +00:00
{
2021-10-23 16:51:17 +00:00
rdr._files[i].Hash1 = br.ReadUInt32();
rdr._files[i].Hash2 = br.ReadUInt32();
2021-09-27 12:42:46 +00:00
}
2021-10-23 16:51:17 +00:00
rdr._dataOffset = br.BaseStream.Position;
return rdr;
}
2022-10-07 22:57:12 +00:00
public ValueTask DisposeAsync()
2021-10-23 16:51:17 +00:00
{
2022-10-07 22:57:12 +00:00
return ValueTask.CompletedTask;
2021-10-23 16:51:17 +00:00
}
public void Dump(Action<string> print)
{
throw new NotImplementedException();
2021-09-27 12:42:46 +00:00
}
}