1 /* <!-- copyright */
2 /*
3  * aria2 - The high speed download utility
4  *
5  * Copyright (C) 2006 Tatsuhiro Tsujikawa
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  * In addition, as a special exception, the copyright holders give
22  * permission to link the code of portions of this program with the
23  * OpenSSL library under certain conditions as described in each
24  * individual source file, and distribute linked combinations
25  * including the two.
26  * You must obey the GNU General Public License in all respects
27  * for all of the code used other than OpenSSL.  If you modify
28  * file(s) with this exception, you may extend this exception to your
29  * version of the file(s), but you are not obligated to do so.  If you
30  * do not wish to do so, delete this exception statement from your
31  * version.  If you delete this exception statement from all source
32  * files in the program, then also delete it here.
33  */
34 /* copyright --> */
35 #ifndef D_PIECE_H
36 #define D_PIECE_H
37 
38 #include "common.h"
39 
40 #include <stdint.h>
41 #include <vector>
42 #include <string>
43 #include <memory>
44 
45 #include "Command.h"
46 #include "a2functional.h"
47 
48 namespace aria2 {
49 
50 class BitfieldMan;
51 class WrDiskCache;
52 class WrDiskCacheEntry;
53 class DiskAdaptor;
54 class MessageDigest;
55 
56 class Piece {
57 private:
58   std::unique_ptr<BitfieldMan> bitfield_;
59   std::unique_ptr<WrDiskCacheEntry> wrCache_;
60   std::unique_ptr<MessageDigest> mdctx_;
61   std::vector<cuid_t> users_;
62   std::string hashType_;
63 
64   size_t index_;
65 
66   int64_t length_;
67   int64_t nextBegin_;
68 
69   bool usedBySegment_;
70 
71   Piece(const Piece& piece) = delete;
72   Piece& operator=(const Piece& piece) = delete;
73 
74 public:
75   static const int32_t BLOCK_LENGTH = 16_k;
76 
77   Piece();
78   Piece(size_t index, int64_t length, int32_t blockLength = BLOCK_LENGTH);
79 
80   ~Piece();
81 
82   bool operator==(const Piece& piece) const { return index_ == piece.index_; }
83 
84   bool operator<(const Piece& piece) const { return index_ < piece.index_; }
85 
86   // TODO This function only used by unit tests
87   bool getMissingUnusedBlockIndex(size_t& index) const;
88 
89   // Appends at most n missing unused block index to indexes. For all
90   // i in retrieved indexes, call bitfield->setUseBit(i). This
91   // function just append index to indexes and it doesn't remove
92   // anything from it. Returns the number of indexes to retrieved.
93   size_t getMissingUnusedBlockIndex(std::vector<size_t>& indexes,
94                                     size_t n) const;
95 
96   bool getFirstMissingBlockIndexWithoutLock(size_t& index) const;
97   bool getAllMissingBlockIndexes(unsigned char* misbitfield,
98                                  size_t mislen) const;
99   void completeBlock(size_t blockIndex);
100   void cancelBlock(size_t blockIndex);
101 
102   size_t countCompleteBlock() const;
103 
104   size_t countMissingBlock() const;
105 
106   bool hasBlock(size_t blockIndex) const;
107 
108   /**
109    * Returns true if all blocks of this piece have been downloaded, otherwise
110    * returns false.
111    */
112   bool pieceComplete() const;
113 
114   size_t countBlock() const;
115 
116   int32_t getBlockLength(size_t index) const;
117 
118   int32_t getBlockLength() const;
119 
getIndex()120   size_t getIndex() const { return index_; }
121 
setIndex(size_t index)122   void setIndex(size_t index) { index_ = index; }
123 
getLength()124   int64_t getLength() const { return length_; }
125 
setLength(int64_t length)126   void setLength(int64_t length) { length_ = length; }
127 
128   const unsigned char* getBitfield() const;
129 
130   void setBitfield(const unsigned char* bitfield, size_t len);
131 
132   size_t getBitfieldLength() const;
133 
134   void clearAllBlock(WrDiskCache* diskCache);
135   void setAllBlock();
136 
137   std::string toString() const;
138 
139   bool isBlockUsed(size_t index) const;
140 
141   // Calculates completed length
142   int64_t getCompletedLength();
143 
144   void setHashType(const std::string& hashType);
145 
146   // Updates hash value. This function compares begin and private variable
147   // nextBegin_ and only when they are equal, hash is updated eating data and
148   // returns true. Otherwise returns false.
149   bool updateHash(int64_t begin, const unsigned char* data, size_t dataLength);
150 
151   bool isHashCalculated() const;
152 
153   // Returns raw hash value, not hex digest, which is calculated
154   // by updateHash().  Please note that this function returns hash
155   // value only once. Second invocation without updateHash() returns
156   // empty string.
157   std::string getDigest();
158 
159   void destroyHashContext();
160 
161   // Returns raw hash value, not hex digest, which is calculated using
162   // cached data and data on disk.
163   std::string getDigestWithWrCache(size_t pieceLength,
164                                    const std::shared_ptr<DiskAdaptor>& adaptor);
165   /**
166    * Loses current bitfield state.
167    */
168   void reconfigure(int64_t length);
169 
170   void addUser(cuid_t cuid);
171   void removeUser(cuid_t cuid);
getUsed()172   bool getUsed() const { return !users_.empty(); }
173   bool usedBy(cuid_t cuid) const;
getUsedBySegment()174   bool getUsedBySegment() const { return usedBySegment_; }
setUsedBySegment(bool f)175   void setUsedBySegment(bool f) { usedBySegment_ = f; }
176 
177   void initWrCache(WrDiskCache* diskCache,
178                    const std::shared_ptr<DiskAdaptor>& diskAdaptor);
179   void flushWrCache(WrDiskCache* diskCache);
180   void clearWrCache(WrDiskCache* diskCache);
181   void updateWrCache(WrDiskCache* diskCache, unsigned char* data, size_t offset,
182                      size_t len, size_t capacity, int64_t goff);
updateWrCache(WrDiskCache * diskCache,unsigned char * data,size_t offset,size_t len,int64_t goff)183   void updateWrCache(WrDiskCache* diskCache, unsigned char* data, size_t offset,
184                      size_t len, int64_t goff)
185   {
186     updateWrCache(diskCache, data, offset, len, len, goff);
187   }
188   size_t appendWrCache(WrDiskCache* diskCache, int64_t goff,
189                        const unsigned char* data, size_t len);
190   void releaseWrCache(WrDiskCache* diskCache);
getWrDiskCacheEntry()191   WrDiskCacheEntry* getWrDiskCacheEntry() const { return wrCache_.get(); }
192 };
193 
194 } // namespace aria2
195 
196 #endif // D_PIECE_H
197