kget
btdatasource.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "btdatasource.h"
00012 #include "btcache.h"
00013 #include "btchunkselector.h"
00014 #include "bittorrentsettings.h"
00015 #include "core/download.h"
00016 #include <torrent/torrentcontrol.h>
00017 #include <util/error.h>
00018 #include <torrent/globals.h>
00019 #include <torrent/server.h>
00020 #include <btversion.h>
00021 #include <util/log.h>
00022 #include <util/bitset.h>
00023 #include <peer/authenticationmonitor.h>
00024 #include <util/functions.h>
00025
00026 #include <kdebug.h>
00027 #include <kstandarddirs.h>
00028
00029 using namespace bt;
00030
00031 BTDataSource::BTDataSource()
00032 : TransferDataSource(0),
00033 m_offset(0),
00034 m_bytes(0),
00035 m_source(KUrl()),
00036 m_torrentSource(KUrl())
00037 {
00038 bt::InitLog(KStandardDirs::locateLocal("appdata", "torrentlog.log"));
00039
00040 bt::SetClientInfo("KGet",2,1,0,bt::NORMAL,"KG");
00041
00042 bt::Uint16 i = 0;
00043 do
00044 {
00045 kDebug(5001) << "Trying to set port to" << BittorrentSettings::port() + i;
00046 bt::Globals::instance().initServer(BittorrentSettings::port() + i);
00047 i++;
00048 }while (!bt::Globals::instance().getServer().isOK() && i < 10);
00049
00050 if (!bt::Globals::instance().getServer().isOK())
00051 return;
00052 tc = new TorrentControl();
00053 csf = new BTChunkSelectorFactory();
00054 cf = new BTCacheFactory();
00055 connect(cf, SIGNAL(cacheAdded(BTCache*)), SLOT(cacheAdded(BTCache *)));
00056 connect(csf, SIGNAL(selectorAdded(BTChunkSelector*)), SLOT(selectorAdded(BTChunkSelector*)));
00057 tc->setChunkSelectorFactory(csf);
00058 tc->setCacheFactory(cf);
00059 connect(&timer, SIGNAL(timeout()), SLOT(update()));
00060 }
00061
00062 BTDataSource::~BTDataSource()
00063 {
00064 delete tc;
00065 delete cs;
00066 delete cf;
00067 }
00068
00069 void BTDataSource::cacheAdded(BTCache *cache)
00070 {
00071 connect(cache, SIGNAL(dataArrived(const KIO::fileoffset_t &, const QByteArray &)), SLOT(getData(const KIO::fileoffset_t &, const QByteArray &)));
00072 }
00073
00074 void BTDataSource::selectorAdded(BTChunkSelector* selector)
00075 {
00076 cs = selector;
00077 }
00078
00079 void BTDataSource::start()
00080 {
00081 if (m_torrentSource.isEmpty())
00082 {
00083 Download *download = new Download(m_source, KStandardDirs::locateLocal("appdata", "tmp/") + m_source.fileName());
00084 connect(download, SIGNAL(finishedSuccessfully(KUrl, QByteArray)), SLOT(init(KUrl, QByteArray)));
00085 }
00086 else
00087 {
00088 cs->excludeAll();
00089 const BitSet & bits = tc->availableChunksBitSet();
00090 bool av = true;
00091 Uint32 firstChunk = m_offset / tc->getStats().chunk_size;
00092 Uint32 lastChunk = ((m_offset + m_bytes) / tc->getStats().chunk_size) + 1;
00093 for (int i = firstChunk * tc->getStats().chunk_size * 8; i <= lastChunk * tc->getStats().chunk_size * 8; i++)
00094 {
00095 if (!bits.get(i))
00096 {
00097 emit broken();
00098 av = false;
00099 continue;
00100 }
00101 }
00102 if (av)
00103 {
00104 cs->reincluded(firstChunk, lastChunk);
00105 tc->start();
00106 timer.start(250);
00107 }
00108 }
00109 }
00110
00111 void BTDataSource::stop()
00112 {
00113 tc->stop(true);
00114 timer.stop();
00115 }
00116
00117 void BTDataSource::update()
00118 {
00119 bt::UpdateCurrentTime();
00120 bt::AuthenticationMonitor::instance().update();
00121 tc->update();
00122 }
00123
00124 void BTDataSource::init(const KUrl &torrentSource, const QByteArray &data)
00125 {
00126 Q_UNUSED(data);
00127 m_torrentSource = torrentSource;
00128 try
00129 {
00130 tc->init(0, m_torrentSource.url(), QString(), QString(), 0);
00131 }
00132 catch (bt::Error &err)
00133 {
00134 kDebug(5001) << err.toString();
00135
00136 }
00137 start();
00138 }
00139
00140 void BTDataSource::addSegment(const KUrl &srcUrl, const KIO::fileoffset_t offset, const KIO::fileoffset_t bytes)
00141 {
00142 kDebug(5001);
00143 if (m_source == srcUrl)
00144 {
00145 if (offset < m_offset)
00146 {
00147 m_offset = offset;
00148 if (m_bytes < bytes + m_offset - offset)
00149 {
00150 m_bytes = bytes + m_offset - offset;
00151 }
00152 }
00153 if (offset > m_offset && m_bytes < bytes + m_offset - offset)
00154 {
00155 m_bytes = bytes + m_offset - offset;
00156 }
00157 if (offset == m_offset && m_bytes < bytes)
00158 {
00159 m_bytes = bytes;
00160 }
00161 }
00162 else
00163 {
00164 m_source = srcUrl;
00165 m_offset = offset;
00166 m_bytes = bytes;
00167 }
00168 }
00169
00170 void BTDataSource::getData(const KIO::fileoffset_t &off, const QByteArray &dataArray)
00171 {
00172 QByteArray splittedData;
00173 if (off < m_offset)
00174 splittedData = dataArray.right(dataArray.size() - (m_offset - off));
00175 else if (m_offset + m_bytes < off + dataArray.size())
00176 splittedData = dataArray.left((off + dataArray.size()) - (m_offset + m_bytes));
00177 else
00178 splittedData = dataArray;
00179
00180 emit data(off, splittedData);
00181
00182 if (m_offset + m_bytes == off + dataArray.size())
00183 emit finished();
00184 }
00185
00186 #include "btdatasource.moc"