File indexing completed on 2025-01-05 04:37:22

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #ifndef BTPEERDOWNLOADER_H
0007 #define BTPEERDOWNLOADER_H
0008 
0009 #include <download/request.h>
0010 #include <interfaces/piecedownloader.h>
0011 #include <qlist.h>
0012 #include <qobject.h>
0013 
0014 namespace bt
0015 {
0016 class Peer;
0017 class Request;
0018 class Piece;
0019 
0020 /**
0021  * Request with a timestamp.
0022  */
0023 struct TimeStampedRequest {
0024     Request req;
0025     TimeStamp time_stamp;
0026 
0027     TimeStampedRequest();
0028 
0029     /**
0030      * Constructor, set the request and calculate the timestamp.
0031      * @param r The Request
0032      */
0033     TimeStampedRequest(const Request &r);
0034 
0035     /**
0036      * Copy constructor, copy the request and the timestamp
0037      * @param r The Request
0038      */
0039     TimeStampedRequest(const TimeStampedRequest &t);
0040 
0041     /// Destructor
0042     ~TimeStampedRequest();
0043 
0044     /// Smaller then operator, uses timestamps to compare
0045     bool operator<(const TimeStampedRequest &t) const
0046     {
0047         return time_stamp < t.time_stamp;
0048     }
0049 
0050     /**
0051      * Equality operator, compares requests only.
0052      * @param r The Request
0053      * @return true if equal
0054      */
0055     bool operator==(const Request &r) const;
0056 
0057     /**
0058      * Equality operator, compares requests only.
0059      * @param r The Request
0060      * @return true if equal
0061      */
0062     bool operator==(const TimeStampedRequest &r) const;
0063 
0064     /**
0065      * Assignment operator.
0066      * @param r The Request to copy
0067      * @return *this
0068      */
0069     TimeStampedRequest &operator=(const Request &r);
0070 
0071     /**
0072      * Assignment operator.
0073      * @param r The TimeStampedRequest to copy
0074      * @return *this
0075      */
0076     TimeStampedRequest &operator=(const TimeStampedRequest &r);
0077 };
0078 
0079 /**
0080  * @author Joris Guisson
0081  * @brief Class which downloads pieces from a Peer
0082  *
0083  * This class downloads Piece's from a Peer.
0084  */
0085 class PeerDownloader : public PieceDownloader
0086 {
0087     Q_OBJECT
0088 public:
0089     /**
0090      * Constructor, set the Peer
0091      * @param peer The Peer
0092      * @param chunk_size Size of a chunk in bytes
0093      */
0094     PeerDownloader(Peer *peer, Uint32 chunk_size);
0095     ~PeerDownloader() override;
0096 
0097     /// See if we can add a request to the wait_queue
0098     bool canAddRequest() const override;
0099     bool canDownloadChunk() const override;
0100 
0101     /// Get the number of active requests
0102     Uint32 getNumRequests() const;
0103 
0104     /// Is the Peer choked.
0105     bool isChoked() const override;
0106 
0107     /// Is NULL (is the Peer set)
0108     bool isNull() const
0109     {
0110         return peer == nullptr;
0111     }
0112 
0113     /**
0114      * See if the Peer has a Chunk
0115      * @param idx The Chunk's index
0116      */
0117     bool hasChunk(Uint32 idx) const override;
0118 
0119     /// Get the Peer
0120     const Peer *getPeer() const
0121     {
0122         return peer;
0123     }
0124 
0125     /**
0126      * Check for timed out requests.
0127      */
0128     void checkTimeouts() override;
0129 
0130     /// Get the maximum number of chunk downloads
0131     Uint32 getMaxChunkDownloads() const;
0132 
0133     /**
0134      * The peer has been choked, all pending requests are rejected.
0135      * (except for allowed fast ones)
0136      */
0137     void choked();
0138 
0139     QString getName() const override;
0140     Uint32 getDownloadRate() const override;
0141 
0142     /**
0143      * Called when a piece has arrived.
0144      * @param p The Piece
0145      */
0146     void piece(const Piece &p);
0147 
0148 public Q_SLOTS:
0149     /**
0150      * Send a Request. Note that the DownloadCap
0151      * may not allow this. (In which case it will
0152      * be stored temporarely in the unsent_reqs list)
0153      * @param req The Request
0154      */
0155     void download(const Request &req) override;
0156 
0157     /**
0158      * Cancel a Request.
0159      * @param req The Request
0160      */
0161     void cancel(const Request &req) override;
0162 
0163     /**
0164      * Cancel all Requests
0165      */
0166     void cancelAll() override;
0167 
0168     /**
0169      * Handles a rejected request.
0170      * @param req
0171      */
0172     void onRejected(const Request &req);
0173 
0174     /**
0175      * Send requests and manage wait queue
0176      */
0177     void update();
0178 
0179 private Q_SLOTS:
0180     void peerDestroyed();
0181 
0182 private:
0183     Peer *peer;
0184     QList<TimeStampedRequest> reqs;
0185     QList<Request> wait_queue;
0186     Uint32 max_wait_queue_size;
0187     Uint32 chunk_size;
0188 };
0189 
0190 }
0191 
0192 #endif