2020-08-11 13:41:30 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
2021-09-27 12:42:46 +00:00
|
|
|
|
using System.Threading;
|
2020-08-11 13:41:30 +00:00
|
|
|
|
using Wabbajack.Common;
|
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
|
namespace Wabbajack.Compression.BSA.TES5Archive;
|
|
|
|
|
|
|
|
|
|
internal class FileNameBlock
|
2020-08-11 13:41:30 +00:00
|
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
|
public readonly Lazy<ReadOnlyMemorySlice<byte>[]> Names;
|
2020-08-11 13:41:30 +00:00
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
|
public FileNameBlock(Reader bsa, long position)
|
|
|
|
|
{
|
|
|
|
|
Names = new Lazy<ReadOnlyMemorySlice<byte>[]>(
|
|
|
|
|
mode: LazyThreadSafetyMode.ExecutionAndPublication,
|
|
|
|
|
valueFactory: () =>
|
|
|
|
|
{
|
|
|
|
|
using var stream = bsa.GetStream();
|
|
|
|
|
stream.BaseStream.Position = position;
|
|
|
|
|
ReadOnlyMemorySlice<byte> data = stream.ReadBytes(checked((int) bsa._totalFileNameLength));
|
|
|
|
|
var names = new ReadOnlyMemorySlice<byte>[bsa._fileCount];
|
|
|
|
|
for (var i = 0; i < bsa._fileCount; i++)
|
2020-08-11 13:41:30 +00:00
|
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
|
var index = data.Span.IndexOf(default(byte));
|
|
|
|
|
if (index == -1) throw new InvalidDataException("Did not end all of its strings in null bytes");
|
|
|
|
|
names[i] = data.Slice(0, index + 1);
|
|
|
|
|
var str = names[i].ReadStringTerm(bsa.HeaderType);
|
|
|
|
|
data = data.Slice(index + 1);
|
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
|
// Data doesn't seem to need to be fully consumed.
|
|
|
|
|
// Official BSAs have overflow of zeros
|
|
|
|
|
return names;
|
|
|
|
|
});
|
2020-08-11 13:41:30 +00:00
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
}
|