Пример #1
0
        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());
        }
Пример #2
0
        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);
        }