public Packfile(string archivePath, FileMode mode = FileMode.Open) { if (mode == FileMode.Open) { ArchiveFileHandle = File.Open(archivePath, mode, FileAccess.Read, FileShare.Read); using (var reader = new BinaryReader(ArchiveFileHandle, Encoding.UTF8, true)) { Header = PackfileHeader.FromData(reader); if (Header.Magic != PackfileHeader.HardcodedMagic) { throw new InvalidDataException("Unknown header magic"); } FileEntries = new FileEntry[Header.FileEntryCount]; BlockEntries = new BlockEntry[Header.BlockEntryCount]; for (uint i = 0; i < FileEntries.Length; i++) { FileEntries[i] = FileEntry.FromData(reader); } for (uint i = 0; i < BlockEntries.Length; i++) { BlockEntries[i] = BlockEntry.FromData(reader); } } } else if (mode == FileMode.Create || mode == FileMode.CreateNew) { throw new NotImplementedException("Writing archives is not supported at the moment"); } else { throw new NotImplementedException("Archive file mode must be Open, Create, or CreateNew"); } }
/// <summary> /// Open an archive (.bin) file and prepare for reading /// </summary> /// <param name="archivePath">Disk path</param> public PackfileReader(string archivePath) { _fileHandle = CreateReadStream(archivePath); using var reader = new BinaryReader(_fileHandle, Encoding.UTF8, true); Header = PackfileHeader.FromData(reader); _fileEntries = new List <FileEntry>((int)Header.FileEntryCount); _blockEntries = new List <BlockEntry>(Header.BlockEntryCount); Span <byte> fileData = reader.ReadBytesStrict((int)Header.FileEntryCount * FileEntry.DataHeaderSize); Span <byte> blockData = reader.ReadBytesStrict(Header.BlockEntryCount * BlockEntry.DataHeaderSize); for (int i = 0; i < (int)Header.FileEntryCount; i++) { var data = fileData.Slice(i * FileEntry.DataHeaderSize); _fileEntries.Add(FileEntry.FromData(data, Header)); } for (int i = 0; i < Header.BlockEntryCount; i++) { var data = blockData.Slice(i * BlockEntry.DataHeaderSize); _blockEntries.Add(BlockEntry.FromData(data, Header)); } }