コード例 #1
0
        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);
        }
コード例 #2
0
ファイル: Gfsa.cs プロジェクト: obluda3/Kuriimu2
        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);
        }