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