Fix configuration loading in tairentctl.
[tairent.git] / src / main / storage.h
blob9e0991dca9fa5a4365f0fe1b5a936c8d0e45ed26
1 /***************************************************************************
2 * *
3 * Copyright (C) 2006 David Brodsky *
4 * *
5 * This program is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU General Public License as *
7 * published by the Free Software Foundation and appearing *
8 * in the file LICENSE.GPL included in the packaging of this file. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
13 * General Public License for more details. *
14 * *
15 ***************************************************************************/
17 #ifndef _main_storage_h
18 #define _main_storage_h
20 #include <list>
21 #include <map>
22 #include <set>
24 #include <tairon/core/signals.h>
26 #include "core/bencode.h"
28 class TiXmlElement;
29 class TiXmlNode;
31 namespace Tairent
34 namespace Core
37 class BitField;
39 }; // namespace Core
41 namespace Main
44 class Connection;
45 class HashChecker;
47 struct PieceReadersStruct;
48 struct PieceWritersStruct;
50 /** \brief Struct for file descriptor and number of references to the file.
52 struct FileStruct
54 /** File descriptor.
56 int fd;
58 /** Number of references.
60 unsigned int refCount;
63 /** \brief Struct containing informations about file's offset and its length.
65 struct FilePositionStruct
67 /** Filename.
69 String name;
71 /** Length of the file.
73 uint64_t length;
75 /** Offset of the file from the beginning.
77 uint64_t start;
80 /** \brief Struct for informations about piece mapped to the memory.
82 struct PieceStruct
84 /** \brief Struct for part of the piece that belongs to one file.
86 struct FilePieceStruct {
87 /** File from which this piece is mapped.
89 const String *filename;
91 /** Beginning of the piece in the memory.
93 char *mem;
95 /** Real beginning of the piece in the memory due to alignment.
97 void *priv;
99 /** Position of the part in the piece.
101 uint32_t start;
103 /** Length of the part.
105 uint32_t length;
107 /** Real length of the part.
109 uint32_t privLength;
112 /** Number of references to the piece.
114 unsigned int refCount;
116 /** List of piece's parts.
118 std::list<FilePieceStruct> pieces;
121 /** \brief Struct for piece's requests.
123 struct RequestStruct
125 /** Contains indexes of chunks that haven't been requested yet.
127 std::set<uint32_t> queued;
129 /** Contains indexes of chunks that have been requested.
131 std::set<uint32_t> requested;
134 /** \brief Storage is an abstraction layer over filesystem.
136 class Storage
138 public:
139 /** Constructs a new Storage object and loads fast-resume info (if
140 * available).
142 * \param i Info part of the torrent metainfo;
143 * \param n Node with fast-resume data.
145 Storage(const Tairent::Core::BEncode &i, TiXmlNode *n = 0);
147 /** Destroys the object.
149 ~Storage();
151 /** Adds a bitfield to the availability list.
153 void addBitField(Tairent::Core::BitField *b);
155 /** Tells this storage that everything has been downloaded.
157 void complete();
159 /** Returns bitfield of this storage.
161 Tairent::Core::BitField *getBitField() {
162 return bitfield;
165 /** Returns info part of the torrent metainfo.
167 const Tairent::Core::BEncode &getMetaInfo() {
168 return info;
171 /** Returns informations about piece.
173 PieceStruct *getPiece(uint32_t index);
175 /** Returns number of bytes that are still left to download.
177 uint64_t getRemainingSize();
179 /** Informs this storage that a peer has something new. Returns true if
180 * the piece is interesting for us.
182 * \param index Piece index the peer has.
184 bool gotHave(uint32_t index);
186 /** Starts downloading of the incoming piece.
188 void gotPiece(uint32_t index, uint32_t start, Connection *c);
190 /** Sends requested piece to the peer.
192 * \param index Index of the piece.
193 * \param start Start of the chunk within the piece.
194 * \param length Length of the requested chunk.
195 * \param c Connection to the peer.
197 void gotRequest(uint32_t index, uint32_t start, uint32_t length, Connection *c);
199 /** Returns true if this storage has stored some piece; otherwise
200 * returns false.
202 bool hasSomething();
204 /** Returns true if there is nothing left to be downloaded; otherwise
205 * returns false.
207 bool isComplete();
209 /** Picks a piece to download. If there is a piece to download then
210 * this method returns true; otherwise returns false.
212 * \param b Peer's bitfield.
213 * \param index Index of the block.
214 * \param start Start of the piece within the block.
215 * \param length Length of the piece.
217 bool pickPiece(Tairent::Core::BitField *b, uint32_t &index, uint32_t &start, uint32_t &length);
219 /** Informs that a requested piece was downloaded.
221 void pieceDownloaded(uint32_t index, uint32_t start);
223 /** Informs that a piece requested by a peer has been sent.
225 void pieceSent(uint32_t index);
227 /** Removes a bitfield from the availability list.
229 void removeBitField(Tairent::Core::BitField *b);
231 /** Informs this storage that we don't expect some pieces to arrive so
232 * it should rerequest them.
234 * \param r Mapping piece index => list of piece parts to rerequest.
236 void reRequest(const std::map<uint32_t, std::set<uint32_t> > &r);
238 /** Returns an XML element that contains informations needed to fast
239 * resume this storage.
241 TiXmlElement *save();
243 /** Returns true if the client should be interested; otherwise returns
244 * false. (See BitTorrent protocol for details.)
246 bool shouldBeInterested(Tairent::Core::BitField *b);
248 /** Unmaps piece that hasn't been read.
250 void unmapPieces(PieceReadersStruct *readers);
252 /** Unmaps piece that hasn't been sent.
254 void unmapPieces(PieceWritersStruct *writers);
256 public:
257 /** This signal is emitted when a peer has sent an invalid data.
259 Tairon::Core::Signal1<void, Connection *> invalidDataSignal;
261 /** Emitted when a piece has been successfuly downloaded and its hash
262 * checked against the one from metainfo.
264 Tairon::Core::Signal1<void, uint32_t> pieceDownloadedSignal;
266 private:
267 /** Fills files list and computes total length.
269 void buildFilesList();
271 /** Closes opened file if it isn't used.
273 void closeFile(const String &name);
275 /** Creates a file and truncates it to the specified length.
277 void createFile(const String &name, uint64_t length);
279 /** Creates files for this torrent.
281 void createFiles();
283 /** Returns length of a chunk.
285 * \param index Piece number.
286 * \param start Offset of the chunk within the piece.
288 inline uint32_t getChunkLength(uint32_t index, uint32_t start);
290 /** Returns length of a piece.
292 * \param index Piece number.
294 inline uint32_t getPieceLength(uint32_t index);
296 /** Called when a recieved piece's hash is the same as in the info.
298 void hashCorrect(uint32_t index, HashChecker *checker);
300 /** Called when a recieved piece's hash isn't the same as in the info.
302 void hashIncorrect(uint32_t index, HashChecker *checker);
304 /** Converts a path list to a string.
306 String listToString(const Tairent::Core::BEncode::List &l);
308 /** Loads fast resume data from an XML node.
310 void load(TiXmlNode *n);
312 /** Loads bitfield from a node.
314 void loadBitField(TiXmlNode *n);
316 /** Loads information about queued parts from a node.
318 void loadQueued(TiXmlNode *n);
320 /** Maps a piece to the memory.
322 void mapPiece(uint32_t index);
324 /** Opens a file and returns its descriptor.
326 * \param filename Path with the file including its name.
328 int openFile(const String &filename);
330 /** Creates a permutation of pieces numbers.
332 void scramble();
334 /** Unmaps apiece from the memory. The piece isn't actually unmapped
335 * but moved to the cache from which it will be deleted when it will be
336 * needed.
338 void unmapPiece(uint32_t index);
340 private:
341 /** How many peers have specific piece.
343 unsigned short *availability;
345 /** Bitfield of this storage.
347 Tairent::Core::BitField *bitfield;
349 /** List of opened files.
351 std::map<String, FileStruct> files;
353 /** List of positions of files.
355 std::list<FilePositionStruct> filesPositions;
357 /** List of active checkers.
359 std::set<HashChecker *> hashCheckers;
361 /** Info part of the torrent metainfo.
363 const Tairent::Core::BEncode &info;
365 /** Number of pieces.
367 size_t pieceCount;
369 /** Length of one piece.
371 uint32_t pieceLength;
373 /** Mapping from piece index to its struct.
375 std::map<uint32_t, PieceStruct *> pieces;
377 /** List of active requests. The key is a piece index.
379 std::map<uint32_t, RequestStruct *> requests;
381 /** A permutation of length pieceCount.
383 std::list<uint32_t> scrambled;
385 /** Sum of lengths of all files.
387 uint64_t totalLength;
390 }; // namespace Main
392 }; // namespace Tairent
394 #endif
396 // vim: ai sw=4 ts=4 noet fdm=marker