downloadlist.h

Go to the documentation of this file.
00001 /**
00002  *  Copyright (C) 2004-2005 Alo Sarv <madcat_@users.sourceforge.net>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 /** \file downloadlist.h Interface for Download and DownloadList classes */
00020 
00021 #ifndef __DOWNLOADLIST_H__
00022 #define __DOWNLOADLIST_H__
00023 
00024 #include <hn/hnfwd.h>
00025 #include "ed2kfwd.h"
00026 #include <hn/hash.h>
00027 #include <boost/tuple/tuple.hpp>
00028 #include <boost/signals.hpp>
00029 
00030 class DownloadList;
00031 namespace Detail {
00032         struct MIDownloadList;
00033         struct DownloadIter;
00034 }
00035 
00036 /**
00037  * Constants related to source-exchange times
00038  */
00039 enum {
00040         SRCEXCH_CTIME = 40*60*1000, //!< one query per client per 40 minutes
00041         SRCEXCH_FTIME = 5*60*1000   //!< one query per file per 5 minutes
00042 };
00043 
00044 /**
00045  * Download is a wrapper class around ed2k-compatible PartData objects. It keeps
00046  * track of which clients are offering this file, providing means of getting an
00047  * overview of sources-per-file and cross-reference. Download objects are
00048  * owned and managed by DownloadList class.
00049  */
00050 class Download {
00051         //! identical to AnswerSources::Source
00052         typedef boost::tuple<uint32_t, uint16_t, uint32_t, uint16_t> Source;
00053         typedef std::set<Client*>::const_iterator CIter;
00054 public:
00055         uint32_t getSourceCount() const { return m_sources.size(); }
00056         uint64_t getLastSrcExch() const { return m_lastSrcExch; }
00057         uint64_t getLastUdpQuery() const { return m_lastUdpQuery; }
00058         PartData* getPartData() const { return m_partData; }
00059         uint32_t getSourceLimit() const { return m_sourceLimit; }
00060         Hash<ED2KHash> getHash() const { return m_hash; }
00061         uint32_t getSize() const;
00062 
00063         void addSource(Client *c) { m_sources.insert(c); }
00064         void delSource(Client *c) { m_sources.erase(c); }
00065         void setSourceLimit(uint32_t l) { m_sourceLimit = l; }
00066         void setLastSrcExch(uint64_t t) { m_lastSrcExch = t; }
00067 
00068         /**
00069          * Generate a vector of sources, for sending with AnswerSources packet
00070          * for example. Up to 500 sources may be returned.
00071          */
00072         std::vector<Source> getSources() const;
00073 
00074         /**
00075          * Check if a client is allowed to request sources for this file at
00076          * this time.
00077          *
00078          * @param c      Client wishing to perform SourceExchange request
00079          * @return       True if request is allowed, false otherwise
00080          */
00081         bool isSourceReqAllowed(Client *c) const;
00082 
00083 private:
00084         friend class DownloadList;
00085         friend bool operator<(const Download &x, const Download &y) {
00086                 return x.m_hash < y.m_hash;
00087         }
00088 
00089         /**
00090          * Construct new Download; this is allowed only by DownloadList
00091          *
00092          * @param pd      PartData object to wrap around
00093          * @param hash    Hash of the PartData object
00094          */
00095         Download(PartData *pd, const Hash<ED2KHash> &hash);
00096 
00097         //! Destructor only allowed by DownloadList
00098         ~Download();
00099 
00100         //! Copy-construction is forbidden and not implemented
00101         Download(const Download&);
00102         //! Assignment operator is forbidden and not implemented
00103         Download& operator=(const Download&);
00104 
00105         /**
00106          * Called prior to this object's destruction, signals all sources that
00107          * download is being destroyed.
00108          */
00109         void destroy();
00110 
00111         PartData*         m_partData;      //!< Implementation object
00112         Hash<ED2KHash>    m_hash;          //!< hash of this file
00113         std::set<Client*> m_sources;       //!< list of sources of this file
00114         uint64_t          m_lastSrcExch;   //!< time of last source-exchange req
00115         uint32_t          m_sourceLimit;   //!< limit sources
00116         uint64_t          m_lastUdpQuery;  //!< last udp query time
00117 };
00118 
00119 namespace Detail {
00120         struct MIDownloadList;
00121         struct MIDownloadListIterator;
00122 }
00123 
00124 /**
00125  * DownloadList is a container for Download objects, wrapping around PartData
00126  * objects. The purpose is to provide a simpler and faster interface than
00127  * FilesList, and to provide some ed2k-specific features that FilesList cannot
00128  * offer.
00129  *
00130  * Two public signals declared in this class indicate when new downloads are
00131  * added or removed. Iterating on the list can be done using nested type Iter,
00132  * and begin() / end() functions.
00133  */
00134 class DownloadList {
00135 public:
00136         /**
00137          * Iterator for the underlying implementation.
00138          */
00139         class Iter {
00140                 typedef boost::shared_ptr<Detail::MIDownloadListIterator> Impl;
00141         public:
00142                 Download& operator*();
00143                 Download& operator->();
00144                 void operator++();
00145                 void operator--();
00146                 bool operator==(const Iter&) const;
00147                 bool operator!=(const Iter&) const;
00148         private:
00149                 friend class DownloadList;
00150                 Iter(Impl impl);  //!< Only allowed by DownloadList
00151                 Impl m_impl;      //!< Implementation object
00152         };
00153 
00154         /**
00155          * \returns Iterator to the beginning of the list
00156          */
00157         Iter begin();
00158 
00159         /**
00160          * \return Returns iterator to one-past-end of the list
00161          */
00162         Iter end();
00163 
00164         /**
00165          * \returns Reference to the only instance of this Singleton class
00166          */
00167         static DownloadList& instance();
00168 
00169         /**
00170          * Find a specific download, searching with hash
00171          *
00172          * \param hash       Hash to be searched for
00173          * \returns          Pointer to the file, or 0 if not found
00174          */
00175         Download* find(const Hash<ED2KHash> &hash) const;
00176 
00177         /**
00178          * Check the validity of a Download pointer
00179          *
00180          * @param ptr      Pointer to check validity
00181          * @return         True if the pointer is valid; false otherwise
00182          */
00183         bool valid(Download *ptr) const;
00184 
00185         /**
00186          * Selects next download for sending ServerUDP query to
00187          *
00188          * \returns Download to be queried, or 0 if something goes wrong
00189          */
00190         Download* getNextForUdpQuery();
00191 
00192         //! Emitted when a download is removed
00193         boost::signal<void (Download&)> onRemoved;
00194         //! Emitted when a download is added
00195         boost::signal<void (Download&)> onAdded;
00196 private:
00197         DownloadList();
00198         DownloadList(const DownloadList&);
00199         ~DownloadList();
00200         DownloadList& operator=(const DownloadList&);
00201 
00202         friend class ED2K;
00203         void init();    //!< Initialize this class
00204         void exit();    //!< Exit this class
00205 
00206         void onPDEvent(PartData *pd, int evt);
00207         void onSFEvent(SharedFile *sf, int evt);
00208 
00209         /**
00210          * Try to add a SharedFile to the list. The file needs to have ed2k-
00211          * compatible hashes, must be <4gb in size and must be partial to be
00212          * added to the list. If addition succeeds, onAdded() signal is emitted.
00213          *
00214          * \param file   SharedFile to be added
00215          */
00216         void tryAddFile(SharedFile *sf);
00217 
00218         //! List implementation
00219         boost::scoped_ptr<Detail::MIDownloadList> m_list;
00220 };
00221 
00222 #endif