public HierarchicalIntegrityVerificationStream(IntegrityVerificationInfo[] levelInfo, bool enableIntegrityChecks) { Levels = new Stream[levelInfo.Length]; EnableIntegrityChecks = enableIntegrityChecks; Levels[0] = levelInfo[0].Data; for (int i = 1; i < Levels.Length; i++) { var levelData = new IntegrityVerificationStream(levelInfo[i], Levels[i - 1], enableIntegrityChecks); Levels[i] = new RandomAccessSectorStream(levelData); } DataLevel = Levels[Levels.Length - 1]; }
public HierarchicalIntegrityVerificationStream(IntegrityVerificationInfo[] levelInfo, IntegrityCheckLevel integrityCheckLevel) { Levels = new Stream[levelInfo.Length]; IntegrityCheckLevel = integrityCheckLevel; LevelValidities = new Validity[levelInfo.Length - 1][]; IntegrityStreams = new IntegrityVerificationStream[levelInfo.Length - 1]; Levels[0] = levelInfo[0].Data; for (int i = 1; i < Levels.Length; i++) { var levelData = new IntegrityVerificationStream(levelInfo[i], Levels[i - 1], integrityCheckLevel); Levels[i] = new RandomAccessSectorStream(levelData); LevelValidities[i - 1] = levelData.BlockValidities; IntegrityStreams[i - 1] = levelData; } DataLevel = Levels[Levels.Length - 1]; }
/// <summary> /// Checks the hashes of any unchecked blocks and returns the <see cref="Validity"/> of the data. /// </summary> /// <param name="returnOnError">If <see langword="true"/>, return as soon as an invalid block is found.</param> /// <param name="logger">An optional <see cref="IProgressReport"/> for reporting progress.</param> /// <returns>The <see cref="Validity"/> of the data of the specified hash level.</returns> public Validity Validate(bool returnOnError, IProgressReport logger = null) { Validity[] validities = LevelValidities[LevelValidities.Length - 1]; IntegrityVerificationStream stream = IntegrityStreams[IntegrityStreams.Length - 1]; // Restore the original position of the stream when we're done validating long initialPosition = stream.Position; long blockSize = stream.SectorSize; int blockCount = (int)Util.DivideByRoundUp(Length, blockSize); var buffer = new byte[blockSize]; var result = Validity.Valid; logger?.SetTotal(blockCount); for (int i = 0; i < blockCount; i++) { if (validities[i] == Validity.Unchecked) { stream.Position = blockSize * i; stream.Read(buffer, 0, buffer.Length, IntegrityCheckLevel.IgnoreOnInvalid); } if (validities[i] == Validity.Invalid) { result = Validity.Invalid; if (returnOnError) { break; } } logger?.ReportAdd(1); } logger?.SetTotal(0); stream.Position = initialPosition; return(result); }