File indexing completed on 2025-01-05 04:37:09
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #include "singledatachecker.h" 0007 #include <klocalizedstring.h> 0008 #include <torrent/globals.h> 0009 #include <torrent/torrent.h> 0010 #include <util/array.h> 0011 #include <util/error.h> 0012 #include <util/file.h> 0013 #include <util/functions.h> 0014 #include <util/log.h> 0015 0016 namespace bt 0017 { 0018 SingleDataChecker::SingleDataChecker(bt::Uint32 from, bt::Uint32 to) 0019 : DataChecker(from, to) 0020 { 0021 } 0022 0023 SingleDataChecker::~SingleDataChecker() 0024 { 0025 } 0026 0027 void SingleDataChecker::check(const QString &path, const Torrent &tor, const QString &, const BitSet ¤t_status) 0028 { 0029 // open the file 0030 Uint32 num_chunks = tor.getNumChunks(); 0031 Uint32 chunk_size = tor.getChunkSize(); 0032 File fptr; 0033 if (!fptr.open(path, "rb")) { 0034 throw Error(i18n("Cannot open file %1: %2", path, fptr.errorString())); 0035 } 0036 0037 if (from >= tor.getNumChunks()) 0038 from = 0; 0039 if (to >= tor.getNumChunks()) 0040 to = tor.getNumChunks() - 1; 0041 0042 // initialize the bitset 0043 result = BitSet(num_chunks); 0044 // loop over all chunks 0045 Array<Uint8> buf(chunk_size); 0046 TimeStamp last_emitted = bt::Now(); 0047 for (Uint32 i = from; i <= to && !need_to_stop; i++) { 0048 if (!fptr.eof()) { 0049 // read the chunk 0050 Uint32 size = i == num_chunks - 1 ? tor.getLastChunkSize() : tor.getChunkSize(); 0051 0052 fptr.seek(File::BEGIN, (Int64)i * tor.getChunkSize()); 0053 fptr.read(buf, size); 0054 // generate and test hash 0055 SHA1Hash h = SHA1Hash::generate(buf, size); 0056 bool ok = (h == tor.getHash(i)); 0057 result.set(i, ok); 0058 if (ok && current_status.get(i)) 0059 downloaded++; 0060 else if (!ok && current_status.get(i)) 0061 failed++; 0062 else if (!ok && !current_status.get(i)) 0063 not_downloaded++; 0064 else if (ok && !current_status.get(i)) 0065 found++; 0066 } else { 0067 // at end of file so set to default values for a failed chunk 0068 result.set(i, false); 0069 if (!current_status.get(i)) 0070 not_downloaded++; 0071 else 0072 failed++; 0073 } 0074 0075 TimeStamp now = Now(); 0076 if (now - last_emitted > 1000 || i == num_chunks - 1) { // Emit signals once every second 0077 status(failed, found, downloaded, not_downloaded); 0078 progress(i - from, from - to + 1); 0079 last_emitted = now; 0080 } 0081 } 0082 0083 status(failed, found, downloaded, not_downloaded); 0084 } 0085 0086 }