public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandler resultHandler) {
if (isDisposed_) {
throw new ObjectDisposedException("ZipFile");
}
var status=new TestStatus(this);
if (resultHandler!=null) {
resultHandler(status, null);
}
HeaderTest test=testData?(HeaderTest.Header|HeaderTest.Extract):HeaderTest.Header;
bool testing=true;
try {
int entryIndex=0;
while (testing&&(entryIndex<Count)) {
if (resultHandler!=null) {
status.SetEntry(this[entryIndex]);
status.SetOperation(TestOperation.EntryHeader);
resultHandler(status, null);
}
try {
TestLocalHeader(this[entryIndex], test);
} catch (ZipException ex) {
status.AddError();
if (resultHandler!=null) {
resultHandler(status,
string.Format("Exception during test - '{0}'", ex.Message));
}
if (strategy==TestStrategy.FindFirstError) {
testing=false;
}
}
if (testing&&testData&&this[entryIndex].IsFile) {
if (resultHandler!=null) {
status.SetOperation(TestOperation.EntryData);
resultHandler(status, null);
}
var crc=new Crc32();
using (Stream entryStream=GetInputStream(this[entryIndex])) {
var buffer=new byte[4096];
long totalBytes=0;
int bytesRead;
while ((bytesRead=entryStream.Read(buffer, 0, buffer.Length))>0) {
crc.Update(buffer, 0, bytesRead);
if (resultHandler!=null) {
totalBytes+=bytesRead;
status.SetBytesTested(totalBytes);
resultHandler(status, null);
}
}
}
if (this[entryIndex].Crc!=crc.Value) {
status.AddError();
if (resultHandler!=null) {
resultHandler(status, "CRC mismatch");
}
if (strategy==TestStrategy.FindFirstError) {
testing=false;
}
}
if ((this[entryIndex].Flags&(int)GeneralBitFlags.Descriptor)!=0) {
var helper=new ZipHelperStream(baseStream_);
var data=new DescriptorData();
helper.ReadDataDescriptor(this[entryIndex].LocalHeaderRequiresZip64, data);
if (this[entryIndex].Crc!=data.Crc) {
status.AddError();
}
if (this[entryIndex].CompressedSize!=data.CompressedSize) {
status.AddError();
}
if (this[entryIndex].Size!=data.Size) {
status.AddError();
}
}
}
if (resultHandler!=null) {
status.SetOperation(TestOperation.EntryComplete);
resultHandler(status, null);
}
entryIndex+=1;
}
if (resultHandler!=null) {
status.SetOperation(TestOperation.MiscellaneousTests);
resultHandler(status, null);
}
// TODO: the 'Corrina Johns' test where local headers are missing from
// the central directory. They are therefore invisible to many archivers.
} catch (Exception ex) {
status.AddError();
if (resultHandler!=null) {
resultHandler(status, string.Format("Exception during test - '{0}'", ex.Message));
}
}
if (resultHandler!=null) {
status.SetOperation(TestOperation.Complete);
status.SetEntry(null);
resultHandler(status, null);
}
return (status.ErrorCount==0);
}