private static IFdsBlock[] DumpFast(IFamicomDumperConnectionExt dumper, bool dumpHiddenFiles = false, bool printDiskInfo = false) { Console.Write($"Reading disk... "); var blocks = dumper.ReadFdsBlocks().ToArray(); Console.WriteLine($"Done"); List <IFdsBlock> result = new(); if (blocks.Length == 0) { throw new IOException("Invalid disk info block"); } if (!blocks[0].CrcOk) { throw new IOException($"Invalid CRC on disk info block"); } var fdsBlockDiskInfo = FdsBlockDiskInfo.FromBytes(blocks[0].Data); if (!fdsBlockDiskInfo.IsValid) { throw new IOException($"Invalid disk info block type"); } if (printDiskInfo) { PrintDiskHeaderInfo(fdsBlockDiskInfo); } result.Add(fdsBlockDiskInfo); if (blocks.Length == 1) { throw new IOException("Invalid file amount block"); } if (!blocks[1].CrcOk) { throw new IOException($"Invalid CRC on file amount block"); } var fdsBlockFileAmount = FdsBlockFileAmount.FromBytes(blocks[1].Data); if (!fdsBlockFileAmount.IsValid) { throw new IOException($"Invalid file amount block type"); } var fileAmount = fdsBlockFileAmount.FileAmount; byte visibleBlockAmount = (byte)(2 + fileAmount * 2); if (printDiskInfo) { Console.WriteLine($"Number of non-hidden files: {fileAmount}"); } result.Add(fdsBlockFileAmount); // Check files and print info for (int blockNumber = 2; blockNumber < (dumpHiddenFiles ? blocks.Length : visibleBlockAmount); blockNumber++) { if (!blocks[blockNumber].CrcOk) { if (blocks.Length < visibleBlockAmount) { throw new IOException($"Invalid CRC on block #{blockNumber} (file #{(blockNumber - 2) / 2})"); } else { if (printDiskInfo) { Console.WriteLine($"Invalid CRC on block #{blockNumber}, it's not hidden file, aboritng"); } break; } } IFdsBlock block = (blockNumber % 2 == 0) ? FdsBlockFileHeader.FromBytes(blocks[blockNumber].Data) : FdsBlockFileData.FromBytes(blocks[blockNumber].Data); if (!block.IsValid) { if (blocks.Length < visibleBlockAmount) { throw new IOException($"Invalid block #{blockNumber} (file #{(blockNumber - 2) / 2}) type"); } else { break; } } if (block is FdsBlockFileHeader && printDiskInfo) { Console.WriteLine($"File #{(blockNumber - 2) / 2}/{fileAmount}:"); PrintFileHeaderInfo(block as FdsBlockFileHeader); } result.Add(block); } if (blocks.Length < visibleBlockAmount) { throw new IOException($"Only {(blocks.Length - 2) / 2} of {fileAmount} valid files received"); } if (dumpHiddenFiles && printDiskInfo) { Console.WriteLine($"Number of hidden files: {(blocks.Length - 2) / 2 - fileAmount}"); } return(result.ToArray()); }
private static IEnumerable <IFdsBlock> DumpSlow(IFamicomDumperConnectionExt dumper, bool dumpHiddenFiles = false, bool printDiskInfo = false) { var result = new List <IFdsBlock>(); byte blockNumber = 0; byte fileAmount = 0; byte visibleBlockAmount = 0; while (true) { switch (blockNumber) { case 0: Console.Write("Reading block #0 (disk info block)... "); break; case 1: Console.Write("Reading block #1 (file amount block)... "); break; default: if ((blockNumber % 2) == 0) { Console.Write($"Reading block #{blockNumber} (file #{(blockNumber - 2) / 2}/{(result[1] as FdsBlockFileAmount).FileAmount} header block)... "); } else { Console.Write($"Reading block #{blockNumber} (file #{(blockNumber - 2) / 2}/{(result[1] as FdsBlockFileAmount).FileAmount} data block)... "); } break; } var fdsData = dumper.ReadFdsBlocks(blockNumber, 1); if (fdsData.Length == 0) { throw new IOException($"Can't read block #{blockNumber}"); } if (!fdsData[0].CrcOk) { switch (blockNumber) { case 0: throw new IOException($"Invalid CRC on disk info block"); case 1: throw new IOException($"Invalid CRC on file amount block"); } // Fatal error if bad CRC on non-hidden file if (result.Count < visibleBlockAmount) { throw new IOException($"Invalid CRC on block"); } else { break; } } IFdsBlock block; switch (blockNumber) { case 0: block = FdsBlockDiskInfo.FromBytes(fdsData[0].Data); break; case 1: block = FdsBlockFileAmount.FromBytes(fdsData[0].Data); fileAmount = (block as FdsBlockFileAmount).FileAmount; visibleBlockAmount = (byte)(2 + fileAmount * 2); break; default: if ((blockNumber % 2) == 0) { block = FdsBlockFileHeader.FromBytes(fdsData[0].Data); } else { block = FdsBlockFileData.FromBytes(fdsData[0].Data); } break; } if (!block.IsValid) { switch (block.GetType().Name) { case nameof(FdsBlockDiskInfo): throw new IOException($"Invalid disk info block"); case nameof(FdsBlockFileAmount): throw new IOException($"Invalid file amount block"); } // Fatal error if bad block ID on non-hidden file if (result.Count < visibleBlockAmount) { throw new IOException($"Invalid block"); } else { break; } } result.Add(block); Console.WriteLine($"OK"); // Some info if (printDiskInfo) { switch (blockNumber) { case 0: PrintDiskHeaderInfo(block as FdsBlockDiskInfo); break; case 1: Console.WriteLine($"Number of non-hidden files: {fileAmount}"); break; default: if ((blockNumber % 2) == 0) { Console.WriteLine($"File #{(blockNumber - 2) / 2}:"); PrintFileHeaderInfo(block as FdsBlockFileHeader); } break; } } // Abort if last file dumped if (!dumpHiddenFiles && (result.Count >= 2) && (result.Count >= visibleBlockAmount)) { break; } blockNumber++; } if (dumpHiddenFiles) { Console.WriteLine($"Number of hidden files: {(result.Count - 2) / 2 - (result[1] as FdsBlockFileAmount).FileAmount}"); } return(result); }