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(); }
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); } } }
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; }
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(); }
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); } } }
private Par2FileReader(Stream stream, bool multithreadCPU, bool multithreadIO) : base(stream) { par2RecoverySet = new Par2RecoverySet(multithreadCPU, multithreadIO); }
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); }