public IList <IArchiveFileInfo> Load(Stream input) { using var br = new BinaryReaderX(input, true); // Header _header = br.ReadType <XfsaHeader>(); // Read directory entries var directoryEntries = XfsaSupport.ReadCompressedTableEntries <Xfsa1DirectoryEntry>(input, _header.directoryEntriesOffset, _header.directoryHashOffset - _header.directoryEntriesOffset, _header.directoryEntriesCount); // Read directory hashes var directoryHashes = XfsaSupport.ReadCompressedTableEntries <uint>(input, _header.directoryHashOffset, _header.fileEntriesOffset - _header.directoryHashOffset, _header.directoryHashCount); // Read file entry table var entries = XfsaSupport.ReadCompressedTableEntries <Xfsa1FileEntry>(input, _header.fileEntriesOffset, _header.nameOffset - _header.fileEntriesOffset, _header.fileEntriesCount); // Read nameTable var nameComp = new SubStream(input, _header.nameOffset, _header.dataOffset - _header.nameOffset); var nameStream = new MemoryStream(); Level5Compressor.Decompress(nameComp, nameStream); // Add Files var names = new BinaryReaderX(nameStream); var result = new List <IArchiveFileInfo>(); foreach (var directory in directoryEntries) { names.BaseStream.Position = directory.DirectoryNameOffset; var directoryName = names.ReadCStringSJIS(); var filesInDirectory = entries.Skip(directory.firstFileIndex).Take(directory.FileCount); foreach (var file in filesInDirectory) { var fileStream = new SubStream(input, _header.dataOffset + file.FileOffset, file.FileSize); names.BaseStream.Position = directory.FileNameStartOffset + file.NameOffset; var fileName = names.ReadCStringSJIS(); result.Add(new XfsaArchiveFileInfo <Xfsa1FileEntry>(fileStream, directoryName + fileName, file) { PluginIds = XfsaSupport.RetrievePluginMapping(fileStream, fileName) }); } } return(result); }
public IList <IArchiveFileInfo> Load(Stream input) { using var br = new BinaryReaderX(input, true); // Read header _header = br.ReadType <GfsaHeader>(); // Read tables var directoryEntries = XfsaSupport.ReadCompressedTableEntries <GfsaDirectoryEntry>(input, _header.directoryOffset, _header.fileOffset - _header.directoryOffset, _header.directoryCount); var fileEntries = XfsaSupport.ReadCompressedTableEntries <GfsaFileEntry>(input, _header.fileOffset, _header.unkOffset - _header.fileOffset, _header.fileCount); input.Position = _header.unkOffset; _unkTable = br.ReadBytes(_header.stringOffset - _header.unkOffset); // Read strings var nameComp = new SubStream(input, _header.stringOffset, _header.fileDataOffset - _header.stringOffset); var nameStream = new MemoryStream(); Level5Compressor.Decompress(nameComp, nameStream); var(directories, files) = ReadStrings(nameStream); // Add files var result = new List <IArchiveFileInfo>(); foreach (var dirEntry in directoryEntries) { var dirName = directories.FirstOrDefault(x => x.Hash == dirEntry.hash)?.Value; for (var fileIndex = dirEntry.fileIndex; fileIndex < dirEntry.fileIndex + dirEntry.fileCount; fileIndex++) { var fileEntry = fileEntries[fileIndex]; var fileName = files.Skip(dirEntry.fileIndex).Take(dirEntry.fileCount).FirstOrDefault(x => x.Hash == fileEntry.hash)?.Value; var fileData = new SubStream(input, _header.fileDataOffset + fileEntry.Offset, fileEntry.Size); result.Add(CreateAfi(fileData, Path.Combine(dirName, fileName), fileEntry)); } } return(result); }