/// <summary> /// Reads the block. /// </summary> /// <param name="position">The position.</param> /// <param name="currentDirectory">The current directory.</param> private void ReadBlockAt(ulong position, PK2Directory currentDirectory = null) { var currentBlockBuffer = FileAdapter.GetInstance().ReadData((long)position, 2560); var currentBlock = new PK2Block(currentBlockBuffer, position); //Check if the chain continues at another position if (currentBlock.Entries[19].NextChain > 0) { ReadBlockAt(currentBlock.Entries[19].NextChain); } //Read the subfolder chain //The folder "." and ".." are required if you which to use "free-browsing" mode, without reading the whole index at once foreach (var pk2Entry in currentBlock.Entries.Where(entry => !entry.Name.StartsWith(".") && entry.Position > 0)) { switch (pk2Entry.Type) { case PK2EntryType.Directory: if (Config.Mode == PK2Mode.Index) { var subDirectory = new PK2Directory(pk2Entry, currentDirectory?.Path); _directories.Add(subDirectory); ReadBlockAt(pk2Entry.Position, subDirectory); } else { ReadBlockAt(pk2Entry.Position); } break; case PK2EntryType.File: if (Config.Mode == PK2Mode.Index) { _files.Add(new PK2File(pk2Entry, currentDirectory?.Path)); } break; } } if (Config.Mode == PK2Mode.IndexBlocks) { Blocks.Add(currentBlock); } }
/// <summary> /// Reads the block at. /// This function does not recursively ready any "sub-chunks" /// </summary> /// <param name="position">The position.</param> /// <returns></returns> private void ReadBlockAt(ulong position) { Blocks = new PK2BlockCollection(); Directories = new List <PK2Directory>(); Files = new List <PK2File>(); while (true) { try { var currentBlockBuffer = FileAdapter.GetInstance().ReadData((long)position, 2560); var currentBlock = new PK2Block(currentBlockBuffer, position); Blocks.Blocks.Add(currentBlock); foreach (var entry in currentBlock.Entries) { switch (entry.Type) { case PK2EntryType.Directory: Directories.Add(new PK2Directory(entry, "")); break; case PK2EntryType.File: Files.Add(new PK2File(entry, "")); break; } } //read the next block (only if the first block was not enough for the folder) if (currentBlock.Entries[19].NextChain > 0) { position = currentBlock.Entries[19].NextChain; continue; } break; } catch { throw new InvalidBlockException((long)position); } //should only be thrown, if the user fakes any position data in any entry! } }