| 1 |
/* |
|---|
| 2 |
* Copyright (C) 2004-2006 Alo Sarv <madcat_@users.sourceforge.net> |
|---|
| 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 |
/** |
|---|
| 20 |
* \file downloadlist.h Interface for Download and DownloadList classes |
|---|
| 21 |
*/ |
|---|
| 22 |
|
|---|
| 23 |
#ifndef __ED2K_DOWNLOADLIST_H__ |
|---|
| 24 |
#define __ED2K_DOWNLOADLIST_H__ |
|---|
| 25 |
|
|---|
| 26 |
#include <hncore/ed2k/fwd.h> |
|---|
| 27 |
#include <hnbase/hash.h> |
|---|
| 28 |
#include <hnbase/event.h> |
|---|
| 29 |
#include <hncore/fwd.h> |
|---|
| 30 |
#include <boost/tuple/tuple.hpp> |
|---|
| 31 |
#include <boost/signals.hpp> |
|---|
| 32 |
|
|---|
| 33 |
namespace Donkey { |
|---|
| 34 |
|
|---|
| 35 |
class DownloadList; |
|---|
| 36 |
namespace Detail { |
|---|
| 37 |
struct MIDownloadList; |
|---|
| 38 |
struct DownloadIter; |
|---|
| 39 |
} |
|---|
| 40 |
|
|---|
| 41 |
/** |
|---|
| 42 |
* Constants related to source-exchange times |
|---|
| 43 |
*/ |
|---|
| 44 |
enum { |
|---|
| 45 |
SRCEXCH_CTIME = 40*60*1000, //!< one query per client per 40 minutes |
|---|
| 46 |
SRCEXCH_FTIME = 5*60*1000 //!< one query per file per 5 minutes |
|---|
| 47 |
}; |
|---|
| 48 |
|
|---|
| 49 |
/** |
|---|
| 50 |
* Download is a wrapper class around ed2k-compatible PartData objects. It keeps |
|---|
| 51 |
* track of which clients are offering this file, providing means of getting an |
|---|
| 52 |
* overview of sources-per-file and cross-reference. Download objects are |
|---|
| 53 |
* owned and managed by DownloadList class. |
|---|
| 54 |
*/ |
|---|
| 55 |
class Download : public Trackable { |
|---|
| 56 |
//! identical to AnswerSources::Source |
|---|
| 57 |
typedef boost::tuple<uint32_t, uint16_t, uint32_t, uint16_t> Source; |
|---|
| 58 |
typedef std::set<Client*>::const_iterator CIter; |
|---|
| 59 |
public: |
|---|
| 60 |
uint32_t getSourceCount() const { return m_sources.size(); } |
|---|
| 61 |
uint64_t getLastSrcExch() const { return m_lastSrcExch; } |
|---|
| 62 |
PartData* getPartData() const { return m_partData; } |
|---|
| 63 |
uint32_t getSourceLimit() const { return m_sourceLimit; } |
|---|
| 64 |
Hash<ED2KHash> getHash() const { return m_hash; } |
|---|
| 65 |
uint32_t getSize() const; |
|---|
| 66 |
|
|---|
| 67 |
void addSource(Client *c) { m_sources.insert(c); } |
|---|
| 68 |
void delSource(Client *c) { m_sources.erase(c); } |
|---|
| 69 |
void setSourceLimit(uint32_t l) { m_sourceLimit = l; } |
|---|
| 70 |
void setLastSrcExch(uint64_t t) { m_lastSrcExch = t; } |
|---|
| 71 |
|
|---|
| 72 |
/** |
|---|
| 73 |
* Generate a vector of sources, for sending with AnswerSources packet |
|---|
| 74 |
* for example. Up to 500 sources may be returned. |
|---|
| 75 |
*/ |
|---|
| 76 |
std::vector<Source> getSources() const; |
|---|
| 77 |
|
|---|
| 78 |
/** |
|---|
| 79 |
* Check if a client is allowed to request sources for this file at |
|---|
| 80 |
* this time. |
|---|
| 81 |
* |
|---|
| 82 |
* @param c Client wishing to perform SourceExchange request |
|---|
| 83 |
* @return True if request is allowed, false otherwise |
|---|
| 84 |
*/ |
|---|
| 85 |
bool isSourceReqAllowed(Client *c) const; |
|---|
| 86 |
|
|---|
| 87 |
private: |
|---|
| 88 |
friend class DownloadList; |
|---|
| 89 |
friend bool operator<(const Download &x, const Download &y) { |
|---|
| 90 |
return x.m_hash < y.m_hash; |
|---|
| 91 |
} |
|---|
| 92 |
|
|---|
| 93 |
/** |
|---|
| 94 |
* Construct new Download; this is allowed only by DownloadList |
|---|
| 95 |
* |
|---|
| 96 |
* @param pd PartData object to wrap around |
|---|
| 97 |
* @param hash Hash of the PartData object |
|---|
| 98 |
*/ |
|---|
| 99 |
Download(PartData *pd, const Hash<ED2KHash> &hash); |
|---|
| 100 |
|
|---|
| 101 |
//! Destructor only allowed by DownloadList |
|---|
| 102 |
~Download(); |
|---|
| 103 |
|
|---|
| 104 |
//! Copy-construction is forbidden and not implemented |
|---|
| 105 |
Download(const Download&); |
|---|
| 106 |
//! Assignment operator is forbidden and not implemented |
|---|
| 107 |
Download& operator=(const Download&); |
|---|
| 108 |
|
|---|
| 109 |
/** |
|---|
| 110 |
* Called prior to this object's destruction, signals all sources that |
|---|
| 111 |
* download is being destroyed. |
|---|
| 112 |
*/ |
|---|
| 113 |
void destroy(); |
|---|
| 114 |
|
|---|
| 115 |
/** |
|---|
| 116 |
* Signal handler for PartData::getLinks signal. |
|---|
| 117 |
*/ |
|---|
| 118 |
void getLink(PartData *file, std::vector<std::string>& links); |
|---|
| 119 |
|
|---|
| 120 |
PartData* m_partData; //!< Implementation object |
|---|
| 121 |
Hash<ED2KHash> m_hash; //!< hash of this file |
|---|
| 122 |
std::set<Client*> m_sources; //!< list of sources of this file |
|---|
| 123 |
uint64_t m_lastSrcExch; //!< time of last source-exchange req |
|---|
| 124 |
uint32_t m_sourceLimit; //!< limit sources |
|---|
| 125 |
}; |
|---|
| 126 |
|
|---|
| 127 |
namespace Detail { |
|---|
| 128 |
struct MIDownloadList; |
|---|
| 129 |
struct MIDownloadListIterator; |
|---|
| 130 |
} |
|---|
| 131 |
|
|---|
| 132 |
/** |
|---|
| 133 |
* DownloadList is a container for Download objects, wrapping around PartData |
|---|
| 134 |
* objects. The purpose is to provide a simpler and faster interface than |
|---|
| 135 |
* FilesList, and to provide some ed2k-specific features that FilesList cannot |
|---|
| 136 |
* offer. |
|---|
| 137 |
* |
|---|
| 138 |
* Two public signals declared in this class indicate when new downloads are |
|---|
| 139 |
* added or removed. Iterating on the list can be done using nested type Iter, |
|---|
| 140 |
* and begin() / end() functions. |
|---|
| 141 |
*/ |
|---|
| 142 |
class DownloadList { |
|---|
| 143 |
public: |
|---|
| 144 |
/** |
|---|
| 145 |
* Iterator for the underlying implementation. |
|---|
| 146 |
*/ |
|---|
| 147 |
class Iter { |
|---|
| 148 |
typedef boost::shared_ptr<Detail::MIDownloadListIterator> Impl; |
|---|
| 149 |
public: |
|---|
| 150 |
Download& operator*(); |
|---|
| 151 |
Download& operator->(); |
|---|
| 152 |
void operator++(); |
|---|
| 153 |
void operator--(); |
|---|
| 154 |
bool operator==(const Iter&) const; |
|---|
| 155 |
bool operator!=(const Iter&) const; |
|---|
| 156 |
private: |
|---|
| 157 |
friend class DownloadList; |
|---|
| 158 |
Iter(Impl impl); //!< Only allowed by DownloadList |
|---|
| 159 |
Impl m_impl; //!< Implementation object |
|---|
| 160 |
}; |
|---|
| 161 |
|
|---|
| 162 |
/** |
|---|
| 163 |
* \returns Iterator to the beginning of the list |
|---|
| 164 |
*/ |
|---|
| 165 |
Iter begin(); |
|---|
| 166 |
|
|---|
| 167 |
/** |
|---|
| 168 |
* \return Returns iterator to one-past-end of the list |
|---|
| 169 |
*/ |
|---|
| 170 |
Iter end(); |
|---|
| 171 |
|
|---|
| 172 |
/** |
|---|
| 173 |
* \returns Reference to the only instance of this Singleton class |
|---|
| 174 |
*/ |
|---|
| 175 |
static DownloadList& instance(); |
|---|
| 176 |
|
|---|
| 177 |
/** |
|---|
| 178 |
* Find a specific download, searching with hash |
|---|
| 179 |
* |
|---|
| 180 |
* \param hash Hash to be searched for |
|---|
| 181 |
* \returns Pointer to the file, or 0 if not found |
|---|
| 182 |
*/ |
|---|
| 183 |
Download* find(const Hash<ED2KHash> &hash) const; |
|---|
| 184 |
|
|---|
| 185 |
/** |
|---|
| 186 |
* Check the validity of a Download pointer |
|---|
| 187 |
* |
|---|
| 188 |
* @param ptr Pointer to check validity |
|---|
| 189 |
* @return True if the pointer is valid; false otherwise |
|---|
| 190 |
*/ |
|---|
| 191 |
bool valid(Download *ptr) const; |
|---|
| 192 |
|
|---|
| 193 |
//! Emitted when a download is removed |
|---|
| 194 |
boost::signal<void (Download&)> onRemoved; |
|---|
| 195 |
//! Emitted when a download is added |
|---|
| 196 |
boost::signal<void (Download&)> onAdded; |
|---|
| 197 |
private: |
|---|
| 198 |
DownloadList(); |
|---|
| 199 |
DownloadList(const DownloadList&); |
|---|
| 200 |
~DownloadList(); |
|---|
| 201 |
DownloadList& operator=(const DownloadList&); |
|---|
| 202 |
|
|---|
| 203 |
friend class ED2K; |
|---|
| 204 |
void init(); //!< Initialize this class |
|---|
| 205 |
void exit(); //!< Exit this class |
|---|
| 206 |
|
|---|
| 207 |
void onPDEvent(PartData *pd, int evt); |
|---|
| 208 |
void onSFEvent(SharedFile *sf, int evt); |
|---|
| 209 |
|
|---|
| 210 |
/** |
|---|
| 211 |
* Imports ed2k-compatible downloads from location |
|---|
| 212 |
* |
|---|
| 213 |
* @param p Path to import from |
|---|
| 214 |
*/ |
|---|
| 215 |
void import(boost::filesystem::path p); |
|---|
| 216 |
|
|---|
| 217 |
/** |
|---|
| 218 |
* Attempts to import a single file |
|---|
| 219 |
* |
|---|
| 220 |
* @param p File to be imported |
|---|
| 221 |
*/ |
|---|
| 222 |
void doImport(const boost::filesystem::path &p); |
|---|
| 223 |
|
|---|
| 224 |
/** |
|---|
| 225 |
* Try to add a download to the list. The file needs to have ed2k- |
|---|
| 226 |
* compatible hashes and must be <4gb in size. If addition succeeds, |
|---|
| 227 |
* onAdded() signal is emitted (but only if the download is in `running' |
|---|
| 228 |
* state. |
|---|
| 229 |
* |
|---|
| 230 |
* \param file File to be added |
|---|
| 231 |
*/ |
|---|
| 232 |
void tryAddFile(PartData *pd); |
|---|
| 233 |
|
|---|
| 234 |
//! List implementation |
|---|
| 235 |
boost::scoped_ptr<Detail::MIDownloadList> m_list; |
|---|
| 236 |
}; |
|---|
| 237 |
|
|---|
| 238 |
} // end namespace Donkey |
|---|
| 239 |
|
|---|
| 240 |
#endif |
|---|