summaryrefslogtreecommitdiffstats
path: root/libktorrent/datachecker
diff options
context:
space:
mode:
Diffstat (limited to 'libktorrent/datachecker')
-rw-r--r--libktorrent/datachecker/Makefile.am8
-rw-r--r--libktorrent/datachecker/datachecker.cpp34
-rw-r--r--libktorrent/datachecker/datachecker.h78
-rw-r--r--libktorrent/datachecker/datacheckerlistener.cpp33
-rw-r--r--libktorrent/datachecker/datacheckerlistener.h80
-rw-r--r--libktorrent/datachecker/datacheckerthread.cpp58
-rw-r--r--libktorrent/datachecker/datacheckerthread.h61
-rw-r--r--libktorrent/datachecker/multidatachecker.cpp201
-rw-r--r--libktorrent/datachecker/multidatachecker.h49
-rw-r--r--libktorrent/datachecker/singledatachecker.cpp103
-rw-r--r--libktorrent/datachecker/singledatachecker.h44
11 files changed, 749 insertions, 0 deletions
diff --git a/libktorrent/datachecker/Makefile.am b/libktorrent/datachecker/Makefile.am
new file mode 100644
index 0000000..b5e9ee0
--- /dev/null
+++ b/libktorrent/datachecker/Makefile.am
@@ -0,0 +1,8 @@
+INCLUDES = -I$(srcdir)/.. -I$(srcdir)/. $(all_includes)
+METASOURCES = AUTO
+libdatachecker_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libdatachecker.la
+libdatachecker_la_SOURCES = datachecker.cpp multidatachecker.cpp \
+ singledatachecker.cpp datacheckerlistener.cpp datacheckerthread.cpp
+noinst_HEADERS = datacheckerlistener.h datacheckerthread.h
+KDE_CXXFLAGS = $(USE_EXCEPTIONS) $(USE_RTTI)
diff --git a/libktorrent/datachecker/datachecker.cpp b/libktorrent/datachecker/datachecker.cpp
new file mode 100644
index 0000000..04bd08e
--- /dev/null
+++ b/libktorrent/datachecker/datachecker.cpp
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "datachecker.h"
+
+namespace bt {
+
+ DataChecker::DataChecker() : listener(0)
+ {
+ }
+
+
+ DataChecker::~DataChecker()
+ {
+ }
+
+
+}
diff --git a/libktorrent/datachecker/datachecker.h b/libktorrent/datachecker/datachecker.h
new file mode 100644
index 0000000..e181925
--- /dev/null
+++ b/libktorrent/datachecker/datachecker.h
@@ -0,0 +1,78 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef BTDATACHECKER_H
+#define BTDATACHECKER_H
+
+#include <util/bitset.h>
+#include "datacheckerlistener.h"
+
+class QString;
+
+
+namespace bt
+{
+ class Torrent;
+
+
+ /**
+ * @author Joris Guisson
+ *
+ * Checks which data is downloaded, given a torrent and a file or directory containing
+ * files of the torrent.
+ */
+ class DataChecker
+ {
+ public:
+ DataChecker();
+ virtual ~DataChecker();
+
+ /// Set the listener
+ void setListener(DataCheckerListener* l) {listener = l;}
+
+ /**
+ * Check to see which chunks have been downloaded of a torrent, and which chunks fail.
+ * The corresponding bitsets should be filled with this information.
+ * If anything goes wrong and Error should be thrown.
+ * @param path path to the file or dir (this needs to end with the name suggestion of the torrent)
+ * @param tor The torrent
+ * @param dnddir DND dir, optional argument if we know this
+ */
+ virtual void check(const QString & path,const Torrent & tor,const QString & dnddir) = 0;
+
+ /**
+ * Get the BitSet representing all the downloaded chunks.
+ */
+ const BitSet & getDownloaded() const {return downloaded;}
+
+ /**
+ * Get the BitSet representing all the failed chunks.
+ */
+ const BitSet & getFailed() const {return failed;}
+
+ /// Get the listener
+ DataCheckerListener* getListener() {return listener;}
+ protected:
+ BitSet failed,downloaded;
+ DataCheckerListener* listener;
+ };
+
+}
+
+#endif
diff --git a/libktorrent/datachecker/datacheckerlistener.cpp b/libktorrent/datachecker/datacheckerlistener.cpp
new file mode 100644
index 0000000..a4a2201
--- /dev/null
+++ b/libktorrent/datachecker/datacheckerlistener.cpp
@@ -0,0 +1,33 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "datacheckerlistener.h"
+
+namespace bt
+{
+
+ DataCheckerListener::DataCheckerListener(bool auto_import) : stopped(false),auto_import(auto_import)
+ {}
+
+
+ DataCheckerListener::~DataCheckerListener()
+ {}
+
+
+}
diff --git a/libktorrent/datachecker/datacheckerlistener.h b/libktorrent/datachecker/datacheckerlistener.h
new file mode 100644
index 0000000..a770bab
--- /dev/null
+++ b/libktorrent/datachecker/datacheckerlistener.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef BTDATACHECKERLISTENER_H
+#define BTDATACHECKERLISTENER_H
+
+#include <util/constants.h>
+
+namespace bt
+{
+
+ /**
+ @author Joris Guisson <joris.guisson@gmail.com>
+ */
+ class DataCheckerListener
+ {
+ public:
+ DataCheckerListener(bool auto_import);
+ virtual ~DataCheckerListener();
+
+ /**
+ * Called when a chunk has been proccessed.
+ * @param num The number processed
+ * @param total The total number of pieces to process
+ */
+ virtual void progress(Uint32 num,Uint32 total) = 0;
+
+ /**
+ * Called when a failed or dowloaded chunk is found.
+ * @param num_failed The number of failed chunks
+ * @param num_downloaded Number of downloaded chunks
+ */
+ virtual void status(Uint32 num_failed,Uint32 num_downloaded) = 0;
+
+ /**
+ * Data check has been finished.
+ */
+ virtual void finished() = 0;
+
+ /**
+ * Test if we need to stop.
+ */
+ bool needToStop() const {return stopped;}
+
+ /// Check if the check has been stopped
+ bool isStopped() const {return stopped;}
+
+ /// Is this an auto_import
+ bool isAutoImport() const {return auto_import;}
+
+ /**
+ * Stop the data check.
+ */
+ void stop() {stopped = true;}
+ private:
+ bool stopped;
+
+ protected:
+ bool auto_import;
+ };
+
+}
+
+#endif
diff --git a/libktorrent/datachecker/datacheckerthread.cpp b/libktorrent/datachecker/datacheckerthread.cpp
new file mode 100644
index 0000000..12a58d7
--- /dev/null
+++ b/libktorrent/datachecker/datacheckerthread.cpp
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <util/log.h>
+#include <util/error.h>
+#include <torrent/torrent.h>
+#include "datachecker.h"
+#include "datacheckerthread.h"
+
+namespace bt
+{
+
+ DataCheckerThread::DataCheckerThread(DataChecker* dc,
+ const QString & path,
+ const Torrent & tor,
+ const QString & dnddir)
+ : dc(dc),path(path),tor(tor),dnddir(dnddir)
+ {
+ running = true;
+ }
+
+
+ DataCheckerThread::~DataCheckerThread()
+ {
+ delete dc;
+ }
+
+ void DataCheckerThread::run()
+ {
+ try
+ {
+ dc->check(path,tor,dnddir);
+ }
+ catch (bt::Error & e)
+ {
+ error = e.toString();
+ Out(SYS_GEN|LOG_DEBUG) << error << endl;
+ }
+ running = false;
+ }
+
+}
diff --git a/libktorrent/datachecker/datacheckerthread.h b/libktorrent/datachecker/datacheckerthread.h
new file mode 100644
index 0000000..749e3e8
--- /dev/null
+++ b/libktorrent/datachecker/datacheckerthread.h
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef BTDATACHECKERTHREAD_H
+#define BTDATACHECKERTHREAD_H
+
+#include <qthread.h>
+
+namespace bt
+{
+ class Torrent;
+ class DataChecker;
+
+ /**
+ @author Joris Guisson <joris.guisson@gmail.com>
+
+ Thread which runs the data check.
+ */
+ class DataCheckerThread : public QThread
+ {
+ DataChecker* dc;
+ QString path;
+ const Torrent & tor;
+ QString dnddir;
+ bool running;
+ QString error;
+ public:
+ DataCheckerThread(DataChecker* dc,const QString & path,const Torrent & tor,const QString & dnddir);
+ virtual ~DataCheckerThread();
+
+ virtual void run();
+
+ /// Get the data checker
+ DataChecker* getDataChecker() {return dc;}
+
+ /// Are we still running
+ bool isRunning() const {return running;}
+
+ /// Get the error (if any occured)
+ QString getError() const {return error;}
+ };
+
+}
+
+#endif
diff --git a/libktorrent/datachecker/multidatachecker.cpp b/libktorrent/datachecker/multidatachecker.cpp
new file mode 100644
index 0000000..3c26721
--- /dev/null
+++ b/libktorrent/datachecker/multidatachecker.cpp
@@ -0,0 +1,201 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson & Maggioni Marcello *
+ * joris.guisson@gmail.com *
+ * marcello.maggioni@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <klocale.h>
+#include <kapplication.h>
+#include <util/log.h>
+#include <util/file.h>
+#include <util/fileops.h>
+#include <util/error.h>
+#include <util/array.h>
+#include <util/functions.h>
+#include <torrent/dndfile.h>
+#include <torrent/globals.h>
+#include <torrent/torrent.h>
+#include <torrent/torrentfile.h>
+#include "multidatachecker.h"
+
+namespace bt
+{
+
+ MultiDataChecker::MultiDataChecker(): DataChecker(),buf(0)
+ {}
+
+
+ MultiDataChecker::~MultiDataChecker()
+ {
+ delete [] buf;
+ }
+
+ void MultiDataChecker::check(const QString& path, const Torrent& tor,const QString & dnddir)
+ {
+ Uint32 num_chunks = tor.getNumChunks();
+ // initialize the bitsets
+ downloaded = BitSet(num_chunks);
+ failed = BitSet(num_chunks);
+
+ cache = path;
+ if (!cache.endsWith(bt::DirSeparator()))
+ cache += bt::DirSeparator();
+
+ dnd_dir = dnddir;
+ if (!dnddir.endsWith(bt::DirSeparator()))
+ dnd_dir += bt::DirSeparator();
+
+ Uint64 chunk_size = tor.getChunkSize();
+ Uint32 cur_chunk = 0;
+ TimeStamp last_update_time = bt::GetCurrentTime();
+
+ buf = new Uint8[chunk_size];
+
+ for (cur_chunk = 0;cur_chunk < num_chunks;cur_chunk++)
+ {
+ Uint32 cs = (cur_chunk == num_chunks - 1) ? tor.getFileLength() % chunk_size : chunk_size;
+ if (cs == 0)
+ cs = chunk_size;
+ if (!loadChunk(cur_chunk,cs,tor))
+ {
+ downloaded.set(cur_chunk,false);
+ failed.set(cur_chunk,true);
+ continue;
+ }
+
+ bool ok = (SHA1Hash::generate(buf,cs) == tor.getHash(cur_chunk));
+ downloaded.set(cur_chunk,ok);
+ failed.set(cur_chunk,!ok);
+
+ if (listener)
+ {
+ listener->status(failed.numOnBits(),downloaded.numOnBits());
+ listener->progress(cur_chunk,num_chunks);
+ if (listener->needToStop())
+ return;
+ }
+
+ TimeStamp now = bt::GetCurrentTime();
+ if (now - last_update_time > 1000)
+ {
+ Out() << "Checked " << cur_chunk << " chunks" << endl;
+ // KApplication::kApplication()->processEvents();
+ last_update_time = now;
+ }
+ }
+ }
+
+ static Uint32 ReadFullChunk(Uint32 chunk,Uint32 cs,
+ const TorrentFile & tf,
+ const Torrent & tor,
+ Uint8* buf,
+ const QString & cache)
+ {
+ File fptr;
+ if (!fptr.open(cache + tf.getPath(), "rb"))
+ {
+ Out() << QString("Warning : Cannot open %1 : %2").arg(cache +
+ tf.getPath()).arg(fptr.errorString()) << endl;
+ return 0;
+ }
+
+ Uint64 off = tf.fileOffset(chunk,tor.getChunkSize());
+ fptr.seek(File::BEGIN,off);
+ return fptr.read(buf,cs);
+ }
+
+ bool MultiDataChecker::loadChunk(Uint32 ci,Uint32 cs,const Torrent & tor)
+ {
+ QValueList<Uint32> tflist;
+ tor.calcChunkPos(ci,tflist);
+
+ // one file is simple
+ if (tflist.count() == 1)
+ {
+ const TorrentFile & f = tor.getFile(tflist.first());
+ if (!f.doNotDownload())
+ {
+ ReadFullChunk(ci,cs,f,tor,buf,cache);
+ return true;
+ }
+ return false;
+ }
+
+ Uint64 read = 0; // number of bytes read
+ for (Uint32 i = 0;i < tflist.count();i++)
+ {
+ const TorrentFile & f = tor.getFile(tflist[i]);
+
+ // first calculate offset into file
+ // only the first file can have an offset
+ // the following files will start at the beginning
+ Uint64 off = 0;
+ if (i == 0)
+ off = f.fileOffset(ci,tor.getChunkSize());
+
+ Uint32 to_read = 0;
+ // then the amount of data we can read from this file
+ if (i == 0)
+ to_read = f.getLastChunkSize();
+ else if (i == tflist.count() - 1)
+ to_read = cs - read;
+ else
+ to_read = f.getSize();
+
+ // read part of data
+ if (f.doNotDownload())
+ {
+ if (!dnd_dir.isNull() && bt::Exists(dnd_dir + f.getPath() + ".dnd"))
+ {
+ Uint32 ret = 0;
+ DNDFile dfd(dnd_dir + f.getPath() + ".dnd");
+ if (i == 0)
+ ret = dfd.readLastChunk(buf,read,cs);
+ else if (i == tflist.count() - 1)
+ ret = dfd.readFirstChunk(buf,read,cs);
+ else
+ ret = dfd.readFirstChunk(buf,read,cs);
+
+ if (ret > 0 && ret != to_read)
+ Out() << "Warning : MultiDataChecker::load ret != to_read (dnd)" << endl;
+ }
+ }
+ else
+ {
+ if (!bt::Exists(cache + f.getPath()) || bt::FileSize(cache + f.getPath()) < off)
+ return false;
+
+ File fptr;
+ if (!fptr.open(cache + f.getPath(), "rb"))
+ {
+ Out() << QString("Warning : Cannot open %1 : %2").arg(cache +
+ f.getPath()).arg(fptr.errorString()) << endl;
+ return false;
+ }
+ else
+ {
+ fptr.seek(File::BEGIN,off);
+ if (fptr.read(buf+read,to_read) != to_read)
+ Out() << "Warning : MultiDataChecker::load ret != to_read" << endl;
+ }
+ }
+ read += to_read;
+ }
+ return true;
+ }
+}
diff --git a/libktorrent/datachecker/multidatachecker.h b/libktorrent/datachecker/multidatachecker.h
new file mode 100644
index 0000000..d095e99
--- /dev/null
+++ b/libktorrent/datachecker/multidatachecker.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef BTMULTIDATACHECKER_H
+#define BTMULTIDATACHECKER_H
+
+#include "datachecker.h"
+
+namespace bt
+{
+
+ /**
+ @author Joris Guisson
+ */
+ class MultiDataChecker : public DataChecker
+ {
+ public:
+ MultiDataChecker();
+ virtual ~MultiDataChecker();
+
+ virtual void check(const QString& path, const Torrent& tor,const QString & dnddir);
+ private:
+ bool loadChunk(Uint32 ci,Uint32 cs,const Torrent & to);
+
+ private:
+ QString cache;
+ QString dnd_dir;
+ Uint8* buf;
+ };
+
+}
+
+#endif
diff --git a/libktorrent/datachecker/singledatachecker.cpp b/libktorrent/datachecker/singledatachecker.cpp
new file mode 100644
index 0000000..0579338
--- /dev/null
+++ b/libktorrent/datachecker/singledatachecker.cpp
@@ -0,0 +1,103 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <klocale.h>
+#include <kapplication.h>
+#include <util/log.h>
+#include <util/file.h>
+#include <util/error.h>
+#include <util/array.h>
+#include <util/functions.h>
+#include <torrent/globals.h>
+#include <torrent/torrent.h>
+#include "singledatachecker.h"
+
+namespace bt
+{
+
+ SingleDataChecker::SingleDataChecker(): DataChecker()
+ {}
+
+
+ SingleDataChecker::~SingleDataChecker()
+ {}
+
+
+ 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());
+ }
+ }
+
+}
diff --git a/libktorrent/datachecker/singledatachecker.h b/libktorrent/datachecker/singledatachecker.h
new file mode 100644
index 0000000..20107b3
--- /dev/null
+++ b/libktorrent/datachecker/singledatachecker.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef BTSINGLEDATACHECKER_H
+#define BTSINGLEDATACHECKER_H
+
+#include "datachecker.h"
+
+namespace bt
+{
+
+ /**
+ * @author Joris Guisson
+ *
+ * Data checker for single file torrents.
+ */
+ class SingleDataChecker : public DataChecker
+ {
+ public:
+ SingleDataChecker();
+ virtual ~SingleDataChecker();
+
+ virtual void check(const QString& path, const Torrent& tor,const QString & dnddir);
+ };
+
+}
+
+#endif