예제 #1
0
        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");
            }
        }
예제 #2
0
        /// <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));
            }
        }