1 /***************************************************************************
3 * Copyright (C) 2006 David Brodsky *
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. *
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. *
15 ***************************************************************************/
17 #ifndef _main_storage_h
18 #define _main_storage_h
24 #include <tairon/core/signals.h>
26 #include "core/bencode.h"
47 struct PieceReadersStruct
;
48 struct PieceWritersStruct
;
50 /** \brief Struct for file descriptor and number of references to the file.
58 /** Number of references.
60 unsigned int refCount
;
63 /** \brief Struct containing informations about file's offset and its length.
65 struct FilePositionStruct
71 /** Length of the file.
75 /** Offset of the file from the beginning.
80 /** \brief Struct for informations about piece mapped to the memory.
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.
95 /** Real beginning of the piece in the memory due to alignment.
99 /** Position of the part in the piece.
103 /** Length of the part.
107 /** Real length of the part.
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.
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.
139 /** Constructs a new Storage object and loads fast-resume info (if
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.
151 /** Adds a bitfield to the availability list.
153 void addBitField(Tairent::Core::BitField
*b
);
155 /** Returns bitfield of this storage.
157 Tairent::Core::BitField
*getBitField() {
161 /** Returns info part of the torrent metainfo.
163 const Tairent::Core::BEncode
&getMetaInfo() {
167 /** Returns informations about piece.
169 PieceStruct
*getPiece(uint32_t index
);
171 /** Returns number of bytes that are still left to download.
173 uint64_t getRemainingSize();
175 /** Informs this storage that a peer has something new. Returns true if
176 * the piece is interesting for us.
178 * \param index Piece index the peer has.
180 bool gotHave(uint32_t index
);
182 /** Starts downloading of the incoming piece.
184 void gotPiece(uint32_t index
, uint32_t start
, Connection
*c
);
186 /** Sends requested piece to the peer.
188 * \param index Index of the piece.
189 * \param start Start of the chunk within the piece.
190 * \param length Length of the requested chunk.
191 * \param c Connection to the peer.
193 void gotRequest(uint32_t index
, uint32_t start
, uint32_t length
, Connection
*c
);
195 /** Returns true if this storage has stored some piece; otherwise
200 /** Picks a piece to download. If there is a piece to download then
201 * this method returns true; otherwise returns false.
203 * \param b Peer's bitfield.
204 * \param index Index of the block.
205 * \param start Start of the piece within the block.
206 * \param length Length of the piece.
208 bool pickPiece(Tairent::Core::BitField
*b
, uint32_t &index
, uint32_t &start
, uint32_t &length
);
210 /** Informs that a requested piece was downloaded.
212 void pieceDownloaded(uint32_t index
, uint32_t start
);
214 /** Informs that a piece requested by a peer has been sent.
216 void pieceSent(uint32_t index
);
218 /** Removes a bitfield from the availability list.
220 void removeBitField(Tairent::Core::BitField
*b
);
222 /** Informs this storage that we don't expect some pieces to arrive so
223 * it should rerequest them.
225 * \param r Mapping piece index => list of piece parts to rerequest.
227 void reRequest(const std::map
<uint32_t, std::set
<uint32_t> > &r
);
229 /** Returns an XML element that contains informations needed to fast
230 * resume this storage.
232 TiXmlElement
*save();
234 /** Returns true if the client should be interested; otherwise returns
235 * false. (See BitTorrent protocol for details.)
237 bool shouldBeInterested(Tairent::Core::BitField
*b
);
239 /** Unmaps piece that hasn't been read.
241 void unmapPieces(PieceReadersStruct
*readers
);
243 /** Unmaps piece that hasn't been sent.
245 void unmapPieces(PieceWritersStruct
*writers
);
248 /** This signal is emitted when a peer has sent an invalid data.
250 Tairon::Core::Signal1
<void, Connection
*> invalidDataSignal
;
252 /** Emitted when a piece has been successfuly downloaded and its hash
253 * checked against the one from metainfo.
255 Tairon::Core::Signal1
<void, uint32_t> pieceDownloadedSignal
;
258 /** Fills files list and computes total length.
260 void buildFilesList();
262 /** Closes opened file if it isn't used.
264 void closeFile(const String
&name
);
266 /** Creates a file and truncates it to the specified length.
268 void createFile(const String
&name
, uint64_t length
);
270 /** Creates files for this torrent.
274 /** Returns length of a chunk.
276 * \param index Piece number.
277 * \param start Offset of the chunk within the piece.
279 inline uint32_t getChunkLength(uint32_t index
, uint32_t start
);
281 /** Returns length of a piece.
283 * \param index Piece number.
285 inline uint32_t getPieceLength(uint32_t index
);
287 /** Called when a recieved piece's hash is the same as in the info.
289 void hashCorrect(uint32_t index
, HashChecker
*checker
);
291 /** Called when a recieved piece's hash isn't the same as in the info.
293 void hashIncorrect(uint32_t index
, HashChecker
*checker
);
295 /** Converts a path list to a string.
297 String
listToString(const Tairent::Core::BEncode::List
&l
);
299 /** Loads fast resume data from an XML node.
301 void load(TiXmlNode
*n
);
303 /** Loads bitfield from a node.
305 void loadBitField(TiXmlNode
*n
);
307 /** Loads information about queued parts from a node.
309 void loadQueued(TiXmlNode
*n
);
311 /** Maps a piece to the memory.
313 void mapPiece(uint32_t index
);
315 /** Opens a file and returns its descriptor.
317 * \param filename Path with the file including its name.
319 int openFile(const String
&filename
);
321 /** Creates a permutation of pieces numbers.
325 /** Unmaps apiece from the memory. The piece isn't actually unmapped
326 * but moved to the cache from which it will be deleted when it will be
329 void unmapPiece(uint32_t index
);
332 /** How many peers have specific piece.
334 unsigned short *availability
;
336 /** Bitfield of this storage.
338 Tairent::Core::BitField
*bitfield
;
340 /** List of opened files.
342 std::map
<String
, FileStruct
> files
;
344 /** List of positions of files.
346 std::list
<FilePositionStruct
> filesPositions
;
348 /** List of active checkers.
350 std::set
<HashChecker
*> hashCheckers
;
352 /** Info part of the torrent metainfo.
354 const Tairent::Core::BEncode
&info
;
356 /** Number of pieces.
360 /** Length of one piece.
362 uint32_t pieceLength
;
364 /** Mapping from piece index to its struct.
366 std::map
<uint32_t, PieceStruct
*> pieces
;
368 /** List of active requests. The key is a piece index.
370 std::map
<uint32_t, RequestStruct
*> requests
;
372 /** A permutation of length pieceCount.
374 std::list
<uint32_t> scrambled
;
376 /** Sum of lengths of all files.
378 uint64_t totalLength
;
383 }; // namespace Tairent
387 // vim: ai sw=4 ts=4 noet fdm=marker