1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 | //
// This file is part of the aMule Project.
//
// Copyright (c) 2008-2011 aMule Team ( admin@amule.org / http://www.amule.org )
//
// Any parts of this program derived from the xMule, lMule or eMule project,
// or contributed by third-party developers are copyrighted by their
// respective authors.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
//
#ifndef GAPLIST_H
#define GAPLIST_H
#include <map>
class CGapList {
private:
// The internal gap list:
// Each gap is stored as a map entry.
// The first (key) is the end, the second (value) the start.
typedef std::map<uint64,uint64> ListType;
typedef ListType::iterator iterator;
ListType m_gaplist;
// size of the part file the list belongs to
uint64 m_filesize;
// number of parts
uint16 m_iPartCount;
// size of the last part
uint32 m_sizeLastPart;
// total gapsize
uint64 m_totalGapSize;
// flag if it's valid
bool m_totalGapSizeValid;
// cache completeness of parts
enum ePartComplete {
complete,
incomplete,
unknown
};
std::vector<uint8_t> m_partsComplete;
// get size of any part
uint32 GetPartSize(uint16 part) const { return part == m_iPartCount - 1 ? m_sizeLastPart : PARTSIZE; }
// check arguments, clip end, false: error
inline bool ArgCheck(uint64 gapstart, uint64 &gapend) const;
public:
// construct
CGapList() { Init(0, false); } // NO MORE uninitialized variables >:(
// setup (and eventually clear) list, optionally as empty (one large gap)
void Init(uint64 fileSize, bool empty);
// add a gap for a range
void AddGap(uint64 gapstart, uint64 gapend);
// add a gap for a part
void AddGap(uint16 part);
// fill a gap for a range
void FillGap(uint64 gapstart, uint64 gapend);
// fill a gap for a part
void FillGap(uint16 part);
// Is this range complete ?
bool IsComplete(uint64 gapstart, uint64 gapend) const;
// Is this part complete ?
bool IsComplete(uint16 part);
// Is the whole file complete ?
bool IsComplete() const { return m_gaplist.empty(); }
// number of gaps
uint32 size() const { return m_gaplist.size(); }
// no gaps ?
bool empty() const { return m_gaplist.empty(); }
// size of all gaps
uint64 GetGapSize();
// size of gaps inside one part
uint32 GetGapSize(uint16 part) const;
// Iterator class to loop through the gaps read-only
// Gaps are returned just as start/end value
class const_iterator {
// iterator for internal list
ListType::const_iterator m_it;
public:
// constructs
const_iterator() {};
const_iterator(const ListType::const_iterator& it) { m_it = it; };<--- Variable 'm_it' is assigned in constructor body. Consider performing initialization in initialization list. [+]When an object of a class is created, the constructors of all member variables are called consecutively in the order the variables are declared, even if you don't explicitly write them to the initialization list. You could avoid assigning 'm_it' a value by passing the value to the constructor in the initialization list. <--- Class 'const_iterator' has a constructor with 1 argument that is not explicit. [+]Class 'const_iterator' has a constructor with 1 argument that is not explicit. Such, so called "Converting constructors", should in general be explicit for type safety reasons as that prevents unintended implicit conversions.
// operators
bool operator != (const const_iterator& it) const { return m_it != it.m_it; }
const_iterator& operator ++ () { ++ m_it; return *this; }
// get start of gap pointed to
uint64 start() const { return (* m_it).second; }
// get end of gap pointed to
uint64 end() const { return (* m_it).first; }
};
// begin/end iterators for looping
const_iterator begin() const { return const_iterator(m_gaplist.begin()); }
const_iterator end() const { return const_iterator(m_gaplist.end()); }
};
#endif // GAPLIST_H
// File_checked_for_headers
|