/* */ #include "DownloadContext.h" #include #include "FileEntry.h" #include "StringFormat.h" #include "util.h" #include "wallclock.h" #include "DlAbortEx.h" namespace aria2 { DownloadContext::DownloadContext(): dir_(A2STR::DOT_C), pieceLength_(0), checksumVerified_(false), knowsTotalLength_(true), ownerRequestGroup_(0), downloadStartTime_(0), downloadStopTime_(downloadStartTime_) {} DownloadContext::DownloadContext(size_t pieceLength, uint64_t totalLength, const std::string& path): dir_(A2STR::DOT_C), pieceLength_(pieceLength), checksumVerified_(false), knowsTotalLength_(true), ownerRequestGroup_(0), downloadStartTime_(0), downloadStopTime_(0) { SharedHandle fileEntry(new FileEntry(path, totalLength, 0)); fileEntries_.push_back(fileEntry); } void DownloadContext::resetDownloadStartTime() { downloadStartTime_ = global::wallclock; downloadStopTime_.reset(0); } void DownloadContext::resetDownloadStopTime() { downloadStopTime_ = global::wallclock; } int64_t DownloadContext::calculateSessionTime() const { if(downloadStopTime_ > downloadStartTime_) { return downloadStartTime_.differenceInMillis(downloadStopTime_); } else { return 0; } } SharedHandle DownloadContext::findFileEntryByOffset(off_t offset) const { if(fileEntries_.empty() || (offset > 0 && fileEntries_.back()->getOffset()+fileEntries_.back()->getLength() <= static_cast(offset))){ return SharedHandle(); } SharedHandle obj(new FileEntry()); obj->setOffset(offset); std::vector >::const_iterator i = std::upper_bound(fileEntries_.begin(), fileEntries_.end(), obj); if(i != fileEntries_.end() && (*i)->getOffset() == offset) { return *i; } else { return *(--i); } } void DownloadContext::setFilePathWithIndex (size_t index, const std::string& path) { if(0 < index && index <= fileEntries_.size()) { // We don't escape path because path may come from users. fileEntries_[index-1]->setPath(path); } else { throw DL_ABORT_EX(StringFormat("No such file with index=%u", static_cast(index)).str()); } } void DownloadContext::setFileFilter(IntSequence seq) { std::vector fileIndexes = seq.flush(); std::sort(fileIndexes.begin(), fileIndexes.end()); fileIndexes.erase(std::unique(fileIndexes.begin(), fileIndexes.end()), fileIndexes.end()); bool selectAll = fileIndexes.empty() || fileEntries_.size() == 1; int32_t index = 1; for(std::vector >::const_iterator i = fileEntries_.begin(), eoi = fileEntries_.end(); i != eoi; ++i, ++index) { (*i)->setRequested (selectAll || std::binary_search(fileIndexes.begin(), fileIndexes.end(), index)); } } void DownloadContext::setAttribute (const std::string& key, const SharedHandle& value) { std::map >::value_type p = std::make_pair(key, value); std::pair >::iterator, bool> r = attrs_.insert(p); if(!r.second) { (*r.first).second = value; } } const SharedHandle& DownloadContext::getAttribute (const std::string& key) { std::map >::const_iterator itr = attrs_.find(key); if(itr == attrs_.end()) { throw DL_ABORT_EX(StringFormat("No attribute named %s", key.c_str()).str()); } else { return (*itr).second; } } bool DownloadContext::hasAttribute(const std::string& key) const { return attrs_.count(key) == 1; } void DownloadContext::releaseRuntimeResource() { for(std::vector >::const_iterator i = fileEntries_.begin(), eoi = fileEntries_.end(); i != eoi; ++i) { (*i)->releaseRuntimeResource(); } } size_t DownloadContext::getNumPieces() const { if(pieceLength_ == 0) { return 0; } else { assert(!fileEntries_.empty()); return (fileEntries_.back()->getLastOffset()+pieceLength_-1)/pieceLength_; } } uint64_t DownloadContext::getTotalLength() const { if(fileEntries_.empty()) { return 0; } else { return fileEntries_.back()->getLastOffset(); } } const std::string& DownloadContext::getBasePath() const { if(basePath_.empty()) { assert(!fileEntries_.empty()); return getFirstFileEntry()->getPath(); } else { return basePath_; } } bool DownloadContext::isChecksumVerificationNeeded() const { return pieceHashAlgo_.empty() && !checksum_.empty() && !checksumHashAlgo_.empty() && !checksumVerified_; } } // namespace aria2