Example #1
0
        private void UpdateRecoverySet(Par2RecoverySet oldRecoverySet, Par2RecoverySet newRecoverySet)
        {
            if (oldRecoverySet.CreatorPacket == null && newRecoverySet.CreatorPacket != null)
            {
                oldRecoverySet.CreatorPacket = newRecoverySet.CreatorPacket;
            }

            if (oldRecoverySet.MainPacket == null && newRecoverySet.MainPacket != null)
            {
                oldRecoverySet.MainPacket = newRecoverySet.MainPacket;
            }

            foreach (string key in newRecoverySet.FileSets.Keys)
            {
                if (!oldRecoverySet.FileSets.Keys.Contains(key))
                {
                    oldRecoverySet.FileSets.Add(key, newRecoverySet.FileSets[key]);
                }
            }

            oldRecoverySet.RecoveryPackets.AddRange(newRecoverySet.RecoveryPackets);

            // Cleaning
            newRecoverySet.RecoveryPackets.Clear();
            newRecoverySet.FileSets.Clear();
        }
Example #2
0
        private void UpdateOrAddRecoverySet(Par2RecoverySet recoverySet)
        {
            lock (syncObject)
            {
                string setid = ToolKit.ToHex(recoverySet.MainPacket.header.setid);

                if (!setids.Keys.Contains(setid))
                {
                    setids.Add(setid, recoverySet);
                }
                else
                {
                    UpdateRecoverySet(setids[setid], recoverySet);
                }
            }
        }
Example #3
0
        private ParResult Create(ref List<string> inputFiles, ref List<string> recoveryFiles, Par2LibraryArguments args)
        {
            // Initialize the base par2 filename if not set in the command line
            if (args.par2filename == string.Empty)
            {
                //args.par2filename = args.inputFiles[0] + ".par2";
                args.par2filename = args.inputFiles[0];
            }

            Par2RecoverySet recoverySet = new Par2RecoverySet(args.multithreadCPU, args.multithreadIO, args);

            // Compute block size from block count or vice versa depending on which was
            // specified on the command line
            if (!recoverySet.ComputeBlockSizeAndBlockCount(ref inputFiles))
                return ParResult.InvalidCommandLineArguments;

            // Determine how many recovery blocks to create based on the source block
            // count and the requested level of redundancy.
            if (recoverySet.redundancy > 0 && !recoverySet.ComputeRecoveryBlockCount(recoverySet.redundancy))
                return ParResult.InvalidCommandLineArguments;

            // Determine how much recovery data can be computed on one pass
            if (!recoverySet.CalculateProcessBlockSize(GetMemoryLimit()))
                return ParResult.LogicError;

            // Determine how many recovery files to create.
            if (!recoverySet.ComputeRecoveryFileCount())
                return ParResult.InvalidCommandLineArguments;

            //if (noiselevel > CommandLine::nlQuiet)
            //{
            // Display information.
            Console.WriteLine("Block size: " + recoverySet.MainPacket.blocksize);
            Console.WriteLine("Source file count: " + recoverySet.SourceFiles.Count);
            Console.WriteLine("Source block count: " + recoverySet.sourceblockcount);
            if (recoverySet.redundancy > 0 || recoverySet.recoveryblockcount == 0)
                Console.WriteLine("Redundancy: " + recoverySet.redundancy + '%');
            Console.WriteLine("Recovery block count: " + recoverySet.recoveryblockcount);
            Console.WriteLine("Recovery file count: " + recoverySet.recoveryfilecount);
            //}

            // Open all of the source files, compute the Hashes and CRC values, and store
            // the results in the file verification and file description packets.
            if (!recoverySet.OpenSourceFiles(ref inputFiles))
                return ParResult.FileIOError;

            // Create the main packet and determine the setid to use with all packets
            //if (!recoverySet.CreateMainPacket(Par2LibraryArguments args))
            //  return ParResult.LogicError;

            recoverySet.criticalpackets.Add(recoverySet.MainPacket);

            // Create the creator packet.
            if (!recoverySet.CreateCreatorPacket())
                return ParResult.LogicError;

            // Initialise all of the source blocks ready to start reading data from the source files.
            if (!recoverySet.CreateSourceBlocks())
                return ParResult.LogicError;

            // Create all of the output files and allocate all packets to appropriate file offets.
            if (!recoverySet.InitialiseOutputFiles(args.par2filename))
                return ParResult.FileIOError;

            if (recoverySet.recoveryblockcount > 0)
            {
                // Allocate memory buffers for reading and writing data to disk.
                if (!recoverySet.AllocateBuffers())
                    return ParResult.MemoryError;

                // Compute the Reed Solomon matrix
                if (!recoverySet.ComputeRSMatrix())  //TODO: Unify and switch for Create and Verify/Repair
                    return ParResult.LogicError;

                // Set the total amount of data to be processed.
                /*progress = 0;
                totaldata = blocksize * sourceblockcount * recoveryblockcount;
                previouslyReportedFraction = -10000000;	// Big negative*/

                //Par2RecoverySet.LogArrayToFile<byte>(@"outputbuffer.before.createparityblocks.log", recoverySet.outputbuffer);

                // Start at an offset of 0 within a block.
                ulong blockoffset = 0;
                while (blockoffset < recoverySet.MainPacket.blocksize) // Continue until the end of the block.
                {
                    // Work out how much data to process this time.
                    ulong blocklength = (ulong)Math.Min(recoverySet.chunksize, recoverySet.MainPacket.blocksize - blockoffset);

                    // Read source data, process it through the RS matrix and write it to disk.
                    if (!recoverySet.ProcessData(blockoffset, blocklength))
                        return ParResult.FileIOError;

                    blockoffset += blocklength;
                }

                //Par2RecoverySet.LogArrayToFile<byte>(@"outputbuffer.after.createparityblocks.log", recoverySet.outputbuffer);

                //if (noiselevel > CommandLine::nlQuiet)
                //  cout << "Writing recovery packets" << endl;

                // Finish computation of the recovery packets and write the headers to disk.
                if (!recoverySet.WriteRecoveryPacketHeaders())
                    return ParResult.FileIOError;

                // Finish computing the full file hash values of the source files
                if (!recoverySet.FinishFileHashComputation())
                    return ParResult.LogicError;
            }

            // Fill in all remaining details in the critical packets.
            if (!recoverySet.FinishCriticalPackets())
                return ParResult.LogicError;

            //if (noiselevel > CommandLine::nlQuiet)
            //  cout << "Writing verification packets" << endl;

            // Write all other critical packets to disk.
            if (!recoverySet.WriteCriticalPackets())
                return ParResult.FileIOError;

            // Close all files.
            if (!recoverySet.CloseFiles())
                return ParResult.FileIOError;

            //if (noiselevel > CommandLine::nlSilent)
            //  cout << "Done" << endl;

            return ParResult.Success;
        }
Example #4
0
        private void UpdateRecoverySet(Par2RecoverySet oldRecoverySet, Par2RecoverySet newRecoverySet)
        {
            if (oldRecoverySet.CreatorPacket == null && newRecoverySet.CreatorPacket != null)
                oldRecoverySet.CreatorPacket = newRecoverySet.CreatorPacket;

            if (oldRecoverySet.MainPacket == null && newRecoverySet.MainPacket != null)
                oldRecoverySet.MainPacket = newRecoverySet.MainPacket;

            foreach (string key in newRecoverySet.FileSets.Keys)
            {
                if (!oldRecoverySet.FileSets.Keys.Contains(key))
                    oldRecoverySet.FileSets.Add(key, newRecoverySet.FileSets[key]);
            }

            oldRecoverySet.RecoveryPackets.AddRange(newRecoverySet.RecoveryPackets);

            // Cleaning
            newRecoverySet.RecoveryPackets.Clear();
            newRecoverySet.FileSets.Clear();
        }
Example #5
0
        private void UpdateOrAddRecoverySet(Par2RecoverySet recoverySet)
        {
            lock (syncObject)
            {
                string setid = ToolKit.ToHex(recoverySet.MainPacket.header.setid);

                if (!setids.Keys.Contains(setid))
                    setids.Add(setid, recoverySet);
                else
                {
                    UpdateRecoverySet(setids[setid], recoverySet);
                }
            }
        }
Example #6
0
 private Par2FileReader(Stream stream, bool multithreadCPU, bool multithreadIO)
     : base(stream)
 {
     par2RecoverySet = new Par2RecoverySet(multithreadCPU, multithreadIO);
 }
Example #7
0
        private ParResult Create(ref List <string> inputFiles, ref List <string> recoveryFiles, Par2LibraryArguments args)
        {
            // Initialize the base par2 filename if not set in the command line
            if (args.par2filename == string.Empty)
            {
                //args.par2filename = args.inputFiles[0] + ".par2";
                args.par2filename = args.inputFiles[0];
            }

            Par2RecoverySet recoverySet = new Par2RecoverySet(args.multithreadCPU, args.multithreadIO, args);

            // Compute block size from block count or vice versa depending on which was
            // specified on the command line
            if (!recoverySet.ComputeBlockSizeAndBlockCount(ref inputFiles))
            {
                return(ParResult.InvalidCommandLineArguments);
            }

            // Determine how many recovery blocks to create based on the source block
            // count and the requested level of redundancy.
            if (recoverySet.redundancy > 0 && !recoverySet.ComputeRecoveryBlockCount(recoverySet.redundancy))
            {
                return(ParResult.InvalidCommandLineArguments);
            }

            // Determine how much recovery data can be computed on one pass
            if (!recoverySet.CalculateProcessBlockSize(GetMemoryLimit()))
            {
                return(ParResult.LogicError);
            }

            // Determine how many recovery files to create.
            if (!recoverySet.ComputeRecoveryFileCount())
            {
                return(ParResult.InvalidCommandLineArguments);
            }

            //if (noiselevel > CommandLine::nlQuiet)
            //{
            // Display information.
            Console.WriteLine("Block size: " + recoverySet.MainPacket.blocksize);
            Console.WriteLine("Source file count: " + recoverySet.SourceFiles.Count);
            Console.WriteLine("Source block count: " + recoverySet.sourceblockcount);
            if (recoverySet.redundancy > 0 || recoverySet.recoveryblockcount == 0)
            {
                Console.WriteLine("Redundancy: " + recoverySet.redundancy + '%');
            }
            Console.WriteLine("Recovery block count: " + recoverySet.recoveryblockcount);
            Console.WriteLine("Recovery file count: " + recoverySet.recoveryfilecount);
            //}

            // Open all of the source files, compute the Hashes and CRC values, and store
            // the results in the file verification and file description packets.
            if (!recoverySet.OpenSourceFiles(ref inputFiles))
            {
                return(ParResult.FileIOError);
            }

            // Create the main packet and determine the setid to use with all packets
            //if (!recoverySet.CreateMainPacket(Par2LibraryArguments args))
            //  return ParResult.LogicError;

            recoverySet.criticalpackets.Add(recoverySet.MainPacket);

            // Create the creator packet.
            if (!recoverySet.CreateCreatorPacket())
            {
                return(ParResult.LogicError);
            }

            // Initialise all of the source blocks ready to start reading data from the source files.
            if (!recoverySet.CreateSourceBlocks())
            {
                return(ParResult.LogicError);
            }

            // Create all of the output files and allocate all packets to appropriate file offets.
            if (!recoverySet.InitialiseOutputFiles(args.par2filename))
            {
                return(ParResult.FileIOError);
            }

            if (recoverySet.recoveryblockcount > 0)
            {
                // Allocate memory buffers for reading and writing data to disk.
                if (!recoverySet.AllocateBuffers())
                {
                    return(ParResult.MemoryError);
                }

                // Compute the Reed Solomon matrix
                if (!recoverySet.ComputeRSMatrix())  //TODO: Unify and switch for Create and Verify/Repair
                {
                    return(ParResult.LogicError);
                }

                // Set the total amount of data to be processed.

                /*progress = 0;
                 * totaldata = blocksize * sourceblockcount * recoveryblockcount;
                 * previouslyReportedFraction = -10000000;	// Big negative*/

                //Par2RecoverySet.LogArrayToFile<byte>(@"outputbuffer.before.createparityblocks.log", recoverySet.outputbuffer);

                // Start at an offset of 0 within a block.
                ulong blockoffset = 0;
                while (blockoffset < recoverySet.MainPacket.blocksize) // Continue until the end of the block.
                {
                    // Work out how much data to process this time.
                    ulong blocklength = (ulong)Math.Min(recoverySet.chunksize, recoverySet.MainPacket.blocksize - blockoffset);

                    // Read source data, process it through the RS matrix and write it to disk.
                    if (!recoverySet.ProcessData(blockoffset, blocklength))
                    {
                        return(ParResult.FileIOError);
                    }

                    blockoffset += blocklength;
                }

                //Par2RecoverySet.LogArrayToFile<byte>(@"outputbuffer.after.createparityblocks.log", recoverySet.outputbuffer);

                //if (noiselevel > CommandLine::nlQuiet)
                //  cout << "Writing recovery packets" << endl;

                // Finish computation of the recovery packets and write the headers to disk.
                if (!recoverySet.WriteRecoveryPacketHeaders())
                {
                    return(ParResult.FileIOError);
                }

                // Finish computing the full file hash values of the source files
                if (!recoverySet.FinishFileHashComputation())
                {
                    return(ParResult.LogicError);
                }
            }

            // Fill in all remaining details in the critical packets.
            if (!recoverySet.FinishCriticalPackets())
            {
                return(ParResult.LogicError);
            }

            //if (noiselevel > CommandLine::nlQuiet)
            //  cout << "Writing verification packets" << endl;

            // Write all other critical packets to disk.
            if (!recoverySet.WriteCriticalPackets())
            {
                return(ParResult.FileIOError);
            }

            // Close all files.
            if (!recoverySet.CloseFiles())
            {
                return(ParResult.FileIOError);
            }

            //if (noiselevel > CommandLine::nlSilent)
            //  cout << "Done" << endl;

            return(ParResult.Success);
        }