void SingleDataChecker::check(const QString& path, const Torrent& tor,const QString &) { // open the file Uint32 num_chunks = tor.getNumChunks(); Uint32 chunk_size = tor.getChunkSize(); File fptr; if (!fptr.open(path,"rb")) { throw Error(i18n("Cannot open file : %1 : %2") .arg(path).arg( fptr.errorString())); } // initialize the bitsets downloaded = BitSet(num_chunks); failed = BitSet(num_chunks); TimeStamp last_update_time = bt::GetCurrentTime(); // loop over all chunks Array<Uint8> buf(chunk_size); for (Uint32 i = 0;i < num_chunks;i++) { if (listener) { listener->progress(i,num_chunks); if (listener->needToStop()) // if we need to stop just return return; } TimeStamp now = bt::GetCurrentTime(); if (now - last_update_time > 1000) { Out(SYS_DIO|LOG_DEBUG) << "Checked " << i << " chunks" << endl; last_update_time = now; } if (!fptr.eof()) { // read the chunk Uint32 size = i == num_chunks - 1 && tor.getFileLength() % tor.getChunkSize() > 0 ? tor.getFileLength() % tor.getChunkSize() : (Uint32)tor.getChunkSize(); fptr.seek(File::BEGIN,(Int64)i*tor.getChunkSize()); fptr.read(buf,size); // generate and test hash SHA1Hash h = SHA1Hash::generate(buf,size); bool ok = (h == tor.getHash(i)); downloaded.set(i,ok); failed.set(i,!ok); } else { // at end of file so set to default values for a failed chunk downloaded.set(i,false); failed.set(i,true); } if (listener) listener->status(failed.numOnBits(),downloaded.numOnBits()); } }