/* */ #include "BtDependency.h" #include "RequestGroup.h" #include "Option.h" #include "LogFactory.h" #include "Logger.h" #include "DownloadContext.h" #include "RecoverableException.h" #include "message.h" #include "prefs.h" #include "util.h" #include "PieceStorage.h" #include "DiskAdaptor.h" #include "File.h" #include "bittorrent_helper.h" #include "DlAbortEx.h" namespace aria2 { BtDependency::BtDependency(const RequestGroupWeakHandle& dependant, const RequestGroupHandle& dependee): _dependant(dependant), _dependee(dependee), _logger(LogFactory::getInstance()) {} BtDependency::~BtDependency() {} bool BtDependency::resolve() { if(_dependee->getNumCommand() == 0 && _dependee->downloadFinished()) { RequestGroupHandle dependee = _dependee; // cut reference here _dependee.reset(); SharedHandle context(new DownloadContext()); context->setDir(_dependant->getDownloadContext()->getDir()); try { DiskAdaptorHandle diskAdaptor = dependee->getPieceStorage()->getDiskAdaptor(); diskAdaptor->openExistingFile(); std::string content = util::toString(diskAdaptor); bittorrent::loadFromMemory (content, context, File(dependee->getFirstFilePath()).getBasename()); if(context->getFileEntries().size() != _dependant->getDownloadContext()->getFileEntries().size()) { throw DL_ABORT_EX("The number of file in torrent doesn't match to" " the dependent."); } // Copy file path in _dependant's FileEntries to newly created // context's FileEntries to endorse the path structure of // _dependant. URIs and singleHostMultiConnection are also copied. for(std::vector >::const_iterator s = _dependant->getDownloadContext()->getFileEntries().begin(), d = context->getFileEntries().begin(); d != context->getFileEntries().end(); ++s, ++d) { (*d)->setPath((*s)->getPath()); (*d)->addUris((*s)->getRemainingUris().begin(), (*s)->getRemainingUris().end()); if(!(*s)->isSingleHostMultiConnectionEnabled()) { (*d)->disableSingleHostMultiConnection(); } } } catch(RecoverableException& e) { _logger->error(EX_EXCEPTION_CAUGHT, e); _logger->info("BtDependency for GID#%d failed. Go without Bt.", _dependant->getGID()); return true; } _logger->debug("Dependency resolved for GID#%d", _dependant->getGID()); _dependant->setDownloadContext(context); context->setOwnerRequestGroup(_dependant.get()); return true; } else if(_dependee->getNumCommand() == 0) { // _dependee's download failed. // cut reference here _dependee.reset(); _logger->debug("BtDependency for GID#%d failed. Go without Bt.", _dependant->getGID()); return true; } else { return false; } } } // namespace aria2