1 /* 2 * Copyright (C) 2001-2009 Jacek Sieka, arnetheduck on gmail point com 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 */ 18 19 #ifndef DCPLUSPLUS_DCPP_QUEUE_ITEM_H 20 #define DCPLUSPLUS_DCPP_QUEUE_ITEM_H 21 22 #include "User.h" 23 #include "FastAlloc.h" 24 #include "MerkleTree.h" 25 #include "Flags.h" 26 #include "forward.h" 27 #include "Segment.h" 28 29 namespace dcpp { 30 31 class QueueManager; 32 33 class QueueItem : public Flags, public FastAlloc<QueueItem> { 34 public: 35 typedef QueueItem* Ptr; 36 typedef std::list<Ptr> List; 37 typedef List::iterator Iter; 38 typedef unordered_map<string*, Ptr, noCaseStringHash, noCaseStringEq> StringMap; 39 typedef StringMap::iterator StringIter; 40 typedef unordered_map<UserPtr, Ptr, User::Hash> UserMap; 41 typedef UserMap::iterator UserIter; 42 typedef unordered_map<UserPtr, List, User::Hash> UserListMap; 43 typedef UserListMap::iterator UserListIter; 44 45 enum Priority { 46 DEFAULT = -1, 47 PAUSED = 0, 48 LOWEST, 49 LOW, 50 NORMAL, 51 HIGH, 52 HIGHEST, 53 LAST 54 }; 55 56 enum FileFlags { 57 /** Normal download, no flags set */ 58 FLAG_NORMAL = 0x00, 59 /** This is a user file listing download */ 60 FLAG_USER_LIST = 0x02, 61 /** The file list is downloaded to use for directory download (used with USER_LIST) */ 62 FLAG_DIRECTORY_DOWNLOAD = 0x04, 63 /** The file is downloaded to be viewed in the gui */ 64 FLAG_CLIENT_VIEW = 0x08, 65 /** Flag to indicate that file should be viewed as a text file */ 66 FLAG_TEXT = 0x20, 67 /** Match the queue against this list */ 68 FLAG_MATCH_QUEUE = 0x80, 69 /** The file list downloaded was actually an .xml.bz2 list */ 70 FLAG_XML_BZLIST = 0x100, 71 /** Only download a part of the file list */ 72 FLAG_PARTIAL_LIST = 0x200 73 }; 74 75 class Source : public Flags { 76 public: 77 enum { 78 FLAG_NONE = 0x00, 79 FLAG_FILE_NOT_AVAILABLE = 0x01, 80 FLAG_PASSIVE = 0x02, 81 FLAG_REMOVED = 0x04, 82 FLAG_CRC_FAILED = 0x08, 83 FLAG_CRC_WARN = 0x10, 84 FLAG_NO_TTHF = 0x20, 85 FLAG_BAD_TREE = 0x40, 86 FLAG_NO_TREE = 0x80, 87 FLAG_SLOW_SOURCE = 0x100, 88 FLAG_UNTRUSTED = 0x200, 89 FLAG_MASK = FLAG_FILE_NOT_AVAILABLE 90 | FLAG_PASSIVE | FLAG_REMOVED | FLAG_CRC_FAILED | FLAG_CRC_WARN 91 | FLAG_BAD_TREE | FLAG_NO_TREE | FLAG_SLOW_SOURCE | FLAG_UNTRUSTED 92 }; 93 Source(const UserPtr & aUser)94 Source(const UserPtr& aUser) : user(aUser) { } Source(const Source & aSource)95 Source(const Source& aSource) : Flags(aSource), user(aSource.user) { } 96 97 bool operator==(const UserPtr& aUser) const { return user == aUser; } getUser()98 UserPtr& getUser() { return user; } 99 GETSET(UserPtr, user, User); 100 }; 101 102 typedef std::vector<Source> SourceList; 103 typedef SourceList::iterator SourceIter; 104 typedef SourceList::const_iterator SourceConstIter; 105 106 typedef set<Segment> SegmentSet; 107 typedef SegmentSet::iterator SegmentIter; 108 typedef SegmentSet::const_iterator SegmentConstIter; 109 QueueItem(const string & aTarget,int64_t aSize,Priority aPriority,int aFlag,time_t aAdded,const TTHValue & tth)110 QueueItem(const string& aTarget, int64_t aSize, Priority aPriority, int aFlag, 111 time_t aAdded, const TTHValue& tth) : 112 Flags(aFlag), target(aTarget), size(aSize), 113 priority(aPriority), added(aAdded), tthRoot(tth) 114 { } 115 QueueItem(const QueueItem & rhs)116 QueueItem(const QueueItem& rhs) : 117 Flags(rhs), done(rhs.done), downloads(rhs.downloads), target(rhs.target), 118 size(rhs.size), priority(rhs.priority), added(rhs.added), tthRoot(rhs.tthRoot), 119 sources(rhs.sources), badSources(rhs.badSources), tempTarget(rhs.tempTarget) 120 { } 121 ~QueueItem()122 virtual ~QueueItem() { } 123 124 int countOnlineUsers() const; hasOnlineUsers()125 bool hasOnlineUsers() const { return countOnlineUsers() > 0; } 126 getSources()127 SourceList& getSources() { return sources; } getSources()128 const SourceList& getSources() const { return sources; } getBadSources()129 SourceList& getBadSources() { return badSources; } getBadSources()130 const SourceList& getBadSources() const { return badSources; } 131 getOnlineUsers(UserList & l)132 void getOnlineUsers(UserList& l) const { 133 for(SourceConstIter i = sources.begin(); i != sources.end(); ++i) 134 if(i->getUser()->isOnline()) 135 l.push_back(i->getUser()); 136 } 137 getTargetFileName()138 string getTargetFileName() const { return Util::getFileName(getTarget()); } 139 getSource(const UserPtr & aUser)140 SourceIter getSource(const UserPtr& aUser) { return find(sources.begin(), sources.end(), aUser); } getBadSource(const UserPtr & aUser)141 SourceIter getBadSource(const UserPtr& aUser) { return find(badSources.begin(), badSources.end(), aUser); } getSource(const UserPtr & aUser)142 SourceConstIter getSource(const UserPtr& aUser) const { return find(sources.begin(), sources.end(), aUser); } getBadSource(const UserPtr & aUser)143 SourceConstIter getBadSource(const UserPtr& aUser) const { return find(badSources.begin(), badSources.end(), aUser); } 144 isSource(const UserPtr & aUser)145 bool isSource(const UserPtr& aUser) const { return getSource(aUser) != sources.end(); } isBadSource(const UserPtr & aUser)146 bool isBadSource(const UserPtr& aUser) const { return getBadSource(aUser) != badSources.end(); } isBadSourceExcept(const UserPtr & aUser,Flags::MaskType exceptions)147 bool isBadSourceExcept(const UserPtr& aUser, Flags::MaskType exceptions) const { 148 SourceConstIter i = getBadSource(aUser); 149 if(i != badSources.end()) 150 return i->isAnySet(exceptions^Source::FLAG_MASK); 151 return false; 152 } 153 154 int64_t getDownloadedBytes() const; getDownloadedFraction()155 double getDownloadedFraction() const { return static_cast<double>(getDownloadedBytes()) / getSize(); } 156 getDownloads()157 DownloadList& getDownloads() { return downloads; } 158 159 /** Next segment that is not done and not being downloaded, zero-sized segment returned if there is none is found */ 160 Segment getNextSegment(int64_t blockSize, int64_t wantedSize) const; 161 162 void addSegment(const Segment& segment); resetDownloaded()163 void resetDownloaded() { done.clear(); } 164 isFinished()165 bool isFinished() const { 166 return done.size() == 1 && *done.begin() == Segment(0, getSize()); 167 } 168 isRunning()169 bool isRunning() const { 170 return !isWaiting(); 171 } isWaiting()172 bool isWaiting() const { 173 return downloads.empty(); 174 } 175 getListName()176 string getListName() const { 177 dcassert(isSet(QueueItem::FLAG_USER_LIST)); 178 if(isSet(QueueItem::FLAG_XML_BZLIST)) { 179 return getTarget() + ".xml.bz2"; 180 } else { 181 return getTarget() + ".xml"; 182 } 183 } 184 185 const string& getTempTarget(); setTempTarget(const string & aTempTarget)186 void setTempTarget(const string& aTempTarget) { tempTarget = aTempTarget; } 187 188 GETSET(SegmentSet, done, Done); 189 GETSET(DownloadList, downloads, Downloads); 190 GETSET(string, target, Target); 191 GETSET(int64_t, size, Size); 192 GETSET(Priority, priority, Priority); 193 GETSET(time_t, added, Added); 194 GETSET(TTHValue, tthRoot, TTH); 195 private: 196 QueueItem& operator=(const QueueItem&); 197 198 friend class QueueManager; 199 SourceList sources; 200 SourceList badSources; 201 string tempTarget; 202 203 void addSource(const UserPtr& aUser); 204 void removeSource(const UserPtr& aUser, int reason); 205 }; 206 207 } // namespace dcpp 208 209 #endif // !defined(QUEUE_ITEM_H) 210