move torrent_handle documentation into header file

This commit is contained in:
Arvid Norberg 2013-08-06 02:50:57 +00:00
parent d782fc224c
commit 55ed312b76
5 changed files with 612 additions and 1200 deletions

View File

@ -63,6 +63,12 @@ category_mapping = {
'identify_client.hpp': 'Utility', 'identify_client.hpp': 'Utility',
'thread.hpp': 'Utility', 'thread.hpp': 'Utility',
'ip_filter.hpp': 'Filter', 'ip_filter.hpp': 'Filter',
'session_settings.hpp': 'Settings',
}
category_fun_mapping = {
'min_memory_usage()': 'Settings',
'high_performance_seed()': 'Settings',
} }
def categorize_symbol(name, filename): def categorize_symbol(name, filename):
@ -75,6 +81,9 @@ def categorize_symbol(name, filename):
or name.endswith('error_code_enum'): or name.endswith('error_code_enum'):
return 'Error Codes' return 'Error Codes'
if name in category_fun_mapping:
return category_fun_mapping[name]
return 'Core' return 'Core'
def first_item(itr): def first_item(itr):
@ -624,7 +633,7 @@ def linkify_symbols(string):
w = w[:-1] w = w[:-1]
if w in symbols: if w in symbols:
words[i] = (leading_tabs * '\t') + print_link(words[i].strip(), symbols[w]) + trailing words[i] = (leading_tabs * '\t') + print_link(w, symbols[w]) + trailing
ret.append(' '.join(words)) ret.append(' '.join(words))
return '\n'.join(ret) return '\n'.join(ret)

View File

@ -16,7 +16,8 @@ REFERENCE_TARGETS = \
reference-Bencoding \ reference-Bencoding \
reference-Alerts \ reference-Alerts \
reference-RSS \ reference-RSS \
reference-Filter reference-Filter \
reference-Settings
TARGETS = index \ TARGETS = index \
udp_tracker_protocol \ udp_tracker_protocol \

File diff suppressed because it is too large Load Diff

View File

@ -94,7 +94,7 @@ namespace libtorrent
struct TORRENT_EXPORT session_settings struct TORRENT_EXPORT session_settings
{ {
session_settings(std::string const& user_agent_ = "libtorrent/" session_settings(std::string const& user_agent = "libtorrent/"
LIBTORRENT_VERSION); LIBTORRENT_VERSION);
~session_settings(); ~session_settings();

View File

@ -81,10 +81,21 @@ namespace libtorrent
void throw_invalid_handle(); void throw_invalid_handle();
#endif #endif
// holds the state of a block in a piece. Who we requested
// it from and how far along we are at downloading it.
struct TORRENT_EXPORT block_info struct TORRENT_EXPORT block_info
{ {
enum block_state_t enum block_state_t
{ none, requested, writing, finished }; {
// This block has not been downloaded or requested form any peer.
none,
// The block has been requested, but not completely downloaded yet.
requested,
// The block has been downloaded and is currently queued for being written to disk.
writing,
// The block has been written to disk.
finished
};
private: private:
TORRENT_UNION addr_t TORRENT_UNION addr_t
@ -98,6 +109,7 @@ namespace libtorrent
boost::uint16_t port; boost::uint16_t port;
public: public:
// The peer is the ip address of the peer this block was downloaded from.
void set_peer(tcp::endpoint const& ep) void set_peer(tcp::endpoint const& ep)
{ {
#if TORRENT_USE_IPV6 #if TORRENT_USE_IPV6
@ -109,7 +121,6 @@ namespace libtorrent
addr.v4 = ep.address().to_v4().to_bytes(); addr.v4 = ep.address().to_v4().to_bytes();
port = ep.port(); port = ep.port();
} }
tcp::endpoint peer() const tcp::endpoint peer() const
{ {
#if TORRENT_USE_IPV6 #if TORRENT_USE_IPV6
@ -120,18 +131,18 @@ namespace libtorrent
return tcp::endpoint(address_v4(addr.v4), port); return tcp::endpoint(address_v4(addr.v4), port);
} }
// number of bytes downloaded in this block // the number of bytes that have been received for this block
unsigned bytes_progress:15; unsigned bytes_progress:15;
// the total number of bytes in this block // the total number of bytes in this block.
unsigned block_size:15; unsigned block_size:15;
// the state this block is in (see block_state_t) // the state this block is in (see block_state_t)
unsigned state:2; unsigned state:2;
// the number of peers that has requested this block // the number of peers that is currently requesting this block. Typically this
// typically 0 or 1. If > 1, this block is in // is 0 or 1, but at the end of the torrent blocks may be requested by more peers in parallel to
// end game mode // speed things up.
unsigned num_peers:14; unsigned num_peers:14;
private: private:
#if TORRENT_USE_IPV6 #if TORRENT_USE_IPV6
@ -142,7 +153,11 @@ namespace libtorrent
struct TORRENT_EXPORT partial_piece_info struct TORRENT_EXPORT partial_piece_info
{ {
// the index of the piece in question. ``blocks_in_piece`` is the
// number of blocks in this particular piece. This number will be the same for most pieces, but
// the last piece may have fewer blocks than the standard pieces.
int piece_index; int piece_index;
int blocks_in_piece; int blocks_in_piece;
// the number of blocks in the finished state // the number of blocks in the finished state
int finished; int finished;
@ -150,11 +165,53 @@ namespace libtorrent
int writing; int writing;
// the number of blocks in the requested state // the number of blocks in the requested state
int requested; int requested;
// this is an array of ``blocks_in_piece`` number of
// items. One for each block in the piece.
//
// .. warning:: This is a pointer that points to an array
// that's owned by the session object. The next time
// get_download_queue() is called, it will be invalidated.
block_info* blocks; block_info* blocks;
enum state_t { none, slow, medium, fast }; enum state_t { none, slow, medium, fast };
// the download speed class this piece falls into.
// this is used internally to cluster peers of the same
// speed class together when requesting blocks.
//
// set to either ``fast``, ``medium``, ``slow`` or ``none``. It tells which
// download rate category the peers downloading this piece falls into. ``none`` means that no
// peer is currently downloading any part of the piece. Peers prefer picking pieces from
// the same category as themselves. The reason for this is to keep the number of partially
// downloaded pieces down. Pieces set to ``none`` can be converted into any of ``fast``,
// ``medium`` or ``slow`` as soon as a peer want to download from it.
state_t piece_state; state_t piece_state;
}; };
// You will usually have to store your torrent handles somewhere, since it's the
// object through which you retrieve information about the torrent and aborts the torrent.
//
// .. warning::
// Any member function that returns a value or fills in a value has to
// be made synchronously. This means it has to wait for the main thread
// to complete the query before it can return. This might potentially be
// expensive if done from within a GUI thread that needs to stay responsive.
// Try to avoid quering for information you don't need, and try to do it
// in as few calls as possible. You can get most of the interesting information
// about a torrent from the ``torrent_handle::status()`` call.
//
// The default constructor will initialize the handle to an invalid state. Which
// means you cannot perform any operation on it, unless you first assign it a
// valid handle. If you try to perform any operation on an uninitialized handle,
// it will throw ``invalid_handle``.
//
// .. warning:: All operations on a torrent_handle may throw libtorrent_exception
// exception, in case the handle is no longer refering to a torrent. There is
// one exception is_valid() will never throw.
// Since the torrents are processed by a background thread, there is no
// guarantee that a handle will remain valid between two calls.
//
struct TORRENT_EXPORT torrent_handle struct TORRENT_EXPORT torrent_handle
{ {
friend class invariant_access; friend class invariant_access;
@ -165,35 +222,125 @@ namespace libtorrent
torrent_handle() {} torrent_handle() {}
// flags for add_piece().
enum flags_t { overwrite_existing = 1 }; enum flags_t { overwrite_existing = 1 };
// This function will write ``data`` to the storage as piece ``piece``, as if it had
// been downloaded from a peer. ``data`` is expected to point to a buffer of as many
// bytes as the size of the specified piece. The data in the buffer is copied and
// passed on to the disk IO thread to be written at a later point.
//
// By default, data that's already been downloaded is not overwritten by this buffer. If
// you trust this data to be correct (and pass the piece hash check) you may pass the
// overwrite_existing flag. This will instruct libtorrent to overwrite any data that
// may already have been downloaded with this data.
//
// Since the data is written asynchronously, you may know that is passed or failed the
// hash check by waiting for piece_finished_alert or hash_failed_alert.
void add_piece(int piece, char const* data, int flags = 0) const; void add_piece(int piece, char const* data, int flags = 0) const;
// This function starts an asynchronous read operation of the specified piece from
// this torrent. You must have completed the download of the specified piece before
// calling this function.
//
// When the read operation is completed, it is passed back through an alert,
// read_piece_alert_. Since this alert is a reponse to an explicit call, it will
// always be posted, regardless of the alert mask.
//
// Note that if you read multiple pieces, the read operations are not guaranteed to
// finish in the same order as you initiated them.
void read_piece(int piece) const; void read_piece(int piece) const;
// Returns true if this piece has been completely downloaded, and false otherwise.
bool have_piece(int piece) const; bool have_piece(int piece) const;
void get_full_peer_list(std::vector<peer_list_entry>& v) const; void get_full_peer_list(std::vector<peer_list_entry>& v) const;
// takes a reference to a vector that will be cleared and filled
// with one entry for each peer connected to this torrent, given the handle is valid. If the
// torrent_handle_ is invalid, it will throw libtorrent_exception exception. Each entry in
// the vector contains information about that particular peer. See peer_info.
void get_peer_info(std::vector<peer_info>& v) const; void get_peer_info(std::vector<peer_info>& v) const;
enum status_flags_t enum status_flags_t
{ {
// calculates ``distributed_copies``, ``distributed_full_copies`` and ``distributed_fraction``.
query_distributed_copies = 1, query_distributed_copies = 1,
// includes partial downloaded blocks in ``total_done`` and ``total_wanted_done``.
query_accurate_download_counters = 2, query_accurate_download_counters = 2,
// includes ``last_seen_complete``.
query_last_seen_complete = 4, query_last_seen_complete = 4,
// includes ``pieces``.
query_pieces = 8, query_pieces = 8,
// includes ``verified_pieces`` (only applies to torrents in *seed mode*).
query_verified_pieces = 16, query_verified_pieces = 16,
// includes ``torrent_file``, which is all the static information from the .torrent file.
query_torrent_file = 32, query_torrent_file = 32,
// includes ``name``, the name of the torrent. This is either derived from the .torrent
// file, or from the ``&dn=`` magnet link argument or possibly some other source. If the
// name of the torrent is not known, this is an empty string.
query_name = 64, query_name = 64,
// includes ``save_path``, the path to the directory the files of the torrent are saved to.
query_save_path = 128, query_save_path = 128,
}; };
// the flags specify which fields are calculated. By default everything // ``status()`` will return a structure with information about the status of this
// is included, you may save CPU by not querying fields you don't need // torrent. If the torrent_handle_ is invalid, it will throw libtorrent_exception_ exception.
// See torrent_status_. The ``flags`` argument filters what information is returned
// in the torrent_status. Some information in there is relatively expensive to calculate, and
// if you're not interested in it (and see performance issues), you can filter them out.
//
// By default everything is included. The flags you can use to decide what to *include* are
// defined in the status_flags_t enum.
torrent_status status(boost::uint32_t flags = 0xffffffff) const; torrent_status status(boost::uint32_t flags = 0xffffffff) const;
// ``get_download_queue()`` takes a non-const reference to a vector which it will fill with
// information about pieces that are partially downloaded or not downloaded at all but partially
// requested. See partial_piece_info for the fields in the returned vector.
void get_download_queue(std::vector<partial_piece_info>& queue) const; void get_download_queue(std::vector<partial_piece_info>& queue) const;
// flags for set_piece_deadline().
enum deadline_flags { alert_when_available = 1 }; enum deadline_flags { alert_when_available = 1 };
// This function sets or resets the deadline associated with a specific piece
// index (``index``). libtorrent will attempt to download this entire piece before
// the deadline expires. This is not necessarily possible, but pieces with a more
// recent deadline will always be prioritized over pieces with a deadline further
// ahead in time. The deadline (and flags) of a piece can be changed by calling this
// function again.
//
// The ``flags`` parameter can be used to ask libtorrent to send an alert once the
// piece has been downloaded, by passing alert_when_available. When set, the
// read_piece_alert_ alert will be delivered, with the piece data, when it's downloaded.
//
// If the piece is already downloaded when this call is made, nothing happens, unless
// the alert_when_available flag is set, in which case it will do the same thing
// as calling read_piece() for ``index``.
//
// ``deadline`` is the number of milliseconds until this piece should be completed.
//
// ``reset_piece_deadline`` removes the deadline from the piece. If it hasn't already
// been downloaded, it will no longer be considered a priority.
//
void set_piece_deadline(int index, int deadline, int flags = 0) const; void set_piece_deadline(int index, int deadline, int flags = 0) const;
void reset_piece_deadline(int index) const; void reset_piece_deadline(int index) const;
// This sets the bandwidth priority of this torrent. The priority of a torrent determines
// how much bandwidth its peers are assigned when distributing upload and download rate quotas.
// A high number gives more bandwidth. The priority must be within the range [0, 255].
//
// The default priority is 0, which is the lowest priority.
//
// To query the priority of a torrent, use the ``torrent_handle::status()`` call.
//
// Torrents with higher priority will not nececcarily get as much bandwidth as they can
// consume, even if there's is more quota. Other peers will still be weighed in when
// bandwidth is being distributed. With other words, bandwidth is not distributed strictly
// in order of priority, but the priority is used as a weight.
//
// Peers whose Torrent has a higher priority will take precedence when distributing unchoke slots.
// This is a strict prioritization where every interested peer on a high priority torrent will
// be unchoked before any other, lower priority, torrents have any peers unchoked.
void set_priority(int prio) const; void set_priority(int prio) const;
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
@ -210,18 +357,62 @@ namespace libtorrent
piece_granularity = 1 piece_granularity = 1
}; };
// This function fills in the supplied vector with the the number of bytes downloaded
// of each file in this torrent. The progress values are ordered the same as the files
// in the `torrent_info`_. This operation is not very cheap. Its complexity is *O(n + mj)*.
// Where *n* is the number of files, *m* is the number of downloading pieces and *j*
// is the number of blocks in a piece.
//
// The ``flags`` parameter can be used to specify the granularity of the file progress. If
// left at the default value of 0, the progress will be as accurate as possible, but also
// more expensive to calculate. If ``torrent_handle::piece_granularity`` is specified,
// the progress will be specified in piece granularity. i.e. only pieces that have been
// fully downloaded and passed the hash check count. When specifying piece granularity,
// the operation is a lot cheaper, since libtorrent already keeps track of this internally
// and no calculation is required.
void file_progress(std::vector<size_type>& progress, int flags = 0) const; void file_progress(std::vector<size_type>& progress, int flags = 0) const;
// If the torrent is in an error state (i.e. ``torrent_status::error`` is non-empty), this
// will clear the error and start the torrent again.
void clear_error() const; void clear_error() const;
// ``trackers()`` will return the list of trackers for this torrent. The
// announce entry contains both a string ``url`` which specify the announce url
// for the tracker as well as an int ``tier``, which is specifies the order in
// which this tracker is tried. If you want libtorrent to use another list of
// trackers for this torrent, you can use ``replace_trackers()`` which takes
// a list of the same form as the one returned from ``trackers()`` and will
// replace it. If you want an immediate effect, you have to call
// force_reannounce(). See announce_entry.
//
// ``add_tracker()`` will look if the specified tracker is already in the set.
// If it is, it doesn't do anything. If it's not in the current set of trackers,
// it will insert it in the tier specified in the announce_entry.
//
// The updated set of trackers will be saved in the resume data, and when a torrent
// is started with resume data, the trackers from the resume data will replace the
// original ones.
std::vector<announce_entry> trackers() const; std::vector<announce_entry> trackers() const;
void replace_trackers(std::vector<announce_entry> const&) const; void replace_trackers(std::vector<announce_entry> const&) const;
void add_tracker(announce_entry const&) const; void add_tracker(announce_entry const&) const;
// ``add_url_seed()`` adds another url to the torrent's list of url seeds. If the
// given url already exists in that list, the call has no effect. The torrent
// will connect to the server and try to download pieces from it, unless it's
// paused, queued, checking or seeding. ``remove_url_seed()`` removes the given
// url if it exists already. ``url_seeds()`` return a set of the url seeds
// currently in this torrent. Note that urls that fails may be removed
// automatically from the list.
//
// See `HTTP seeding`_ for more information.
void add_url_seed(std::string const& url) const; void add_url_seed(std::string const& url) const;
void remove_url_seed(std::string const& url) const; void remove_url_seed(std::string const& url) const;
std::set<std::string> url_seeds() const; std::set<std::string> url_seeds() const;
// These functions are identical as the ``*_url_seed()`` variants, but they
// operate on BEP 17 web seeds instead of BEP 19.
//
// See `HTTP seeding`_ for more information.
void add_http_seed(std::string const& url) const; void add_http_seed(std::string const& url) const;
void remove_http_seed(std::string const& url) const; void remove_http_seed(std::string const& url) const;
std::set<std::string> http_seeds() const; std::set<std::string> http_seeds() const;
@ -229,43 +420,275 @@ namespace libtorrent
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> const& ext void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> const& ext
, void* userdata = 0); , void* userdata = 0);
// ``set_metadata`` expects the *info* section of metadata. i.e. The buffer passed in will be
// hashed and verified against the info-hash. If it fails, a ``metadata_failed_alert`` will be
// generated. If it passes, a ``metadata_received_alert`` is generated. The function returns
// true if the metadata is successfully set on the torrent, and false otherwise. If the torrent
// already has metadata, this function will not affect the torrent, and false will be returned.
bool set_metadata(char const* metadata, int size) const; bool set_metadata(char const* metadata, int size) const;
// Returns true if this handle refers to a valid torrent and false if it hasn't been initialized
// or if the torrent it refers to has been aborted. Note that a handle may become invalid after
// it has been added to the session. Usually this is because the storage for the torrent is
// somehow invalid or if the filenames are not allowed (and hence cannot be opened/created) on
// your filesystem. If such an error occurs, a file_error_alert_ is generated and all handles
// that refers to that torrent will become invalid.
bool is_valid() const; bool is_valid() const;
// flags for pause()
enum pause_flags_t { graceful_pause = 1 }; enum pause_flags_t { graceful_pause = 1 };
// ``pause()``, and ``resume()`` will disconnect all peers and reconnect all peers respectively.
// When a torrent is paused, it will however remember all share ratios to all peers and remember
// all potential (not connected) peers. Torrents may be paused automatically if there is a file
// error (e.g. disk full) or something similar. See file_error_alert_.
//
// To know if a torrent is paused or not, call ``torrent_handle::status()`` and inspect
// ``torrent_status::paused``.
//
// The ``flags`` argument to pause can be set to ``torrent_handle::graceful_pause`` which will
// delay the disconnect of peers that we're still downloading outstanding requests from. The torrent
// will not accept any more requests and will disconnect all idle peers. As soon as a peer is
// done transferring the blocks that were requested from it, it is disconnected. This is a graceful
// shut down of the torrent in the sense that no downloaded bytes are wasted.
//
// torrents that are auto-managed may be automatically resumed again. It does not make sense to
// pause an auto-managed torrent without making it not automanaged first. Torrents are auto-managed
// by default when added to the session. For more information, see queuing_.
void pause(int flags = 0) const; void pause(int flags = 0) const;
void resume() const; void resume() const;
// Explicitly sets the upload mode of the torrent. In upload mode, the torrent will not
// request any pieces. If the torrent is auto managed, it will automatically be taken out
// of upload mode periodically (see ``session_settings::optimistic_disk_retry``). Torrents
// are automatically put in upload mode whenever they encounter a disk write error.
//
// ``m`` should be true to enter upload mode, and false to leave it.
//
// To test if a torrent is in upload mode, call ``torrent_handle::status()`` and inspect
// ``torrent_status::upload_mode``.
void set_upload_mode(bool b) const; void set_upload_mode(bool b) const;
// Enable or disable share mode for this torrent. When in share mode, the torrent will
// not necessarily be downloaded, especially not the whole of it. Only parts that are likely
// to be distributed to more than 2 other peers are downloaded, and only if the previous
// prediction was correct.
void set_share_mode(bool b) const; void set_share_mode(bool b) const;
// Instructs libtorrent to flush all the disk caches for this torrent and close all
// file handles. This is done asynchronously and you will be notified that it's complete
// through cache_flushed_alert_.
//
// Note that by the time you get the alert, libtorrent may have cached more data for the
// torrent, but you are guaranteed that whatever cached data libtorrent had by the time
// you called ``torrent_handle::flush_cache()`` has been written to disk.
void flush_cache() const; void flush_cache() const;
// Set to true to apply the session global IP filter to this torrent (which is the
// default). Set to false to make this torrent ignore the IP filter.
void apply_ip_filter(bool b) const; void apply_ip_filter(bool b) const;
// ``force_recheck`` puts the torrent back in a state where it assumes to have no resume data.
// All peers will be disconnected and the torrent will stop announcing to the tracker. The torrent
// will be added to the checking queue, and will be checked (all the files will be read and
// compared to the piece hashes). Once the check is complete, the torrent will start connecting
// to peers again, as normal.
void force_recheck() const; void force_recheck() const;
enum save_resume_flags_t { flush_disk_cache = 1, save_info_dict = 2 }; enum save_resume_flags_t { flush_disk_cache = 1, save_info_dict = 2 };
// ``save_resume_data()`` generates fast-resume data and returns it as an entry_. This entry_
// is suitable for being bencoded. For more information about how fast-resume works, see `fast resume`_.
//
// The ``flags`` argument is a bitmask of flags ORed together. If the flag ``torrent_handle::flush_cache``
// is set, the disk cache will be flushed before creating the resume data. This avoids a problem with
// file timestamps in the resume data in case the cache hasn't been flushed yet.
//
// If the flag ``torrent_handle::save_info_dict`` is set, the resume data will contain the metadata
// from the torrent file as well. This is default for any torrent that's added without a torrent
// file (such as a magnet link or a URL).
//
// This operation is asynchronous, ``save_resume_data`` will return immediately. The resume data
// is delivered when it's done through an save_resume_data_alert.
//
// The fast resume data will be empty in the following cases:
//
// 1. The torrent handle is invalid.
// 2. The torrent is checking (or is queued for checking) its storage, it will obviously
// not be ready to write resume data.
// 3. The torrent hasn't received valid metadata and was started without metadata
// (see libtorrent's `metadata from peers`_ extension)
//
// Note that by the time you receive the fast resume data, it may already be invalid if the torrent
// is still downloading! The recommended practice is to first pause the session, then generate the
// fast resume data, and then close it down. Make sure to not remove_torrent() before you receive
// the save_resume_data_alert though. There's no need to pause when saving intermittent resume data.
//
//.. warning:: If you pause every torrent individually instead of pausing the session, every torrent
// will have its paused state saved in the resume data!
//
//.. warning:: The resume data contains the modification timestamps for all files. If one file has
// been modified when the torrent is added again, the will be rechecked. When shutting down, make
// sure to flush the disk cache before saving the resume data. This will make sure that the file
// timestamps are up to date and won't be modified after saving the resume data. The recommended way
// to do this is to pause the torrent, which will flush the cache and disconnect all peers.
//
//.. note:: It is typically a good idea to save resume data whenever a torrent is completed or paused. In those
// cases you don't need to pause the torrent or the session, since the torrent will do no more writing
// to its files. If you save resume data for torrents when they are paused, you can accelerate the
// shutdown process by not saving resume data again for paused torrents. Completed torrents should
// have their resume data saved when they complete and on exit, since their statistics might be updated.
//
// In full allocation mode the reume data is never invalidated by subsequent
// writes to the files, since pieces won't move around. This means that you don't need to
// pause before writing resume data in full or sparse mode. If you don't, however, any data written to
// disk after you saved resume data and before the session_ closed is lost.
//
// It also means that if the resume data is out dated, libtorrent will not re-check the files, but assume
// that it is fairly recent. The assumption is that it's better to loose a little bit than to re-check
// the entire file.
//
// It is still a good idea to save resume data periodically during download as well as when
// closing down.
//
// Example code to pause and save resume data for all torrents and wait for the alerts::
//
// extern int outstanding_resume_data; // global counter of outstanding resume data
// std::vector<torrent_handle> handles = ses.get_torrents();
// ses.pause();
// for (std::vector<torrent_handle>::iterator i = handles.begin();
// i != handles.end(); ++i)
// {
// torrent_handle& h = *i;
// if (!h.is_valid()) continue;
// torrent_status s = h.status();
// if (!s.has_metadata) continue;
// if (!s.need_save_resume_data()) continue;
//
// h.save_resume_data();
// ++outstanding_resume_data;
// }
//
// while (outstanding_resume_data > 0)
// {
// alert const* a = ses.wait_for_alert(seconds(10));
//
// // if we don't get an alert within 10 seconds, abort
// if (a == 0) break;
//
// std::auto_ptr<alert> holder = ses.pop_alert();
//
// if (alert_cast<save_resume_data_failed_alert>(a))
// {
// process_alert(a);
// --outstanding_resume_data;
// continue;
// }
//
// save_resume_data_alert const* rd = alert_cast<save_resume_data_alert>(a);
// if (rd == 0)
// {
// process_alert(a);
// continue;
// }
//
// torrent_handle h = rd->handle;
// torrent_status st = h.status(torrent_handle::query_save_path | torrent_handle::query_name);
// std::ofstream out((st.save_path
// + "/" + st.name + ".fastresume").c_str()
// , std::ios_base::binary);
// out.unsetf(std::ios_base::skipws);
// bencode(std::ostream_iterator<char>(out), *rd->resume_data);
// --outstanding_resume_data;
// }
//
//.. note:: Note how ``outstanding_resume_data`` is a global counter in this example.
// This is deliberate, otherwise there is a race condition for torrents that
// was just asked to save their resume data, they posted the alert, but it has
// not been received yet. Those torrents would report that they don't need to
// save resume data again, and skipped by the initial loop, and thwart the counter
// otherwise.
void save_resume_data(int flags = 0) const; void save_resume_data(int flags = 0) const;
// This function returns true if any whole chunk has been downloaded since the
// torrent was first loaded or since the last time the resume data was saved. When
// saving resume data periodically, it makes sense to skip any torrent which hasn't
// downloaded anything since the last time.
//
//.. note:: A torrent's resume data is considered saved as soon as the alert
// is posted. It is important to make sure this alert is received and handled
// in order for this function to be meaningful.
bool need_save_resume_data() const; bool need_save_resume_data() const;
// changes whether the torrent is auto managed or not. For more info,
// see queuing_.
void auto_managed(bool m) const; void auto_managed(bool m) const;
// Every torrent that is added is assigned a queue position exactly one greater than
// the greatest queue position of all existing torrents. Torrents that are being
// seeded have -1 as their queue position, since they're no longer in line to be downloaded.
//
// When a torrent is removed or turns into a seed, all torrents with greater queue positions
// have their positions decreased to fill in the space in the sequence.
//
// ``queue_position()`` returns the torrent's position in the download queue. The torrents
// with the smallest numbers are the ones that are being downloaded. The smaller number,
// the closer the torrent is to the front of the line to be started.
//
// The queue position is also available in the torrent_status.
//
// The ``queue_position_*()`` functions adjust the torrents position in the queue. Up means
// closer to the front and down means closer to the back of the queue. Top and bottom refers
// to the front and the back of the queue respectively.
int queue_position() const; int queue_position() const;
void queue_position_up() const; void queue_position_up() const;
void queue_position_down() const; void queue_position_down() const;
void queue_position_top() const; void queue_position_top() const;
void queue_position_bottom() const; void queue_position_bottom() const;
// Sets or gets the flag that derermines if countries should be resolved for the peers of this
// torrent. It defaults to false. If it is set to true, the peer_info_ structure for the peers
// in this torrent will have their ``country`` member set. See peer_info_ for more information
// on how to interpret this field.
void resolve_countries(bool r); void resolve_countries(bool r);
bool resolve_countries() const; bool resolve_countries() const;
// For SSL torrents, use this to specify a path to a .pem file to use as this client's certificate.
// The certificate must be signed by the certificate in the .torrent file to be valid.
//
// ``cert`` is a path to the (signed) certificate in .pem format corresponding to this torrent.
//
// ``private_key`` is a path to the private key for the specified certificate. This must be in .pem
// format.
//
// ``dh_params`` is a path to the Diffie-Hellman parameter file, which needs to be in .pem format.
// You can generate this file using the openssl command like this:
// ``openssl dhparam -outform PEM -out dhparams.pem 512``.
//
// ``passphrase`` may be specified if the private key is encrypted and requires a passphrase to
// be decrypted.
//
// Note that when a torrent first starts up, and it needs a certificate, it will suspend connecting
// to any peers until it has one. It's typically desirable to resume the torrent after setting the
// ssl certificate.
//
// If you receive a torrent_need_cert_alert_, you need to call this to provide a valid cert. If you
// don't have a cert you won't be allowed to connect to any peers.
void set_ssl_certificate(std::string const& certificate void set_ssl_certificate(std::string const& certificate
, std::string const& private_key , std::string const& private_key
, std::string const& dh_params , std::string const& dh_params
, std::string const& passphrase = ""); , std::string const& passphrase = "");
// Returns the storage implementation for this torrent. This depends on the
// storage contructor function that was passed to add_torrent.
storage_interface* get_storage_impl() const; storage_interface* get_storage_impl() const;
// Returns a pointer to the torrent_info object associated with this torrent. The
// torrent_info object is a copy of the internal object. If the torrent doesn't
// have metadata, the object being returned will not be fully filled in.
// The torrent may be in a state without metadata only if
// it was started without a .torrent file, e.g. by using the libtorrent extension of
// just supplying a tracker and info-hash.
boost::intrusive_ptr<torrent_info> torrent_file() const; boost::intrusive_ptr<torrent_info> torrent_file() const;
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
@ -337,6 +760,12 @@ namespace libtorrent
TORRENT_DEPRECATED_PREFIX TORRENT_DEPRECATED_PREFIX
void filter_files(std::vector<bool> const& files) const TORRENT_DEPRECATED; void filter_files(std::vector<bool> const& files) const TORRENT_DEPRECATED;
// ``use_interface()`` sets the network interface this torrent will use when it opens outgoing
// connections. By default, it uses the same interface as the session_ uses to listen on. The
// parameter must be a string containing one or more, comma separated, ip-address (either an
// IPv4 or IPv6 address). When specifying multiple interfaces, the torrent will round-robin
// which interface to use for each outgoing conneciton. This is useful for clients that are
// multi-homed.
TORRENT_DEPRECATED_PREFIX TORRENT_DEPRECATED_PREFIX
void use_interface(const char* net_interface) const TORRENT_DEPRECATED; void use_interface(const char* net_interface) const TORRENT_DEPRECATED;
@ -348,26 +777,86 @@ namespace libtorrent
// ================ end deprecation ============ // ================ end deprecation ============
#endif #endif
// Fills the specified ``std::vector<int>`` with the availability for each
// piece in this torrent. libtorrent does not keep track of availability for
// seeds, so if the torrent is seeding the availability for all pieces is
// reported as 0.
//
// The piece availability is the number of peers that we are connected that has
// advertized having a particular piece. This is the information that libtorrent
// uses in order to prefer picking rare pieces.
void piece_availability(std::vector<int>& avail) const; void piece_availability(std::vector<int>& avail) const;
// priority must be within the range [0, 7] // These functions are used to set and get the prioritiy of individual pieces.
// By default all pieces have priority 1. That means that the random rarest
// first algorithm is effectively active for all pieces. You may however
// change the priority of individual pieces. There are 8 different priority
// levels:
//
// 0. piece is not downloaded at all
// 1. normal priority. Download order is dependent on availability
// 2. higher than normal priority. Pieces are preferred over pieces with
// the same availability, but not over pieces with lower availability
// 3. pieces are as likely to be picked as partial pieces.
// 4. pieces are preferred over partial pieces, but not over pieces with
// lower availability
// 5. *currently the same as 4*
// 6. piece is as likely to be picked as any piece with availability 1
// 7. maximum priority, availability is disregarded, the piece is preferred
// over any other piece with lower priority
//
// The exact definitions of these priorities are implementation details, and
// subject to change. The interface guarantees that higher number means higher
// priority, and that 0 means do not download.
//
// ``piece_priority`` sets or gets the priority for an individual piece,
// specified by ``index``.
//
// ``prioritize_pieces`` takes a vector of integers, one integer per piece in
// the torrent. All the piece priorities will be updated with the priorities
// in the vector.
//
// ``piece_priorities`` returns a vector with one element for each piece in the
// torrent. Each element is the current priority of that piece.
void piece_priority(int index, int priority) const; void piece_priority(int index, int priority) const;
int piece_priority(int index) const; int piece_priority(int index) const;
void prioritize_pieces(std::vector<int> const& pieces) const; void prioritize_pieces(std::vector<int> const& pieces) const;
std::vector<int> piece_priorities() const; std::vector<int> piece_priorities() const;
// priority must be within the range [0, 7] // ``index`` must be in the range [0, number_of_files).
//
// ``file_priority()`` queries or sets the priority of file ``index``.
//
// ``prioritize_files()`` takes a vector that has at as many elements as there are
// files in the torrent. Each entry is the priority of that file. The function
// sets the priorities of all the pieces in the torrent based on the vector.
//
// ``file_priorities()`` returns a vector with the priorities of all files.
//
// The priority values are the same as for piece_priority().
//
// Whenever a file priority is changed, all other piece priorities are reset
// to match the file priorities. In order to maintain sepcial priorities for
// particular pieces, piece_priority() has to be called again for those pieces.
//
// You cannot set the file priorities on a torrent that does not yet
// have metadata or a torrent that is a seed. ``file_priority(int, int)`` and
// prioritize_files() are both no-ops for such torrents.
void file_priority(int index, int priority) const; void file_priority(int index, int priority) const;
int file_priority(int index) const; int file_priority(int index) const;
void prioritize_files(std::vector<int> const& files) const; void prioritize_files(std::vector<int> const& files) const;
std::vector<int> file_priorities() const; std::vector<int> file_priorities() const;
// forces this torrent to reannounce // ``force_reannounce()`` will force this torrent to do another tracker request, to receive new
// (make a rerequest from the tracker) // peers. The second overload of ``force_reannounce`` that takes a ``time_duration`` as
// argument will schedule a reannounce in that amount of time from now.
//
// If the tracker's ``min_interval`` has not passed since the last announce, the forced
// announce will be scheduled to happen immediately as the ``min_interval`` expires. This is
// to honor trackers minimum re-announce interval settings.
//
// ``force_dht_announce`` will announce the torrent to the DHT immediately.
void force_reannounce() const; void force_reannounce() const;
// announces this torrent to the DHT immediately
void force_dht_announce() const; void force_dht_announce() const;
// forces a reannounce in the specified amount of time. // forces a reannounce in the specified amount of time.
@ -376,32 +865,113 @@ namespace libtorrent
// timed out. // timed out.
void force_reannounce(boost::posix_time::time_duration) const; void force_reannounce(boost::posix_time::time_duration) const;
// performs a scrape request // ``scrape_tracker()`` will send a scrape request to the tracker. A scrape request queries the
// tracker for statistics such as total number of incomplete peers, complete peers, number of
// downloads etc.
//
// This request will specifically update the ``num_complete`` and ``num_incomplete`` fields in
// the torrent_status_ struct once it completes. When it completes, it will generate a
// scrape_reply_alert_. If it fails, it will generate a scrape_failed_alert_.
void scrape_tracker() const; void scrape_tracker() const;
// ``set_upload_limit`` will limit the upload bandwidth used by this particular torrent to the
// limit you set. It is given as the number of bytes per second the torrent is allowed to upload.
// ``set_download_limit`` works the same way but for download bandwidth instead of upload bandwidth.
// Note that setting a higher limit on a torrent then the global limit (``session_settings::upload_rate_limit``)
// will not override the global rate limit. The torrent can never upload more than the global rate
// limit.
//
// ``upload_limit`` and ``download_limit`` will return the current limit setting, for upload and
// download, respectively.
void set_upload_limit(int limit) const; void set_upload_limit(int limit) const;
int upload_limit() const; int upload_limit() const;
void set_download_limit(int limit) const; void set_download_limit(int limit) const;
int download_limit() const; int download_limit() const;
// ``set_sequential_download()`` enables or disables *sequential download*. When enabled, the piece
// picker will pick pieces in sequence instead of rarest first.
//
// Enabling sequential download will affect the piece distribution negatively in the swarm. It should be
// used sparingly.
void set_sequential_download(bool sd) const; void set_sequential_download(bool sd) const;
// manually connect a peer // ``connect_peer()`` is a way to manually connect to peers that one believe is a part of the
// torrent. If the peer does not respond, or is not a member of this torrent, it will simply
// be disconnected. No harm can be done by using this other than an unnecessary connection
// attempt is made. If the torrent is uninitialized or in queued or checking mode, this
// will throw libtorrent_exception_. The second (optional) argument will be bitwised ORed into
// the source mask of this peer. Typically this is one of the source flags in peer_info_.
// i.e. ``tracker``, ``pex``, ``dht`` etc.
void connect_peer(tcp::endpoint const& adr, int source = 0) const; void connect_peer(tcp::endpoint const& adr, int source = 0) const;
// -1 means unlimited unchokes // ``set_max_uploads()`` sets the maximum number of peers that's unchoked at the same time on this
// torrent. If you set this to -1, there will be no limit. This defaults to infinite. The primary
// setting controlling this is the global unchoke slots limit, set by unchoke_slots_limit
// in session_settings.
//
// ``max_uploads()`` returns the current settings.
void set_max_uploads(int max_uploads) const; void set_max_uploads(int max_uploads) const;
int max_uploads() const; int max_uploads() const;
// -1 means unlimited connections // ``set_max_connections()`` sets the maximum number of connection this torrent will open. If all
// connections are used up, incoming connections may be refused or poor connections may be closed.
// This must be at least 2. The default is unlimited number of connections. If -1 is given to the
// function, it means unlimited. There is also a global limit of the number of connections, set
// by ``connections_limit`` in session_settings_.
//
// ``max_connections()`` returns the current settings.
void set_max_connections(int max_connections) const; void set_max_connections(int max_connections) const;
int max_connections() const; int max_connections() const;
// sets a username and password that will be sent along in the HTTP-request
// of the tracker announce. Set this if the tracker requires authorization.
void set_tracker_login(std::string const& name void set_tracker_login(std::string const& name
, std::string const& password) const; , std::string const& password) const;
// post condition: save_path() == save_path if true is returned // Moves the file(s) that this torrent are currently seeding from or downloading to. If
// the given ``save_path`` is not located on the same drive as the original save path,
// the files will be copied to the new drive and removed from their original location.
// This will block all other disk IO, and other torrents download and upload rates may
// drop while copying the file.
//
// Since disk IO is performed in a separate thread, this operation is also asynchronous.
// Once the operation completes, the ``storage_moved_alert`` is generated, with the new
// path as the message. If the move fails for some reason, ``storage_moved_failed_alert``
// is generated instead, containing the error message.
//
// The ``flags`` argument determines the behavior of the copying/moving of the files
// in the torrent. see move_flags_t.
//
// * always_replace_files = 0
// * fail_if_exist = 1
// * dont_replace = 2
//
// ``always_replace_files`` is the default and replaces any file that exist in both the
// source directory and the target directory.
//
// ``fail_if_exist`` first check to see that none of the copy operations would cause an
// overwrite. If it would, it will fail. Otherwise it will proceed as if it was in
// ``always_replace_files`` mode. Note that there is an inherent race condition here.
// If the files in the target directory appear after the check but before the copy
// or move completes, they will be overwritten. When failing because of files already
// existing in the target path, the ``error`` of ``move_storage_failed_alert`` is set
// to ``boost::system::errc::file_exists``.
//
// The intention is that a client may use this as a probe, and if it fails, ask the user
// which mode to use. The client may then re-issue the ``move_storage`` call with one
// of the other modes.
//
// ``dont_replace`` always takes the existing file in the target directory, if there is
// one. The source files will still be removed in that case.
//
// Files that have been renamed to have absolute pahts are not moved by this function.
// Keep in mind that files that don't belong to the torrent but are stored in the torrent's
// directory may be moved as well. This goes for files that have been renamed to
// absolute paths that still end up inside the save path.
void move_storage(std::string const& save_path, int flags = 0) const; void move_storage(std::string const& save_path, int flags = 0) const;
// Renames the file with the given index asynchronously. The rename operation is complete
// when either a file_renamed_alert or file_rename_failed_alert is posted.
void rename_file(int index, std::string const& new_name) const; void rename_file(int index, std::string const& new_name) const;
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
@ -416,8 +986,11 @@ namespace libtorrent
#endif // TORRENT_NO_DEPRECATE #endif // TORRENT_NO_DEPRECATE
#endif // TORRENT_USE_WSTRING #endif // TORRENT_USE_WSTRING
// Enables or disabled super seeding/initial seeding for this torrent. The torrent
// needs to be a seed for this to take effect.
void super_seeding(bool on) const; void super_seeding(bool on) const;
// ``info_hash()`` returns the info-hash for the torrent.
sha1_hash info_hash() const; sha1_hash info_hash() const;
bool operator==(const torrent_handle& h) const bool operator==(const torrent_handle& h) const
@ -429,6 +1002,11 @@ namespace libtorrent
bool operator<(const torrent_handle& h) const bool operator<(const torrent_handle& h) const
{ return m_torrent.lock() < h.m_torrent.lock(); } { return m_torrent.lock() < h.m_torrent.lock(); }
// This function is intended only for use by plugins and the alert dispatch function. Any code
// that runs in libtorrent's network thread may not use the public API of torrent_handle.
// Doing so results in a dead-lock. For such routines, the ``native_handle`` gives access to the
// underlying type representing the torrent. This type does not have a stable API and should
// be relied on as little as possible.
boost::shared_ptr<torrent> native_handle() const; boost::shared_ptr<torrent> native_handle() const;
private: private: